Documentation
¶
Overview ¶
Package adapters bridges runtime plugin contributions (WS9a list sources and WS9c Live TV channel sources) into Ether's collection, personalization and Live TV registries.
Package adapters bridges installed Ether plugins (internal/plugins) into the core media, catalogue, live TV, subtitle, marker, notification and ranking interfaces (SPEC §5.1.3, WS9).
Index ¶
- Constants
- func AttachDebrid(mgr *plugins.Manager, svc *debrid.Service)
- func AttachMetadata(mgr *plugins.Manager, registry metadataRegistry)
- func AttachSubtitles(mgr *plugins.Manager, svc *subtitles.Service)
- func ExpandAddonIndexers(ctx context.Context, mgr *plugins.Manager, rows []config.Indexer) []config.Indexer
- func IsLocalPayload(b []byte) bool
- type Bridge
- type DebridSourceBackend
- type Engine
- func (e *Engine) Check(ctx context.Context, payload []byte) (bool, error)
- func (e *Engine) CheckRelease(ctx context.Context, releaseID string, payload []byte) (bool, error)
- func (e *Engine) Open(ctx context.Context, releaseID string, payload []byte) (core.MediaSource, error)
- func (e *Engine) Prefetch(ctx context.Context, releaseID string, payload []byte, offset, length int64) error
- type KindCatalog
- func (c *KindCatalog) Ancestors(ctx context.Context, key core.RatingKey) ([]core.Title, core.Library, error)
- func (c *KindCatalog) Browse(ctx context.Context, lib core.Library, q frontend.ItemQuery, cursor string, ...) (experience.PluginBrowsePage, error)
- func (c *KindCatalog) Children(ctx context.Context, parent core.RatingKey, recursive bool, cursor string, ...) (experience.PluginBrowsePage, error)
- func (c *KindCatalog) Count(ctx context.Context, lib core.Library) (int, error)
- func (c *KindCatalog) Facets(ctx context.Context, lib core.Library, facet string) ([]core.FacetValue, error)
- func (c *KindCatalog) IsPluginLibraryActive(ctx context.Context, lib core.Library) bool
- func (c *KindCatalog) Item(ctx context.Context, key core.RatingKey) (experience.PluginItemView, error)
- func (c *KindCatalog) ItemsMany(ctx context.Context, keys []core.RatingKey) (map[core.RatingKey]experience.PluginItemView, error)
- func (c *KindCatalog) Libraries(ctx context.Context) ([]core.Library, error)
- func (c *KindCatalog) Library(ctx context.Context, id core.LibraryID) (core.Library, error)
- func (c *KindCatalog) QuotaFor(pluginID, libraryKey string) blobcache.Quota
- func (c *KindCatalog) RootMediaType(ctx context.Context, lib core.Library) core.MediaType
- func (c *KindCatalog) Search(ctx context.Context, lib core.Library, query string, q frontend.ItemQuery, ...) ([]core.Title, error)
- type KindCatalogDeps
- type KindResolver
- func (r *KindResolver) KindLeaves(ctx context.Context, viewer *core.Viewer, parent core.RatingKey) ([]frontend.KindLeaf, error)
- func (r *KindResolver) OpenKind(ctx context.Context, viewer *core.Viewer, key core.RatingKey, accept []string) (*frontend.KindMedia, error)
- func (r *KindResolver) ResolveSources(ctx context.Context, _ string, q core.SourceQuery) ([]core.SourceCandidate, error)
- type KindResolverDeps
- type LocalPayload
- type MarkerBridge
- type Ranking
- type RankingManager
- type SourceStats
- type StreamSources
- func (s *StreamSources) Backend(ix config.Indexer) (newznab.Backend, error)
- func (s *StreamSources) Bind(mgr *plugins.Manager, deb *debrid.Service)
- func (s *StreamSources) FetchNZB(ctx context.Context, r core.Release) ([]byte, error)
- func (s *StreamSources) HasEnabledPlugins(ctx context.Context) bool
- func (s *StreamSources) HasTorrentIndexer() bool
- func (s *StreamSources) MissingSources() error
- func (s *StreamSources) Name() string
- func (s *StreamSources) Order() []string
- func (s *StreamSources) ResolveTorrent(ctx context.Context, r core.Release) (core.Release, error)
- func (s *StreamSources) Search(ctx context.Context, req core.SearchRequest) ([]core.Release, error)
- func (s *StreamSources) SearchRescue(ctx context.Context, req core.SearchRequest) ([]core.Release, error)
- func (s *StreamSources) SearchRescueWith(ctx context.Context, req core.SearchRequest, arrived func([]core.Release)) ([]core.Release, error)
- func (s *StreamSources) SearchWith(ctx context.Context, req core.SearchRequest, arrived func([]core.Release)) ([]core.Release, error)
- func (s *StreamSources) SetAnimeIDs(a stremio.AnimeIDs)
- func (s *StreamSources) SetClock(now func() time.Time)
- func (s *StreamSources) SetNZBClient(c *http.Client)
- func (s *StreamSources) SetOrder(ids []string)
- func (s *StreamSources) SetUsenetReady(fn func() bool)
- func (s *StreamSources) Stats(ctx context.Context) []SourceStats
- func (s *StreamSources) WrapEngine(inner core.Engine) *Engine
- type SubtitleProbe
Constants ¶
const MaxPluginListItems = stremio.MaxCatalogItems
MaxPluginListItems bounds one list source refresh.
Variables ¶
This section is empty.
Functions ¶
func AttachDebrid ¶
AttachDebrid registers native plugin providers without copying their sealed credentials into server configuration. Disable/remove immediately unregisters.
func AttachMetadata ¶
AttachMetadata makes both native and adapted providers use the catalogue's shared registration, identity checks, persistence and materialization policy.
func ExpandAddonIndexers ¶
func ExpandAddonIndexers(ctx context.Context, mgr *plugins.Manager, rows []config.Indexer) []config.Indexer
ExpandAddonIndexers is the indexer list the running search manager searches: the owner's rows, then one row per installed plugin that serves streams (an Ether source plugin, or a Stremio add-on installed from Plugins with its streams on). Plugin rows are never saved: the plugin is their configuration, and the Indexers page stays the owner's own list.
func IsLocalPayload ¶
IsLocalPayload reports whether b is an encoded LocalPayload.
Types ¶
type Bridge ¶
type Bridge struct {
// contains filtered or unexported fields
}
Bridge tracks the source kinds registered for each plugin so enable, disable, update and uninstall cleanly replace or remove them.
type DebridSourceBackend ¶
type DebridSourceBackend interface {
CheckCached(ctx context.Context, hashes []string) (map[string]bool, bool)
Acquire(ctx context.Context, rel core.Release) ([]byte, error)
}
DebridSourceBackend is the subset of debrid.Service used by KindResolver for host-mediated debrid cache checks and torrent acquisition.
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine wraps an inner core.Engine (and core.ReleaseHealthChecker) so ETHER-LOCAL/1 payloads open granted local files directly via os.Open and satisfy core.LocalFileSource.
func (*Engine) CheckRelease ¶
CheckRelease implements core.ReleaseHealthChecker.
type KindCatalog ¶
type KindCatalog struct {
// contains filtered or unexported fields
}
KindCatalog bridges plugin media-kind declarations and lifecycle events to the libraries, pluginitems and blobcache stores, and implements experience.PluginLibraries so client surfaces read exclusively from the local store on browse, detail, children and facet paths.
func AttachKindCatalog ¶
func AttachKindCatalog(syncCtx context.Context, deps KindCatalogDeps) *KindCatalog
AttachKindCatalog constructs a KindCatalog and registers its OnSync and OnRemove lifecycle hooks on deps.Manager. Call before Manager.Start so already-installed kind plugins are reconciled on startup.
func (*KindCatalog) Ancestors ¶
func (c *KindCatalog) Ancestors(ctx context.Context, key core.RatingKey) ([]core.Title, core.Library, error)
Ancestors implements experience.PluginLibraries, returning ancestors ordered from root to immediate parent.
func (*KindCatalog) Browse ¶
func (c *KindCatalog) Browse(ctx context.Context, lib core.Library, q frontend.ItemQuery, cursor string, limit int) (experience.PluginBrowsePage, error)
Browse implements experience.PluginLibraries. It reads strictly from the pluginitems store and never invokes the plugin runtime.
func (*KindCatalog) Children ¶
func (c *KindCatalog) Children(ctx context.Context, parent core.RatingKey, recursive bool, cursor string, limit int) (experience.PluginBrowsePage, error)
Children implements experience.PluginLibraries.
func (*KindCatalog) Facets ¶
func (c *KindCatalog) Facets(ctx context.Context, lib core.Library, facet string) ([]core.FacetValue, error)
Facets implements experience.PluginLibraries.
func (*KindCatalog) IsPluginLibraryActive ¶
IsPluginLibraryActive reports whether lib's owning plugin is installed, enabled, has catalog_provider active (not disabled via RolesOff), declares a library for KindKey, and has no required setup blockers. Runtime crash state intentionally does NOT hide the library so synced items remain browsable offline when a plugin fails at runtime.
func (*KindCatalog) Item ¶
func (c *KindCatalog) Item(ctx context.Context, key core.RatingKey) (experience.PluginItemView, error)
Item implements experience.PluginLibraries.
func (*KindCatalog) ItemsMany ¶
func (c *KindCatalog) ItemsMany(ctx context.Context, keys []core.RatingKey) (map[core.RatingKey]experience.PluginItemView, error)
ItemsMany implements experience.PluginLibraries.
func (*KindCatalog) QuotaFor ¶
func (c *KindCatalog) QuotaFor(pluginID, libraryKey string) blobcache.Quota
QuotaFor returns the declared blobcache quota for (pluginID, libraryKey), used by blobcache.Cache.HostBackends and KindResolver.
func (*KindCatalog) RootMediaType ¶
RootMediaType implements experience.PluginLibraries.
func (*KindCatalog) Search ¶
func (c *KindCatalog) Search(ctx context.Context, lib core.Library, query string, q frontend.ItemQuery, limit int) ([]core.Title, error)
Search implements experience.PluginLibraries: local FTS5/tsvector search plus optional 2-second bounded live plugin search with background upsert (§15.4).
type KindCatalogDeps ¶
type KindCatalogDeps struct {
Manager *plugins.Manager
Libraries *libraries.Service
Items *pluginitems.Service
Blobs *blobcache.Cache
BlobDir string
Logger *slog.Logger
LiveSearchTimeout time.Duration
}
KindCatalogDeps configures a KindCatalog adapter.
type KindResolver ¶
type KindResolver struct {
// contains filtered or unexported fields
}
KindResolver implements frontend.KindStreams for plugin content kinds and supplies the host-side ResolveSources callback for plugins.KindBackends.
func NewKindResolver ¶
func NewKindResolver(deps KindResolverDeps) *KindResolver
NewKindResolver constructs a KindResolver.
func (*KindResolver) KindLeaves ¶
func (r *KindResolver) KindLeaves(ctx context.Context, viewer *core.Viewer, parent core.RatingKey) ([]frontend.KindLeaf, error)
KindLeaves implements frontend.KindStreams.
func (*KindResolver) OpenKind ¶
func (r *KindResolver) OpenKind(ctx context.Context, viewer *core.Viewer, key core.RatingKey, accept []string) (*frontend.KindMedia, error)
OpenKind implements frontend.KindStreams.
func (*KindResolver) ResolveSources ¶
func (r *KindResolver) ResolveSources(ctx context.Context, _ string, q core.SourceQuery) ([]core.SourceCandidate, error)
ResolveSources implements plugins.KindBackends.ResolveSources for plugins granted permissions.sources ("search" or "acquire"). Capability and permission checks are enforced upstream in plugins/host_kinds.go.
type KindResolverDeps ¶
type KindResolverDeps struct {
Manager *plugins.Manager
Libraries *libraries.Service
Items *pluginitems.Service
Blobs *blobcache.Cache
Catalog *KindCatalog
Indexer core.Indexer
Debrid DebridSourceBackend
Engine core.Engine
HTTP *http.Client
Authorize func(ctx context.Context, viewer *core.Viewer, key core.RatingKey) error
Logger *slog.Logger
}
KindResolverDeps configures a KindResolver.
type LocalPayload ¶
type LocalPayload struct {
PluginID string `json:"pluginId"`
ReleaseID string `json:"releaseId"`
FilePath string `json:"filePath"`
Name string `json:"name"`
Size int64 `json:"size"`
Origin string `json:"origin,omitempty"`
Remote bool `json:"remote,omitempty"`
}
LocalPayload describes a local file stream authorized through a plugin's folders: read grant (SPEC §5.1.4). Permission and symlink containment are re-verified on every CheckRelease and Open call so revoking a folder grant takes effect immediately.
func DecodeLocalPayload ¶
func DecodeLocalPayload(b []byte) (LocalPayload, error)
DecodeLocalPayload parses an encoded LocalPayload.
func (LocalPayload) Encode ¶
func (p LocalPayload) Encode() []byte
Encode serializes p with the local payload prefix.
type MarkerBridge ¶
type MarkerBridge struct {
// contains filtered or unexported fields
}
func AttachMarkers ¶
func (*MarkerBridge) Schedule ¶
func (b *MarkerBridge) Schedule(key core.RatingKey, d time.Duration) <-chan struct{}
Schedule queues work without contacting a plugin on the caller's path.
func (*MarkerBridge) Wait ¶
func (b *MarkerBridge) Wait()
Wait waits for the background worker to stop after its context is cancelled.
type Ranking ¶
type Ranking struct {
Manager RankingManager
Registry *extend.Registry
}
func (Ranking) NewResolve ¶
func (a Ranking) NewResolve(ctx context.Context, caps core.ClientCaps) resolver.RankingSession
type RankingManager ¶
type RankingManager interface {
HotReady(string) (plugins.HotRuntime, bool)
RecordRanking(context.Context, string, plugins.RankingReport)
}
Ranking bridges the resolver to installed hosted hot-path plugins.
type SourceStats ¶
type SourceStats struct {
PluginID string `json:"pluginId"`
Name string `json:"name"`
Class string `json:"class"`
Searches int64 `json:"searches"`
Grabs int64 `json:"grabs"`
Failures int64 `json:"failures"`
}
SourceStats reports per-plugin stream-source activity for the Sources -> Usage tab.
type StreamSources ¶
type StreamSources struct {
// contains filtered or unexported fields
}
StreamSources adapts enabled `stream_source` plugins into a core.Indexer (and core.StreamingIndexer / core.RescueIndexer) alongside an optional inner indexer (typically *newznab.Manager).
func NewStreamSources ¶
func NewStreamSources(inner core.Indexer) *StreamSources
NewStreamSources constructs a StreamSources adapter wrapping inner.
func (*StreamSources) Backend ¶
Backend returns the search backend of an add-on indexer row (newznab.Options.Backend). Backends are kept per row so throttling state survives between searches.
func (*StreamSources) Bind ¶
func (s *StreamSources) Bind(mgr *plugins.Manager, deb *debrid.Service)
Bind attaches the plugin manager and debrid service once they are built.
func (*StreamSources) FetchNZB ¶
FetchNZB implements core.Indexer. An Ether plugin's lazy and local-file streams are opened here at play time (their GUID names the plugin and the stream); everything else is the inner indexer's.
func (*StreamSources) HasEnabledPlugins ¶
func (s *StreamSources) HasEnabledPlugins(ctx context.Context) bool
HasEnabledPlugins reports whether at least one stream_source plugin is enabled.
func (*StreamSources) HasTorrentIndexer ¶
func (s *StreamSources) HasTorrentIndexer() bool
HasTorrentIndexer implements the debrid sourceInventory contract.
func (*StreamSources) MissingSources ¶
func (s *StreamSources) MissingSources() error
MissingSources implements the debrid/resolver sourceInventory contract.
func (*StreamSources) Order ¶
func (s *StreamSources) Order() []string
Order returns the current preferred plugin source order.
func (*StreamSources) ResolveTorrent ¶
ResolveTorrent implements debrid.TorrentResolver.
func (*StreamSources) Search ¶
func (s *StreamSources) Search(ctx context.Context, req core.SearchRequest) ([]core.Release, error)
Search implements core.Indexer.
func (*StreamSources) SearchRescue ¶
func (s *StreamSources) SearchRescue(ctx context.Context, req core.SearchRequest) ([]core.Release, error)
SearchRescue implements core.RescueIndexer.
func (*StreamSources) SearchRescueWith ¶
func (s *StreamSources) SearchRescueWith(ctx context.Context, req core.SearchRequest, arrived func([]core.Release)) ([]core.Release, error)
SearchRescueWith implements core.StreamingRescueIndexer.
func (*StreamSources) SearchWith ¶
func (s *StreamSources) SearchWith(ctx context.Context, req core.SearchRequest, arrived func([]core.Release)) ([]core.Release, error)
SearchWith implements core.StreamingIndexer. Add-on streams are searched as indexer rows inside inner (see Backend).
func (*StreamSources) SetAnimeIDs ¶
func (s *StreamSources) SetAnimeIDs(a stremio.AnimeIDs)
SetAnimeIDs wires the anime id mapping used for add-ons that look anime up by Kitsu, MAL, AniList or AniDB ids.
func (*StreamSources) SetClock ¶
func (s *StreamSources) SetClock(now func() time.Time)
SetClock overrides the clock used for rate-limit windows in tests.
func (*StreamSources) SetNZBClient ¶
func (s *StreamSources) SetNZBClient(c *http.Client)
SetNZBClient overrides the client that downloads add-on NZBs (tests).
func (*StreamSources) SetOrder ¶
func (s *StreamSources) SetOrder(ids []string)
SetOrder sets the preferred plugin source order (plugin IDs).
func (*StreamSources) SetUsenetReady ¶
func (s *StreamSources) SetUsenetReady(fn func() bool)
SetUsenetReady wires the Usenet readiness check so non-plugin Usenet releases still require an enabled Usenet provider when plugin sources are active.
func (*StreamSources) Stats ¶
func (s *StreamSources) Stats(ctx context.Context) []SourceStats
Stats returns per-plugin search and grab counters for enabled stream_source plugins.
func (*StreamSources) WrapEngine ¶
func (s *StreamSources) WrapEngine(inner core.Engine) *Engine
WrapEngine wraps inner with local-file payload support backed by s.
type SubtitleProbe ¶
type SubtitleProbe struct {
// contains filtered or unexported fields
}
SubtitleProbe exercises the ordinary subtitle broker with one installed provider. Offers and explicit picks are isolated from viewer selections and production sidecars. Each session is single-use, bounded and cleaned up.
func NewSubtitleProbe ¶
func NewSubtitleProbe(mgr *plugins.Manager, catalog probeCatalog) *SubtitleProbe
func (*SubtitleProbe) Close ¶
func (p *SubtitleProbe) Close()
func (*SubtitleProbe) Handler ¶
func (p *SubtitleProbe) Handler() http.Handler