model

package
v0.61.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 12, 2026 License: GPL-3.0 Imports: 33 Imported by: 2

Documentation

Index

Constants

View Source
const (
	DefaultLibraryID   = 1
	DefaultLibraryName = "Music Library"
)

Variables

View Source
var (
	KindMediaFileArtwork = Kind{"mf", "media_file"}
	KindArtistArtwork    = Kind{"ar", "artist"}
	KindAlbumArtwork     = Kind{"al", "album"}
	KindPlaylistArtwork  = Kind{"pl", "playlist"}
	KindDiscArtwork      = Kind{"dc", "disc"}
	KindRadioArtwork     = Kind{"ra", "radio"}
)
View Source
var (
	ErrNotFound      = errors.New("data not found")
	ErrInvalidAuth   = errors.New("invalid authentication")
	ErrNotAuthorized = errors.New("not authorized")
	ErrExpired       = errors.New("access expired")
	ErrNotAvailable  = errors.New("functionality not available")
	ErrValidation    = errors.New("validation error")
)
View Source
var (
	RoleInvalid     = Role{"invalid"}
	RoleArtist      = Role{"artist"}
	RoleAlbumArtist = Role{"albumartist"}
	RoleComposer    = Role{"composer"}
	RoleConductor   = Role{"conductor"}
	RoleLyricist    = Role{"lyricist"}
	RoleArranger    = Role{"arranger"}
	RoleProducer    = Role{"producer"}
	RoleDirector    = Role{"director"}
	RoleEngineer    = Role{"engineer"}
	RoleMixer       = Role{"mixer"}
	RoleRemixer     = Role{"remixer"}
	RoleDJMixer     = Role{"djmixer"}
	RolePerformer   = Role{"performer"}
	// RoleMainCredit is a credit where the artist is an album artist or artist
	RoleMainCredit = Role{"maincredit"}
)
View Source
var AlbumLevelTags = sync.OnceValue(func() map[TagName]struct{} {
	tags := make(map[TagName]struct{})
	m := TagMappings()
	for t, conf := range m {
		if conf.Album {
			tags[t] = struct{}{}
		}
	}
	return tags
})

AlbumLevelTags contains all Tags marked as `album: true` in the mappings.yml file. They are not "first-class citizens" in the Album struct, but are still stored in the album table, in the `tags` column.

Functions

func DiscArtworkID added in v0.61.0

func DiscArtworkID(albumID string, discNumber int) string

func FolderID added in v0.55.0

func FolderID(lib Library, path string) string

FolderID generates a unique ID for a folder in a library. The ID is generated based on the library ID and the folder path relative to the library root. Any leading or trailing slashes are removed from the folder path.

func GetEntityByID added in v0.49.0

func GetEntityByID(ctx context.Context, ds DataStore, id string) (any, error)

TODO: Should the type be encoded in the ID?

func IsAudioFile added in v0.49.0

func IsAudioFile(filePath string) bool

func IsImageFile added in v0.49.0

func IsImageFile(filePath string) bool

func IsValidPlaylist added in v0.49.0

func IsValidPlaylist(filePath string) bool

func ParseDiscArtworkID added in v0.61.0

func ParseDiscArtworkID(id string) (albumID string, discNumber int, err error)

func TagMainMappings added in v0.55.0

func TagMainMappings() map[TagName]TagConf

func TagMappings added in v0.55.0

func TagMappings() map[TagName]TagConf

func UploadedImagePath added in v0.61.0

func UploadedImagePath(entityType, filename string) string

UploadedImagePath returns the absolute filesystem path for a manually uploaded entity cover image. Returns empty string if filename is empty.

Types

type Album

type Album struct {
	Annotations `structs:"-" hash:"ignore"`

	ID            string `structs:"id" json:"id"`
	LibraryID     int    `structs:"library_id" json:"libraryId"`
	LibraryPath   string `structs:"-" json:"libraryPath" hash:"ignore"`
	LibraryName   string `structs:"-" json:"libraryName" hash:"ignore"`
	Name          string `structs:"name" json:"name"`
	EmbedArtPath  string `structs:"embed_art_path" json:"-"`
	AlbumArtistID string `structs:"album_artist_id" json:"albumArtistId"` // Deprecated, use Participants
	// AlbumArtist is the display name used for the album artist.
	AlbumArtist          string   `structs:"album_artist" json:"albumArtist"`
	MaxYear              int      `structs:"max_year" json:"maxYear"`
	MinYear              int      `structs:"min_year" json:"minYear"`
	Date                 string   `structs:"date" json:"date,omitempty"`
	MaxOriginalYear      int      `structs:"max_original_year" json:"maxOriginalYear"`
	MinOriginalYear      int      `structs:"min_original_year" json:"minOriginalYear"`
	OriginalDate         string   `structs:"original_date" json:"originalDate,omitempty"`
	ReleaseDate          string   `structs:"release_date" json:"releaseDate,omitempty"`
	Compilation          bool     `structs:"compilation" json:"compilation"`
	Comment              string   `structs:"comment" json:"comment,omitempty"`
	SongCount            int      `structs:"song_count" json:"songCount"`
	Duration             float32  `structs:"duration" json:"duration"`
	Size                 int64    `structs:"size" json:"size"`
	Discs                Discs    `structs:"discs" json:"discs,omitempty"`
	SortAlbumName        string   `structs:"sort_album_name" json:"sortAlbumName,omitempty"`
	SortAlbumArtistName  string   `structs:"sort_album_artist_name" json:"sortAlbumArtistName,omitempty"`
	OrderAlbumName       string   `structs:"order_album_name" json:"orderAlbumName"`
	OrderAlbumArtistName string   `structs:"order_album_artist_name" json:"orderAlbumArtistName"`
	CatalogNum           string   `structs:"catalog_num" json:"catalogNum,omitempty"`
	MbzAlbumID           string   `structs:"mbz_album_id" json:"mbzAlbumId,omitempty"`
	MbzAlbumArtistID     string   `structs:"mbz_album_artist_id" json:"mbzAlbumArtistId,omitempty"`
	MbzAlbumType         string   `structs:"mbz_album_type" json:"mbzAlbumType,omitempty"`
	MbzAlbumComment      string   `structs:"mbz_album_comment" json:"mbzAlbumComment,omitempty"`
	MbzReleaseGroupID    string   `structs:"mbz_release_group_id" json:"mbzReleaseGroupId,omitempty"`
	FolderIDs            []string `structs:"folder_ids" json:"-" hash:"set"` // All folders that contain media_files for this album
	ExplicitStatus       string   `structs:"explicit_status" json:"explicitStatus"`

	// External metadata fields
	Description           string     `structs:"description" json:"description,omitempty" hash:"ignore"`
	SmallImageUrl         string     `structs:"small_image_url" json:"smallImageUrl,omitempty" hash:"ignore"`
	MediumImageUrl        string     `structs:"medium_image_url" json:"mediumImageUrl,omitempty" hash:"ignore"`
	LargeImageUrl         string     `structs:"large_image_url" json:"largeImageUrl,omitempty" hash:"ignore"`
	ExternalUrl           string     `structs:"external_url" json:"externalUrl,omitempty" hash:"ignore"`
	ExternalInfoUpdatedAt *time.Time `structs:"external_info_updated_at" json:"externalInfoUpdatedAt" hash:"ignore"`

	Genre        string       `structs:"genre" json:"genre" hash:"ignore"`               // Easy access to the most common genre
	Genres       Genres       `structs:"-" json:"genres" hash:"ignore"`                  // Easy access to all genres for this album
	Tags         Tags         `structs:"tags" json:"tags,omitempty" hash:"ignore"`       // All imported tags for this album
	Participants Participants `structs:"participants" json:"participants" hash:"ignore"` // All artists that participated in this album

	Missing    bool      `structs:"missing" json:"missing"`                      // If all file of the album ar missing
	ImportedAt time.Time `structs:"imported_at" json:"importedAt" hash:"ignore"` // When this album was imported/updated
	CreatedAt  time.Time `structs:"created_at" json:"createdAt"`                 // Oldest CreatedAt for all songs in this album
	UpdatedAt  time.Time `structs:"updated_at" json:"updatedAt"`                 // Newest UpdatedAt for all songs in this album
}

