Files
zampler/internal/samples/scan.go
T

87 lines
1.6 KiB
Go

package samples
import (
"errors"
"maps"
"os"
"path"
"slices"
)
var ScanExtensions = []string{"aac", "flac", "m4a", "mp3", "ogg", "wav"}
func (db *DB) MultiScan(rootDirs ...string) (Files, error) {
files := Files{}
for _, rootDir := range rootDirs {
moreFiles, err := db.Scan(rootDir)
if err != nil {
return nil, err
}
maps.Copy(files, moreFiles)
}
return files, nil
}
func (db *DB) Scan(rootDir string) (Files, error) {
if !path.IsAbs(rootDir) {
return nil, errors.New("rootDir must be absolute path")
}
log := db.log.With().Str("rootDir", rootDir).Logger()
log.Debug().Msg("Scanning for files")
paths, err := scanRecursive(rootDir)
if err != nil {
return nil, err
}
l := len(rootDir)
files := Files{}
for _, path := range paths {
file, err := NewFile(rootDir, path[l:])
if err != nil {
log.Warn().Err(err).Str("path", file.Path).Msg("Failed to read file")
}
id := file.ID()
files[id] = file
log.Trace().Str("id", id).Str("path", file.Path).Str("hash", file.Hash()).Msg("Found")
}
log.Debug().Int("files", len(files)).Msg("Completed scan")
return files, nil
}
func scanRecursive(dir string, exts ...string) ([]string, error) {
paths := []string{}
entries, err := os.ReadDir(dir)
if err != nil {
return nil, err
}
for _, entry := range entries {
path := path.Join(dir, entry.Name())
if entry.IsDir() {
subPaths, err := scanRecursive(path)
if err != nil {
return nil, err
}
paths = append(paths, subPaths...)
} else {
ext := parseExtension(path)
if slices.Contains(ScanExtensions, ext) {
paths = append(paths, path)
}
}
}
return paths, nil
}