package reveil import ( "crypto/sha512" "io/fs" "os" "path/filepath" "strings" "time" "git.nemunai.re/nemunaire/reveil/config" ) type Track struct { Id Identifier `json:"id"` Name string `json:"name"` Path string `json:"path"` Enabled bool `json:"enabled"` } func LoadTrack(path string, d fs.FileInfo) (track *Track, err error) { hash := sha512.Sum512([]byte(path)) return &Track{ Id: hash[:], Name: strings.TrimSuffix(d.Name(), filepath.Ext(d.Name())), Path: path, Enabled: len(strings.Split(path, "/")) == 2, }, nil } func LoadTracks(cfg *config.Config) (tracks []*Track, err error) { err = filepath.Walk(cfg.TracksDir, func(path string, d fs.FileInfo, err error) error { if d.Mode().IsRegular() { hash := sha512.Sum512([]byte(path)) tracks = append(tracks, &Track{ Id: hash[:], Name: strings.TrimSuffix(d.Name(), filepath.Ext(d.Name())), Path: path, Enabled: len(strings.Split(path, "/")) == 2, }) } return nil }) return } func (t *Track) Open() (*os.File, error) { return os.Open(t.Path) } func (t *Track) Size() (int64, error) { if st, err := os.Stat(t.Path); err != nil { return 0, err } else { return st.Size(), err } } func (t *Track) ContentType() string { switch filepath.Ext(t.Path) { case ".flac": return "audio/flac" case ".mp3": return "audio/mpeg" case ".ogg": return "audio/ogg" case ".wav": return "audio/vnd.wav" } return "application/octet-stream" } func (t *Track) Rename(newName string) error { newPath := filepath.Join(filepath.Dir(t.Path), newName+filepath.Ext(t.Path)) err := os.Rename( t.Path, newPath, ) if err != nil { return err } t.Path = newPath // Recalculate hash hash := sha512.Sum512([]byte(t.Path)) t.Id = hash[:] return nil } func (t *Track) MoveTo(path string) error { os.Mkdir(filepath.Dir(path), 0755) err := os.Rename( t.Path, path, ) if err != nil { return err } t.Path = path // Recalculate hash hash := sha512.Sum512([]byte(t.Path)) t.Id = hash[:] return nil } func (t *Track) Disable() error { if t.Enabled { date := time.Now() return t.MoveTo(filepath.Join(filepath.Dir(t.Path), date.Format("20060102"), filepath.Base(t.Path))) } return nil } func (t *Track) Enable(cfg *config.Config) error { if !t.Enabled { return t.MoveTo(filepath.Join(cfg.TracksDir, filepath.Base(t.Path))) } return nil } func (t *Track) Remove() error { return os.Remove(t.Path) }