func (Album) CoverArtID added in v0.49.0

func (a Album) CoverArtID() ArtworkID

func (Album) Equals added in v0.55.0

func (a Album) Equals(other Album) bool

Equals compares two Album structs, ignoring calculated fields

func (Album) FullName added in v0.61.0

func (a Album) FullName() string

func (*Album) SetTags added in v0.55.0

func (a *Album) SetTags(tags TagList)

type AlbumCursor added in v0.55.0

type AlbumCursor iter.Seq2[Album, error]

type AlbumRepository

type AlbumRepository interface {
	CountAll(...QueryOptions) (int64, error)
	Exists(id string) (bool, error)
	Put(*Album) error
	UpdateExternalInfo(*Album) error
	Get(id string) (*Album, error)
	GetAll(...QueryOptions) (Albums, error)

	// The following methods are used exclusively by the scanner:
	Touch(ids ...string) error
	TouchByMissingFolder() (int64, error)
	GetTouchedAlbums(libID int) (AlbumCursor, error)
	RefreshPlayCounts() (int64, error)
	CopyAttributes(fromID, toID string, columns ...string) error

	AnnotatedRepository
	SearchableRepository[Albums]
}

type Albums

type Albums []Album

type AnnotatedRepository

type AnnotatedRepository interface {
	IncPlayCount(itemID string, ts time.Time) error
	SetStar(starred bool, itemIDs ...string) error
	SetRating(rating int, itemID string) error
	ReassignAnnotation(prevID string, newID string) error
}

type Annotations

type Annotations struct {
	PlayCount     int64      `structs:"play_count"     json:"playCount,omitempty"`
	PlayDate      *time.Time `structs:"play_date"      json:"playDate,omitempty" `
	Rating        int        `structs:"rating"         json:"rating,omitempty"   `
	RatedAt       *time.Time `structs:"rated_at"       json:"ratedAt,omitempty"  `
	Starred       bool       `structs:"starred"        json:"starred,omitempty"  `
	StarredAt     *time.Time `structs:"starred_at"     json:"starredAt,omitempty"`
	AverageRating float64    `structs:"average_rating" json:"averageRating,omitempty"`
}

type Artist

type Artist struct {
	Annotations `structs:"-"`

	ID string `structs:"id" json:"id"`

	// Data based on tags
	Name            string `structs:"name" json:"name"`
	SortArtistName  string `structs:"sort_artist_name" json:"sortArtistName,omitempty"`
	OrderArtistName string `structs:"order_artist_name" json:"orderArtistName,omitempty"`
	MbzArtistID     string `structs:"mbz_artist_id" json:"mbzArtistId,omitempty"`

	// Data calculated from files
	Stats      map[Role]ArtistStats `structs:"-" json:"stats,omitempty"`
	Size       int64                `structs:"-" json:"size,omitempty"`
	AlbumCount int                  `structs:"-" json:"albumCount,omitempty"`
	SongCount  int                  `structs:"-" json:"songCount,omitempty"`

	// Data imported from external sources
	Biography             string     `structs:"biography" json:"biography,omitempty"`
	SmallImageUrl         string     `structs:"small_image_url" json:"smallImageUrl,omitempty"`
	MediumImageUrl        string     `structs:"medium_image_url" json:"mediumImageUrl,omitempty"`
	LargeImageUrl         string     `structs:"large_image_url" json:"largeImageUrl,omitempty"`
	ExternalUrl           string     `structs:"external_url" json:"externalUrl,omitempty"`
	SimilarArtists        Artists    `structs:"similar_artists"  json:"-"`
	ExternalInfoUpdatedAt *time.Time `structs:"external_info_updated_at" json:"externalInfoUpdatedAt,omitempty"`

	Missing bool `structs:"missing" json:"missing"`

	UploadedImage string `structs:"uploaded_image" json:"uploadedImage,omitempty"`

	CreatedAt *time.Time `structs:"created_at" json:"createdAt,omitempty"`
	UpdatedAt *time.Time `structs:"updated_at" json:"updatedAt,omitempty"`
}

func (Artist) ArtistImageUrl

func (a Artist) ArtistImageUrl() string

func (Artist) CoverArtID added in v0.49.0

func (a Artist) CoverArtID() ArtworkID

func (Artist) Roles added in v0.55.0

func (a Artist) Roles() []Role

Roles returns the roles this artist has participated in., based on the Stats field

func (Artist) UploadedImagePath added in v0.61.0

func (a Artist) UploadedImagePath() string

type ArtistIndex

type ArtistIndex struct {
	ID      string
	Artists Artists
}

type ArtistIndexes

type ArtistIndexes []ArtistIndex

type ArtistInfo

type ArtistInfo struct {
	ID             string
	Name           string
	MBID           string
	Biography      string
	SmallImageUrl  string
	MediumImageUrl string
	LargeImageUrl  string
	LastFMUrl      string
	SimilarArtists Artists
}

type ArtistRepository

type ArtistRepository interface {
	CountAll(options ...QueryOptions) (int64, error)
	Exists(id string) (bool, error)
	Put(m *Artist, colsToUpdate ...string) error
	UpdateExternalInfo(a *Artist) error
	Get(id string) (*Artist, error)
	GetAll(options ...QueryOptions) (Artists, error)
	GetIndex(includeMissing bool, libraryIds []int, roles ...Role) (ArtistIndexes, error)

	// The following methods are used exclusively by the scanner:
	RefreshPlayCounts() (int64, error)
	RefreshStats(allArtists bool) (int64, error)

	AnnotatedRepository
	SearchableRepository[Artists]
}

type ArtistStats added in v0.55.0

type ArtistStats struct {
	SongCount  int   `json:"songCount"`
	AlbumCount int   `json:"albumCount"`
	Size       int64 `json:"size"`
}

type Artists

type Artists []Artist

type ArtworkID added in v0.49.0

type ArtworkID struct {
	Kind       Kind
	ID         string
	LastUpdate time.Time
}

func MustParseArtworkID added in v0.49.0

func MustParseArtworkID(id string) ArtworkID

func NewArtworkID added in v0.49.0

func NewArtworkID(kind Kind, id string, lastUpdate *time.Time) ArtworkID

func ParseArtworkID added in v0.49.0

func ParseArtworkID(id string) (ArtworkID, error)

func (ArtworkID) String added in v0.49.0

func (id ArtworkID) String() string

type Bookmark

