From a1bf9cf30acde3f2bb4d07274e263fa6d8c6cca1 Mon Sep 17 00:00:00 2001 From: "Alexander \"Arav\" Andreev" Date: Sun, 6 Aug 2023 03:17:18 +0400 Subject: [PATCH] Use flags instead of config file. Also replaced HttpServer with a new code. --- cmd/dwelling-radio/main.go | 27 +++++++++++---------------- init/radio.service | 7 ++++++- internal/http/handlers.go | 26 ++++++++++++++++---------- internal/http/http.go | 29 +++++++++++++++++++++++++++-- 4 files changed, 60 insertions(+), 29 deletions(-) diff --git a/cmd/dwelling-radio/main.go b/cmd/dwelling-radio/main.go index 7f38df4..937d738 100644 --- a/cmd/dwelling-radio/main.go +++ b/cmd/dwelling-radio/main.go @@ -1,7 +1,6 @@ package main import ( - "dwelling-radio/internal/configuration" ihttp "dwelling-radio/internal/http" "dwelling-radio/internal/radio" "dwelling-radio/web" @@ -18,7 +17,12 @@ import ( ) var ( - configPath *string = flag.String("conf", "config.yaml", "path to configuration file") + listenAddress = flag.String("listen", "/var/run/dwelling-radio/sock", "listen address (ip:port|unix_path)") + icecastUrl = flag.String("ic-url", "", "URL to an Icecast's status-json.xsl") + icecastPlaylistPath = flag.String("ic-playlist", "/var/log/icecast/playlist.log", "path to an Icecast's playlist.log file") + filelistPath = flag.String("filelist", "/srv/radio/filelist.html", "path to a filelist.html file") + mostListenedSongPath = flag.String("mls-file", "/mnt/data/appdata/mostlistenedsong", "path to a file that stores info about the most listened song") + songListLen = flag.Int("lst-len", 10, "number of songs to show in last N songs table") showVersion *bool = flag.Bool("v", false, "show version") ) @@ -34,24 +38,19 @@ func main() { return } - config, err := configuration.Load(*configPath) - if err != nil { - log.Fatalln(err) - } - - if data, err := os.ReadFile(config.MostListenedSongPath); err == nil { + if data, err := os.ReadFile(*mostListenedSongPath); err == nil { if err := radio.LoadMostListenedSong(data); err != nil { log.Fatalln(err) } } playlistWatcher := radio.NewPlaylistLogWatcher() - if err := playlistWatcher.Watch(config.Icecast.Playlist, config.ListLastNSongs); err != nil { + if err := playlistWatcher.Watch(*icecastPlaylistPath, *songListLen); err != nil { log.Fatalln(err) } defer playlistWatcher.Close() - hand := ihttp.NewHandlers(config) + hand := ihttp.NewHandlers(*icecastUrl, *icecastPlaylistPath, *filelistPath, *songListLen) r := httpr.New() r.Handler(http.MethodGet, "/", hand.Index) @@ -70,20 +69,16 @@ func main() { srv := ihttp.NewHttpServer(r) - if err := srv.Start(config.SplitNetworkAddress()); err != nil { + if err := srv.Start(*listenAddress); err != nil { log.Fatalln(err) } - if typ, addr := config.SplitNetworkAddress(); typ == "unix" { - defer os.Remove(addr) - } - doneSignal := make(chan os.Signal, 1) signal.Notify(doneSignal, os.Interrupt, syscall.SIGINT, syscall.SIGTERM, syscall.SIGSEGV) <-doneSignal - os.WriteFile(config.MostListenedSongPath, radio.StoreMostListenedSong(), fs.ModePerm) + os.WriteFile(*mostListenedSongPath, radio.StoreMostListenedSong(), fs.ModePerm) if err := srv.Stop(); err != nil { log.Fatalln(err) diff --git a/init/radio.service b/init/radio.service index 1759142..3ef528f 100755 --- a/init/radio.service +++ b/init/radio.service @@ -7,7 +7,12 @@ After=network-online.target icecast.service Type=simple Restart=on-failure DynamicUser=yes -ExecStart=/usr/bin/dwelling-radio -conf /etc/dwelling/radio.yaml +ExecStart=/usr/bin/dwelling-radio -listen /var/run/dwelling-radio/sock \ + -ic-url http://radio.arav.home.arpa/status-json.xsl \ + -ic-playlist /var/log/icecast/playlist.log \ + -filelist /srv/radio/filelist.html \ + -mls-file /mnt/data/appdata/mostlistenedsong \ + -lst-len 10 ReadOnlyPaths=/ diff --git a/internal/http/handlers.go b/internal/http/handlers.go index a880355..4f8768d 100644 --- a/internal/http/handlers.go +++ b/internal/http/handlers.go @@ -1,7 +1,6 @@ package http import ( - "dwelling-radio/internal/configuration" "dwelling-radio/internal/radio" "dwelling-radio/pkg/utils" "dwelling-radio/web" @@ -15,15 +14,22 @@ import ( const FormatISO8601 = "2006-01-02T15:04:05-0700" type Handlers struct { - conf *configuration.Configuration + icecastUrl string + icecastPlaylistPath string + songListLen int + filelistPath string } -func NewHandlers(conf *configuration.Configuration) *Handlers { - return &Handlers{conf: conf} +func NewHandlers(icecastUrl, icecastPlaylistPath, filelistPath string, songListLen int) *Handlers { + return &Handlers{ + icecastUrl: icecastUrl, + icecastPlaylistPath: icecastPlaylistPath, + songListLen: songListLen, + filelistPath: filelistPath} } func (h *Handlers) Index(w http.ResponseWriter, r *http.Request) { - status, err := radio.IcecastGetStatus(h.conf.Icecast.URL) + status, err := radio.IcecastGetStatus(h.icecastUrl) if err != nil { log.Println("failed to get Icecast status:", err) } else { @@ -36,7 +42,7 @@ func (h *Handlers) Index(w http.ResponseWriter, r *http.Request) { } } - songs, err := radio.IcecastLastSongs(h.conf.Icecast.Playlist) + songs, err := radio.IcecastLastSongs(h.icecastPlaylistPath) if err != nil { log.Println("cannot retrieve last songs:", err) } else { @@ -47,11 +53,11 @@ func (h *Handlers) Index(w http.ResponseWriter, r *http.Request) { } } - web.Index(utils.MainSite(r.Host), h.conf.ListLastNSongs, status, &songs, r, w) + web.Index(utils.MainSite(r.Host), h.songListLen, status, &songs, r, w) } func (h *Handlers) Status(w http.ResponseWriter, r *http.Request) { - status, err := radio.IcecastGetStatus(h.conf.Icecast.URL) + status, err := radio.IcecastGetStatus(h.icecastUrl) if err != nil { log.Println("cannot retrieve Icecast status:", err) http.Error(w, "cannot retrieve Icecast status", http.StatusInternalServerError) @@ -71,7 +77,7 @@ func (h *Handlers) Status(w http.ResponseWriter, r *http.Request) { } func (h *Handlers) LastSong(w http.ResponseWriter, r *http.Request) { - song, err := radio.IcecastLastSong(h.conf.Icecast.Playlist) + song, err := radio.IcecastLastSong(h.icecastPlaylistPath) if err != nil { log.Println("cannot retrieve last songs:", err) } @@ -97,7 +103,7 @@ func (h *Handlers) Playlist(w http.ResponseWriter, _ *http.Request) { func (h *Handlers) Filelist(w http.ResponseWriter, _ *http.Request) { w.Header().Add("Content-Type", "text/html") - data, _ := os.ReadFile(h.conf.FilelistPath) + data, _ := os.ReadFile(h.filelistPath) w.Write(data) } diff --git a/internal/http/http.go b/internal/http/http.go index 7a82e8b..477e662 100644 --- a/internal/http/http.go +++ b/internal/http/http.go @@ -5,12 +5,15 @@ import ( "log" "net" "net/http" + "net/netip" "os" + "strings" "time" ) type HttpServer struct { - s http.Server + s http.Server + addr net.Addr } func NewHttpServer(r http.Handler) *HttpServer { @@ -20,7 +23,23 @@ func NewHttpServer(r http.Handler) *HttpServer { Handler: r}} } -func (s *HttpServer) Start(network, address string) error { +func (s *HttpServer) Start(address string) error { + var network string + if !strings.ContainsRune(address, ':') { + network = "unix" + } else { + ap, err := netip.ParseAddrPort(address) + if err != nil { + return err + } + + if ap.Addr().Is4() { + network = "tcp4" + } else if ap.Addr().Is6() { + network = "tcp6" + } + } + listener, err := net.Listen(network, address) if err != nil { return err @@ -30,6 +49,8 @@ func (s *HttpServer) Start(network, address string) error { os.Chmod(address, 0777) } + s.addr = listener.Addr() + go func() { if err = s.s.Serve(listener); err != nil && err != http.ErrServerClosed { log.Fatalln(err) @@ -43,6 +64,10 @@ func (s *HttpServer) Stop() error { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() + if s.addr.Network() == "unix" { + defer os.Remove(s.addr.String()) + } + if err := s.s.Shutdown(ctx); err != nil { return err }