1
0
dwelling-radio/cmd/dwelling-radio/main.go

111 lines
3.0 KiB
Go

package main
import (
ihttp "dwelling-radio/internal/http"
"dwelling-radio/internal/radio"
"dwelling-radio/web"
"flag"
"fmt"
"io/fs"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"git.arav.su/Arav/httpr"
)
var (
listenAddress = flag.String("listen", "/var/run/dwelling-radio/sock", "listen address (ip:port|unix_path)")
filelistPath = flag.String("filelist", "/mnt/data/appdata/radio/filelist.html", "path to a filelist.html file")
playlist = flag.String("playlist", "", "path to a playlist")
fallbackSong = flag.String("fallback-song", "", "path to a fallbacl song")
mostListenedSongPath = flag.String("mls-file", "/mnt/data/appdata/radio/mostlistenedsong", "path to a file that stores info about the most listened song")
songListLen = flag.Int("list-length", 10, "number of songs to show in last N songs table")
showVersion = flag.Bool("v", false, "show version")
)
var version string
func main() {
flag.Parse()
log.SetFlags(log.Lshortfile)
if *showVersion {
fmt.Println("dwelling-radio ver.", version, "\nCopyright (c) 2022,2023 Alexander \"Arav\" Andreev <me@arav.su>")
return
}
var mostListenedSong radio.MostListenedSong
if data, err := os.ReadFile(*mostListenedSongPath); err == nil {
if err := mostListenedSong.Load(data); err != nil {
log.Fatalln(err)
}
}
songList := radio.NewSongList(*songListLen)
lstnrs := radio.NewListenerCounter()
plylst, err := radio.NewPlaylist(*playlist, true)
if err != nil {
log.Fatalln(err)
}
hand := ihttp.NewHandlers(*filelistPath, songList, lstnrs, &mostListenedSong)
r := httpr.New()
r.Handler(http.MethodGet, "/", hand.Index)
r.Handler(http.MethodGet, "/playlist", hand.Playlist)
r.Handler(http.MethodGet, "/filelist", hand.Filelist)
r.Handler(http.MethodGet, "/robots.txt", ihttp.RobotsTxt)
r.Handler(http.MethodGet, "/sitemap.xml", ihttp.SitemapXML)
r.Handler(http.MethodGet, "/favicon.svg", ihttp.Favicon)
r.ServeStatic("/assets/*filepath", web.Assets())
djh := ihttp.NewDJHandlers(lstnrs, plylst, songList, &mostListenedSong, *fallbackSong)
s := r.Sub("/api")
s.Handler(http.MethodPost, "/listener/icecast", djh.ListenersUpdate)
s.Handler(http.MethodGet, "/playlist", djh.PlaylistNext)
s.Handler(http.MethodGet, "/status", djh.Status)
srv := ihttp.NewHttpServer(r)
if err := srv.Start(*listenAddress); err != nil {
log.Fatalln(err)
}
defer func() {
fileData := mostListenedSong.Store()
if fileData != nil {
err := os.WriteFile(*mostListenedSongPath, fileData, fs.ModePerm)
if err != nil {
log.Println("failed to store a most listened song:", err)
}
}
if err := srv.Stop(); err != nil {
log.Fatalln(err)
}
}()
sysSignal := make(chan os.Signal, 1)
signal.Notify(sysSignal, os.Interrupt, syscall.SIGINT, syscall.SIGTERM, syscall.SIGABRT, syscall.SIGSEGV, syscall.SIGHUP)
for {
switch <-sysSignal {
case os.Interrupt, syscall.SIGINT, syscall.SIGTERM, syscall.SIGABRT, syscall.SIGSEGV:
return
case syscall.SIGHUP:
if err := plylst.Reload(); err != nil {
log.Println(err)
}
}
}
}