type Bookmark struct {
	Item      MediaFile `structs:"item" json:"item"`
	Comment   string    `structs:"comment" json:"comment"`
	Position  int64     `structs:"position" json:"position"`
	ChangedBy string    `structs:"changed_by" json:"changed_by"`
	CreatedAt time.Time `structs:"created_at" json:"createdAt"`
	UpdatedAt time.Time `structs:"updated_at" json:"updatedAt"`
}

type Bookmarkable

type Bookmarkable struct {
	BookmarkPosition int64 `structs:"-" json:"bookmarkPosition"`
}

type BookmarkableRepository

type BookmarkableRepository interface {
	AddBookmark(id, comment string, position int64) error
	DeleteBookmark(id string) error
	GetBookmarks() (Bookmarks, error)
}

type Bookmarks

type Bookmarks []Bookmark

type DataStore

type DataStore interface {
	Library(ctx context.Context) LibraryRepository
	Folder(ctx context.Context) FolderRepository
	Album(ctx context.Context) AlbumRepository
	Artist(ctx context.Context) ArtistRepository
	MediaFile(ctx context.Context) MediaFileRepository
	Genre(ctx context.Context) GenreRepository
	Tag(ctx context.Context) TagRepository
	Playlist(ctx context.Context) PlaylistRepository
	PlayQueue(ctx context.Context) PlayQueueRepository
	Transcoding(ctx context.Context) TranscodingRepository
	Player(ctx context.Context) PlayerRepository
	Radio(ctx context.Context) RadioRepository
	Share(ctx context.Context) ShareRepository
	Property(ctx context.Context) PropertyRepository
	User(ctx context.Context) UserRepository
	UserProps(ctx context.Context) UserPropsRepository
	ScrobbleBuffer(ctx context.Context) ScrobbleBufferRepository
	Scrobble(ctx context.Context) ScrobbleRepository
	Plugin(ctx context.Context) PluginRepository

	Resource(ctx context.Context, model any) ResourceRepository

	WithTx(block func(tx DataStore) error, scope ...string) error
	WithTxImmediate(block func(tx DataStore) error, scope ...string) error
	GC(ctx context.Context, libraryIDs ...int) error
}

type DiscID added in v0.46.0

type DiscID struct {
	AlbumID     string `json:"albumId"`
	ReleaseDate string `json:"releaseDate"`
	DiscNumber  int    `json:"discNumber"`
}

type Discs added in v0.51.0

type Discs map[int]string

func (Discs) Add added in v0.51.0

func (d Discs) Add(discNumber int, discSubtitle string)

type Folder added in v0.55.0

type Folder struct {
	ID              string    `structs:"id"`
	LibraryID       int       `structs:"library_id"`
	LibraryPath     string    `structs:"-" json:"-" hash:"ignore"`
	Path            string    `structs:"path"`
	Name            string    `structs:"name"`
	ParentID        string    `structs:"parent_id"`
	NumAudioFiles   int       `structs:"num_audio_files"`
	NumPlaylists    int       `structs:"num_playlists"`
	ImageFiles      []string  `structs:"image_files"`
	ImagesUpdatedAt time.Time `structs:"images_updated_at"`
	Hash            string    `structs:"hash"`
	Missing         bool      `structs:"missing"`
	UpdateAt        time.Time `structs:"updated_at"`
	CreatedAt       time.Time `structs:"created_at"`
}

Folder represents a folder in the library. Its path is relative to the library root. ALWAYS use NewFolder to create a new instance.

func NewFolder added in v0.55.0

func NewFolder(lib Library, folderPath string) *Folder

func (Folder) AbsolutePath added in v0.55.0

func (f Folder) AbsolutePath() string

func (Folder) String added in v0.55.0

func (f Folder) String() string

type FolderCursor added in v0.55.0

type FolderCursor iter.Seq2[Folder, error]

type FolderRepository added in v0.55.0

type FolderRepository interface {
	Get(id string) (*Folder, error)
	GetByPath(lib Library, path string) (*Folder, error)
	GetAll(...QueryOptions) ([]Folder, error)
	CountAll(...QueryOptions) (int64, error)
	GetFolderUpdateInfo(lib Library, targetPaths ...string) (map[string]FolderUpdateInfo, error)
	Put(*Folder) error
	MarkMissing(missing bool, ids ...string) error
	GetTouchedWithPlaylists() (FolderCursor, error)
}

type FolderUpdateInfo added in v0.57.0

type FolderUpdateInfo struct {
	UpdatedAt time.Time
	Hash      string
}

type Genre

type Genre struct {
	ID         string `structs:"id" json:"id,omitempty" toml:"id,omitempty" yaml:"id,omitempty"`
	Name       string `structs:"name" json:"name"`
	SongCount  int    `structs:"-" json:"-" toml:"-" yaml:"-"`
	AlbumCount int    `structs:"-" json:"-" toml:"-" yaml:"-"`
}

type GenreRepository

type GenreRepository interface {
	GetAll(...QueryOptions) (Genres, error)
}

type Genres

type Genres []Genre

type Kind added in v0.49.0

type Kind struct {
	// contains filtered or unexported fields
}

func (Kind) String added in v0.49.0

func (k Kind) String() string

type Libraries added in v0.53.0

type Libraries []Library

func (Libraries) IDs added in v0.58.0

func (l Libraries) IDs() []int

type Library added in v0.53.0

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"`
}

type LibraryRepository added in v0.53.0

type LibraryRepository interface {
	Get(id int) (*Library, error)
	// GetPath returns the path of the library with the given ID.
	// Its implementation must be optimized to avoid unnecessary queries.
	GetPath(id int) (string, error)
	GetAll(...QueryOptions) (Libraries, error)
	CountAll(...QueryOptions) (int64, error)
	Put(*Library) error
	Delete(id int) error
	StoreMusicFolder() error
	AddArtist(id int, artistID string) error

	// User-library association methods
	GetUsersWithLibraryAccess(libraryID int) (Users, error)

	// TODO These methods should be moved to a core service
	ScanBegin(id int, fullScan bool) error
	ScanEnd(id int) error
	ScanInProgress() (bool, error)
	RefreshStats(id int) error
}

type Line added in v0.51.0

type Line struct {
	Start *int64 `structs:"start,omitempty" json:"start,omitempty"`
	Value string `structs:"value"           json:"value"`
}

type LyricList added in v0.51.0

type LyricList []Lyrics

type Lyrics added in v0.51.0

type Lyrics struct {
	DisplayArtist string `structs:"displayArtist,omitempty" json:"displayArtist,omitempty"`
	DisplayTitle  string `structs:"displayTitle,omitempty"  json:"displayTitle,omitempty"`
	Lang          string `structs:"lang"                    json:"lang"`
	Line          []Line `structs:"line"                    json:"line"`
	Offset        *int64 `structs:"offset,omitempty"        json:"offset,omitempty"`
	Synced        bool   `structs:"synced"                  json:"synced"`
}

func ToLyrics added in v0.51.0

func ToLyrics(language, text string) (*Lyrics, error)

func (Lyrics) IsEmpty added in v0.55.0

func (l Lyrics) IsEmpty() bool

type MediaFile

