package model
import (
"cmp"
"context"
"strings"
"time"
"github.com/deluan/rest"
"github.com/navidrome/navidrome/conf"
"github.com/navidrome/navidrome/utils/slice"
)
type Library struct {
ID int `json:"id" db:"id"`
Name string `json:"name" db:"name"`
Path string `json:"path" db:"path"`
RemotePath string `json:"remotePath" db:"remote_path"`
LastScanAt time.Time `json:"lastScanAt" db:"last_scan_at"`
LastScanStartedAt time.Time `json:"lastScanStartedAt" db:"last_scan_started_at"`
FullScanInProgress bool `json:"fullScanInProgress" db:"full_scan_in_progress"`
UpdatedAt time.Time `json:"updatedAt" db:"updated_at"`
CreatedAt time.Time `json:"createdAt" db:"created_at"`
TotalSongs int `json:"totalSongs" db:"total_songs"`
TotalAlbums int `json:"totalAlbums" db:"total_albums"`
TotalArtists int `json:"totalArtists" db:"total_artists"`
TotalFolders int `json:"totalFolders" db:"total_folders"`
TotalFiles int `json:"totalFiles" db:"total_files"`
TotalMissingFiles int `json:"totalMissingFiles" db:"total_missing_files"`
TotalSize int64 `json:"totalSize" db:"total_size"`
TotalDuration float64 `json:"totalDuration" db:"total_duration"`
DefaultNewUsers bool `json:"defaultNewUsers" db:"default_new_users"`
PIDAlbum string `json:"pidAlbum" db:"pid_album"`
PIDTrack string `json:"pidTrack" db:"pid_track"`
ScannedPIDAlbum string `json:"-" db:"scanned_pid_album"`
ScannedPIDTrack string `json:"-" db:"scanned_pid_track"`
}
type PIDConfig struct {
Track string
Album string
}
func (l Library) EffectivePID() PIDConfig {
return PIDConfig{
Track: cmp.Or(l.PIDTrack, conf.Server.PID.Track),
Album: cmp.Or(l.PIDAlbum, conf.Server.PID.Album),
}
}
func (l Library) PIDChanged() bool {
pid := l.EffectivePID()
return !strings.EqualFold(l.ScannedPIDAlbum, pid.Album) || !strings.EqualFold(l.ScannedPIDTrack, pid.Track)
}
func (l Library) NeedsPIDRescan() bool {
return !l.LastScanAt.IsZero() && l.PIDChanged()
}
const (
DefaultLibraryID = 1
DefaultLibraryName = "Music Library"
)
type Libraries []Library
func (l Libraries) IDs() []int {
return slice.Map(l, func(lib Library) int { return lib.ID })
}
type LibraryRepository interface {
rest.Repository[Library]
Get(ctx context.Context, id int) (*Library, error)
GetPath(ctx context.Context, id int) (string, error)
GetAll(ctx context.Context, options ...QueryOptions) (Libraries, error)
CountAll(ctx context.Context, options ...QueryOptions) (int64, error)
Put(ctx context.Context, l *Library, colsToUpdate ...string) error
Delete(ctx context.Context, id int) error
StoreMusicFolder(ctx context.Context) error
AddArtist(ctx context.Context, id int, artistID string) error
GetUsersWithLibraryAccess(ctx context.Context, libraryID int) (Users, error)
ScanBegin(ctx context.Context, id int, fullScan bool) error
ScanEnd(ctx context.Context, id int) error
SetScannedPID(ctx context.Context, id int, pid PIDConfig) error
ScanInProgress(ctx context.Context) (bool, error)
RefreshStats(ctx context.Context, id int) error
}