package reveil import ( "crypto/sha512" "io/fs" "os" "path/filepath" "strings" "git.nemunai.re/nemunaire/reveil/config" ) const CURRENT_GONG = "_current_gong" type Gong struct { Id Identifier `json:"id"` Name string `json:"name"` Path string `json:"path"` Enabled bool `json:"enabled"` } func CurrentGongPath(cfg *config.Config) string { return filepath.Join(cfg.GongsDir, CURRENT_GONG) } func LoadGong(cfg *config.Config, path string, d fs.FileInfo) (gong *Gong, err error) { // Retrieve the path of the current gong current_gong, err := os.Readlink(CurrentGongPath(cfg)) if err == nil { current_gong, _ = filepath.Abs(filepath.Join(cfg.GongsDir, current_gong)) } hash := sha512.Sum512([]byte(path)) pabs, _ := filepath.Abs(path) return &Gong{ Id: hash[:], Name: strings.TrimSuffix(d.Name(), filepath.Ext(d.Name())), Path: path, Enabled: current_gong == pabs, }, nil } func LoadGongs(cfg *config.Config) (gongs []*Gong, err error) { // Retrieve the path of the current gong current_gong, err := os.Readlink(CurrentGongPath(cfg)) if err == nil { current_gong, _ = filepath.Abs(filepath.Join(cfg.GongsDir, current_gong)) } // Retrieve the list err = filepath.Walk(cfg.GongsDir, func(path string, d fs.FileInfo, err error) error { if d.Mode().IsRegular() { hash := sha512.Sum512([]byte(path)) pabs, _ := filepath.Abs(path) gongs = append(gongs, &Gong{ Id: hash[:], Name: strings.TrimSuffix(d.Name(), filepath.Ext(d.Name())), Path: path, Enabled: current_gong == pabs, }) } return nil }) return } func (g *Gong) Open() (*os.File, error) { return os.Open(g.Path) } func (g *Gong) Size() (int64, error) { if st, err := os.Stat(g.Path); err != nil { return 0, err } else { return st.Size(), err } } func (g *Gong) ContentType() string { switch filepath.Ext(g.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 (g *Gong) Rename(newName string) error { newPath := filepath.Join(filepath.Dir(g.Path), newName+filepath.Ext(g.Path)) err := os.Rename( g.Path, newPath, ) if err != nil { return err } g.Path = newPath return nil } func (g *Gong) SetDefault(cfg *config.Config) error { linkpath := CurrentGongPath(cfg) os.Remove(linkpath) pabs, err := filepath.Abs(g.Path) if err != nil { pabs = g.Path } gdirabs, err := filepath.Abs(cfg.GongsDir) if err != nil { gdirabs = cfg.GongsDir } return os.Symlink(strings.TrimPrefix(strings.TrimPrefix(pabs, gdirabs), "/"), linkpath) } func (g *Gong) Remove() error { return os.Remove(g.Path) }