type MediaFile struct {
	Annotations  `structs:"-" hash:"ignore"`
	Bookmarkable `structs:"-" hash:"ignore"`

	ID          string `structs:"id"  json:"id" hash:"ignore"`
	PID         string `structs:"pid" json:"-" hash:"ignore"`
	LibraryID   int    `structs:"library_id" json:"libraryId" hash:"ignore"`
	LibraryPath string `structs:"-" json:"libraryPath" hash:"ignore"`
	LibraryName string `structs:"-" json:"libraryName" hash:"ignore"`
	FolderID    string `structs:"folder_id" json:"folderId" hash:"ignore"`
	Path        string `structs:"path" json:"path" hash:"ignore"`
	Title       string `structs:"title" json:"title"`
	Album       string `structs:"album" json:"album"`
	ArtistID    string `structs:"artist_id" json:"artistId"` // Deprecated: Use Participants instead
	// Artist is the display name used for the artist.
	Artist        string `structs:"artist" json:"artist"`
	AlbumArtistID string `structs:"album_artist_id" json:"albumArtistId"` // Deprecated: Use Participants instead
	// AlbumArtist is the display name used for the album artist.
	AlbumArtist          string   `structs:"album_artist" json:"albumArtist"`
	AlbumID              string   `structs:"album_id" json:"albumId" hash:"ignore"`
	HasCoverArt          bool     `structs:"has_cover_art" json:"hasCoverArt"`
	TrackNumber          int      `structs:"track_number" json:"trackNumber"`
	DiscNumber           int      `structs:"disc_number" json:"discNumber"`
	DiscSubtitle         string   `structs:"disc_subtitle" json:"discSubtitle,omitempty"`
	Year                 int      `structs:"year" json:"year"`
	Date                 string   `structs:"date" json:"date,omitempty"`
	OriginalYear         int      `structs:"original_year" json:"originalYear"`
	OriginalDate         string   `structs:"original_date" json:"originalDate,omitempty"`
	ReleaseYear          int      `structs:"release_year" json:"releaseYear"`
	ReleaseDate          string   `structs:"release_date" json:"releaseDate,omitempty"`
	Size                 int64    `structs:"size" json:"size"`
	Suffix               string   `structs:"suffix" json:"suffix"`
	Duration             float32  `structs:"duration" json:"duration"`
	BitRate              int      `structs:"bit_rate" json:"bitRate"`
	SampleRate           int      `structs:"sample_rate" json:"sampleRate"`
	BitDepth             int      `structs:"bit_depth" json:"bitDepth"`
	Channels             int      `structs:"channels" json:"channels"`
	Codec                string   `structs:"codec" json:"codec"`
	ProbeData            string   `structs:"probe_data" json:"-" hash:"ignore"`
	Genre                string   `structs:"genre" json:"genre"`
	Genres               Genres   `structs:"-" json:"genres,omitempty"`
	SortTitle            string   `structs:"sort_title" json:"sortTitle,omitempty"`
	SortAlbumName        string   `structs:"sort_album_name" json:"sortAlbumName,omitempty"`
	SortArtistName       string   `structs:"sort_artist_name" json:"sortArtistName,omitempty"`            // Deprecated: Use Participants instead
	SortAlbumArtistName  string   `structs:"sort_album_artist_name" json:"sortAlbumArtistName,omitempty"` // Deprecated: Use Participants instead
	OrderTitle           string   `structs:"order_title" json:"orderTitle,omitempty"`
	OrderAlbumName       string   `structs:"order_album_name" json:"orderAlbumName"`
	OrderArtistName      string   `structs:"order_artist_name" json:"orderArtistName"`            // Deprecated: Use Participants instead
	OrderAlbumArtistName string   `structs:"order_album_artist_name" json:"orderAlbumArtistName"` // Deprecated: Use Participants instead
	Compilation          bool     `structs:"compilation" json:"compilation"`
	Comment              string   `structs:"comment" json:"comment,omitempty"`
	Lyrics               string   `structs:"lyrics" json:"lyrics"`
	BPM                  int      `structs:"bpm" json:"bpm,omitempty"`
	ExplicitStatus       string   `structs:"explicit_status" json:"explicitStatus"`
	CatalogNum           string   `structs:"catalog_num" json:"catalogNum,omitempty"`
	MbzRecordingID       string   `structs:"mbz_recording_id" json:"mbzRecordingID,omitempty"`
	MbzReleaseTrackID    string   `structs:"mbz_release_track_id" json:"mbzReleaseTrackId,omitempty"`
	MbzAlbumID           string   `structs:"mbz_album_id" json:"mbzAlbumId,omitempty"`
	MbzReleaseGroupID    string   `structs:"mbz_release_group_id" json:"mbzReleaseGroupId,omitempty"`
	MbzArtistID          string   `structs:"mbz_artist_id" json:"mbzArtistId,omitempty"`            // Deprecated: Use Participants instead
	MbzAlbumArtistID     string   `structs:"mbz_album_artist_id" json:"mbzAlbumArtistId,omitempty"` // Deprecated: Use Participants instead
	MbzAlbumType         string   `structs:"mbz_album_type" json:"mbzAlbumType,omitempty"`
	MbzAlbumComment      string   `structs:"mbz_album_comment" json:"mbzAlbumComment,omitempty"`
	RGAlbumGain          *float64 `structs:"rg_album_gain" json:"rgAlbumGain"`
	RGAlbumPeak          *float64 `structs:"rg_album_peak" json:"rgAlbumPeak"`
	RGTrackGain          *float64 `structs:"rg_track_gain" json:"rgTrackGain"`
	RGTrackPeak          *float64 `structs:"rg_track_peak" json:"rgTrackPeak"`

	Tags         Tags         `structs:"tags" json:"tags,omitempty" hash:"ignore"`       // All imported tags from the original file
	Participants Participants `structs:"participants" json:"participants" hash:"ignore"` // All artists that participated in this track

	Missing   bool      `structs:"missing" json:"missing" hash:"ignore"`      // If the file is not found in the library's FS
	BirthTime time.Time `structs:"birth_time" json:"birthTime" hash:"ignore"` // Time of file creation (ctime)
	CreatedAt time.Time `structs:"created_at" json:"createdAt" hash:"ignore"` // Time this entry was created in the DB
	UpdatedAt time.Time `structs:"updated_at" json:"updatedAt" hash:"ignore"` // Time of file last update (mtime)
}

func (MediaFile) AbsolutePath added in v0.55.0

func (mf MediaFile) AbsolutePath() string

func (MediaFile) AlbumCoverArtID added in v0.49.0

func (mf MediaFile) AlbumCoverArtID() ArtworkID

func (MediaFile) AudioCodec added in v0.61.0

func (mf MediaFile) AudioCodec() string

AudioCodec returns the audio codec for this file. Uses the stored Codec field if available, otherwise infers from Suffix and audio properties.

func (MediaFile) ContentType

func (mf MediaFile) ContentType() string

func (MediaFile) CoverArtID added in v0.49.0

func (mf MediaFile) CoverArtID() ArtworkID

func (MediaFile) DiscCoverArtID added in v0.61.0

func (mf MediaFile) DiscCoverArtID() ArtworkID

DiscCoverArtID returns the disc artwork ID when the media file has a disc number, otherwise it returns the album artwork ID.

func (MediaFile) Equals added in v0.55.0

func (mf MediaFile) Equals(other MediaFile) bool

Equals compares two MediaFiles by their hash. It does not consider the ID, PID, Path and other identifier fields. Check the structure for the fields that are marked with `hash:"ignore"`.

func (MediaFile) FullAlbumName added in v0.61.0

func (mf MediaFile) FullAlbumName() string

func (MediaFile) FullTitle added in v0.55.0

func (mf MediaFile) FullTitle() string

func (MediaFile) Hash added in v0.55.0

func (mf MediaFile) Hash() string

