Implemented lastPlayedSong() function that retrieves one song from a playlist.log file that doesn't run external commands for it.
And now we start with an empty list.
This commit is contained in:
parent
23f246857e
commit
c935db8ce7
@ -1,11 +1,12 @@
|
||||
package radio
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"dwelling-radio/pkg/watcher"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os/exec"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
@ -17,6 +18,8 @@ import (
|
||||
const (
|
||||
IcecastPlaylistDateFormat = "02/Jan/2006:15:04:05 -0700"
|
||||
SongTimeFormat = "2006 15:04-0700"
|
||||
|
||||
bufferSize = 8192
|
||||
)
|
||||
|
||||
type IcecastStatusDTO struct {
|
||||
@ -85,7 +88,7 @@ func IcecastLastPlayedSongs(lastNSongs int, playlistPath string) ([]Song, error)
|
||||
}
|
||||
}
|
||||
|
||||
return lastPlayedSongs(lastNSongs, playlistPath)
|
||||
return make([]Song, 0), nil
|
||||
}
|
||||
|
||||
func IcecastLastSong(playlistPath string) (Song, error) {
|
||||
@ -97,45 +100,65 @@ func IcecastLastSong(playlistPath string) (Song, error) {
|
||||
}
|
||||
}
|
||||
|
||||
songs, err := lastPlayedSongs(1, playlistPath)
|
||||
if len(songs) == 0 {
|
||||
return Song{}, nil
|
||||
song, err := lastPlayedSong(playlistPath)
|
||||
if err != nil {
|
||||
return Song{}, err
|
||||
}
|
||||
|
||||
return songs[0], err
|
||||
return *song, nil
|
||||
}
|
||||
|
||||
func lastPlayedSongs(lastNSongs int, playlistPath string) ([]Song, error) {
|
||||
songs := make([]Song, 0)
|
||||
func lastPlayedSong(playlistPath string) (*Song, error) {
|
||||
buf := make([]byte, bufferSize)
|
||||
var last_song_line string
|
||||
|
||||
cmd := fmt.Sprintf("tail -n%d %s | head -n-1 | cut -d'|' -f1,3,4", lastNSongs+1, playlistPath)
|
||||
out, err := exec.Command("bash", "-c", cmd).CombinedOutput()
|
||||
playlist, err := os.Open(playlistPath)
|
||||
if err != nil {
|
||||
return songs, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(out) == 0 {
|
||||
return songs, nil
|
||||
playlist_stat, _ := playlist.Stat()
|
||||
|
||||
if playlist_stat.Size() == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
for _, song := range strings.Split(string(out), "\n") {
|
||||
ts := strings.Split(song, "|")
|
||||
if len(ts) <= 1 {
|
||||
continue
|
||||
}
|
||||
tim, _ := time.Parse(IcecastPlaylistDateFormat, ts[0])
|
||||
songs = append(songs, Song{
|
||||
Time: tim.Format(SongTimeFormat),
|
||||
Listeners: ts[1],
|
||||
Song: ts[2]})
|
||||
playlist.Seek(-bufferSize, os.SEEK_END)
|
||||
|
||||
_, err = playlist.Read(buf)
|
||||
if err != nil && err != io.EOF {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return songs, nil
|
||||
newline_end_pos := bytes.LastIndexByte(buf, '\n')
|
||||
|
||||
if newline_end_pos == -1 && !bytes.ContainsRune(buf, '|') {
|
||||
return nil, nil
|
||||
} else if newline_end_pos == -1 {
|
||||
newline_end_pos = len(buf)
|
||||
}
|
||||
|
||||
newline_start_pos := bytes.LastIndexByte(buf[:newline_end_pos-1], '\n')
|
||||
|
||||
last_song_line = string(buf[newline_start_pos+1 : newline_end_pos-1])
|
||||
|
||||
if strings.Count(last_song_line, "|") != 3 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
fields := strings.Split(last_song_line, "|")
|
||||
|
||||
tim, _ := time.Parse(IcecastPlaylistDateFormat, fields[0])
|
||||
|
||||
return &Song{
|
||||
Time: tim.Format(SongTimeFormat),
|
||||
Listeners: fields[2],
|
||||
Song: fields[3]}, nil
|
||||
}
|
||||
|
||||
var playlistWatcher watcher.InotifyWatcher
|
||||
var playlistFired chan uint32 = make(chan uint32)
|
||||
var lastPlayedCache []Song
|
||||
var lastPlayedCache []Song = make([]Song, 10)
|
||||
var lastPlayedCacheMutex sync.Mutex
|
||||
|
||||
func IcecastWatchPlaylist(playlistPath string, lastNSongs int) error {
|
||||
@ -157,9 +180,11 @@ func IcecastWatchPlaylist(playlistPath string, lastNSongs int) error {
|
||||
case mask := <-playlistFired:
|
||||
if mask&syscall.IN_MODIFY > 0 {
|
||||
lastPlayedCacheMutex.Lock()
|
||||
songs, err := lastPlayedSongs(lastNSongs, playlistPath)
|
||||
if err == nil && len(songs) > 0 {
|
||||
lastPlayedCache = songs
|
||||
if song, err := lastPlayedSong(playlistPath); err == nil {
|
||||
lastPlayedCache = append(lastPlayedCache, *song)
|
||||
if len(lastPlayedCache) > lastNSongs {
|
||||
lastPlayedCache = lastPlayedCache[1:]
|
||||
}
|
||||
}
|
||||
lastPlayedCacheMutex.Unlock()
|
||||
} else if mask&syscall.IN_IGNORED > 0 {
|
||||
@ -171,13 +196,6 @@ func IcecastWatchPlaylist(playlistPath string, lastNSongs int) error {
|
||||
}
|
||||
}()
|
||||
|
||||
lastPlayedCacheMutex.Lock()
|
||||
songs, err := lastPlayedSongs(lastNSongs, playlistPath)
|
||||
if err == nil && len(songs) > 0 {
|
||||
lastPlayedCache = songs
|
||||
}
|
||||
lastPlayedCacheMutex.Unlock()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user