87 lines
1.6 KiB
Go
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
|
|
}
|