Documentation
¶
Overview ¶
Package stremio is the Stremio addon-source module: the first official optional Module, built exactly as a third party would build one. It is its own Go module (github.com/mosaic-media/module-stremio-addons) importing only the published SDK (contracts/platform/v1) and the standard library, and it is compiled into the Platform binary and invoked through the capability registry (ADR 0007, ADR 0008).
It consumes the Stremio addon protocol as a client: it points at one or more addon HTTP endpoints and, guided by each addon's manifest, uses whatever resources that addon declares. Metadata (the meta resource) creates the Work and its season/episode tree with an external-id source binding; streams (the stream resource) attach a RemoteLocation Part. The two are independent — a meta-only addon yields metadata with no Parts, so a user can enrich local media through Stremio addons without adopting remote streaming. Streams are opt-in by which addons are configured, not by the module.
It owns no schema (ADR 0012): everything it does to the graph goes through ContentService, acting as the Caller the Platform hands it (ADR 0017). Stream locations are snapshotted at import; resolving or transcoding them at play time is a separate, future concern (the Remote Media module), deliberately not here.
Index ¶
- Constants
- type AddonCatalogEntry
- type AddonInfo
- type AppExtras
- type Capability
- func (c *Capability) CatalogItems(ctx context.Context, req v1.CatalogItemsRequest) (v1.CatalogItemsResponse, error)
- func (c *Capability) Catalogs(ctx context.Context, req v1.CatalogsRequest) (v1.CatalogsResponse, error)
- func (c *Capability) Import(ctx context.Context, svc v1.ContentService, req v1.ImportRequest) (v1.ImportResult, error)
- func (c *Capability) Manifest() v1.Manifest
- func (c *Capability) Metadata(ctx context.Context, req v1.MetadataRequest) (v1.ContentMetadata, error)
- func (c *Capability) Search(ctx context.Context, req v1.SearchRequest) (v1.SearchResponse, error)
- func (c *Capability) SettingsUI(ctx context.Context, req v1.SettingsUIRequest) (v1.SettingsUIResponse, error)
- func (c *Capability) Streams(ctx context.Context, req v1.StreamRequest) (v1.StreamResponse, error)
- func (c *Capability) Subtitles(ctx context.Context, req v1.SubtitlesRequest) (v1.SubtitlesResponse, error)
- type CatalogDecl
- type Client
- func (c *Client) AddonCatalog(ctx context.Context) ([]AddonCatalogEntry, error)
- func (c *Client) CatalogItems(ctx context.Context, typ, id string, skip int) ([]MetaPreview, error)
- func (c *Client) Catalogs(ctx context.Context) ([]CatalogDecl, error)
- func (c *Client) InstalledAddons(ctx context.Context) []AddonInfo
- func (c *Client) Meta(ctx context.Context, typ, id string) (Meta, bool, error)
- func (c *Client) MetaMerged(ctx context.Context, typ, id string) (Meta, MetaProvenance, bool, error)
- func (c *Client) Search(ctx context.Context, query string) ([]MetaPreview, error)
- func (c *Client) Stream(ctx context.Context, typ, id string) (Stream, bool, error)
- func (c *Client) Streams(ctx context.Context, typ, id string) ([]Stream, error)
- func (c *Client) Subtitles(ctx context.Context, typ, id string) ([]Subtitle, bool, error)
- type Credit
- type ExtraDecl
- type Link
- type Manifest
- type Meta
- type MetaPreview
- type MetaProvenance
- type ResourceDecl
- type Stream
- type Subtitle
- type Video
Constants ¶
const ( // CapabilityID is the id the Platform registers this module under and a // caller names to invoke it. CapabilityID = "stremio" )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AddonCatalogEntry ¶
type AddonCatalogEntry struct {
TransportURL string `json:"transportUrl"`
Manifest Manifest `json:"manifest"`
}
AddonCatalogEntry is one installable addon a catalog of addons lists (ADR 0038): its transport (manifest) URL and enough of its manifest to name it.
type AddonInfo ¶
AddonInfo is the display detail for one configured addon (ADR 0038): the name, logo and description from its manifest, whether it is configurable, and the normalised base URL that identifies it. An addon whose manifest cannot be fetched still yields an entry (named by its URL) so a user can remove it.
type AppExtras ¶ added in v0.15.0
type AppExtras struct {
Cast []Credit `json:"cast"`
Directors []Credit `json:"directors"`
Writers []Credit `json:"writers"`
}
AppExtras is the richer credit block some addons attach alongside the standard meta fields.
type Capability ¶
type Capability struct {
// contains filtered or unexported fields
}
Capability is the Stremio addon-source module (ADR 0008's capability surface, first populated). It holds only an HTTP client; the addons it sources from are the bundled default (Cinemeta) plus whatever a user adds through its settings at invocation time (ADR 0021), so metadata and search work out of the box and the same registered module serves whatever else each user configures. It owns no schema and imports no Platform internals.
func New ¶
func New(httpClient *http.Client) *Capability
New builds the capability over an HTTP client (nil for a default). Addon URLs are not supplied here — the bundled default is always present and user addons arrive as settings on each invocation.
func (*Capability) CatalogItems ¶
func (c *Capability) CatalogItems(ctx context.Context, req v1.CatalogItemsRequest) (v1.CatalogItemsResponse, error)
CatalogItems lists one collection's entries as virtual candidates the admin can select to publish (ADR 0028). It does not touch the object graph.
func (*Capability) Catalogs ¶
func (c *Capability) Catalogs(ctx context.Context, req v1.CatalogsRequest) (v1.CatalogsResponse, error)
Catalogs lists the collections the configured addons expose (RoleCatalog — the addon `catalog` resource), for the admin collection browser.
func (*Capability) Import ¶
func (c *Capability) Import(ctx context.Context, svc v1.ContentService, req v1.ImportRequest) (v1.ImportResult, error)
Import materialises the virtual item named by req.Ref — a result a search or catalog browse produced (ADR 0028) — from the configured addons into the Platform. It fetches metadata (required), searches to avoid duplicating, creates the Work with an external-id binding, builds the tree, and attaches a RemoteLocation Part wherever a stream addon serves one. Metadata alone is a complete import; streams are additive.
func (*Capability) Manifest ¶
func (c *Capability) Manifest() v1.Manifest
Manifest is the module's self-declaration, including the provider roles it fills (ADR 0027). It sources metadata and searches and browses catalogs, and resolves streams — the four Stremio addon resources.
func (*Capability) Metadata ¶
func (c *Capability) Metadata(ctx context.Context, req v1.MetadataRequest) (v1.ContentMetadata, error)
Metadata resolves descriptive detail for a ref (RoleMetadata — the addon `meta` resource). It is the enrichment surface: the descriptive fields, not the containment tree, which Import builds where the source's structure is known (ADR 0027).
func (*Capability) Search ¶
func (c *Capability) Search(ctx context.Context, req v1.SearchRequest) (v1.SearchResponse, error)
Search returns virtual candidates for free text (RoleSearch — the addon `catalog/…/search` resource). No raw id: this is what makes user search in Mosaic work over source content that is not in the library (ADR 0028).
func (*Capability) SettingsUI ¶
func (c *Capability) SettingsUI(ctx context.Context, req v1.SettingsUIRequest) (v1.SettingsUIResponse, error)
SettingsUI renders the module's own settings screen as SDUI (RoleSettingsUI, ADR 0038): add an addon by manifest URL, view the installed addons as cards (name, logo, description) with a way to configure or remove them, toggle the bundled Cinemeta default, and browse a grid of installable addons (the addon_catalog resource) to add without a URL. Every mutating control is an Invoke of the Platform's configureModule command with the complete new settings document, so the Platform stays the one that persists them. The screen is returned as serialised UINode JSON — the SDK stays SDUI-agnostic.
func (*Capability) Streams ¶
func (c *Capability) Streams(ctx context.Context, req v1.StreamRequest) (v1.StreamResponse, error)
Streams resolves playable locations for a materialised item's ref (RoleStream — the addon `stream` resource). Import snapshots streams at materialise time; this exposes the same resolution as a role other flows can call. It returns an empty response, no error, when no addon serves a stream (the meta-only case).
func (*Capability) Subtitles ¶
func (c *Capability) Subtitles(ctx context.Context, req v1.SubtitlesRequest) (v1.SubtitlesResponse, error)
Subtitles resolves subtitle tracks for a materialised item's ref (RoleSubtitles — the addon `subtitles` resource, ADR 0037). Like Streams it is a source role; the consumer is a player that does not exist yet, so this is built ahead of it. It returns an empty response, no error, when no addon serves subtitles.
type CatalogDecl ¶
type CatalogDecl struct {
Type string `json:"type"`
ID string `json:"id"`
Name string `json:"name"`
// Extra is the modern shape: a list of accepted parameters, each named.
Extra []ExtraDecl `json:"extra"`
// ExtraSupported is the older shape: a bare list of accepted parameter
// names. Both are read so search is detected whichever an addon uses.
ExtraSupported []string `json:"extraSupported"`
}
CatalogDecl is one entry of a manifest's catalogs array — a collection the addon exposes (Popular, Top). A catalog is typed and addressed by its id; the extra declarations say which query parameters it accepts, the one that matters here being "search".
func (CatalogDecl) SupportsSearch ¶
func (c CatalogDecl) SupportsSearch() bool
SupportsSearch reports whether the catalog accepts a search query.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a minimal client of the Stremio addon protocol — the HTTP contract documented at stremio.github.io/stremio-addon-sdk. It talks to one or more addons and routes each request to an addon whose manifest declares the needed resource and type. A meta-only addon therefore serves metadata and a stream addon serves streams, and neither resource depends on the other.
func NewClient ¶
NewClient builds a client over the given addon URLs. A nil httpClient gets a default with a sane timeout. Each URL is normalised to the addon's base URL (see normaliseAddonURL) so that either the base URL or the manifest URL a user copies from Stremio works. Manifests are not fetched here; they are fetched on first use so construction stays offline.
func (*Client) AddonCatalog ¶
func (c *Client) AddonCatalog(ctx context.Context) ([]AddonCatalogEntry, error)
AddonCatalog fetches the union of every configured addon's addon catalogs — the installable addons a user can add without pasting a manifest URL. Addons that do not serve the resource contribute nothing; a fetch that errors is skipped rather than failing the whole browse. De-duped by transport URL.
func (*Client) CatalogItems ¶
CatalogItems lists one catalog's entries, from the first addon whose manifest declares a catalog of that type and id. skip pages through a large catalog (0 for the first page). It returns nil, no error, when no configured addon declares the catalog.
func (*Client) InstalledAddons ¶
InstalledAddons returns display detail for each configured addon, in the client's effective (deduped, default-first) order. Manifests are fetched and cached; an unreachable addon is named by its URL rather than dropped, so it stays removable.
func (*Client) Meta ¶
Meta fetches metadata for a content id from the first configured addon whose manifest serves the meta resource for the type. It returns ok=false, no error, when no configured addon serves meta for it.
func (*Client) MetaMerged ¶ added in v0.13.0
func (c *Client) MetaMerged(ctx context.Context, typ, id string) (Meta, MetaProvenance, bool, error)
MetaMerged asks every addon that serves `meta` and combines their answers by the tiered rule above. It also reports which addon supplied each tier, so an odd-looking detail screen is an answerable question rather than a guess.
func (*Client) Search ¶
Search queries every search-capable catalog across every configured addon and returns the union, de-duplicated by content id. A catalog that errors on the search query is skipped rather than failing the whole search, so one broken addon does not blank the results. It returns nil, no error, when nothing matches or no addon offers search.
func (*Client) Streams ¶ added in v0.10.0
Stream fetches the best stream for a content id (a movie id, or an episode id of the form tt...:season:episode) from the first addon whose manifest serves the stream resource for the type. Stremio ranks streams best-first, so the first entry is taken. It returns ok=false, no error, when no configured addon serves a stream — the metadata-only case. Streams fetches every stream a configured addon offers for a content id.
Import stores all of them (ADR 0049): a candidate never expires, so keeping the set costs nothing to keep correct, and it is what lets a consumer choose a release the calling client can actually play instead of being handed whatever happened to be first. Only the resolved URL is perishable, and that is cached separately.
func (*Client) Subtitles ¶
Subtitles fetches subtitle tracks for a content id (a movie id or an episode id of the form tt...:season:episode) from the first addon whose manifest serves the subtitles resource for the type. It returns ok=false, no error, when no configured addon serves subtitles (ADR 0037).
type Credit ¶ added in v0.15.0
type Credit struct {
Name string `json:"name"`
Character string `json:"character"`
Photo string `json:"photo"`
}
Credit is one person with the two things `links` cannot express: the character they played, and a photograph of them.
type ExtraDecl ¶
type ExtraDecl struct {
Name string `json:"name"`
}
ExtraDecl is one accepted catalog parameter.
type Link ¶
type Link struct {
Name string `json:"name"`
Category string `json:"category"`
URL string `json:"url"`
}
Link is one entry of a meta's `links` array — the modern Cinemeta shape that carries cast, directors, writers and genres as categorised references.
type Manifest ¶
type Manifest struct {
ID string `json:"id"`
Name string `json:"name"`
Version string `json:"version"`
Description string `json:"description"`
Logo string `json:"logo"`
Resources []ResourceDecl `json:"resources"`
Types []string `json:"types"`
Catalogs []CatalogDecl `json:"catalogs"`
// AddonCatalogs are catalogs of *other addons* this addon exposes (the
// `addon_catalog` resource) — how a user discovers installable addons without
// a manifest URL (ADR 0038).
AddonCatalogs []CatalogDecl `json:"addonCatalogs"`
BehaviorHints addonBehaviorHints `json:"behaviorHints"`
}
Manifest is the subset of a Stremio addon manifest this client reads.
type Meta ¶
type Meta struct {
ID string `json:"id"`
Type string `json:"type"`
Name string `json:"name"`
Poster string `json:"poster"`
Background string `json:"background"`
Logo string `json:"logo"`
Description string `json:"description"`
ReleaseInfo string `json:"releaseInfo"`
Genres []string `json:"genres"`
// ImdbRating is Cinemeta's rating, a string ("8.0") in its API.
ImdbRating string `json:"imdbRating"`
// Runtime is a display string whose format varies ("120 min").
Runtime string `json:"runtime"`
// Cast is the legacy top-level cast (names). Modern Cinemeta also puts cast
// in Links with category "Cast"; both are read (see castNames).
Cast []string `json:"cast"`
Links []Link `json:"links"`
Videos []Video `json:"videos"`
// AppExtras is where an addon proxying a real metadata database puts credits
// that the base Stremio meta shape has no room for. `links` carries cast as
// a name and a search URL — no character, no photo — so an addon with better
// data has nowhere to put it and puts it here instead.
AppExtras AppExtras `json:"app_extras"`
}
Meta is the subset of a meta response this client reads. For a series, Videos lists the episodes, each carrying its season and episode number. Logo/ImdbRating/Runtime/Cast/Links back the rich detail surface (ADR 0034); Cinemeta provides them all — the module simply decoded none of them before.
type MetaPreview ¶
type MetaPreview struct {
ID string `json:"id"`
Type string `json:"type"`
Name string `json:"name"`
Poster string `json:"poster"`
ReleaseInfo string `json:"releaseInfo"`
}
MetaPreview is the subset of a catalog/search meta entry this client reads — the lightweight item shape a catalog returns, distinct from the full Meta a meta lookup returns. ReleaseInfo is a year ("2017") or a range ("2008-2013").
type MetaProvenance ¶ added in v0.14.0
MetaProvenance records which addon supplied each tier of a merged record.
It costs almost nothing and turns "why does this look odd" into something answerable. Metadata assembled from several sources is exactly the kind of thing that is hard to debug after the fact without it.
type ResourceDecl ¶
ResourceDecl is one entry of a manifest's resources array. Stremio allows each entry to be either a bare string ("meta") or an object carrying its own types and id prefixes; this unmarshals both shapes.
func (*ResourceDecl) UnmarshalJSON ¶
func (r *ResourceDecl) UnmarshalJSON(b []byte) error
UnmarshalJSON accepts either a bare string or the object form.
type Stream ¶
type Stream struct {
Name string `json:"name"`
Title string `json:"title"`
Description string `json:"description"`
URL string `json:"url"`
InfoHash string `json:"infoHash"`
FileIdx int `json:"fileIdx"`
BehaviorHints behaviorHints `json:"behaviorHints"`
}
Stream is the subset of a stream object this client reads. A stream is either a direct URL or a torrent identified by InfoHash. Description/ BehaviorHints carry the release detail (quality, size) addons pack into the title, which parseStreamMeta teases back out (ADR 0037).
type Subtitle ¶
Subtitle is the subset of a subtitles response entry this client reads (ADR 0037): a track's language and the file URL.
type Video ¶
type Video struct {
ID string `json:"id"`
Title string `json:"title"`
Name string `json:"name"`
Season int `json:"season"`
Episode int `json:"episode"`
Overview string `json:"overview"`
// Thumbnail is a still image URL for the episode.
Thumbnail string `json:"thumbnail"`
// Released is the episode's air date (an ISO datetime in Cinemeta).
Released string `json:"released"`
}
Video is one episode of a series' meta. Overview/Thumbnail/Released back the episode preview (ADR 0034); Cinemeta provides them on each video entry.
func (Video) EpisodeTitle ¶
EpisodeTitle is the video's title, falling back to its name and then a generated label, so an item always has something to show.