library

package
v1.5.4 Latest Latest
Warning

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

Go to latest
Published: Apr 2, 2023 License: GPL-3.0 Imports: 25 Imported by: 0

Documentation

Overview

Package library deals with the actual media library. It is creates the Library type.

Every media receives an ID in the library. The main thing a search result returns is the tracks' IDs. They are used to get the media, again using the Library. That way the real location of the file is never revealed to the interface.

Index

Constants

View Source
const (
	// UnknownLabel will be used in case some media tag is missing. As a consequence
	// if there are many files with missing title, artist and album only
	// one of them will be saved in the library.
	UnknownLabel = "Unknown"

	// SQLiteMemoryFile can be used as a database path for the sqlite's Open method.
	// When using it, one would create a memory database which does not write
	// anything on disk. See https://www.sqlite.org/inmemorydb.html for more info
	// on the subject of in-memory databases. We are using a shared cache because
	// this causes all the different connections in the database/sql pool to be
	// connected to the same "memory file". Without this. every new connection
	// would end up creating a new memory database.
	SQLiteMemoryFile = "file::memory:?cache=shared"
)

Variables

View Source
var (
	// LibraryFastScan is a flag, populated by the -fast-library-scan argument.
	//
	// When `false` (the default), scanning the local library will honour the
	// configuration for occasional sleeping while scanning the file system.
	//
	// When `true`, scanning will be as fast as possible. This may generate high
	// IO load for the duration of the scan.
	LibraryFastScan bool

	// ErrAlbumNotFound is returned when no album could be found for particular operation.
	ErrAlbumNotFound = errors.New("Album Not Found")

	// ErrArtistNotFound is returned when no artist could be found for particular operation.
	ErrArtistNotFound = errors.New("Artist Not Found")

	// ErrArtworkNotFound is returned when no artwork can be found for particular album.
	ErrArtworkNotFound = NewArtworkError("Artwork Not Found")

	// ErrCachedArtworkNotFound is returned when the database has been queried and
	// its cache says the artwork was not found in the recent past. No need to continue
	// searching further once you receive this error.
	ErrCachedArtworkNotFound = NewArtworkError("Artwork Not Found (Cached)")

	// ErrArtworkTooBig is returned from operation when the artwork is too big for it to
	// handle.
	ErrArtworkTooBig = NewArtworkError("Artwork Is Too Big")
)

Functions

This section is empty.

Types

type Album added in v1.1.0

type Album struct {
	ID     int64  `json:"album_id"`
	Name   string `json:"album"`
	Artist string `json:"artist"`
}

Album represents an album from the database

type Artist added in v1.1.0

type Artist struct {
	ID   int64  `json:"artist_id"`
	Name string `json:"artist"`
}

Artist represents an artist from the database

type ArtistImageManager added in v1.5.0

type ArtistImageManager interface {
	// FindAndSaveArtistImage returns the image for a particular artist by its ID.
	FindAndSaveArtistImage(
		ctx context.Context,
		artistID int64,
		size ImageSize,
	) (io.ReadCloser, error)

	// SaveArtistImage stores the image for particular artist for later use.
	SaveArtistImage(ctx context.Context, artistID int64, r io.Reader) error

	// RemoveArtistImage removes the stored image for particular artist.
	RemoveArtistImage(ctx context.Context, artistID int64) error
}

ArtistImageManager is an interface for all methods for managing artist imagery.

type ArtworkError added in v1.2.0

type ArtworkError struct {
	Err string
}

ArtworkError represents some kind of artwork error.

func NewArtworkError added in v1.2.0

func NewArtworkError(err string) *ArtworkError

NewArtworkError returns a new artwork error which will have `err` as message.

func (*ArtworkError) Error added in v1.2.0

func (a *ArtworkError) Error() string

Error implements the error interface.

type ArtworkManager added in v1.2.0

type ArtworkManager interface {

	// FindAndSaveAlbumArtwork returns the artwork for a particular album by its ID.
	FindAndSaveAlbumArtwork(
		ctx context.Context,
		albumID int64,
		size ImageSize,
	) (io.ReadCloser, error)

	// SaveAlbumArtwork stores the artwork for particular album for later use.
	SaveAlbumArtwork(ctx context.Context, albumID int64, r io.Reader) error

	// RemoveAlbumArtwork removes the stored artwork for particular album.
	RemoveAlbumArtwork(ctx context.Context, albumID int64) error
}

