--- /dev/null
+package main
+
+import (
+ "crypto/sha256"
+ "encoding/hex"
+ "io"
+ "log"
+ "os"
+ "path/filepath"
+ "sync"
+)
+
+type FileSpec struct {
+ Name string
+ Hash string
+}
+
+type AudioFiles struct {
+ path string
+ list []FileSpec
+ changeWait chan bool
+ filesMutex sync.Mutex
+}
+
+var files AudioFiles
+
+func InitAudioFiles(path string) {
+ files.changeWait = make(chan bool)
+ files.path = path
+ log.Println("initing audio files")
+ files.Refresh()
+ log.Println("done")
+}
+
+func (r *AudioFiles) Refresh() {
+ entries, err := os.ReadDir(r.path)
+ if err != nil {
+ log.Println("couldn't read dir", r.path)
+ return
+ }
+ r.filesMutex.Lock()
+ defer r.filesMutex.Unlock()
+ r.list = nil
+ for _, file := range entries {
+ f, err := os.Open(filepath.Join(r.path, file.Name()))
+ if err != nil {
+ log.Println("couldn't open", file.Name())
+ return
+ }
+ hash := sha256.New()
+ io.Copy(hash, f)
+ r.list = append(r.list, FileSpec{Name: file.Name(), Hash: hex.EncodeToString(hash.Sum(nil))})
+ }
+ log.Println("Files updated", r.list)
+ close(files.changeWait)
+ files.changeWait = make(chan bool)
+}
+
+func (r *AudioFiles) Path() string {
+ return r.path
+}
+
+func (r *AudioFiles) Files() []FileSpec {
+ r.filesMutex.Lock()
+ defer r.filesMutex.Unlock()
+ return r.list
+}
+
+func (r *AudioFiles) Delete(filename string) {
+ path := filepath.Join(r.path, filepath.Base(filename))
+ if filepath.Clean(r.path) != filepath.Clean(path) {
+ os.Remove(path)
+ r.Refresh()
+ }
+}
+
+func (r *AudioFiles) WatchForChanges() ([]FileSpec, chan bool) {
+ r.filesMutex.Lock()
+ defer r.filesMutex.Unlock()
+ return r.list, r.changeWait
+}