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
- Variables
- func SwapTVClient(replacement *http.Client) (restore func())
- type Client
- func (c *Client) Episode(ctx context.Context, rk RatingKey) (*streams.Episode, error)
- func (c *Client) History(ctx context.Context, sinceUnix int64) ([]HistoryItem, error)
- func (c *Client) LoggedUser(ctx context.Context) (*User, error)
- func (c *Client) RecentlyAdded(ctx context.Context, sectionKey RatingKey, sinceUnix int64) ([]streams.Episode, error)
- func (c *Client) SeasonEpisodes(ctx context.Context, rk RatingKey) ([]streams.Episode, error)
- func (c *Client) ServerIdentity(ctx context.Context) (*ServerIdentity, error)
- func (c *Client) SharedUserTokens(ctx context.Context, machineIdentifier string) ([]SharedServerXML, error)
- func (c *Client) ShowEpisodes(ctx context.Context, rk RatingKey) ([]streams.Episode, error)
- func (c *Client) ShowMetadata(ctx context.Context, rk RatingKey) (*Show, error)
- func (c *Client) ShowSections(ctx context.Context) ([]Section, error)
- func (c *Client) UserFromSession(ctx context.Context, clientIdentifier string) (userID, username string, err error)
- type HTTPStatusError
- type HistoryItem
- type RatingKey
- type Season
- type Section
- type ServerIdentity
- type Session
- type SharedServerXML
- type Show
- type User
Constants ¶
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 ¶
var ErrNotFound = plexapi.ErrNotFound
ErrNotFound is the library's 404 sentinel, re-exported for call sites (errors.Is(err, plex.ErrNotFound)).
Functions ¶
func SwapTVClient ¶
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 ¶
Client is an HTTP client for a single Plex Media Server base URL + auth token. Use NewClient, NewClientForUser, or NewClientFromHTTP.
func NewClient ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
ShowEpisodes returns every episode in a show (allLeaves).
func (*Client) ShowMetadata ¶
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 ¶
ShowSections returns the TV-show library sections.
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 ¶
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 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.