Library indexing and filesystem scanner with incremental rescans
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
package library
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"strings"
|
||||
|
||||
"git.noroutes.net/NoRoutes/vibetunes/internal/database"
|
||||
)
|
||||
|
||||
// DirEntry is one immediate child of a directory in filesystem-style
|
||||
// browsing (Subsonic's getIndexes/getMusicDirectory): either a
|
||||
// subdirectory (Dir=true) or a media file.
|
||||
type DirEntry struct {
|
||||
Name string
|
||||
Dir bool
|
||||
File *database.MediaFile // set when Dir is false
|
||||
}
|
||||
|
||||
// ListDirectory returns the immediate children of subPath within a music
|
||||
// folder ("" for the folder root), built from media_files.relative_path.
|
||||
// This is the foundation for filesystem-style browsing, kept separate
|
||||
// from the ID3/tag model in library/index.go so neither is faked in
|
||||
// terms of the other.
|
||||
func ListDirectory(db *sql.DB, folderID, subPath string) ([]DirEntry, error) {
|
||||
files, err := database.ListMediaFilesForFolder(db, folderID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prefix := strings.Trim(subPath, "/")
|
||||
seen := make(map[string]bool)
|
||||
var out []DirEntry
|
||||
for _, f := range files {
|
||||
if f.Missing {
|
||||
continue
|
||||
}
|
||||
rel := f.RelativePath
|
||||
if prefix != "" {
|
||||
if !strings.HasPrefix(rel, prefix+"/") {
|
||||
continue
|
||||
}
|
||||
rel = rel[len(prefix)+1:]
|
||||
}
|
||||
parts := strings.SplitN(rel, "/", 2)
|
||||
name := parts[0]
|
||||
if name == "" || seen[name] {
|
||||
continue
|
||||
}
|
||||
if len(parts) == 2 {
|
||||
seen[name] = true
|
||||
out = append(out, DirEntry{Name: name, Dir: true})
|
||||
continue
|
||||
}
|
||||
seen[name] = true
|
||||
out = append(out, DirEntry{Name: name, Dir: false, File: f})
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
Reference in New Issue
Block a user