Hash returns a hash of the MediaFile based on its tags and audio properties

func (MediaFile) IsEquivalent added in v0.55.0

func (mf MediaFile) IsEquivalent(other MediaFile) bool

IsEquivalent compares two MediaFiles by path only. Used for matching missing tracks.

func (MediaFile) String added in v0.55.0

func (mf MediaFile) String() string

String is mainly used for debugging

func (MediaFile) StructuredLyrics added in v0.51.0

func (mf MediaFile) StructuredLyrics() (LyricList, error)

type MediaFileCursor added in v0.55.0

type MediaFileCursor iter.Seq2[MediaFile, error]

type MediaFileRepository

type MediaFileRepository interface {
	CountAll(options ...QueryOptions) (int64, error)
	CountBySuffix(options ...QueryOptions) (map[string]int64, error)
	Exists(id string) (bool, error)
	Put(m *MediaFile) error
	UpdateProbeData(id string, data string) error
	Get(id string) (*MediaFile, error)
	GetWithParticipants(id string) (*MediaFile, error)
	GetAll(options ...QueryOptions) (MediaFiles, error)
	GetAllByTags(tag TagName, values []string, options ...QueryOptions) (MediaFiles, error)
	GetCursor(options ...QueryOptions) (MediaFileCursor, error)
	Delete(id string) error
	DeleteMissing(ids []string) error
	DeleteAllMissing() (int64, error)
	FindByPaths(paths []string) (MediaFiles, error)

	// The following methods are used exclusively by the scanner:
	MarkMissing(bool, ...*MediaFile) error
	MarkMissingByFolder(missing bool, folderIDs ...string) error
	GetMissingAndMatching(libId int) (MediaFileCursor, error)
	FindRecentFilesByMBZTrackID(missing MediaFile, since time.Time) (MediaFiles, error)
	FindRecentFilesByProperties(missing MediaFile, since time.Time) (MediaFiles, error)

	AnnotatedRepository
	BookmarkableRepository
	SearchableRepository[MediaFiles]
}

type MediaFiles

type MediaFiles []MediaFile

func (MediaFiles) ToAlbum added in v0.49.0

func (mfs MediaFiles) ToAlbum() Album

ToAlbum creates an Album object based on the attributes of this MediaFiles collection. It assumes all mediafiles have the same Album (same ID), or else results are unpredictable.

func (MediaFiles) ToM3U8 added in v0.56.0

func (mfs MediaFiles) ToM3U8(title string, absolutePaths bool) string

ToM3U8 exports the playlist to the Extended M3U8 format, as specified in https://docs.fileformat.com/audio/m3u/#extended-m3u

type Participant added in v0.55.0

type Participant struct {
	Artist
	SubRole string `json:"subRole,omitempty"`
}

type ParticipantList added in v0.55.0

type ParticipantList []Participant

func (ParticipantList) Join added in v0.55.0

func (p ParticipantList) Join(sep string) string

type Participants added in v0.55.0

type Participants map[Role]ParticipantList

func (Participants) Add added in v0.55.0

func (p Participants) Add(role Role, artists ...Artist)

Add adds the artists to the role, ignoring duplicates.

func (Participants) AddWithSubRole added in v0.55.0

func (p Participants) AddWithSubRole(role Role, subRole string, artists ...Artist)

AddWithSubRole adds the artists to the role, ignoring duplicates.

func (Participants) AllArtists added in v0.55.0

func (p Participants) AllArtists() []Artist

AllArtists returns all artists found in the Participants.

func (Participants) AllIDs added in v0.55.0

func (p Participants) AllIDs() []string

AllIDs returns all artist IDs found in the Participants.

func (Participants) AllNames added in v0.55.0

func (p Participants) AllNames() []string

AllNames returns all artist names found in the Participants, including SortArtistNames.

func (Participants) First added in v0.55.0

func (p Participants) First(role Role) Artist

First returns the first artist for the role, or an empty artist if the role is not present.

func (Participants) Hash added in v0.55.0

func (p Participants) Hash() []byte

func (Participants) Merge added in v0.55.0

func (p Participants) Merge(other Participants)

Merge merges the other Participants into this one.

func (Participants) Sort added in v0.55.0

func (p Participants) Sort()

type PlayQueue

type PlayQueue struct {
	ID        string     `structs:"id" json:"id"`
	UserID    string     `structs:"user_id" json:"userId"`
	Current   int        `structs:"current" json:"current"`
	Position  int64      `structs:"position" json:"position"`
	ChangedBy string     `structs:"changed_by" json:"changedBy"`
	Items     MediaFiles `structs:"-" json:"items,omitempty"`
	CreatedAt time.Time  `structs:"created_at" json:"createdAt"`
	UpdatedAt time.Time  `structs:"updated_at" json:"updatedAt"`
}

type PlayQueueRepository

type PlayQueueRepository interface {
	Store(queue *PlayQueue, colNames ...string) error
	// Retrieve returns the playqueue without loading the full MediaFiles
	// (Items only contain IDs)
	Retrieve(userId string) (*PlayQueue, error)
	// RetrieveWithMediaFiles returns the playqueue with full MediaFiles loaded
	RetrieveWithMediaFiles(userId string) (*PlayQueue, error)
	Clear(userId string) error
}

type PlayQueues

type PlayQueues []PlayQueue

type Player

type Player struct {
	Username string `structs:"-" json:"userName"`

	ID              string    `structs:"id" json:"id"`
	Name            string    `structs:"name" json:"name"`
	UserAgent       string    `structs:"user_agent" json:"userAgent"`
	UserId          string    `structs:"user_id" json:"userId"`
	Client          string    `structs:"client" json:"client"`
	IP              string    `structs:"ip" json:"ip"`
	LastSeen        time.Time `structs:"last_seen" json:"lastSeen"`
	TranscodingId   string    `structs:"transcoding_id" json:"transcodingId"`
	MaxBitRate      int       `structs:"max_bit_rate" json:"maxBitRate"`
	ReportRealPath  bool      `structs:"report_real_path" json:"reportRealPath"`
	ScrobbleEnabled bool      `structs:"scrobble_enabled" json:"scrobbleEnabled"`
}

type PlayerRepository

type PlayerRepository interface {
	Get(id string) (*Player, error)
	FindMatch(userId, client, userAgent string) (*Player, error)
	Put(p *Player) error
	CountAll(...QueryOptions) (int64, error)
	CountByClient(...QueryOptions) (map[string]int64, error)
}

type Players

type Players []Player

type Playlist

type Playlist struct {
	ID               string         `structs:"id" json:"id"`
	Name             string         `structs:"name" json:"name"`
	Comment          string         `structs:"comment" json:"comment"`
	Duration         float32        `structs:"duration" json:"duration"`
	Size             int64          `structs:"size" json:"size"`
	SongCount        int            `structs:"song_count" json:"songCount"`
	OwnerName        string         `structs:"-" json:"ownerName"`
	OwnerID          string         `structs:"owner_id" json:"ownerId"`
	Public           bool           `structs:"public" json:"public"`
	Tracks           PlaylistTracks `structs:"-" json:"tracks,omitempty"`
	Path             string         `structs:"path" json:"path"`
	Sync             bool           `structs:"sync" json:"sync"`
	UploadedImage    string         `structs:"uploaded_image" json:"uploadedImage"`
	ExternalImageURL string         `structs:"external_image_url" json:"externalImageUrl,omitempty"`
	CreatedAt        time.Time      `structs:"created_at" json:"createdAt"`
	UpdatedAt        time.Time      `structs:"updated_at" json:"updatedAt"`

	// SmartPlaylist attributes
	Rules       *criteria.Criteria `structs:"rules" json:"rules"`
	EvaluatedAt *time.Time         `structs:"evaluated_at" json:"evaluatedAt"`
}

