Documentation
¶
Overview ¶
Package library holds the media library domain that sits behind the HTTP adapter.
Index ¶
- Constants
- Variables
- func AddedAtIndexes(items []plex.MediaItem) []plex.LetterIndex
- func CacheID(server, thumbPath string) string
- func ItemResponses(items []plex.MediaItem) []api.MediaItemResponse
- func JumpIndex(ctx context.Context, client *plex.Client, server plex.Server, query Query, ...) ([]plex.LetterIndex, error)
- func OrderIndex(buckets []plex.LetterIndex, sortKey string) []plex.LetterIndex
- func ParseStart(raw string) int
- func PlexSort(sortKey string) string
- func ResolveMediaPath(ctx context.Context, cfg *config.Config, selected ServerSelection, ...) (string, error)
- func SessionResponses(sessions []plex.Session) []api.SessionResponse
- func TitleIndexes(items []plex.MediaItem) []plex.LetterIndex
- func TitleJumpKey(titleSort, title string) string
- func YearIndexes(items []plex.MediaItem) []plex.LetterIndex
- type AddedAtCache
- type AudioStream
- type Browsed
- type LetterIndex
- type LibraryCache
- type MediaSource
- func (source *MediaSource) CheckAccess(ctx context.Context, viewer identity.Viewer, mediaID string) error
- func (source *MediaSource) CheckEdit(ctx context.Context, path string, edit clip.Edit, limit time.Duration) error
- func (source *MediaSource) Describe(ctx context.Context, mediaID string) SourceInfo
- func (source *MediaSource) DescribePath(ctx context.Context, path string) SourceInfo
- func (source *MediaSource) DescribePaths(ctx context.Context, paths []string, limit int) map[string]SourceInfo
- func (source *MediaSource) Duration(ctx context.Context, path string) (time.Duration, bool)
- func (source *MediaSource) Resolve(ctx context.Context, mediaID string) (string, error)
- func (source *MediaSource) Sees(ctx context.Context, viewer identity.Viewer, mediaID string) bool
- type Prober
- type Query
- type ServerSelection
- type SourceInfo
- type Window
Constants ¶
const ( // SortTitleAsc lists titles A-Z. SortTitleAsc = "title_asc" // SortTitleDesc lists titles Z-A. SortTitleDesc = "title_desc" // SortYearDesc lists newest years first. SortYearDesc = "year_desc" // SortYearAsc lists oldest years first. SortYearAsc = "year_asc" // SortAddedDesc lists recently added titles first. SortAddedDesc = "added_desc" // SortAddedAsc lists oldest added titles first. SortAddedAsc = "added_asc" // JumpOtherKey is the mark for a jump target that is neither a letter, a year, nor a month. JumpOtherKey = "#" )
const CacheControl = "private, max-age=604800, immutable"
CacheControl tells the browser to reuse a thumbnail for a week.
It is private, because a thumbnail is only served to a signed-in session and a shared cache must not hand it to anyone else.
const PageSize = 48
PageSize is the number of posters shown per media library page.
Variables ¶
var ( // ErrNoServer is returned when no Plex server is selected. ErrNoServer = errors.New("no plex server selected") // account cannot see, because its library is not shared with it. ErrNotShared = errors.New("media item is not shared with this plex account") // ErrDolbyVisionBaseLayer is returned for a Dolby Vision source, such as // profile 5, whose base layer only shows correct colors after Dolby's // reshaping, which ffmpeg does not apply. ErrDolbyVisionBaseLayer = errors.New( "this Dolby Vision source has no HDR10 or SDR base layer, so it cannot " + "be exported with correct colors: use a copy with an HDR10 base layer", ) )
Functions ¶
func AddedAtIndexes ¶
func AddedAtIndexes(items []plex.MediaItem) []plex.LetterIndex
AddedAtIndexes builds mm/yyyy buckets from a sorted library listing.
Parameters:
- items: Media items in added-at order.
Returns:
- index: Consecutive month buckets.
func CacheID ¶
CacheID hashes a server and a Plex thumb path into a cache filename.
Two servers can use the same thumb path for different images, so the server is part of the key.
Parameters:
- server: Identity of the Plex server the thumb comes from.
- thumbPath: Plex thumb path.
Returns:
- id: Hex-encoded SHA-256 digest used as the cache filename.
func ItemResponses ¶
func ItemResponses(items []plex.MediaItem) []api.MediaItemResponse
ItemResponses maps Plex media items onto API payloads.
Parameters:
- items: Media items from a search or a listing.
Returns:
- responses: One payload per item, in the order given.
func JumpIndex ¶
func JumpIndex( ctx context.Context, client *plex.Client, server plex.Server, query Query, cache *AddedAtCache, ) ([]plex.LetterIndex, error)
JumpIndex collects the jump-rail buckets a library section listing shows, which are letters, years, or added-at months depending on the sort.
Parameters:
- ctx: Request context.
- client: PMS client.
- server: PMS to query.
- query: Normalized browse state.
- cache: Cache the added-at buckets are collected through, which may be nil for a browse that cannot reach the added-at sorts.
Returns:
- index: Title, year, or added-at buckets, nil when the browse has no rail.
- err: Non-nil when the buckets could not be collected.
func OrderIndex ¶
func OrderIndex(buckets []plex.LetterIndex, sortKey string) []plex.LetterIndex
OrderIndex sorts or reverses buckets to match the active sort.
Parameters:
- buckets: PMS buckets in default order.
- sortKey: Normalized Outtake sort key.
Returns:
- buckets: Buckets ordered for the jump rail.
func ParseStart ¶
ParseStart parses a non-negative pagination offset.
Parameters:
- raw: Offset carried by the request, which may be absent or malformed.
Returns:
- start: The offset, or 0 when it is not a non-negative integer.
func PlexSort ¶
PlexSort maps an Outtake sort key onto a PMS sort value.
Parameters:
- sortKey: Normalized Outtake sort key.
Returns:
- plexSort: PMS sort query value, or empty when the key is unset.
func ResolveMediaPath ¶
func ResolveMediaPath( ctx context.Context, cfg *config.Config, selected ServerSelection, mediaID string, ) (string, error)
ResolveMediaPath maps a media id onto a local filesystem path.
Parameters:
- ctx: Request context.
- cfg: Configuration carrying the environment and the media remap.
- selected: Plex server selection to resolve against.
- mediaID: Plex media item id.
Returns:
- path: Remapped local path for the media file.
- err: ErrNoServer when no server is selected, or the Plex failure.
func SessionResponses ¶
func SessionResponses(sessions []plex.Session) []api.SessionResponse
SessionResponses maps Plex sessions onto API payloads.
Parameters:
- sessions: Sessions from the binding or from a live PMS poll.
Returns:
- responses: One payload per session, in the order given.
func TitleIndexes ¶
func TitleIndexes(items []plex.MediaItem) []plex.LetterIndex
TitleIndexes builds first-character buckets from a sorted library listing.
Parameters:
- items: Media items in title order.
Returns:
- index: Consecutive letter buckets.
func TitleJumpKey ¶
TitleJumpKey returns the first-letter jump key for a title.
Parameters:
- titleSort: PMS titleSort value, preferred when set.
- title: Display title used when titleSort is empty.
Returns:
- key: A through Z, or JumpOtherKey for anything else.
func YearIndexes ¶
func YearIndexes(items []plex.MediaItem) []plex.LetterIndex
YearIndexes builds year buckets from a sorted library listing.
Parameters:
- items: Media items in year order.
Returns:
- index: Consecutive year buckets.
Types ¶
type AddedAtCache ¶
type AddedAtCache struct {
// contains filtered or unexported fields
}
AddedAtCache stores added-at jump buckets by server, library, and sort.
func (*AddedAtCache) Load ¶
func (cache *AddedAtCache) Load( ctx context.Context, client *plex.Client, server plex.Server, libraryID, sortKey string, ) []plex.LetterIndex
Load returns the cached added-at buckets, collecting them on a miss.
Parameters:
- ctx: Request context.
- client: PMS client.
- server: PMS to query.
- libraryID: Section key.
- sortKey: Normalized Outtake sort key.
Returns:
- index: Month buckets for the jump rail.
type AudioStream ¶
type AudioStream struct {
// Index is the ffmpeg stream index the export posts back.
Index int
// Codec is the audio codec name ffprobe reported.
Codec string
// Language is the stream language, which may be undetermined.
Language string
// Title is the stream title, which is often empty.
Title string
// Channels is the channel count ffprobe reported.
Channels int
// Layout is the channel layout name, empty when the count is unknown.
Layout string
}
AudioStream is one audio track on a source file.
type Browsed ¶
type Browsed struct {
// Libraries are the libraries the selected server offers.
Libraries []plex.Library
// Items are the media items of the requested window, absent for the library
// chooser and for a search that matched nothing.
Items []plex.MediaItem
// Total is how many items the listing matched.
Total int
}
Browsed is what one media library page request resolved to.
func Browse ¶
func Browse( ctx context.Context, libraries *LibraryCache, client *plex.Client, server plex.Server, query Query, window Window, ) (Browsed, error)
Browse lists a server's libraries together with the media of one requested window.
The window is either a search, a container listing, a library section listing, or the library chooser itself.
Parameters:
- ctx: Request context.
- libraries: Cache the server's library list is read through.
- client: PMS client.
- server: PMS to query.
- query: Normalized browse state.
- window: Container offset and page size the listing covers.
Returns:
- browsed: The libraries and the items of the window.
- err: Non-nil when Plex could not be asked, and the libraries are absent.
type LetterIndex ¶
LetterIndex is one jump-rail target on a library section.
func JumpMarks ¶
func JumpMarks(buckets []plex.LetterIndex, sortKey string) []LetterIndex
JumpMarks converts PMS buckets into a readable set of nice ticks.
Parameters:
- buckets: PMS first-character, year, or added-at buckets.
- sortKey: Normalized Outtake sort key.
Returns:
- marks: Jump-rail targets for the active sort.
type LibraryCache ¶ added in v0.4.0
type LibraryCache struct {
// contains filtered or unexported fields
}
LibraryCache keeps each server's library list for a short while.
It spares the sidebar and every browse fragment from each asking Plex for it. Entries are keyed by server, so a server change never reads another server's list. Requests that miss together share one Plex request. The zero value is ready to use.
func (*LibraryCache) Libraries ¶ added in v0.4.0
func (cache *LibraryCache) Libraries( ctx context.Context, client *plex.Client, server plex.Server, ) ([]plex.Library, error)
Libraries returns a server's libraries, asking Plex only when the cached list is missing or older than libraryTTL.
Callers that miss at the same time wait on one request, which runs to the client's timeout even when the caller that started it goes away. A failed request is not cached.
Parameters:
- ctx: Request context. Its end stops this caller waiting.
- client: PMS client.
- server: PMS to query.
Returns:
- libraries: A copy of the server's libraries.
- err: Non-nil when Plex had to be asked and could not answer, or ctx ended first.
type MediaSource ¶
type MediaSource struct {
// contains filtered or unexported fields
}
MediaSource resolves a Plex media item to a local file and describes it.
func NewMediaSource ¶
func NewMediaSource( cfg *config.Config, selected ServerSelection, prober Prober, ) *MediaSource
NewMediaSource returns a source resolver bound to the selected Plex server.
Parameters:
- cfg: Application configuration.
- selected: Plex server selection to resolve against.
- prober: Runner that reports what a media file holds.
Returns:
- source: The resolver under construction.
func (*MediaSource) CheckAccess ¶ added in v0.4.0
func (source *MediaSource) CheckAccess( ctx context.Context, viewer identity.Viewer, mediaID string, ) error
CheckAccess checks that a viewer's Plex account can see a media item.
A render reads the item's file from disk, which Plex's sharing does not guard, so an account that does not own the server is asked about first.
Parameters:
- ctx: Request context.
- viewer: The account asking.
- mediaID: The item's rating key.
Returns:
- err: Nil for the owner or an item the viewer can see, ErrNotShared for one it cannot, or the wrapped failure to ask.
func (*MediaSource) CheckEdit ¶ added in v0.4.0
func (source *MediaSource) CheckEdit( ctx context.Context, path string, edit clip.Edit, limit time.Duration, ) error
CheckEdit probes a source once and reports whether an edit fits it.
The edit must stay within the length cap and inside the source, and name an audio track the source carries. A Dolby Vision source with no displayable base layer is refused outright, because every export of it would come out green and magenta.
Parameters:
- ctx: Request context.
- path: Local media file path.
- edit: The change, with its type resolved.
- limit: Longest clip the installation accepts.
Returns:
- err: Non-nil when the edit may not be rendered from this source.
func (*MediaSource) Describe ¶
func (source *MediaSource) Describe(ctx context.Context, mediaID string) SourceInfo
Describe resolves a Plex media item and probes the file behind it.
Parameters:
- ctx: Request context.
- mediaID: Plex rating key of the source item.
Returns:
- info: What the source turned out to be, zero when it could not be resolved or probed.
func (*MediaSource) DescribePath ¶
func (source *MediaSource) DescribePath(ctx context.Context, path string) SourceInfo
DescribePath probes a media file that has already been resolved.
Parameters:
- ctx: Request context.
- path: Local media file path.
Returns:
- info: What the file turned out to be, zero when it could not be probed.
func (*MediaSource) DescribePaths ¶ added in v0.4.0
func (source *MediaSource) DescribePaths( ctx context.Context, paths []string, limit int, ) map[string]SourceInfo
DescribePaths probes several media files at once and returns what each turned out to be.
At most limit probes run at a time. An empty or repeated path is probed once at most, and a probe that fails reads as a zero description.
Parameters:
- ctx: Request context.
- paths: Local media file paths, which may repeat.
- limit: How many probes may run at once, at least one.
Returns:
- infos: Each distinct path's description.
func (*MediaSource) Duration ¶
Duration probes a media file for its length.
Parameters:
- ctx: Request context.
- path: Local media file path.
Returns:
- duration: How long the file runs.
- ok: False when the probe could not run or reported no length.
func (*MediaSource) Resolve ¶
Resolve maps a Plex media item onto a local filesystem path.
Parameters:
- ctx: Request context.
- mediaID: Plex rating key of the source item.
Returns:
- path: Remapped local path for the media file.
- err: Non-nil when no server is selected or the lookup fails.
func (*MediaSource) Sees ¶ added in v0.4.0
Sees reports whether a viewer's Plex account can see a title.
It asks the way CheckAccess does and remembers a definite answer for a few minutes. A failure to ask reads as not seen and is not remembered, so the next call asks again.
Parameters:
- ctx: Request context.
- viewer: The account asking.
- mediaID: The title's rating key.
Returns:
- seen: True for the owner or a title Plex shares with the viewer.
type Prober ¶
type Prober interface {
// Probe returns what ffprobe found in a media file.
Probe(ctx context.Context, path string) (probe.Info, error)
}
Prober reports what a media file holds.
type Query ¶
type Query struct {
Query string
LibraryID string
ParentID string
Sort string
Letter string
Start int
Before int
}
Query is the media library browse query state.
func NormalizeQuery ¶
NormalizeQuery drops unknown sort values and nested letter jumps.
Parameters:
- query: Raw browse query from the request.
Returns:
- query: Normalized browse state.
func (Query) IsLibraryRoot ¶
IsLibraryRoot reports whether the query is a section listing.
Returns:
- ok: True when a library is selected without a parent or search.
func (Query) ListStart ¶
func (query Query) ListStart(buckets []plex.LetterIndex) int
ListStart returns the Plex container offset for this query.
Parameters:
- buckets: First-character buckets used when letter is set and start is 0.
Returns:
- start: Container offset.
func (Query) ShowJumpIndex ¶
ShowJumpIndex reports whether the library root has a jump rail.
Returns:
- ok: True when the query is a library section listing.
type ServerSelection ¶
type ServerSelection interface {
// Get returns the selected server.
Get() (plex.Server, bool)
// Client builds a Plex client for the selected server.
Client() (*plex.Client, plex.Server, bool)
// ClientWithToken builds a Plex client that reads the selected server
// with another account's token.
ClientWithToken(token string) (*plex.Client, plex.Server, bool)
}
ServerSelection is the Plex server selection a media path is resolved against.
type SourceInfo ¶
type SourceInfo struct {
// Path is the local file the source resolved to.
Path string
// Duration is how long the source runs, zero when it could not be probed.
Duration time.Duration
// ColorTransfer is the video color transfer ffprobe reported.
ColorTransfer string
// HDR reports whether the video transfer is HDR.
HDR bool
// Quality is the recommended encode quality for the source.
Quality string
// AudioStreams are the audio tracks the source carries.
AudioStreams []AudioStream
}
SourceInfo is what probing a media file turned up.