collections

package
v0.3.3 Latest Latest
Warning

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

Go to latest
Published: Nov 4, 2026 License: GPL-3.0 Imports: 42 Imported by: 0

Documentation

Overview

Package collections is Ether's collection engine. It implements core.Collections (what Plex sees in the Collections tab), core.CollectionRows (owner collections offered to the personalization engine as Home and section rows) and the Collection Studio behind the owner UI.

A collection is a core.CollectionSpec: candidates gathered from sources (the catalogue, TMDB lists, collections, discover, keywords, companies, networks, people and streaming services, public Trakt, Letterboxd and MDBList lists, hand-picked titles), filtered by rules, sorted, limited, optionally rotated, and published with generated artwork. External titles join the browsable catalogue so every member is playable. Specs refresh on a schedule in the background, or live on request.

TMDB franchises (the catalogue's TMDB collections with two or more titles) are listed alongside, as before.

Index

Constants

View Source
const (
	MediaMovie = "movie"
	MediaShow  = "show"
	MediaMixed = "mixed"

	MatchAll = "all"
	MatchAny = "any"

	RefreshLive   = "live"
	RefreshHourly = "hourly"
	RefreshDaily  = "daily"
	RefreshWeekly = "weekly"
)

Field, op, sort and source vocabularies.

View Source
const LegacyStremioCatalogKind = "stremioCatalog"

LegacyStremioCatalogKind is the retired source kind of a Stremio catalog entered with its add-on link. Stored specs may still carry it, with the link sealed, until the add-on migration (internal/app) rewrites them to the installed add-on's list source. No kind is registered for it, so such a spec neither validates, builds nor saves: it keeps serving the members of its last build until it is migrated.

View Source
const PreviewItems = 20

PreviewItems is how many items an owner preview of a remote list source reads (SPEC: preview is the first 20).

View Source
const SpecGuide = `` /* 1903-byte string literal not displayed */

SpecGuide documents the collection spec a model writes, for the one-shot generator and the agent's collection_draft tool alike.

Variables

View Source
var ErrBuiltIn = errors.New("built-in collections can be disabled but not deleted")

ErrBuiltIn is returned when deleting a built-in collection.

View Source
var ErrLLMDisabled error = notConfigured{errors.New("the LLM is not enabled (Settings → LLM)")}

ErrLLMDisabled is returned by Generate when no LLM is configured.

View Source
var ErrNoArtwork = errors.New("no artwork for this collection")

ErrNoArtwork means no poster could be produced (no renderer, no members).

View Source
var ErrSnapshotNotBuilt = errors.New("collection snapshot has not been built")

ErrSnapshotNotBuilt means the collection has no persisted build to inspect.

Functions

func BuiltinDescriptors added in v0.3.3

func BuiltinDescriptors() []extend.Descriptor

BuiltinDescriptors returns descriptors for the built-in kinds, without a Service (app startup registers these before services exist).

func BuiltinKey

func BuiltinKey(slug string) core.RatingKey

BuiltinKey returns the rating key of a built-in collection by slug (e.g. "trending-week-movie"), or 0.

func ImportTitlesTx

func ImportTitlesTx(ctx context.Context, tx *sql.Tx, id, userID int64, name string, keys []core.RatingKey, at time.Time) (int64, error)

ImportTitlesTx is the collections-owned writer for a reviewed import. It takes a time, not a number, so the caller cannot pick the wrong unit. The caller commits its migration bookkeeping in the same transaction. Imported lists retain stable IDs and can never replace built-ins or another viewer's.

func IsPreview added in v0.3.3

func IsPreview(ctx context.Context) bool

IsPreview reports whether a gather belongs to an owner-initiated preview.

func Normalize

func Normalize(s *core.CollectionSpec)

Normalize fills defaults in place: an empty source list means the whole catalogue, empty match means "all", and so on. It never fails.

func NormalizeSchedule added in v0.3.2

func NormalizeSchedule(sc *core.CollectionSchedule) *core.CollectionSchedule

NormalizeSchedule trims a schedule's dates and returns nil for a schedule that sets nothing.

func ParseVibe

func ParseVibe(query string) (core.VibeQuery, bool)

ParseVibe turns a natural-language "vibe" query ("90s thrillers under 100 mins", "korean horror", "shows like the office") into a structured filter plus a human title. It is a deterministic, conservative grammar: every word of the query must be consumed by a known pattern (genre, decade/year, runtime, rating, language, media type, mood, person/studio shape or a "like X" seed), otherwise ok is false and the query is treated as a plain title search. No I/O: people and "like" seeds come back unresolved (PersonName / SimilarSeed) for the caller to look up.

func Templates

func Templates() []core.CollectionTemplate

Templates are curated, complete specs the Collection Studio starts from. They name TMDB entities by id and label; labels are resolved by name if an id ever changes. Each previews well on a real catalogue: rules lean on what the catalogue mirror knows (genres, years, ratings, votes, languages), and anything it only partly knows (keywords, runtime, certifications, streaming services) comes from TMDB.

func ValidTMDBImagePath

func ValidTMDBImagePath(p string) bool

ValidTMDBImagePath reports whether p looks like a TMDB image path ("/abc123.jpg"). It rejects traversal and anything that is not a single file name.

func Validate

func Validate(s *core.CollectionSpec) error

Validate checks a normalized spec. It returns a *ValidationError.

func ValidateSchedule added in v0.3.2

func ValidateSchedule(sc *core.CollectionSchedule) error

ValidateSchedule checks a normalized collection schedule. It returns a *ValidationError whose fields are relative to the schedule ("days").

Types

type Chatter

type Chatter interface {
	Enabled() bool
	Chat(ctx context.Context, msgs []llm.Message, jsonMode bool) (string, error)
}

Chatter is the LLM the generator drafts specs with; *llm.Client satisfies it.

type ExternalBases

type ExternalBases struct {
	TraktAPI   string // https://api.trakt.tv
	Letterboxd string // https://letterboxd.com
	MDBList    string // https://mdblist.com
	AniListAPI string // https://graphql.anilist.co
	AnimeIDs   string // the anime id mapping document (anilist -> TMDB/TVDB/IMDb)
	StevenLu   string // https://popular-movies-data.stevenlu.com
}

ExternalBases are the origins external list sources are fetched from. Tests point them at httptest servers; the URLs owners paste are always validated against the real hosts.

type ExternalRef added in v0.3.3

type ExternalRef struct {
	MetadataProvider string
	ProviderID       string
	TMDB             int64
	IMDB             string
	TVDB             int64
	Type             string // "movie" or "show"
	Title            string
	Year             int
}

ExternalRef identifies one item from an external or plugin list source.

type Gather added in v0.3.3

type Gather struct {
	Ctx   context.Context
	Svc   *Service
	Spec  *core.CollectionSpec
	Src   core.CollectionSource
	Rules []*rule
	Want  int
	Kinds []string
	Res   sourceResult
}

Gather is the context one source gather runs with. Kinds append to Res.

func (*Gather) Discover added in v0.3.3

func (g *Gather) Discover(kind string, q url.Values, what string)

Discover runs a discover-backed query for one TMDB kind into the result.

func (*Gather) Fail added in v0.3.3

func (g *Gather) Fail(err error)

Fail ends a preview when a source cannot be evaluated.

func (*Gather) NeedTMDB added in v0.3.3

func (g *Gather) NeedTMDB() bool

NeedTMDB reports whether TMDB is available, recording a warning.

func (*Gather) ResolveExternal added in v0.3.3

func (g *Gather) ResolveExternal(sourceLabel string, refs []ExternalRef, unidentified int) ([]core.Title, int)

ResolveExternal resolves external references to catalogue titles and appends the matched ones to the gather result. unidentified counts items the source read but could not identify at all (no id Ether can match); they are reported with the references that did not resolve, as one "N of M items … could not be matched" warning plus its reasons. It returns the matched titles and the unmatched count.

func (*Gather) Titles added in v0.3.3

func (g *Gather) Titles() []core.Title

Titles returns the titles gathered so far.

func (*Gather) Warn added in v0.3.3

func (g *Gather) Warn(format string, args ...any)

func (*Gather) Warnings added in v0.3.3

func (g *Gather) Warnings() []string

Warnings returns the warnings recorded so far.

type HomeLayoutStore added in v0.3.2

type HomeLayoutStore interface {
	HomeLayout(context.Context) (core.HomeLayout, error)
	SetHomeLayout(context.Context, core.HomeLayout) (core.HomeLayout, error)
}

HomeLayoutStore is the Home layout document the one-time schedule carry-over reads and rewrites. Implemented by internal/personalize.

type KindDescribe added in v0.3.3

type KindDescribe struct {
	Label      extend.Text
	Hint       extend.Text
	Icon       string
	Order      int
	Editor     string
	Params     []extend.ParamField
	Defaults   string // JSON object merged into a new source
	MediaTypes []string
}

KindDescribe carries everything the console needs to offer a kind in the "Add source" picker and edit its params.

type KindRegistry added in v0.3.3

type KindRegistry struct {
	// contains filtered or unexported fields
}

KindRegistry is the set of source kinds a Service can validate and run. Safe for concurrent use; plugins register kinds at runtime.

func NewKindRegistry added in v0.3.3

func NewKindRegistry() *KindRegistry

NewKindRegistry returns a registry holding the built-in kinds.

func (*KindRegistry) Descriptors added in v0.3.3

func (r *KindRegistry) Descriptors() []extend.Descriptor

Descriptors returns the collectionSource descriptors for every kind, for the extend registry. Built-ins register through internal/app/extend_collections.go.

func (*KindRegistry) IDs added in v0.3.3

func (r *KindRegistry) IDs() []string

IDs returns the registered kind ids, sorted.

func (*KindRegistry) Kinds added in v0.3.3

func (r *KindRegistry) Kinds() []SourceKind

Kinds returns every registered kind in registration order.

func (*KindRegistry) Lookup added in v0.3.3

func (r *KindRegistry) Lookup(id string) (SourceKind, bool)

Lookup returns the kind with id, if registered.

func (*KindRegistry) Register added in v0.3.3

func (r *KindRegistry) Register(k SourceKind) error

Register adds a kind. IDs are unique; a duplicate keeps the original.

func (*KindRegistry) Unregister added in v0.3.3

func (r *KindRegistry) Unregister(id string)

Unregister removes a runtime source kind by id.

type LookAhead added in v0.3.0

type LookAhead struct {
	Name    string
	Members []core.RatingKey
}

LookAhead is a server-wide collection that lists upcoming releases.

type Option

type Option func(*Service)

Option customises a Service.

func WithArtwork

func WithArtwork(r *artwork.Renderer, im *artwork.Images) Option

WithArtwork enables generated collection posters.

func WithAuth

func WithAuth(a core.Auth) Option

WithAuth lets previews evaluate per-user rules as the owner.

func WithCatalogConfig

func WithCatalogConfig(fn func() config.Catalog) Option

WithCatalogConfig supplies the catalogue settings (region for streaming services, whether unreleased titles are shown).

func WithEphemeralLimits

func WithEphemeralLimits(ttl time.Duration, max int) Option

WithEphemeralLimits bounds the ephemeral registry (tests).

func WithExternalBases

func WithExternalBases(b ExternalBases) Option

WithExternalBases points external list fetches at other origins (tests).

func WithHTTPClient

func WithHTTPClient(c *http.Client) Option

WithHTTPClient sets the client for the external list sites.

func WithIndexTTL

func WithIndexTTL(d time.Duration) Option

WithIndexTTL sets how often the catalogue index checks for changes (default 2m; 0 checks on every use).

func WithKindRegistry added in v0.3.3

func WithKindRegistry(r *KindRegistry) Option

WithKindRegistry swaps the source-kind registry (shared registries let the app register kinds once and serve the same set as descriptors).

func WithLLM

func WithLLM(c Chatter) Option

WithLLM enables the natural-language collection generator.

func WithLiveTTL

func WithLiveTTL(d time.Duration) Option

WithLiveTTL sets how long a live collection's evaluation is reused (default 2m).

func WithNow

func WithNow(fn func() time.Time) Option

WithNow sets the clock (tests).

func WithSchedulerTick

func WithSchedulerTick(d time.Duration) Option

WithSchedulerTick sets how often Run looks for collections due a refresh.

func WithScorer

func WithScorer(sc core.PersonalScorer) Option

WithScorer sets the personal scorer used by the "personal" sort.

func WithSealer added in v0.3.3

func WithSealer(sealer config.FieldSealer) Option

WithSealer lets the service open the add-on links that legacy Stremio catalog sources stored sealed, for MigrateLegacyStremioSources.

func WithState

func WithState(st core.State) Option

WithState enables per-user rules (watched, in progress).

func WithTMDB

func WithTMDB(c TMDB) Option

WithTMDB enables TMDB-backed sources, lookups and rule pushdown.

func WithTraktConfig

func WithTraktConfig(fn func() config.Trakt) Option

WithTraktConfig supplies the Trakt client id used to read public lists.

func WithUserAgent

func WithUserAgent(ua string) Option

WithUserAgent identifies Ether to list sites.

func WithVibeRefiner

func WithVibeRefiner(r core.VibeRefiner) Option

WithVibeRefiner installs the optional LLM refiner consulted when the deterministic parser cannot read a query.

func WithoutDefaults

func WithoutDefaults() Option

WithoutDefaults skips seeding the starter collections (tests).

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service is the collection engine.

func New

func New(db *sql.DB, cat core.Catalog, log *slog.Logger, opts ...Option) (*Service, error)

New creates the collection engine, migrating v1 smart collections and seeding built-ins and starter collections.

func (*Service) AdoptLayoutSchedules added in v0.3.2

func (s *Service) AdoptLayoutSchedules(ctx context.Context, layouts HomeLayoutStore) error

AdoptLayoutSchedules is the one-time carry-over from the time the Home layout kept its own schedule for collection rows: it folds each Everyone schedule of a collection row into the collection's schedule, preserving what viewers see (see foldLayoutSchedules), and removes it from the layout. It runs once per database.

func (*Service) AllowsPlaceholders added in v0.2.37

func (s *Service) AllowsPlaceholders(ctx context.Context, user *core.User, collection core.RatingKey, device string) bool

func (*Service) Artwork

func (s *Service) Artwork(ctx context.Context, id string, w int) ([]byte, string, time.Time, error)

Artwork renders (or fetches, for tmdb/custom modes) a collection's poster at width w. It returns the image, its content type and when it last changed.

func (*Service) BrowseTitles added in v0.2.9

func (s *Service) BrowseTitles(ctx context.Context, q core.BrowseQuery) (core.Page, error)

BrowseTitles lists the released local catalogue with filters and pagination.

func (*Service) CollectionArtwork

func (s *Service) CollectionArtwork(ctx context.Context, user *core.User, key core.RatingKey, element string, w int) ([]byte, string, bool, error)

CollectionArtwork serves generated posters to Plex for owner collections (the thumb/poster elements). ok is false for anything else, so the caller falls back to TMDB artwork.

func (*Service) CollectionSchedules added in v0.3.2

func (s *Service) CollectionSchedules(ctx context.Context) (map[string]*core.CollectionSchedule, error)

CollectionSchedules returns every collection's schedule by public id; collections without one are absent.

func (*Service) Contains added in v0.3.3

func (s *Service) Contains(ctx context.Context, id string, key core.RatingKey) bool

Contains reports whether key is a member of owner collection id (an id from the Collection Studio). It never builds a collection on the caller's path: an unbuilt collection contains nothing yet. Genre and studio facets read the one title's index entry.

func (*Service) CreateSmart

func (s *Service) CreateSmart(ctx context.Context, c core.Collection) (*core.Collection, error)

CreateSmart persists a filter-based smart collection (core.Filter) as a spec. OwnerUserID 0 = server-wide; otherwise only that user sees it.

func (*Service) CreateSpec

func (s *Service) CreateSpec(ctx context.Context, sp core.CollectionSpec) (*core.CollectionSpec, error)

CreateSpec validates, saves and builds a new collection. The build is bounded; if it runs long it finishes in the background.

func (*Service) DeleteSmart

func (s *Service) DeleteSmart(ctx context.Context, key core.RatingKey) error

DeleteSmart removes an owner or user collection. Built-ins and franchises cannot be deleted.

func (*Service) DeleteSpec

func (s *Service) DeleteSpec(ctx context.Context, id string) error

DeleteSpec deletes an owner collection.

func (*Service) Draft added in v0.3.3

func (s *Service) Draft(ctx context.Context, raw, mediaType string) (*core.CollectionSpec, []string, error)

Draft turns a model-written spec (or {"spec": …} envelope) into a clean, validated spec without calling a model: lists and URLs are dropped, names are resolved to TMDB ids. notes say what was changed or dropped.

func (*Service) Facets

func (s *Service) Facets(ctx context.Context, t core.MediaType, facet string) ([]core.FacetValue, error)

Facets lists filter values over the browsable catalogue: genre, decade, contentRating, studio, country, language (and year).

func (*Service) FindPlaceholder added in v0.2.37

func (s *Service) FindPlaceholder(ctx context.Context, user *core.User, key core.RatingKey, device string) (*core.Title, core.RatingKey, error)

func (*Service) Generate

func (s *Service) Generate(ctx context.Context, prompt, mediaType string) (*core.CollectionSpec, string, error)

Generate drafts a spec from a plain-English request with the LLM, resolves the people, keywords and companies it names to TMDB ids, validates it, and explains it.

func (*Service) Get

func (s *Service) Get(ctx context.Context, user *core.User, key core.RatingKey) (*core.Collection, error)

Get returns one collection by key.

func (*Service) GetSpec

func (s *Service) GetSpec(ctx context.Context, id string) (*core.CollectionSpec, error)

GetSpec returns one collection by id (number or built-in slug).

func (*Service) HomeRowsFor

func (s *Service) HomeRowsFor(ctx context.Context, user *core.User, hc core.HubContext) ([]core.CollectionRow, error)

func (*Service) Items

func (s *Service) Items(ctx context.Context, user *core.User, key core.RatingKey, offset, limit int) (core.Page, error)

Items returns a page of a collection's titles as the user sees them.

func (*Service) KindRegistry added in v0.3.3

func (s *Service) KindRegistry() *KindRegistry

KindRegistry exposes this service's source-kind registry.

func (*Service) LastChance

func (s *Service) LastChance(ctx context.Context, user *core.User, key core.RatingKey) (time.Time, error)

LastChance reports the next configured rotation boundary only when a title belongs to this viewer's current subset and is absent from the next subset. It means leaving a rotating collection row, never disappearing from Ether. The method uses already-built members and the current local index. It never triggers a build, fetches a source, or invents a media-availability deadline.

func (*Service) LayoutRow

func (s *Service) LayoutRow(ctx context.Context, user *core.User, hc core.HubContext, id string) (*core.CollectionRow, error)

LayoutRow serves a collection explicitly selected by the owner's Home template or viewer override, even when its default publication targets do not include Home. Private ownership and viewer content limits still apply. The layout policy supplies the publication scope; the row carries the collection's schedule for the caller to apply.

func (*Service) List

func (s *Service) List(ctx context.Context, user *core.User, t core.MediaType) ([]core.Collection, error)

List returns the collections a user sees in a section's Collections tab: owner collections targeted at them, built-ins, and TMDB franchises.

func (*Service) ListComplete added in v0.3.0

func (s *Service) ListComplete(ctx context.Context, user *core.User, typ core.MediaType) ([]core.Collection, error)

ListComplete builds every eligible collection or returns an error. Unlike List, it never suppresses refresh or franchise-list failures; consumers that advertise an exact total must not use a partial result.

func (*Service) ListSpecs

func (s *Service) ListSpecs(ctx context.Context) ([]core.CollectionSpec, error)

ListSpecs returns every collection, owner-made first, then built-ins.

func (*Service) LookAheads added in v0.3.0

func (s *Service) LookAheads(ctx context.Context) ([]LookAhead, error)

LookAheads returns the enabled server-wide collections that admit upcoming releases, with their last built members shared with every viewer. It reads stored builds only.

func (*Service) Lookup

func (s *Service) Lookup(ctx context.Context, kind, q, region string) ([]core.LookupResult, error)

Lookup finds TMDB people, keywords, companies, networks, collections or streaming services by name for the rule and source pickers.

func (*Service) MigrateLegacyStremioSources added in v0.3.3

func (s *Service) MigrateLegacyStremioSources(ctx context.Context, migrate func(context.Context, core.CollectionSource) (core.CollectionSource, error)) error

MigrateLegacyStremioSources rewrites every stored source of kind LegacyStremioCatalogKind in place. migrate receives the source with its add-on link opened and its MediaType set ("movie" or "show"), and returns the source that replaces it. A legacy source without a media type read its catalog for each media type of the collection, so it is migrated once per type and replaced by one source each. The collection keeps its id, members, build state and refresh schedule; its next scheduled refresh reads the new sources. A source whose link cannot be opened or whose migrate fails stays as it was (still sealed), and the first such error is returned so the caller can retry later. Running it again after a full migration finds nothing to do.

func (*Service) Placeholder added in v0.2.37

func (s *Service) Placeholder(ctx context.Context, user *core.User, collection, key core.RatingKey, device string) (*core.Title, error)

func (*Service) Preview

Preview evaluates an unsaved spec and returns the first n titles. Titles come from the in-memory catalogue index, so a preview over the whole catalogue never waits on the database.

func (*Service) PromoteEphemeral

func (s *Service) PromoteEphemeral(ctx context.Context, user *core.User, key core.RatingKey) (*core.Collection, bool, error)

PromoteEphemeral implements core.VibeSearcher: rating an ephemeral collection saves it as a persisted personal smart collection with the same title. The ephemeral key keeps working as an alias.

func (*Service) Prune

func (s *Service) Prune(ctx context.Context) (int64, error)

Prune deletes stale rows from collections_names and collections_external. Specs, members and owner data are never touched. It is meant to be called periodically.

func (*Service) Rebuild

func (s *Service) Rebuild(ctx context.Context, id string) (*core.CollectionSpec, error)

Rebuild evaluates a collection now.

func (*Service) RegisterSourceKind added in v0.3.3

func (s *Service) RegisterSourceKind(k SourceKind) error

RegisterSourceKind adds a source kind to this service (plugin list sources, Stremio catalogs). The kind is then valid in specs, gathers on background builds, and should also be served as a descriptor: call KindRegistry.Descriptors (or Service.SourceDescriptors) and register the result with the extend registry.

func (*Service) Run

func (s *Service) Run(ctx context.Context)

Run refreshes scheduled collections until ctx ends: anything never built or edited since its last build right away, then hourly/daily/weekly per spec. Live collections are evaluated on request instead.

func (*Service) RunDue

func (s *Service) RunDue(ctx context.Context) int

RunDue rebuilds every collection that is due and returns how many were built.

func (*Service) SearchTitles

func (s *Service) SearchTitles(ctx context.Context, q string, t core.MediaType, limit int) ([]core.Title, error)

SearchTitles searches the catalogue (reaching all of TMDB).

func (*Service) SetAuth

func (s *Service) SetAuth(a core.Auth)

SetAuth lets previews apply per-user rules as the owner.

func (*Service) SetBus

func (s *Service) SetBus(bus clusterbus.Bus)

SetBus connects the cluster bus (nil disconnects). A standalone server never calls it.

func (*Service) SetLLM

func (s *Service) SetLLM(c Chatter)

SetLLM installs the model the collection generator drafts with.

func (*Service) SetSchedule added in v0.3.2

func (s *Service) SetSchedule(ctx context.Context, id string, sc *core.CollectionSchedule) error

SetSchedule replaces one collection's schedule (nil clears it), leaving the rest of the collection and its members as they are.

func (*Service) SetScorer

func (s *Service) SetScorer(sc core.PersonalScorer)

SetScorer installs (or replaces) the personal scorer after construction, for when the personalization engine is built after the collections.

func (*Service) SetState

func (s *Service) SetState(st core.State)

SetState installs watch state for per-user rules (watched, in progress).

func (*Service) SetVibeRefiner

func (s *Service) SetVibeRefiner(r core.VibeRefiner)

SetVibeRefiner installs the refiner after construction.

func (*Service) SnapshotItems added in v0.3.3

func (s *Service) SnapshotItems(ctx context.Context, key core.RatingKey, offset, limit int) (core.Page, error)

SnapshotItems returns a page of the last persisted shared members. It does not evaluate personal rules, refresh sources, or build a missing snapshot.

func (*Service) SnapshotList added in v0.3.3

func (s *Service) SnapshotList(ctx context.Context, offset, limit int) ([]core.Collection, error)

SnapshotList returns a bounded page of persisted collection specifications. It does not evaluate sources, expand franchises, or rebuild collection members.

func (*Service) SourceDescriptors added in v0.3.3

func (s *Service) SourceDescriptors() []extend.Descriptor

SourceDescriptors returns extend descriptors for every registered kind.

func (*Service) Templates

func (s *Service) Templates() []core.CollectionTemplate

Templates returns the curated starting points.

func (*Service) TitleDetail

func (s *Service) TitleDetail(ctx context.Context, key core.RatingKey) (*core.Title, error)

TitleDetail returns a title with credits and keywords (fetching details from TMDB when the mirror only has a summary). The owner console also inspects titles viewers cannot open yet, such as an upcoming movie on the release calendar, so an unreleased title Get refuses is read from the mirror instead. Adult titles stay hidden.

func (*Service) TitlesByIMDB added in v0.3.3

func (s *Service) TitlesByIMDB(ctx context.Context, ids []string) []core.Title

TitlesByIMDB resolves up to 24 IMDb ids to catalogue titles, in order, skipping ids the catalogue does not know. The owner console uses it to name the titles a plugin was asked about.

func (*Service) UnregisterSourceKind added in v0.3.3

func (s *Service) UnregisterSourceKind(id string)

UnregisterSourceKind removes a runtime source kind from this service.

func (*Service) UpdateSpec

func (s *Service) UpdateSpec(ctx context.Context, id string, sp core.CollectionSpec) (*core.CollectionSpec, error)

UpdateSpec replaces a collection. Built-ins accept only enabled, targets, artwork, rotate and limit.

func (*Service) ValidateSchedule added in v0.3.2

func (s *Service) ValidateSchedule(sc *core.CollectionSchedule) error

ValidateSchedule normalizes and checks a schedule without saving it.

func (*Service) VibeCollection

func (s *Service) VibeCollection(ctx context.Context, user *core.User, query string) (*core.Collection, []core.Title, bool, error)

VibeCollection implements core.VibeSearcher.

type SourceKind added in v0.3.3

type SourceKind interface {
	// ID is the kind persisted as CollectionSource.Kind.
	ID() string
	Describe() KindDescribe
	Validate(ve *ValidationError, path string, src core.CollectionSource)
	Gather(g *Gather)
}

SourceKind is one collection source kind: how it is described to the console, how its saved source is validated, and how it gathers titles. Gather runs on background build/refresh paths only, never on a request path (list sources included).

To add a kind: implement SourceKind, then register it. Built-ins register in builtinSourceKinds below; runtime additions (plugin list sources) call Service.RegisterSourceKind, or register on a KindRegistry passed with WithKindRegistry. The kind then appears in Descriptors and is served to the console by extend; no console code names individual kinds.

type TMDB

type TMDB interface {
	GetJSON(ctx context.Context, path string, q url.Values, out any) error
}

TMDB is the slice of the TMDB client the collection engine needs: one generic, rate-limited, cached GET. *tmdb.Client satisfies it.

type TitleUpserter

type TitleUpserter interface {
	UpsertTitle(ctx context.Context, t core.Title, browsable bool) error
}

TitleUpserter adds titles to the catalogue mirror; *catalog.Catalog satisfies it. Collection members found outside the catalogue are joined to the browsable set through it.

type ValidationError

type ValidationError struct {
	Fields map[string]string
}

ValidationError lists the problems with a spec, keyed by field path ("name", "sources[1].url", "rules[0].value"). The admin API renders it as a 400 with per-field messages.

func (*ValidationError) Add added in v0.3.3

func (e *ValidationError) Add(field, msg string)

Add records a validation error on field if one is not already present.

func (*ValidationError) Error

func (e *ValidationError) Error() string

func (*ValidationError) InvalidFields

func (e *ValidationError) InvalidFields() map[string]string

InvalidFields exposes the field errors without importing this package.

Jump to

Keyboard shortcuts

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