func (*Playlist) AddMediaFiles added in v0.47.0

func (pls *Playlist) AddMediaFiles(mfs MediaFiles)

func (*Playlist) AddMediaFilesByID added in v0.58.0

func (pls *Playlist) AddMediaFilesByID(mediaFileIds []string)

func (Playlist) CoverArtID added in v0.49.0

func (pls Playlist) CoverArtID() ArtworkID

func (Playlist) IsSmartPlaylist added in v0.47.0

func (pls Playlist) IsSmartPlaylist() bool

func (Playlist) MediaFiles added in v0.47.0

func (pls Playlist) MediaFiles() MediaFiles

func (*Playlist) RemoveTracks added in v0.47.0

func (pls *Playlist) RemoveTracks(idxToRemove []int)

func (*Playlist) SetTracks added in v0.58.0

func (pls *Playlist) SetTracks(tracks PlaylistTracks)

func (*Playlist) ToM3U8 added in v0.49.0

func (pls *Playlist) ToM3U8() string

ToM3U8 exports the playlist to the Extended M3U8 format

func (Playlist) UploadedImagePath added in v0.61.0

func (pls Playlist) UploadedImagePath() string

UploadedImagePath returns the absolute filesystem path for a manually uploaded playlist cover image. Returns empty string if no image has been uploaded. This does NOT cover sidecar images or external URLs — those are resolved by the artwork reader's fallback chain.

type PlaylistRepository

type PlaylistRepository interface {
	ResourceRepository
	CountAll(options ...QueryOptions) (int64, error)
	Exists(id string) (bool, error)
	Put(pls *Playlist) error
	Get(id string) (*Playlist, error)
	GetWithTracks(id string, refreshSmartPlaylist, includeMissing bool) (*Playlist, error)
	GetAll(options ...QueryOptions) (Playlists, error)
	FindByPath(path string) (*Playlist, error)
	Delete(id string) error
	Tracks(playlistId string, refreshSmartPlaylist bool) PlaylistTrackRepository
	GetPlaylists(mediaFileId string) (Playlists, error)
}

type PlaylistTrack

type PlaylistTrack struct {
	ID          string `json:"id"`
	MediaFileID string `json:"mediaFileId"`
	PlaylistID  string `json:"playlistId"`
	MediaFile
}

type PlaylistTrackRepository

type PlaylistTrackRepository interface {
	ResourceRepository
	GetAll(options ...QueryOptions) (PlaylistTracks, error)
	GetAlbumIDs(options ...QueryOptions) ([]string, error)
	Add(mediaFileIds []string) (int, error)
	AddAlbums(albumIds []string) (int, error)
	AddArtists(artistIds []string) (int, error)
	AddDiscs(discs []DiscID) (int, error)
	Delete(id ...string) error
	DeleteAll() error
	Reorder(pos int, newPos int) error
}

type PlaylistTracks

type PlaylistTracks []PlaylistTrack

func (PlaylistTracks) MediaFiles added in v0.47.0

func (plt PlaylistTracks) MediaFiles() MediaFiles

type Playlists

type Playlists []Playlist

type Plugin added in v0.60.0

type Plugin struct {
	ID               string    `structs:"id"                 json:"id"`
	Path             string    `structs:"path"               json:"path"`
	Manifest         string    `structs:"manifest"           json:"manifest"`
	Config           string    `structs:"config"             json:"config,omitempty"`
	Users            string    `structs:"users"              json:"users,omitempty"`
	AllUsers         bool      `structs:"all_users"          json:"allUsers,omitempty"`
	Libraries        string    `structs:"libraries"          json:"libraries,omitempty"`
	AllLibraries     bool      `structs:"all_libraries"      json:"allLibraries,omitempty"`
	AllowWriteAccess bool      `structs:"allow_write_access" json:"allowWriteAccess,omitempty"`
	Enabled          bool      `structs:"enabled"            json:"enabled"`
	LastError        string    `structs:"last_error"         json:"lastError,omitempty"`
	SHA256           string    `structs:"sha256"             json:"sha256"`
	CreatedAt        time.Time `structs:"created_at"         json:"createdAt"`
	UpdatedAt        time.Time `structs:"updated_at"         json:"updatedAt"`
}

type PluginRepository added in v0.60.0

type PluginRepository interface {
	ResourceRepository
	ClearErrors() error
	CountAll(options ...QueryOptions) (int64, error)
	Delete(id string) error
	Get(id string) (*Plugin, error)
	GetAll(options ...QueryOptions) (Plugins, error)
	Put(p *Plugin) error
}

type Plugins added in v0.60.0

type Plugins []Plugin

type PropertyRepository

type PropertyRepository interface {
	Put(id string, value string) error
	Get(id string) (string, error)
	Delete(id string) error
	DefaultGet(id string, defaultValue string) (string, error)
}

type QueryOptions

type QueryOptions struct {
	Sort    string
	Order   string
	Max     int
	Offset  int
	Filters squirrel.Sqlizer
	Seed    string // for random sorting
}

type Radio added in v0.49.0

type Radio struct {
	ID            string    `structs:"id"              json:"id"`
	StreamUrl     string    `structs:"stream_url"      json:"streamUrl"`
	Name          string    `structs:"name"            json:"name"`
	HomePageUrl   string    `structs:"home_page_url"   json:"homePageUrl"`
	UploadedImage string    `structs:"uploaded_image"   json:"uploadedImage,omitempty"`
	CreatedAt     time.Time `structs:"created_at"      json:"createdAt"`
	UpdatedAt     time.Time `structs:"updated_at"      json:"updatedAt"`
}

func (Radio) CoverArtID added in v0.61.0

func (r Radio) CoverArtID() ArtworkID

func (Radio) UploadedImagePath added in v0.61.0

func (r Radio) UploadedImagePath() string

type RadioRepository added in v0.49.0

type RadioRepository interface {
	ResourceRepository
	CountAll(options ...QueryOptions) (int64, error)
	Delete(id string) error
	Get(id string) (*Radio, error)
	GetAll(options ...QueryOptions) (Radios, error)
	Put(u *Radio, colsToUpdate ...string) error
}

type Radios added in v0.49.0

type Radios []Radio

type RawTags added in v0.55.0

type RawTags map[string][]string

type ResourceRepository

type ResourceRepository interface {
	rest.Repository
}

type Role added in v0.55.0

type Role struct {
	// contains filtered or unexported fields
}

Role represents the role of an artist in a track or album.

func RoleFromString added in v0.55.0

func RoleFromString(role string) Role

func (Role) MarshalText added in v0.55.0

func (r Role) MarshalText() (text []byte, err error)

func (Role) String added in v0.55.0

func (r Role) String() string

func (*Role) UnmarshalText added in v0.55.0

func (r *Role) UnmarshalText(text []byte) error

type ScanTarget added in v0.59.0

type ScanTarget struct {
	LibraryID  int
	FolderPath string // Relative path within the library, or "" for entire library
}

ScanTarget represents a specific folder within a library to be scanned. NOTE: This struct is used as a map key, so it should only contain comparable types.