ArtworkManager is an interface for all the methods needed for managing album artwork in the local library.

type BrowseArgs added in v1.2.0

type BrowseArgs struct {
	Page    uint
	PerPage uint
	Order   BrowseOrder
	OrderBy BrowseOrderBy
}

BrowseArgs defines all arguments one can pass to the browse methods to later its behaviour.

type BrowseOrder added in v1.2.0

type BrowseOrder int

BrowseOrder represents different strategies which can be made with respect to the comparison function.

const (
	// OrderUndefined means "order any way you wish"
	OrderUndefined BrowseOrder = iota

	// OrderAsc will order values in an ascending manner defined by their
	// comparison function.
	OrderAsc

	// OrderDesc will order values in a descending mannger defined by their
	// comparison function.
	OrderDesc
)

type BrowseOrderBy added in v1.2.0

type BrowseOrderBy int

BrowseOrderBy represents the different properties by which values could be oredered. For every browse method the semantics for "name" and "id" could be different.

const (
	// OrderByUndefined means "order by any preoperty you wish"
	OrderByUndefined BrowseOrderBy = iota

	// OrderByID will order values by their respective ID field
	OrderByID

	// OrderByName will order vlues by their name
	OrderByName
)

type Browser added in v1.5.1

type Browser interface {
	// BrowseArtists makes it possible to browse through the library artists page by page.
	// Returns a list of artists for particular page and the number of all artists in the
	// library.
	BrowseArtists(BrowseArgs) ([]Artist, int)

	// BrowseAlbums makes it possible to browse through the library albums page by page.
	// Returns a list of albums for particular page and the number of all albums in the
	// library.
	BrowseAlbums(BrowseArgs) ([]Album, int)
}

Browser defines the methods for browsing a library.

type DatabaseExecutable added in v1.2.0

type DatabaseExecutable func(db *sql.DB) error

DatabaseExecutable is the type used for passing "work unit" to the databaseWorker. Every function which wants to do something with the database creates one and sends it to the databaseWorker for execution.

type ImageSize added in v1.5.0

type ImageSize int64

ImageSize is an enum type which defines the different sizes form images from the ArtistImageManager and ArtworkManager.

const (
	// OriginalImage is the full-size image as stored into the image managers.
	OriginalImage ImageSize = iota

	// SmallImage is a size suitable for thumbnails.
	SmallImage
)

type Library

type Library interface {

	// Adds a new path to the library paths. If it hasn't been scanned yet a new scan
	// will be started.
	AddLibraryPath(string)

	// Search the library using a search string. It will match against Artist, Album
	// and Title. Will OR the results. So it is "return anything which Artist matches or
	// Album matches or Title matches"
	Search(string) []SearchResult

	// Returns the real filesystem path. Requires the media ID.
	GetFilePath(int64) string

	// Returns search result will all the files of this album
	GetAlbumFiles(int64) []SearchResult

	// Starts a full library scan. Will scan all paths if
	// they are not scanned already.
	Scan()

	// Adds this media (file) to the library
	AddMedia(string) error

	// Makes sure the library is initialied. This method will be called once on
	// every start of the httpms
	Initialize() error

	// Makes the library forget everything. Also Closes the library.
	Truncate() error

	// Frees all resources this library object is using.
	// Any operations (except Truncate) on closed library will result in panic.
	Close()
}

Library represents the media library which is played using the HTTPMS. It is responsible for scaning the library directories, watching for new files, actually searching for a media by a search term and finding the exact file path in the file system for a media.

type LocalLibrary

type LocalLibrary struct {
	// The configuration for how to scan the libraries.
	ScanConfig config.ScanSection
	// contains filtered or unexported fields
}

LocalLibrary implements the Library interface. Will represent files found on the local storage

func NewLocalLibrary

func NewLocalLibrary(
	ctx context.Context,
	databasePath string,
	sqlFilesFS fs.FS,
) (*LocalLibrary, error)

NewLocalLibrary returns a new LocalLibrary which will use for database the file specified by databasePath. Also creates the database connection so you does not need to worry about that. It accepts the parent's context and create its own child context.

func (*LocalLibrary) AddLibraryPath

func (lib *LocalLibrary) AddLibraryPath(path string)

