Help us shape the future of Go! Take the 2026 Go Developer Survey

library

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Oct 13, 2026 License: AGPL-3.0 Imports: 21 Imported by: 0

Documentation

Overview

Package library holds the media library domain that sits behind the HTTP adapter.

Index

Constants

View Source
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 = "#"
)
View Source
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.

View Source
const PageSize = 48

PageSize is the number of posters shown per media library page.

Variables

View Source
var (
	// ErrNoServer is returned when no Plex server is selected.
	ErrNoServer = errors.New("no plex server selected")

	// ErrNotShared is returned for a media item the asking account's Plex
	// 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

func CacheID(server, thumbPath string) string

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

func ParseStart(raw string) int

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

func PlexSort(sortKey string) string

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

func TitleJumpKey(titleSort, title string) string

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

type LetterIndex struct {
	Title string
	Size  int
}

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

func (source *MediaSource) Duration(ctx context.Context, path string) (time.Duration, bool)

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

func (source *MediaSource) Resolve(ctx context.Context, mediaID string) (string, error)

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

func (source *MediaSource) Sees(ctx context.Context, viewer identity.Viewer, mediaID string) bool

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

func NormalizeQuery(query Query) Query

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

func (query Query) IsLibraryRoot() bool

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

func (query Query) ShowJumpIndex() bool

ShowJumpIndex reports whether the library root has a jump rail.

Returns:

  • ok: True when the query is a library section listing.

func (Query) Window

func (query Query) Window(buckets []plex.LetterIndex) Window

Window returns the PMS offset and page size for this query.

Parameters:

  • buckets: First-character buckets used when letter is set and start is 0.

Returns:

  • window: Container offset and page size.

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.

type Window

type Window struct {
	Start int
	Size  int
}

Window is the PMS container offset and page size for a query.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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