Associate main entities with library

This commit is contained in:
Deluan
2024-05-07 17:52:13 +02:00
committed by Deluan Quintão
parent 477bcaee58
commit 478c709a64
14 changed files with 153 additions and 135 deletions
+32 -33
View File
@@ -23,7 +23,7 @@ import (
)
type TagScanner struct {
rootFolder string
lib model.Library
ds model.DataStore
plsSync *playlistImporter
cnt *counters
@@ -31,10 +31,10 @@ type TagScanner struct {
cacheWarmer artwork.CacheWarmer
}
func NewTagScanner(rootFolder string, ds model.DataStore, playlists core.Playlists, cacheWarmer artwork.CacheWarmer) FolderScanner {
func NewTagScanner(lib model.Library, ds model.DataStore, playlists core.Playlists, cacheWarmer artwork.CacheWarmer) FolderScanner {
s := &TagScanner{
rootFolder: rootFolder,
plsSync: newPlaylistImporter(ds, playlists, cacheWarmer, rootFolder),
lib: lib,
plsSync: newPlaylistImporter(ds, playlists, cacheWarmer, lib.Path),
ds: ds,
cacheWarmer: cacheWarmer,
}
@@ -75,20 +75,20 @@ const (
// - If the playlist is not in the DB, import it, setting sync = true
// - If the playlist is in the DB and sync == true, import it, or else skip it
// Delete all empty albums, delete all empty artists, clean-up playlists
func (s *TagScanner) Scan(ctx context.Context, lastModifiedSince time.Time, progress chan uint32) (int64, error) {
func (s *TagScanner) Scan(ctx context.Context, fullScan bool, progress chan uint32) (int64, error) {
ctx = auth.WithAdminUser(ctx, s.ds)
start := time.Now()
// Special case: if lastModifiedSince is zero, re-import all files
fullScan := lastModifiedSince.IsZero()
// Special case: if LastScanAt is zero, re-import all files
fullScan = fullScan || s.lib.LastScanAt.IsZero()
// If the media folder is empty (no music and no subfolders), abort to avoid deleting all data from DB
empty, err := isDirEmpty(ctx, s.rootFolder)
empty, err := isDirEmpty(ctx, s.lib.Path)
if err != nil {
return 0, err
}
if empty && !fullScan {
log.Error(ctx, "Media Folder is empty. Aborting scan.", "folder", s.rootFolder)
log.Error(ctx, "Media Folder is empty. Aborting scan.", "folder", s.lib.Path)
return 0, nil
}
@@ -101,38 +101,36 @@ func (s *TagScanner) Scan(ctx context.Context, lastModifiedSince time.Time, prog
var changedDirs []string
s.cnt = &counters{}
genres := newCachedGenreRepository(ctx, s.ds.Genre(ctx))
s.mapper = NewMediaFileMapper(s.rootFolder, genres)
refresher := newRefresher(s.ds, s.cacheWarmer, allFSDirs)
s.mapper = NewMediaFileMapper(s.lib.Path, genres)
refresher := newRefresher(s.ds, s.cacheWarmer, s.lib, allFSDirs)
log.Trace(ctx, "Loading directory tree from music folder", "folder", s.rootFolder)
foldersFound, walkerError := walkDirTree(ctx, s.rootFolder)
log.Trace(ctx, "Loading directory tree from music folder", "folder", s.lib.Path)
foldersFound, walkerError := walkDirTree(ctx, s.lib.Path)
for {
folderStats, more := <-foldersFound
if !more {
break
}
progress <- folderStats.AudioFilesCount
allFSDirs[folderStats.Path] = folderStats
go func() {
for folderStats := range foldersFound {
progress <- folderStats.AudioFilesCount
allFSDirs[folderStats.Path] = folderStats
if s.folderHasChanged(folderStats, allDBDirs, lastModifiedSince) {
changedDirs = append(changedDirs, folderStats.Path)
log.Debug("Processing changed folder", "dir", folderStats.Path)
err := s.processChangedDir(ctx, refresher, fullScan, folderStats.Path)
if err != nil {
log.Error("Error updating folder in the DB", "dir", folderStats.Path, err)
if s.folderHasChanged(folderStats, allDBDirs, s.lib.LastScanAt) || fullScan {
changedDirs = append(changedDirs, folderStats.Path)
log.Debug("Processing changed folder", "dir", folderStats.Path)
err := s.processChangedDir(ctx, refresher, fullScan, folderStats.Path)
if err != nil {
log.Error("Error updating folder in the DB", "dir", folderStats.Path, err)
}
}
}
}
}()
if err := <-walkerError; err != nil {
for err := range walkerError {
log.Error("Scan was interrupted by error. See errors above", err)
return 0, err
}
deletedDirs := s.getDeletedDirs(ctx, allFSDirs, allDBDirs)
if len(deletedDirs)+len(changedDirs) == 0 {
log.Debug(ctx, "No changes found in Music Folder", "folder", s.rootFolder, "elapsed", time.Since(start))
log.Debug(ctx, "No changes found in Music Folder", "folder", s.lib.Path, "elapsed", time.Since(start))
return 0, nil
}
@@ -162,8 +160,8 @@ func (s *TagScanner) Scan(ctx context.Context, lastModifiedSince time.Time, prog
log.Debug("Playlist auto-import is disabled")
}
err = s.ds.GC(log.NewContext(ctx), s.rootFolder)
log.Info("Finished processing Music Folder", "folder", s.rootFolder, "elapsed", time.Since(start),
err = s.ds.GC(log.NewContext(ctx), s.lib.Path)
log.Info("Finished processing Music Folder", "folder", s.lib.Path, "elapsed", time.Since(start),
"added", s.cnt.added, "updated", s.cnt.updated, "deleted", s.cnt.deleted, "playlistsImported", s.cnt.playlists)
return s.cnt.total(), err
@@ -179,10 +177,10 @@ func isDirEmpty(ctx context.Context, dir string) (bool, error) {
func (s *TagScanner) getDBDirTree(ctx context.Context) (map[string]struct{}, error) {
start := time.Now()
log.Trace(ctx, "Loading directory tree from database", "folder", s.rootFolder)
log.Trace(ctx, "Loading directory tree from database", "folder", s.lib.Path)
repo := s.ds.MediaFile(ctx)
dirs, err := repo.FindPathsRecursively(s.rootFolder)
dirs, err := repo.FindPathsRecursively(s.lib.Path)
if err != nil {
return nil, err
}
@@ -368,6 +366,7 @@ func (s *TagScanner) addOrUpdateTracksInDB(
if t, ok := currentTracks[n.Path]; ok {
n.Annotations = t.Annotations
}
n.LibraryID = s.lib.ID
err := s.ds.MediaFile(ctx).Put(&n)
if err != nil {
return 0, err