AddLibraryPath adds a library directory to the list of libraries which will be scanned and consequently watched.

func (*LocalLibrary) AddMedia

func (lib *LocalLibrary) AddMedia(filename string) error

AddMedia adds a file specified by its file system name to the library. Will create the needed Artist, Album if necessary.

func (*LocalLibrary) BrowseAlbums added in v1.1.0

func (lib *LocalLibrary) BrowseAlbums(args BrowseArgs) ([]Album, int)

BrowseAlbums implements the Library interface for the local library by getting albums from the database ordered by their name.

func (*LocalLibrary) BrowseArtists added in v1.1.0

func (lib *LocalLibrary) BrowseArtists(args BrowseArgs) ([]Artist, int)

BrowseArtists implements the Library interface for the local library by getting artists from the database ordered by their name. Returns an artists slice and the total count of all artists in the database.

func (*LocalLibrary) Close

func (lib *LocalLibrary) Close()

Close closes the database connection. It is safe to call it as many times as you want.

func (*LocalLibrary) DisableWatching added in v1.5.2

func (lib *LocalLibrary) DisableWatching()

DisableWatching makes it so that the library will no longer add file system watching for new directories.

func (*LocalLibrary) FindAndSaveAlbumArtwork added in v1.2.0

func (lib *LocalLibrary) FindAndSaveAlbumArtwork(
	ctx context.Context,
	albumID int64,
	size ImageSize,
) (io.ReadCloser, error)

FindAndSaveAlbumArtwork implements the ArtworkManager interface for the local library. It would return a previously found artwork if any or try to find one in the filesystem or _on the internet_! This function returns ReadCloser and the caller is responsible for freeing the used resources by calling Close().

When an artwork is found it will be saved in the database and once there it will be served from the db. Wait, wait! Serving binary files from the database?! Isn't that slow? Apparently no with sqlite3. See the following:

* https://www.sqlite.org/intern-v-extern-blob.html * https://www.sqlite.org/fasterthanfs.html

This behaviour have an additional bonus that artwork found on the internet will not be saved on the filesystem and thus "pollute" it with unexpected files. It will be nicely contained in the app's database.

!TODO: Make sure there is no race conditions while getting/saving artwork for particular album. Wink, wink, the database.

func (*LocalLibrary) FindAndSaveArtistImage added in v1.5.0

func (lib *LocalLibrary) FindAndSaveArtistImage(
	ctx context.Context,
	artistID int64,
	size ImageSize,
) (io.ReadCloser, error)

FindAndSaveArtistImage implements the ArtistImageManager for the local library. It will return a previously saved into the database artist image if any or try to find one on the internet (assuming it is configured). This function returns ReadCloser and the caller is responsible for freeing the used resources by calling Close().

When image for an artist is found on the internet then it will be saved in the database for later retrieval.

func (*LocalLibrary) GetAlbumFSPathByID added in v1.2.0

func (lib *LocalLibrary) GetAlbumFSPathByID(albumID int64) (string, error)

GetAlbumFSPathByID returns the album path by its ID

func (*LocalLibrary) GetAlbumFSPathByName added in v1.0.3

func (lib *LocalLibrary) GetAlbumFSPathByName(albumName string) ([]string, error)

GetAlbumFSPathByName returns all the file paths which contain versions of an album.

func (*LocalLibrary) GetAlbumFiles

func (lib *LocalLibrary) GetAlbumFiles(albumID int64) []SearchResult

GetAlbumFiles satisfies the Library interface

func (*LocalLibrary) GetAlbumID

func (lib *LocalLibrary) GetAlbumID(album string, fsPath string) (int64, error)

GetAlbumID returns the id for this album. When missing or on error returns that error.

func (*LocalLibrary) GetArtistID

func (lib *LocalLibrary) GetArtistID(artist string) (int64, error)

GetArtistID returns the id for this artist. When missing or on error returns that error.

func (*LocalLibrary) GetFilePath

func (lib *LocalLibrary) GetFilePath(ID int64) string

GetFilePath returns the filesystem path for a file specified by its ID.

func (*LocalLibrary) GetTrackID

func (lib *LocalLibrary) GetTrackID(
	title string,
	artistID int64,
	albumID int64,
) (int64, error)

GetTrackID returns the id for this track. When missing or on error returns that error.

func (*LocalLibrary) Initialize

