92 lines
2 KiB
Go
92 lines
2 KiB
Go
package main
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"path"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/dhowden/tag"
|
|
)
|
|
|
|
type Metadata struct {
|
|
Title string
|
|
Artist string
|
|
Album string
|
|
Track int
|
|
}
|
|
|
|
func readMetadata(f *os.File) *Metadata {
|
|
var metadata Metadata
|
|
|
|
m, err := tag.ReadFrom(f)
|
|
if err != nil || m.Title() == "" {
|
|
metadata.Title = f.Name()
|
|
} else {
|
|
metadata.Title = m.Title()
|
|
metadata.Artist = m.Artist()
|
|
metadata.Album = m.Album()
|
|
metadata.Track, _ = m.Track()
|
|
}
|
|
|
|
return &metadata
|
|
}
|
|
|
|
type LibraryEntry struct {
|
|
File os.FileInfo
|
|
Metadata *Metadata
|
|
}
|
|
|
|
func (e *LibraryEntry) String() string {
|
|
if e.Metadata.Title != "" {
|
|
if e.Metadata.Artist != "" {
|
|
return e.Metadata.Artist + " - " + e.Metadata.Title
|
|
}
|
|
|
|
return e.Metadata.Title
|
|
}
|
|
|
|
return e.File.Name()
|
|
}
|
|
|
|
func scanFolder(scanPath string) []*LibraryEntry {
|
|
files, err := ioutil.ReadDir(scanPath)
|
|
if err != nil {
|
|
log.Fatalf("failed to scan %s: %s", scanPath, err)
|
|
}
|
|
|
|
var entries []*LibraryEntry
|
|
for _, fileInfo := range files {
|
|
if fileInfo.IsDir() {
|
|
entries = append(entries, &LibraryEntry{File: fileInfo, Metadata: &Metadata{Title: fileInfo.Name()}})
|
|
continue
|
|
} else if !supportedFormat(fileInfo.Name()) {
|
|
continue
|
|
}
|
|
|
|
f, err := os.Open(path.Join(scanPath, fileInfo.Name()))
|
|
if err != nil {
|
|
continue
|
|
}
|
|
metadata := readMetadata(f)
|
|
f.Close()
|
|
|
|
entries = append(entries, &LibraryEntry{File: fileInfo, Metadata: metadata})
|
|
}
|
|
|
|
sort.Slice(entries, func(i, j int) bool {
|
|
if entries[i].File.IsDir() != entries[j].File.IsDir() {
|
|
return entries[i].File.IsDir()
|
|
}
|
|
|
|
if entries[i].Metadata.Album != "" && strings.ToLower(entries[i].Metadata.Album) == strings.ToLower(entries[j].Metadata.Album) && (entries[i].Metadata.Track > 0 || entries[j].Metadata.Track > 0) {
|
|
return entries[i].Metadata.Track < entries[j].Metadata.Track
|
|
}
|
|
|
|
return strings.ToLower(entries[i].Metadata.Album) < strings.ToLower(entries[j].Metadata.Album) && strings.ToLower(entries[i].File.Name()) < strings.ToLower(entries[j].File.Name())
|
|
})
|
|
|
|
return entries
|
|
}
|