aboutsummaryrefslogtreecommitdiff
path: root/localBackend.go
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2022-12-23 08:51:37 +0100
committerFlorian Fischer <florian.fischer@muhq.space>2022-12-23 08:51:37 +0100
commitb7f5ed4e5fcb3b51636a9dad79e7e80f7ebbb102 (patch)
tree1a8c53db5e7fa34f683c8a0afcb8e33ff104b0a7 /localBackend.go
parent97a9b0e75a57c6b55bab8c50827f5ba4b896fd95 (diff)
downloadWRMS-b7f5ed4e5fcb3b51636a9dad79e7e80f7ebbb102.tar.gz
WRMS-b7f5ed4e5fcb3b51636a9dad79e7e80f7ebbb102.zip
implement local storage backendv0.0.2-alpha
The 'local' backend is able to serve the music from a path specified by '-server-music-dir'. Add command line options to select the server port as well as a list of backends.
Diffstat (limited to 'localBackend.go')
-rw-r--r--localBackend.go103
1 files changed, 103 insertions, 0 deletions
diff --git a/localBackend.go b/localBackend.go
new file mode 100644
index 0000000..a09d9a1
--- /dev/null
+++ b/localBackend.go
@@ -0,0 +1,103 @@
+package main
+
+import (
+ "fmt"
+ "github.com/dhowden/tag"
+ "muhq.space/go/wrms/llog"
+ "os"
+ "path"
+ "path/filepath"
+ "strings"
+ "sync"
+)
+
+type LocalBackend struct {
+ musicDir string
+ lock sync.RWMutex
+ songs map[string]*Song
+}
+
+func NewLocalBackend(musicDir string) *LocalBackend {
+ b := LocalBackend{musicDir, sync.RWMutex{}, map[string]*Song{}}
+
+ go b.findSongs()
+ return &b
+}
+
+func (b *LocalBackend) insert(song *Song) {
+ b.lock.Lock()
+ defer b.lock.Unlock()
+ b.songs[song.Uri] = song
+}
+
+func (b *LocalBackend) findSongs() {
+ llog.Debug(fmt.Sprintf("Starting song search under: %s", b.musicDir))
+
+ // Insert some Songs
+ song := NewSong("No!", "Bukahara", "local", "Bukahara/Phantasma/01-No!.ogg")
+
+ for _, s := range []*Song{&song} {
+ b.insert(s)
+ }
+
+ err := filepath.Walk(b.musicDir, func(p string, finfo os.FileInfo, err error) error {
+ if err != nil {
+ llog.Warning(fmt.Sprintf("error %v at path %s\n", err, p))
+ return err
+ }
+
+ if !finfo.Mode().IsRegular() {
+ return nil
+ }
+
+ ext := strings.ToLower(path.Ext(p))
+ for _, excluded := range []string{".png", ".jpg", ".txt", ".pdf", ".m3u"} {
+ if ext == excluded {
+ return nil
+ }
+ }
+
+ f, err := os.Open(p)
+ defer f.Close()
+ if err != nil {
+ llog.Warning(fmt.Sprintf("error %v opening file %s", err, p))
+ return err
+ }
+
+ m, err := tag.ReadFrom(f)
+ if err != nil {
+ llog.Warning(fmt.Sprintf("error reading tags from %s: %v", p, err))
+ // Contiune walking
+ return nil
+ }
+
+ s := NewSong(m.Title(), m.Artist(), "local", p)
+ b.insert(&s)
+ return nil
+ })
+
+ if err != nil {
+ llog.Error(fmt.Sprintf("error walking the path %q: %v", b.musicDir, err))
+ }
+}
+
+func (b *LocalBackend) Play(song *Song, player *Player) {
+ player.PlayUri("file://" + song.Uri)
+}
+
+func (b *LocalBackend) Search(keyword string) []Song {
+ pattern := strings.ToLower(keyword)
+ results := []Song{}
+
+ b.lock.RLock()
+ defer b.lock.RUnlock()
+
+ for _, s := range b.songs {
+ if strings.Contains(strings.ToLower(s.Title), pattern) ||
+ strings.Contains(strings.ToLower(s.Artist), pattern) {
+ results = append(results, *s)
+ }
+ }
+
+ return results
+}