func (lib *LocalLibrary) Initialize() error

Initialize should be run once every time a library is created. It checks for the sqlite database file and creates one if it is absent. If a file is found it does nothing.

func (*LocalLibrary) MediaExistsInLibrary

func (lib *LocalLibrary) MediaExistsInLibrary(filename string) bool

MediaExistsInLibrary checks if the media file with file system path "filename" has been added to the library already.

func (*LocalLibrary) RemoveAlbumArtwork added in v1.2.0

func (lib *LocalLibrary) RemoveAlbumArtwork(ctx context.Context, albumID int64) error

RemoveAlbumArtwork removes the artwork from the library database.

Note that this operation does not make sense for artwork which came from disk. Because future requests will find it again and store in the database.

func (*LocalLibrary) RemoveArtistImage added in v1.5.0

func (lib *LocalLibrary) RemoveArtistImage(ctx context.Context, artistID int64) error

RemoveArtistImage removes particular artist image from the database.

func (*LocalLibrary) Rescan added in v1.5.0

func (lib *LocalLibrary) Rescan(ctx context.Context) error

Rescan goes through the database and for every file reads the meta data again from the disk and updates it.

func (*LocalLibrary) SaveAlbumArtwork added in v1.2.0

func (lib *LocalLibrary) SaveAlbumArtwork(
	ctx context.Context,
	albumID int64,
	r io.Reader,
) error

SaveAlbumArtwork implements the ArtworkManager interface for the local library.

It saves the artwork in `r` in the database. It will read up to 5MB of data from `r` and if this limit is reached, the artwork is considered too big and will not be saved in the db.

func (*LocalLibrary) SaveArtistImage added in v1.5.0

func (lib *LocalLibrary) SaveArtistImage(
	ctx context.Context,
	artistID int64,
	r io.Reader,
) error

SaveArtistImage implements the ArtistImageManager interface for the local library.

It saves the image in `r` in the database. It will read up to 5MB of data from `r` and if this limit is reached, the image is considered too big and will not be saved in the db.

func (*LocalLibrary) Scan

func (lib *LocalLibrary) Scan()

Scan scans all of the folders in paths for media files. New files will be added to the database.

func (*LocalLibrary) Search

func (lib *LocalLibrary) Search(searchTerm string) []SearchResult

Search searches in the library. Will match against the track's name, artist and album.

func (*LocalLibrary) SetArtFinder added in v1.5.0

func (lib *LocalLibrary) SetArtFinder(caf art.Finder)

SetArtFinder bind a particular art.Finder to this library.

func (*LocalLibrary) SetScaler added in v1.5.0

func (lib *LocalLibrary) SetScaler(scl scaler.Scaler)

SetScaler bind a particular image scaler to this loca library.

func (*LocalLibrary) Truncate

func (lib *LocalLibrary) Truncate() error

Truncate closes the library and removes its database file leaving no traces at all.

type MediaFile added in v1.0.2

type MediaFile interface {

	// Artist returns a string which represents the artist responsible for this media file
	Artist() string

	// Album returns a string for the name of the album this media file is part of
	Album() string

	// Title returns the name of this piece of media
	Title() string

	// Track returns the media track number in its album
	Track() int

	// Length returns the duration of this piece of media
	Length() time.Duration
}

MediaFile is an interface which a media object should satisfy in order to be inserted in the library database.

type SearchResult

type SearchResult struct {

	// ID in the library for a media file
	ID int64 `json:"id"`

	// Meta info: Artist ID
	ArtistID int64 `json:"artist_id"`

	// Meta info: Artist
	Artist string `json:"artist"`

	// Meta info: Album ID
	AlbumID int64 `json:"album_id"`

	// Meta info: Album for music
	Album string `json:"album"`

	// Meta info: the title of this media file
	Title string `json:"title"`

	// Meta info: track number for music
	TrackNumber int64 `json:"track"`

	// File format of the underlying data file. Examples: "mp3", "flac", "ogg" etc.
	Format string `json:"format"`

	// Duration is the track length in milliseconds.
	Duration int64 `json:"duration"`
}

SearchResult contains a result for a search term. Contains all the neccessery information to uniquely identify a media in the library.

Directories

Path Synopsis
Code generated by counterfeiter.
Code generated by counterfeiter.

Jump to

Keyboard shortcuts

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