Rename MediaFolder to Library

This commit is contained in:
Deluan 2023-12-12 21:33:27 -05:00
parent 92a98cd558
commit a5b9edf50d
10 changed files with 92 additions and 94 deletions

View File

@ -20,10 +20,10 @@ type ResourceRepository interface {
}
type DataStore interface {
Library(ctx context.Context) LibraryRepository
Album(ctx context.Context) AlbumRepository
Artist(ctx context.Context) ArtistRepository
MediaFile(ctx context.Context) MediaFileRepository
MediaFolder(ctx context.Context) MediaFolderRepository
Genre(ctx context.Context) GenreRepository
Playlist(ctx context.Context) PlaylistRepository
PlayQueue(ctx context.Context) PlayQueueRepository

23
model/library.go Normal file
View File

@ -0,0 +1,23 @@
package model
import (
"io/fs"
"os"
)
type Library struct {
ID int32
Name string
Path string
}
func (f Library) FS() fs.FS {
return os.DirFS(f.Path)
}
type Libraries []Library
type LibraryRepository interface {
Get(id int32) (*Library, error)
GetAll() (Libraries, error)
}

View File

@ -1,23 +0,0 @@
package model
import (
"io/fs"
"os"
)
type MediaFolder struct {
ID int32
Name string
Path string
}
func (f MediaFolder) FS() fs.FS {
return os.DirFS(f.Path)
}
type MediaFolders []MediaFolder
type MediaFolderRepository interface {
Get(id int32) (*MediaFolder, error)
GetAll() (MediaFolders, error)
}

View File

@ -0,0 +1,34 @@
package persistence
import (
"context"
"github.com/navidrome/navidrome/conf"
"github.com/navidrome/navidrome/model"
"github.com/pocketbase/dbx"
)
type libraryRepository struct {
ctx context.Context
}
func NewLibraryRepository(ctx context.Context, _ dbx.Builder) model.LibraryRepository {
return &libraryRepository{ctx}
}
func (r *libraryRepository) Get(id int32) (*model.Library, error) {
library := hardCoded()
return &library, nil
}
func (*libraryRepository) GetAll() (model.Libraries, error) {
return model.Libraries{hardCoded()}, nil
}
func hardCoded() model.Library {
library := model.Library{ID: 0, Path: conf.Server.MusicFolder}
library.Name = "Music Library"
return library
}
var _ model.LibraryRepository = (*libraryRepository)(nil)

View File

@ -1,37 +0,0 @@
package persistence
import (
"context"
"github.com/navidrome/navidrome/conf"
"github.com/navidrome/navidrome/model"
"github.com/pocketbase/dbx"
)
type mediaFolderRepository struct {
ctx context.Context
}
func NewMediaFolderRepository(ctx context.Context, _ dbx.Builder) model.MediaFolderRepository {
return &mediaFolderRepository{ctx}
}
func (r *mediaFolderRepository) Get(id int32) (*model.MediaFolder, error) {
mediaFolder := hardCoded()
return &mediaFolder, nil
}
func (*mediaFolderRepository) GetAll() (model.MediaFolders, error) {
mediaFolder := hardCoded()
result := make(model.MediaFolders, 1)
result[0] = mediaFolder
return result, nil
}
func hardCoded() model.MediaFolder {
mediaFolder := model.MediaFolder{ID: 0, Path: conf.Server.MusicFolder}
mediaFolder.Name = "Music Library"
return mediaFolder
}
var _ model.MediaFolderRepository = (*mediaFolderRepository)(nil)

View File

@ -31,8 +31,8 @@ func (s *SQLStore) MediaFile(ctx context.Context) model.MediaFileRepository {
return NewMediaFileRepository(ctx, s.getDBXBuilder())
}
func (s *SQLStore) MediaFolder(ctx context.Context) model.MediaFolderRepository {
return NewMediaFolderRepository(ctx, s.getDBXBuilder())
func (s *SQLStore) Library(ctx context.Context) model.LibraryRepository {
return NewLibraryRepository(ctx, s.getDBXBuilder())
}
func (s *SQLStore) Genre(ctx context.Context) model.GenreRepository {

View File

@ -17,11 +17,11 @@ import (
type Scanner interface {
RescanAll(ctx context.Context, fullRescan bool) error
Status(mediaFolder string) (*StatusInfo, error)
Status(library string) (*StatusInfo, error)
}
type StatusInfo struct {
MediaFolder string
Library string
Scanning bool
LastScan time.Time
Count uint32
@ -71,47 +71,47 @@ func New(ds model.DataStore, playlists core.Playlists, cacheWarmer artwork.Cache
return s
}
func (s *scanner) rescan(ctx context.Context, mediaFolder string, fullRescan bool) error {
folderScanner := s.folders[mediaFolder]
func (s *scanner) rescan(ctx context.Context, library string, fullRescan bool) error {
folderScanner := s.folders[library]
start := time.Now()
s.setStatusStart(mediaFolder)
defer s.setStatusEnd(mediaFolder, start)
s.setStatusStart(library)
defer s.setStatusEnd(library, start)
lastModifiedSince := time.Time{}
if !fullRescan {
lastModifiedSince = s.getLastModifiedSince(ctx, mediaFolder)
log.Debug("Scanning folder", "folder", mediaFolder, "lastModifiedSince", lastModifiedSince)
lastModifiedSince = s.getLastModifiedSince(ctx, library)
log.Debug("Scanning folder", "folder", library, "lastModifiedSince", lastModifiedSince)
} else {
log.Debug("Scanning folder (full scan)", "folder", mediaFolder)
log.Debug("Scanning folder (full scan)", "folder", library)
}
progress, cancel := s.startProgressTracker(mediaFolder)
progress, cancel := s.startProgressTracker(library)
defer cancel()
changeCount, err := folderScanner.Scan(ctx, lastModifiedSince, progress)
if err != nil {
log.Error("Error importing MediaFolder", "folder", mediaFolder, err)
log.Error("Error scanning Library", "folder", library, err)
}
if changeCount > 0 {
log.Debug(ctx, "Detected changes in the music folder. Sending refresh event",
"folder", mediaFolder, "changeCount", changeCount)
"folder", library, "changeCount", changeCount)
// Don't use real context, forcing a refresh in all open windows, including the one that triggered the scan
s.broker.SendMessage(context.Background(), &events.RefreshResource{})
}
s.updateLastModifiedSince(mediaFolder, start)
s.updateLastModifiedSince(library, start)
return err
}
func (s *scanner) startProgressTracker(mediaFolder string) (chan uint32, context.CancelFunc) {
func (s *scanner) startProgressTracker(library string) (chan uint32, context.CancelFunc) {
ctx, cancel := context.WithCancel(context.Background())
progress := make(chan uint32, 100)
go func() {
s.broker.SendMessage(ctx, &events.ScanStatus{Scanning: true, Count: 0, FolderCount: 0})
defer func() {
if status, ok := s.getStatus(mediaFolder); ok {
if status, ok := s.getStatus(library); ok {
s.broker.SendMessage(ctx, &events.ScanStatus{
Scanning: false,
Count: int64(status.fileCount),
@ -127,7 +127,7 @@ func (s *scanner) startProgressTracker(mediaFolder string) (chan uint32, context
if count == 0 {
continue
}
totalFolders, totalFiles := s.incStatusCounter(mediaFolder, count)
totalFolders, totalFiles := s.incStatusCounter(library, count)
s.broker.SendMessage(ctx, &events.ScanStatus{
Scanning: true,
Count: int64(totalFiles),
@ -198,13 +198,14 @@ func (s *scanner) RescanAll(ctx context.Context, fullRescan bool) error {
core.WriteAfterScanMetrics(ctx, s.ds, true)
return nil
}
func (s *scanner) Status(mediaFolder string) (*StatusInfo, error) {
status, ok := s.getStatus(mediaFolder)
func (s *scanner) Status(library string) (*StatusInfo, error) {
status, ok := s.getStatus(library)
if !ok {
return nil, errors.New("mediaFolder not found")
return nil, errors.New("library not found")
}
return &StatusInfo{
MediaFolder: mediaFolder,
Library: library,
Scanning: status.active,
LastScan: status.lastUpdate,
Count: status.fileCount,
@ -233,7 +234,7 @@ func (s *scanner) updateLastModifiedSince(folder string, t time.Time) {
func (s *scanner) loadFolders() {
ctx := context.TODO()
fs, _ := s.ds.MediaFolder(ctx).GetAll()
fs, _ := s.ds.Library(ctx).GetAll()
for _, f := range fs {
log.Info("Configuring Media Folder", "name", f.Name, "path", f.Path)
s.folders[f.Path] = s.newScanner(f)
@ -246,6 +247,6 @@ func (s *scanner) loadFolders() {
}
}
func (s *scanner) newScanner(f model.MediaFolder) FolderScanner {
func (s *scanner) newScanner(f model.Library) FolderScanner {
return NewTagScanner(f.Path, s.ds, s.pls, s.cacheWarmer)
}

View File

@ -18,9 +18,9 @@ import (
)
func (api *Router) GetMusicFolders(r *http.Request) (*responses.Subsonic, error) {
mediaFolderList, _ := api.ds.MediaFolder(r.Context()).GetAll()
folders := make([]responses.MusicFolder, len(mediaFolderList))
for i, f := range mediaFolderList {
libraries, _ := api.ds.Library(r.Context()).GetAll()
folders := make([]responses.MusicFolder, len(libraries))
for i, f := range libraries {
folders[i].Id = f.ID
folders[i].Name = f.Name
}
@ -29,11 +29,11 @@ func (api *Router) GetMusicFolders(r *http.Request) (*responses.Subsonic, error)
return response, nil
}
func (api *Router) getArtistIndex(r *http.Request, mediaFolderId int, ifModifiedSince time.Time) (*responses.Indexes, error) {
func (api *Router) getArtistIndex(r *http.Request, libId int, ifModifiedSince time.Time) (*responses.Indexes, error) {
ctx := r.Context()
folder, err := api.ds.MediaFolder(ctx).Get(int32(mediaFolderId))
folder, err := api.ds.Library(ctx).Get(int32(libId))
if err != nil {
log.Error(ctx, "Error retrieving MediaFolder", "id", mediaFolderId, err)
log.Error(ctx, "Error retrieving Library", "id", libId, err)
return nil, err
}

View File

@ -12,7 +12,7 @@ import (
)
func (api *Router) GetScanStatus(r *http.Request) (*responses.Subsonic, error) {
// TODO handle multiple mediafolders
// TODO handle multiple libraries
ctx := r.Context()
mediaFolder := conf.Server.MusicFolder
status, err := api.scanner.Status(mediaFolder)

View File

@ -43,8 +43,8 @@ func (db *MockDataStore) MediaFile(context.Context) model.MediaFileRepository {
return db.MockedMediaFile
}
func (db *MockDataStore) MediaFolder(context.Context) model.MediaFolderRepository {
return struct{ model.MediaFolderRepository }{}
func (db *MockDataStore) Library(context.Context) model.LibraryRepository {
return struct{ model.LibraryRepository }{}
}
func (db *MockDataStore) Genre(context.Context) model.GenreRepository {