func ParseTargets added in v0.59.0

func ParseTargets(libFolders []string) ([]ScanTarget, error)

ParseTargets parses scan targets strings into ScanTarget structs. Example: []string{"1:Music/Rock", "2:Classical"}

func (ScanTarget) String added in v0.59.0

func (st ScanTarget) String() string

type Scanner added in v0.59.0

type Scanner interface {
	// ScanAll starts a scan of all libraries. This is a blocking operation.
	ScanAll(ctx context.Context, fullScan bool) (warnings []string, err error)
	// ScanFolders scans specific library/folder pairs, recursing into subdirectories.
	// If targets is nil, it scans all libraries. This is a blocking operation.
	ScanFolders(ctx context.Context, fullScan bool, targets []ScanTarget) (warnings []string, err error)
	Status(context.Context) (*ScannerStatus, error)
}

type ScannerStatus added in v0.59.0

type ScannerStatus struct {
	Scanning    bool
	LastScan    time.Time
	Count       uint32
	FolderCount uint32
	LastError   string
	ScanType    string
	ElapsedTime time.Duration
}

ScannerStatus holds information about the current scan status

type Scrobble added in v0.59.0

type Scrobble struct {
	MediaFileID    string
	UserID         string
	SubmissionTime time.Time
}

type ScrobbleBufferRepository added in v0.45.0

type ScrobbleBufferRepository interface {
	UserIDs(service string) ([]string, error)
	Enqueue(service, userId, mediaFileId string, playTime time.Time) error
	Next(service string, userId string) (*ScrobbleEntry, error)
	Dequeue(entry *ScrobbleEntry) error
	Length() (int64, error)
}

type ScrobbleEntries added in v0.45.0

type ScrobbleEntries []ScrobbleEntry

type ScrobbleEntry added in v0.45.0

type ScrobbleEntry struct {
	ID          string
	Service     string
	UserID      string
	PlayTime    time.Time
	EnqueueTime time.Time
	MediaFileID string
	MediaFile
}

type ScrobbleRepository added in v0.59.0

type ScrobbleRepository interface {
	RecordScrobble(mediaFileID string, submissionTime time.Time) error
}

type SearchableRepository added in v0.55.0

type SearchableRepository[T any] interface {
	Search(q string, options ...QueryOptions) (T, error)
}

type Share added in v0.44.0

type Share struct {
	ID            string     `structs:"id" json:"id,omitempty"`
	UserID        string     `structs:"user_id" json:"userId,omitempty"`
	Username      string     `structs:"-" json:"username,omitempty"`
	Description   string     `structs:"description" json:"description,omitempty"`
	Downloadable  bool       `structs:"downloadable" json:"downloadable"`
	ExpiresAt     *time.Time `structs:"expires_at" json:"expiresAt,omitempty"`
	LastVisitedAt *time.Time `structs:"last_visited_at" json:"lastVisitedAt,omitempty"`
	ResourceIDs   string     `structs:"resource_ids" json:"resourceIds,omitempty"`
	ResourceType  string     `structs:"resource_type" json:"resourceType,omitempty"`
	Contents      string     `structs:"contents" json:"contents,omitempty"`
	Format        string     `structs:"format" json:"format,omitempty"`
	MaxBitRate    int        `structs:"max_bit_rate" json:"maxBitRate,omitempty"`
	VisitCount    int        `structs:"visit_count" json:"visitCount,omitempty"`
	CreatedAt     time.Time  `structs:"created_at" json:"createdAt"`
	UpdatedAt     time.Time  `structs:"updated_at" json:"updatedAt"`
	Tracks        MediaFiles `structs:"-" json:"tracks,omitempty"`
	Albums        Albums     `structs:"-" json:"albums,omitempty"`
	URL           string     `structs:"-" json:"-"`
	ImageURL      string     `structs:"-" json:"-"`
}

func (Share) CoverArtID added in v0.49.0

func (s Share) CoverArtID() ArtworkID

func (Share) ToM3U8 added in v0.55.0

func (s Share) ToM3U8() string

ToM3U8 exports the share to the Extended M3U8 format.

type ShareRepository added in v0.44.0

type ShareRepository interface {
	Exists(id string) (bool, error)
	Get(id string) (*Share, error)
	GetAll(options ...QueryOptions) (Shares, error)
	CountAll(options ...QueryOptions) (int64, error)
}

type Shares added in v0.44.0

type Shares []Share

type Tag added in v0.55.0

type Tag struct {
	ID         string  `json:"id,omitempty"`
	TagName    TagName `json:"tagName,omitempty"`
	TagValue   string  `json:"tagValue,omitempty"`
	AlbumCount int     `json:"albumCount,omitempty"`
	SongCount  int     `json:"songCount,omitempty"`
}

func NewTag added in v0.55.0

func NewTag(name TagName, value string) Tag

func (Tag) String added in v0.55.0

func (t Tag) String() string

type TagConf added in v0.55.0

type TagConf struct {
	Aliases   []string       `yaml:"aliases"`
	Type      TagType        `yaml:"type"`
	MaxLength int            `yaml:"maxLength"`
	Split     []string       `yaml:"split"`
	Album     bool           `yaml:"album"`
	SplitRx   *regexp.Regexp `yaml:"-"`
}

func TagArtistsConf added in v0.55.0

func TagArtistsConf() TagConf

func TagRolesConf added in v0.55.0

func TagRolesConf() TagConf

func (TagConf) SplitTagValue added in v0.55.0

func (c TagConf) SplitTagValue(values []string) []string

SplitTagValue splits a tag value by the split separators, but only if it has a single value.

type TagList added in v0.55.0

type TagList []Tag

func (TagList) GroupByFrequency added in v0.55.0

func (l TagList) GroupByFrequency() Tags

type TagName added in v0.55.0

