plex

package
v1.5.10 Latest Latest
Warning

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

Go to latest
Published: Jul 15, 2026 License: GPL-2.0, GPL-3.0 Imports: 12 Imported by: 0

Documentation

Overview

Package plex adapts the shared github.com/cplieger/plexapi client for plex-language-sync. The transport — header-borne token, refuse-all redirects, same-origin path guard, CA pinning, transparent retry with Retry-After honoring, bounded reads, and the plaintext-URL startup warning — is the library's. This package owns the app's construction shapes (CA path from env, per-user clients), its decode types (the stream-selection domain model in internal/streams), and the app-facing method vocabulary (ShowEpisodes, LoggedUser, SharedUserTokens, ...).

Package plex types: the app-facing container and admin types, plus aliases onto the shared plexapi library where the shapes are the library's own (RatingKey, Section, ServerIdentity, SharedServer). Value types for the stream-selection domain (Episode, Stream, Media, Part, Label) live in internal/streams; this package decodes into them via the generic fetch helpers.

Index

Constants

View Source
const (
	// TypeEpisode is the Plex metadata "type" string for episode items.
	TypeEpisode = plexapi.TypeEpisode
	// MetadataTypeEpisode is the numeric type ID for ?type= filters.
	MetadataTypeEpisode = plexapi.MetadataTypeEpisode
	// SectionTypeShow is the library-section "type" string for TV shows.
	SectionTypeShow = plexapi.SectionTypeShow
)

Plex wire-protocol constants, re-exported from the library so consumers (main, config, scheduler, notify, sync, library.go) keep one import.

Variables

View Source
var ErrNotFound = plexapi.ErrNotFound

ErrNotFound is the library's 404 sentinel, re-exported for call sites (errors.Is(err, plex.ErrNotFound)).

Functions

func SwapTVClient

func SwapTVClient(replacement *http.Client) (restore func())

SwapTVClient replaces the package-level plex.tv HTTP client with the supplied one and returns a function that restores the original. Intended for tests that point shared-server lookups at a local httptest server; production code never calls this.

Types

type Client

type Client struct {
	*plexapi.Client
}

Client is an HTTP client for a single Plex Media Server base URL + auth token. Use NewClient, NewClientForUser, or NewClientFromHTTP.

func NewClient

func NewClient(serverURL, token, caCertPath string) (*Client, error)

NewClient parses serverURL, validates the scheme, and returns a Client. When caCertPath is non-empty, the PEM file at that path is pinned as the sole TLS trust anchor (verification stays ON) — the setup for self-signed Plex certificates. Empty caCertPath uses the OS trust store. The library warns at construction when the URL is plain http to a non-local host (the token would transit unencrypted).

func NewClientForUser

func NewClientForUser(baseURL *url.URL, token, caCertPath string) (*Client, error)

NewClientForUser creates a Client using a different (user-scoped) token but the same server base URL and TLS settings. Plex records stream-selection writes against the requesting token's user, so per-user writes must go through a per-user client.

func NewClientFromHTTP

func NewClientFromHTTP(baseURL *url.URL, token string, hc *http.Client) *Client

NewClientFromHTTP builds a Client from an already-parsed base URL and a caller-supplied http.Client. Intended for tests that point a Client at an httptest.Server — production code uses NewClient. A nil hc gets the library's default hardened transport.

func (*Client) Episode

func (c *Client) Episode(ctx context.Context, rk RatingKey) (*streams.Episode, error)

Episode fetches episode (or any library item) metadata by rating key. Returns ErrNotFound when the item is missing. /library/metadata/{key} is type-agnostic; ShowMetadata wraps this variant for show-level lookups.

func (*Client) History

func (c *Client) History(ctx context.Context, sinceUnix int64) ([]HistoryItem, error)

History fetches recent play history since the given unix timestamp.

Plex supports filter operators on many fields; the documented syntax for "viewedAt >= X" is literally `viewedAt>=X` with a single `>` and a literal (unencoded) operator. A prior version used `viewedAt>>=` (double `>`), which Plex silently ignores — the server returned the full history (21k+ entries on a long-lived server), overflowed the 10 MB read cap in doJSON, and surfaced as a daily WARN ("unexpected end of JSON input") in Loki. Go's url.Parse preserves `>=` as-is, so the single-char fix correctly reaches the server and the response is filtered server-side.

func (*Client) LoggedUser

func (c *Client) LoggedUser(ctx context.Context) (*User, error)

LoggedUser resolves the admin (server owner) user via the library's AdminAccount — system account id 1, the same server-local id space that sessions and watch history report — shaped into the app's User type. plexapi v1.1.2 fixed AdminAccount returning the id-0 placeholder (the /myplex/account envelope + email-username made name-matching resolve the wrong account, so owner play/history events were skipped).

func (*Client) RecentlyAdded

func (c *Client) RecentlyAdded(ctx context.Context, sectionKey RatingKey, sinceUnix int64) ([]streams.Episode, error)

RecentlyAdded fetches recently added episodes from a library section, filtered server-side by addedAt >= sinceUnix.

func (*Client) SeasonEpisodes

func (c *Client) SeasonEpisodes(ctx context.Context, rk RatingKey) ([]streams.Episode, error)

SeasonEpisodes returns the episodes of a single season (children).

func (*Client) ServerIdentity

func (c *Client) ServerIdentity(ctx context.Context) (*ServerIdentity, error)

ServerIdentity returns the Plex server's identity (friendly name, machine ID, version) from GET /. Delegates to the library's Identity.

func (*Client) SharedUserTokens

func (c *Client) SharedUserTokens(ctx context.Context, machineIdentifier string) ([]SharedServerXML, error)

SharedUserTokens fetches shared user tokens from the plex.tv shared_servers endpoint. This calls the plex.tv API (not the local server) through the library's TV client, which never skips TLS verification and never follows redirects — the admin token must not be forwarded anywhere but plex.tv.

func (*Client) ShowEpisodes

func (c *Client) ShowEpisodes(ctx context.Context, rk RatingKey) ([]streams.Episode, error)

ShowEpisodes returns every episode in a show (allLeaves).

func (*Client) ShowMetadata

func (c *Client) ShowMetadata(ctx context.Context, rk RatingKey) (*Show, error)

ShowMetadata fetches the show-level metadata (labels, library) for a show. /library/metadata/{key} returns whatever type the key points to, so this delegates to the same endpoint as Episode but decodes into *Show. Split off from Episode: a show response does not have Media/Part/Stream, so typing it as *Show instead of *Episode keeps the field set honest for callers (e.g. shouldIgnoreShow reads only LibraryTitle + Label).

func (*Client) ShowSections

func (c *Client) ShowSections(ctx context.Context) ([]Section, error)

ShowSections returns the TV-show library sections.

func (*Client) UserFromSession

func (c *Client) UserFromSession(ctx context.Context, clientIdentifier string) (userID, username string, err error)

UserFromSession finds the user associated with a clientIdentifier by querying active sessions. Returns the user ID and username.

type HTTPStatusError added in v1.5.7

type HTTPStatusError = plexapi.StatusError

HTTPStatusError is the library's non-200 error, aliased so the startup fatal-vs-transient classifier keeps matching with errors.As.

type HistoryItem

type HistoryItem struct {
	RatingKey        string          `json:"ratingKey"`
	Type             string          `json:"type"`
	LibraryTitle     string          `json:"librarySectionTitle"`
	AccountID        streams.FlexInt `json:"accountID"`
	LibrarySectionID streams.FlexInt `json:"librarySectionID"`
}

HistoryItem is one entry from GET /status/sessions/history/all.

type RatingKey

type RatingKey = plexapi.RatingKey

RatingKey is the library's validated Plex item identifier. The alias preserves this package's boundary vocabulary (api.PlexReader and the *Client methods take plex.RatingKey); validation semantics — and the exact `invalid rating key %q` error text scrapers grep for — are the library's.

type Season

type Season struct {
	RatingKey       string          `json:"ratingKey"`
	ParentRatingKey string          `json:"parentRatingKey"`
	Title           string          `json:"title"`
	Index           streams.FlexInt `json:"index"`
}

Season is the season-level metadata returned by GET /library/metadata/{key} when the key points to a season: the navigational spine (parent key, season index) without the whole media/part/stream graph.

type Section

type Section = plexapi.Section

Section is a library section returned by GET /library/sections.

type ServerIdentity

type ServerIdentity = plexapi.ServerIdentity

ServerIdentity is the library's GET / identity payload (the app reads FriendlyName, MachineIdentifier, Version).

type Session

type Session struct {
	User struct {
		ID    string `json:"id"`
		Title string `json:"title"`
	} `json:"User"`
	Player struct {
		MachineIdentifier string `json:"machineIdentifier"`
	} `json:"Player"`
}

Session represents a single active session from GET /status/sessions.

type SharedServerXML

type SharedServerXML = plexapi.SharedServer

SharedServerXML is one shared-user entry from the plex.tv shared_servers endpoint (userID, username, user-scoped access token).

type Show

type Show struct {
	RatingKey        string          `json:"ratingKey"`
	Title            string          `json:"title"`
	LibraryTitle     string          `json:"librarySectionTitle"`
	Label            []streams.Label `json:"Label"`
	LibrarySectionID streams.FlexInt `json:"librarySectionID"`
}

Show is the show-level metadata returned by GET /library/metadata/{key} when the key points to a TV show. Split off from Episode so callers asking "what are the show's labels?" don't receive an Episode-typed value.

type User

type User struct {
	ID   string
	Name string
}

User represents the resolved admin (or any) Plex user.

Jump to

Keyboard shortcuts

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