package radio import ( "os" "strings" "sync" "github.com/pkg/errors" ) // Playlist holds a list of paths to a song files. type Playlist struct { mutex sync.Mutex filePath string playlist []string cur int repeat bool } // NewPlaylist returns an instance of a Playlist struct with a loaded playlist. // Returns an error if failed to load a playlist file. func NewPlaylist(filePath string, repeat bool) (*Playlist, error) { p := &Playlist{filePath: filePath, repeat: repeat} return p, p.load() } // Next returns the next song to play. Returns an empty string if repeat is // false and the end of a playlist was reached. func (p *Playlist) Next() (song string) { p.mutex.Lock() defer p.mutex.Unlock() if p.cur == len(p.playlist) { // If the end of a playlist was reached and repeat is set to true, // then go back to the head of it, thus repeating it. Return an empty // string otherwise. if p.repeat { p.cur = 0 } else { return "" } } song = p.playlist[p.cur] p.cur++ return } // Load reads a playlist file. func (p *Playlist) load() error { data, err := os.ReadFile(p.filePath) if err != nil { return errors.Wrap(err, "cannot open a playlist file") } if len(data) == 0 { return errors.New("a playlist file is empty. Did not update") } p.mutex.Lock() p.playlist = strings.Split(string(data), "\n") p.cur = 0 p.mutex.Unlock() return nil } func (p *Playlist) Reload() error { return p.load() }