type TagName string
const (
	TagAlbum          TagName = "album"
	TagTitle          TagName = "title"
	TagTrackNumber    TagName = "track"
	TagDiscNumber     TagName = "disc"
	TagTotalTracks    TagName = "tracktotal"
	TagTotalDiscs     TagName = "disctotal"
	TagDiscSubtitle   TagName = "discsubtitle"
	TagSubtitle       TagName = "subtitle"
	TagGenre          TagName = "genre"
	TagMood           TagName = "mood"
	TagComment        TagName = "comment"
	TagAlbumSort      TagName = "albumsort"
	TagAlbumVersion   TagName = "albumversion"
	TagTitleSort      TagName = "titlesort"
	TagCompilation    TagName = "compilation"
	TagGrouping       TagName = "grouping"
	TagLyrics         TagName = "lyrics"
	TagRecordLabel    TagName = "recordlabel"
	TagReleaseType    TagName = "releasetype"
	TagReleaseCountry TagName = "releasecountry"
	TagMedia          TagName = "media"
	TagCatalogNumber  TagName = "catalognumber"
	TagISRC           TagName = "isrc"
	TagBPM            TagName = "bpm"
	TagExplicitStatus TagName = "explicitstatus"

	TagOriginalDate  TagName = "originaldate"
	TagReleaseDate   TagName = "releasedate"
	TagRecordingDate TagName = "recordingdate"

	TagAlbumArtist      TagName = "albumartist"
	TagAlbumArtists     TagName = "albumartists"
	TagAlbumArtistSort  TagName = "albumartistsort"
	TagAlbumArtistsSort TagName = "albumartistssort"
	TagTrackArtist      TagName = "artist"
	TagTrackArtists     TagName = "artists"
	TagTrackArtistSort  TagName = "artistsort"
	TagTrackArtistsSort TagName = "artistssort"
	TagComposer         TagName = "composer"
	TagComposerSort     TagName = "composersort"
	TagLyricist         TagName = "lyricist"
	TagLyricistSort     TagName = "lyricistsort"
	TagDirector         TagName = "director"
	TagProducer         TagName = "producer"
	TagEngineer         TagName = "engineer"
	TagMixer            TagName = "mixer"
	TagRemixer          TagName = "remixer"
	TagDJMixer          TagName = "djmixer"
	TagConductor        TagName = "conductor"
	TagArranger         TagName = "arranger"
	TagPerformer        TagName = "performer"

	TagReplayGainAlbumGain TagName = "replaygain_album_gain"
	TagReplayGainAlbumPeak TagName = "replaygain_album_peak"
	TagReplayGainTrackGain TagName = "replaygain_track_gain"
	TagReplayGainTrackPeak TagName = "replaygain_track_peak"
	TagR128AlbumGain       TagName = "r128_album_gain"
	TagR128TrackGain       TagName = "r128_track_gain"

	TagMusicBrainzArtistID       TagName = "musicbrainz_artistid"
	TagMusicBrainzRecordingID    TagName = "musicbrainz_recordingid"
	TagMusicBrainzTrackID        TagName = "musicbrainz_trackid"
	TagMusicBrainzAlbumArtistID  TagName = "musicbrainz_albumartistid"
	TagMusicBrainzAlbumID        TagName = "musicbrainz_albumid"
	TagMusicBrainzReleaseGroupID TagName = "musicbrainz_releasegroupid"

	TagMusicBrainzComposerID  TagName = "musicbrainz_composerid"
	TagMusicBrainzLyricistID  TagName = "musicbrainz_lyricistid"
	TagMusicBrainzDirectorID  TagName = "musicbrainz_directorid"
	TagMusicBrainzProducerID  TagName = "musicbrainz_producerid"
	TagMusicBrainzEngineerID  TagName = "musicbrainz_engineerid"
	TagMusicBrainzMixerID     TagName = "musicbrainz_mixerid"
	TagMusicBrainzRemixerID   TagName = "musicbrainz_remixerid"
	TagMusicBrainzDJMixerID   TagName = "musicbrainz_djmixerid"
	TagMusicBrainzConductorID TagName = "musicbrainz_conductorid"
	TagMusicBrainzArrangerID  TagName = "musicbrainz_arrangerid"
	TagMusicBrainzPerformerID TagName = "musicbrainz_performerid"
)

Tag names, as defined in the mappings.yaml file

func (TagName) String added in v0.55.0

func (t TagName) String() string

func (TagName) ToLower added in v0.55.0

func (t TagName) ToLower() TagName

type TagRepository added in v0.55.0

type TagRepository interface {
	Add(libraryID int, tags ...Tag) error
	UpdateCounts() error
}

type TagType added in v0.55.0

type TagType string
const (
	TagTypeString  TagType = "string"
	TagTypeInteger TagType = "int"
	TagTypeFloat   TagType = "float"
	TagTypeDate    TagType = "date"
	TagTypeUUID    TagType = "uuid"
	TagTypePair    TagType = "pair"
)

type Tags added in v0.55.0

type Tags map[TagName][]string

func (Tags) Add added in v0.55.0

func (t Tags) Add(name TagName, v string)

func (Tags) Flatten added in v0.55.0

func (t Tags) Flatten(name TagName) TagList

func (Tags) FlattenAll added in v0.55.0

func (t Tags) FlattenAll() TagList

func (Tags) Hash added in v0.55.0

func (t Tags) Hash() []byte

func (Tags) IDs added in v0.55.0

func (t Tags) IDs() []string

func (Tags) Merge added in v0.55.0

func (t Tags) Merge(tags Tags)

Merge merges the tags from another Tags object into this one, removing any duplicates

func (Tags) Sort added in v0.55.0

func (t Tags) Sort()

func (Tags) ToGenres added in v0.55.0

func (t Tags) ToGenres() (string, Genres)

func (Tags) Values added in v0.55.0

func (t Tags) Values(name TagName) []string

type Transcoding

type Transcoding struct {
	ID             string `structs:"id" json:"id"`
	Name           string `structs:"name" json:"name"`
	TargetFormat   string `structs:"target_format" json:"targetFormat"`
	Command        string `structs:"command" json:"command"`
	DefaultBitRate int    `structs:"default_bit_rate" json:"defaultBitRate"`
}

type TranscodingRepository

type TranscodingRepository interface {
	Get(id string) (*Transcoding, error)
	CountAll(...QueryOptions) (int64, error)
	Put(*Transcoding) error
	FindByFormat(format string) (*Transcoding, error)
}

type Transcodings

type Transcodings []Transcoding

type User

type User struct {
	ID           string     `structs:"id" json:"id"`
	UserName     string     `structs:"user_name" json:"userName"`
	Name         string     `structs:"name" json:"name"`
	Email        string     `structs:"email" json:"email"`
	IsAdmin      bool       `structs:"is_admin" json:"isAdmin"`
	LastLoginAt  *time.Time `structs:"last_login_at" json:"lastLoginAt"`
	LastAccessAt *time.Time `structs:"last_access_at" json:"lastAccessAt"`
	CreatedAt    time.Time  `structs:"created_at" json:"createdAt"`
	UpdatedAt    time.Time  `structs:"updated_at" json:"updatedAt"`

	// Library associations (many-to-many relationship)
	Libraries Libraries `structs:"-" json:"libraries,omitempty"`

	// This is only available on the backend, and it is never sent over the wire
	Password string `structs:"-" json:"-"`
	// This is used to set or change a password when calling Put. If it is empty, the password is not changed.
	// It is received from the UI with the name "password"
	NewPassword string `structs:"password,omitempty" json:"password,omitempty"` //nolint:gosec
	// If changing the password, this is also required
	CurrentPassword string `structs:"current_password,omitempty" json:"currentPassword,omitempty"`
}

func (User) HasLibraryAccess added in v0.58.0

func (u User) HasLibraryAccess(libraryID int) bool

type UserPropsRepository added in v0.44.0

type UserPropsRepository interface {
	Put(userId, key string, value string) error
	Get(userId, key string) (string, error)
	Delete(userId, key string) error
	DefaultGet(userId, key string, defaultValue string) (string, error)
}

type UserRepository

type UserRepository interface {
	ResourceRepository
	CountAll(...QueryOptions) (int64, error)
	Delete(id string) error
	Get(id string) (*User, error)
	GetAll(options ...QueryOptions) (Users, error)
	Put(*User) error
	UpdateLastLoginAt(id string) error
	UpdateLastAccessAt(id string) error
	FindFirstAdmin() (*User, error)
	// FindByUsername must be case-insensitive
	FindByUsername(username string) (*User, error)
	// FindByUsernameWithPassword is the same as above, but also returns the decrypted password
	FindByUsernameWithPassword(username string) (*User, error)

	// Library association methods
	GetUserLibraries(userID string) (Libraries, error)
	SetUserLibraries(userID string, libraryIDs []int) error
}

type Users

type Users []User

Directories

Path Synopsis
Package criteria implements a Criteria API based on Masterminds/squirrel
Package criteria implements a Criteria API based on Masterminds/squirrel

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL