mirror of
https://github.com/navidrome/navidrome.git
synced 2026-10-18 07:30:29 +00:00
100 lines
2.6 KiB
Go
100 lines
2.6 KiB
Go
package plugins
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/navidrome/navidrome/model"
|
|
"github.com/navidrome/navidrome/plugins/host"
|
|
)
|
|
|
|
type libraryServiceImpl struct {
|
|
ds model.DataStore
|
|
hasFilesystemPerm bool
|
|
allowedLibraryIDs []int
|
|
allLibraries bool
|
|
libraryIDMap map[int]struct{}
|
|
}
|
|
|
|
func newLibraryService(ds model.DataStore, perm *LibraryPermission, allowedLibraryIDs []int, allLibraries bool) host.LibraryService {
|
|
hasFS := perm != nil && perm.Filesystem
|
|
libraryIDMap := make(map[int]struct{})
|
|
for _, id := range allowedLibraryIDs {
|
|
libraryIDMap[id] = struct{}{}
|
|
}
|
|
return &libraryServiceImpl{
|
|
ds: ds,
|
|
hasFilesystemPerm: hasFS,
|
|
allowedLibraryIDs: allowedLibraryIDs,
|
|
allLibraries: allLibraries,
|
|
libraryIDMap: libraryIDMap,
|
|
}
|
|
}
|
|
|
|
func (s *libraryServiceImpl) GetLibrary(ctx context.Context, id int32) (*host.Library, error) {
|
|
// Check if the library is accessible
|
|
if !s.isLibraryAccessible(int(id)) {
|
|
return nil, fmt.Errorf("library not accessible: library ID %d is not in the allowed list", id)
|
|
}
|
|
|
|
lib, err := s.ds.Library(ctx).Get(int(id))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("library not found: %w", err)
|
|
}
|
|
|
|
return s.convertLibrary(lib), nil
|
|
}
|
|
|
|
// isLibraryAccessible checks if a library ID is accessible to this plugin.
|
|
func (s *libraryServiceImpl) isLibraryAccessible(id int) bool {
|
|
if s.allLibraries {
|
|
return true
|
|
}
|
|
_, ok := s.libraryIDMap[id]
|
|
return ok
|
|
}
|
|
|
|
func (s *libraryServiceImpl) GetAllLibraries(ctx context.Context) ([]host.Library, error) {
|
|
libs, err := s.ds.Library(ctx).GetAll()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get libraries: %w", err)
|
|
}
|
|
|
|
// Filter libraries based on allowed list
|
|
var result []host.Library
|
|
for _, lib := range libs {
|
|
if s.isLibraryAccessible(lib.ID) {
|
|
result = append(result, *s.convertLibrary(&lib))
|
|
}
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
func (s *libraryServiceImpl) convertLibrary(lib *model.Library) *host.Library {
|
|
hostLib := &host.Library{
|
|
ID: int32(lib.ID),
|
|
Name: lib.Name,
|
|
LastScanAt: lib.LastScanAt.Unix(),
|
|
TotalSongs: int32(lib.TotalSongs),
|
|
TotalAlbums: int32(lib.TotalAlbums),
|
|
TotalArtists: int32(lib.TotalArtists),
|
|
TotalSize: lib.TotalSize,
|
|
TotalDuration: lib.TotalDuration,
|
|
}
|
|
|
|
// Only include path and mount point if filesystem permission is granted
|
|
if s.hasFilesystemPerm {
|
|
hostLib.Path = lib.Path
|
|
hostLib.MountPoint = toPluginMountPoint(int32(lib.ID))
|
|
}
|
|
|
|
return hostLib
|
|
}
|
|
|
|
func toPluginMountPoint(libID int32) string {
|
|
return fmt.Sprintf("/libraries/%d", libID)
|
|
}
|
|
|
|
var _ host.LibraryService = (*libraryServiceImpl)(nil)
|