From 3b51fffa6019c9a0704e524a2ea14c07b8b3754b Mon Sep 17 00:00:00 2001 From: "Alexander \"Arav\" Andreev" Date: Thu, 31 Mar 2022 15:35:04 +0400 Subject: [PATCH] Added last played list cache with updating using Inotify watcher. --- internal/radio/icecast.go | 72 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/internal/radio/icecast.go b/internal/radio/icecast.go index 784f9da..6ae7656 100644 --- a/internal/radio/icecast.go +++ b/internal/radio/icecast.go @@ -1,12 +1,15 @@ package radio import ( + "dwelling-radio/pkg/watcher" "encoding/json" "fmt" "net/http" "os/exec" "strings" "time" + + "github.com/pkg/errors" ) type IcecastStatusDTO struct { @@ -64,6 +67,30 @@ func IcecastGetStatus(icecastURL string) (*IcecastStatus, error) { } func IcecastLastPlayedSongs(lastNSongs int, playlistPath string) ([]Song, error) { + if len(lastPlayedCache) > 0 { + if lastNSongs > len(lastPlayedCache) { + lastNSongs = len(lastPlayedCache) + } + return lastPlayedCache[len(lastPlayedCache)-lastNSongs:], nil + } + + return lastPlayedSongs(lastNSongs, playlistPath) +} + +func IcecastLastSong(playlistPath string) (Song, error) { + if len(lastPlayedCache) > 0 { + return lastPlayedCache[len(lastPlayedCache)-1], nil + } + + songs, err := IcecastLastPlayedSongs(1, playlistPath) + if len(songs) == 0 { + return Song{}, nil + } + + return songs[0], err +} + +func lastPlayedSongs(lastNSongs int, playlistPath string) ([]Song, error) { songs := make([]Song, 0) cmd := fmt.Sprintf("tail -n%d %s | head -n-1 | cut -d'|' -f1,4", lastNSongs+1, playlistPath) @@ -93,3 +120,48 @@ func IcecastLastPlayedSongs(lastNSongs int, playlistPath string) ([]Song, error) return songs, nil } + +var playlistWatcher watcher.InotifyWatcher +var playlistFired chan uint32 +var lastPlayedCache []Song + +func IcecastWatchPlaylist(playlistPath string, lastNSongs int) error { + playlistWatcher, err := watcher.NewInotifyWatcher() + if err != nil { + return errors.Wrap(err, "cannot instantiate inotify watcher") + } + + err = playlistWatcher.AddWatch(playlistPath, watcher.ModMask) + fmt.Println(playlistPath) + if err != nil { + return errors.Wrap(err, "cannot set a playlist to watch") + } + + playlistFired = make(chan uint32) + + playlistWatcher.WatchForMask(playlistFired, watcher.ModMask) + + go func() { + for { + select { + case <-playlistFired: + songs, err := lastPlayedSongs(lastNSongs, playlistPath) + fmt.Println("do we get here?", err) + if err == nil && len(songs) > 0 { + lastPlayedCache = songs + } + } + } + }() + + songs, err := lastPlayedSongs(lastNSongs, playlistPath) + if err == nil && len(songs) > 0 { + lastPlayedCache = songs + } + + return nil +} + +func IcecastWatchClose() { + playlistWatcher.Close() +}