Documentation
¶
Overview ¶
Package etherplugin is the Go authoring SDK for Ether Plugin Protocol v1 (EPP/1).
It provides the same declarative router shape, settings decoder, localization helper, host service client, test harness, and capability templates as `@ether/plugin-sdk` (TypeScript) and `ether_plugin` (Python).
Execution modes ¶
Go plugins run as native HTTP or WebSocket tunnel sidecars. Hosted Go is not supported: the standard Go wasip1 toolchain emits WASI imports, which Ether's sandbox rejects. See README.md for details.
Server packages under `internal/` and `cmd/` must not import this package.
Index ¶
- Constants
- Variables
- func AssertValidViewSpec(doc ViewSpecDocument) error
- func DecodeSettings(schema *SettingsSchema, incoming map[string]any, defaults map[string]any) (map[string]any, map[string]string)
- func LintCopy(raw string, maxRunes int) string
- func PairURL(base string) (string, error)
- func StateDir(explicit, pluginID string) (string, error)
- func TRef(key string) string
- func TunnelURL(base string) (string, error)
- type ActionProposal
- type ActionRequest
- type ActionResponse
- type BehaviorHints
- type CandidateFacts
- type Capability
- type CatalogItem
- type CatalogProvider
- type CatalogRequest
- type CatalogResponse
- type CatalogTitleSummary
- type ChangesProvider
- type ChannelInput
- type ChannelItem
- type ChannelsMeta
- type ChannelsResponse
- type ClientCaps
- type CommandMeta
- type ConfigureResponse
- type ContainerRef
- type Context
- type Contributes
- type Definition
- type EtherEvent
- type EtherManifestBlock
- type EventResponse
- type EventsMeta
- type FieldOption
- type FieldProblem
- type FileRangeResponse
- type FileRequest
- type FolderEntry
- type FolderHash
- type FolderHashJob
- type FrontendAdapter
- type FrontendAdapterMeta
- type GuideRequest
- type GuideResponse
- type HealthDecl
- type HealthResponse
- type Host
- type HostFetchRequest
- type HostFetchResponse
- type I18n
- type IntegrationMeta
- type ItemUnavailable
- type JobRequest
- type JobResponse
- type KindArt
- type KindArtRef
- type KindBrowseDecl
- type KindBrowseRequest
- type KindCacheDecl
- type KindChangePage
- type KindChangesRequest
- type KindField
- type KindItem
- type KindLevel
- type KindLibraryDecl
- type KindMatchDecl
- type KindMatchRequest
- type KindMatchResponse
- type KindMatchScore
- type KindMatcher
- type KindPage
- type KindResolveRequest
- type KindResolveResponse
- type KindResolver
- type KindSyncDecl
- type ListSourceMeta
- type Manifest
- type MarkerItem
- type MarkersMeta
- type MarkersRequest
- type MarkersResponse
- type MediaKindMeta
- type MetaItem
- type MetaRequest
- type MetaResponse
- type MetaVideo
- type MockHost
- func (m *MockHost) CacheOpen(_ context.Context, blobRef string) ([]byte, error)
- func (m *MockHost) CachePut(_ context.Context, _, _ string, data []byte) (string, error)
- func (m *MockHost) CatalogGet(_ context.Context, id string) (*CatalogTitleSummary, error)
- func (m *MockHost) CatalogSearch(_ context.Context, query string, limit, offset int) ([]CatalogTitleSummary, error)
- func (m *MockHost) Fetch(ctx context.Context, req HostFetchRequest) (HostFetchResponse, error)
- func (*MockHost) FoldersHash(context.Context, string, string) (FolderHash, error)
- func (*MockHost) FoldersHashCancel(context.Context, string) (FolderHashJob, error)
- func (*MockHost) FoldersHashPoll(context.Context, string) (FolderHashJob, error)
- func (*MockHost) FoldersHashStart(context.Context, string, string) (FolderHashJob, error)
- func (m *MockHost) FoldersList(_ context.Context, root, path string) ([]FolderEntry, error)
- func (m *MockHost) FoldersStat(_ context.Context, root, path string) (FolderEntry, error)
- func (m *MockHost) KVDelete(_ context.Context, key string) error
- func (m *MockHost) KVGet(_ context.Context, key string) (string, bool, error)
- func (m *MockHost) KVList(_ context.Context, prefix string) ([]string, error)
- func (m *MockHost) KVPut(_ context.Context, key, value string) error
- func (m *MockHost) KindDelete(_ context.Context, kindKey string, externalIDs []string) error
- func (m *MockHost) KindItems(_ context.Context, kindKey, cursor string, limit int) (KindPage, error)
- func (m *MockHost) KindUpsert(_ context.Context, kindKey string, items []KindItem) (int, error)
- func (m *MockHost) Log(_ context.Context, level, message string, attrs map[string]any) error
- func (m *MockHost) NotifyOwner(_ context.Context, text string) error
- func (m *MockHost) ResolveSources(_ context.Context, _ SourceQuery) ([]SourceCandidate, error)
- func (m *MockHost) SecretGet(_ context.Context, name string) (string, error)
- func (m *MockHost) SetWatchState(_ context.Context, viewerID int64, titleID string, watched bool) error
- func (m *MockHost) StreamURL(_ context.Context, viewerID int64, itemRef string) (string, error)
- func (m *MockHost) UpsertCollection(_ context.Context, collection map[string]any) error
- func (m *MockHost) ViewerHistory(_ context.Context, viewerID int64, limit, offset int) ([]ViewerWatchEntry, error)
- type NotificationMeta
- type NotifyRequest
- type NotifyResponse
- type OpenStreamRequest
- type OpenStreamResponse
- type PageMeta
- type PairingInputs
- type Permissions
- type PlayableSource
- type Plugin
- func New(def Definition) *Plugin
- func NewCatalogTemplate(opts TemplateOptions) *Plugin
- func NewConditionTemplate(opts TemplateOptions) *Plugin
- func NewRankerTemplate(opts TemplateOptions) *Plugin
- func NewScrobblerTemplate(opts TemplateOptions) *Plugin
- func NewSubtitlesTemplate(opts TemplateOptions) *Plugin
- func NewViewTemplate(opts TemplateOptions) *Plugin
- func (p *Plugin) CondMatch(candidate CandidateFacts, operator string, value any) bool
- func (p *Plugin) Dispatch(ctx context.Context, req RawRequest) RawResponse
- func (p *Plugin) DispatchTunnelFrame(ctx context.Context, frame TunnelFrame, maxChunkBytes int) []TunnelFrame
- func (p *Plugin) GetSettings() map[string]any
- func (p *Plugin) Manifest() Manifest
- func (p *Plugin) OnCatalog(kind string, c CatalogProvider)
- func (p *Plugin) OnFrontend(key string, a FrontendAdapter)
- func (p *Plugin) OnMatch(kind string, m KindMatcher)
- func (p *Plugin) OnResolve(kind string, r KindResolver)
- func (p *Plugin) OnSetupTest(t SetupTester)
- func (p *Plugin) RankKey(candidate CandidateFacts, config map[string]any) int64
- func (p *Plugin) Serve(ctx context.Context, opts ServeOptions) error
- func (p *Plugin) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (p *Plugin) SetSettings(incoming map[string]any) (map[string]any, map[string]string)
- func (p *Plugin) Start(ctx context.Context, opts ServeOptions) (*ServeHandle, error)
- type PluginAuthor
- type PluginKind
- type Presentations
- type ProgrammeItem
- type RankingStepMeta
- type RawRequest
- type RawResponse
- type RecordedLog
- type ReleaseHint
- type RemoteHostClient
- func (c *RemoteHostClient) CacheOpen(ctx context.Context, blobRef string) ([]byte, error)
- func (c *RemoteHostClient) CachePut(ctx context.Context, libraryKey, name string, data []byte) (string, error)
- func (c *RemoteHostClient) CatalogGet(ctx context.Context, id string) (*CatalogTitleSummary, error)
- func (c *RemoteHostClient) CatalogSearch(ctx context.Context, query string, limit, offset int) ([]CatalogTitleSummary, error)
- func (c *RemoteHostClient) Fetch(ctx context.Context, r HostFetchRequest) (HostFetchResponse, error)
- func (*RemoteHostClient) FoldersHash(context.Context, string, string) (FolderHash, error)
- func (*RemoteHostClient) FoldersHashCancel(context.Context, string) (FolderHashJob, error)
- func (*RemoteHostClient) FoldersHashPoll(context.Context, string) (FolderHashJob, error)
- func (*RemoteHostClient) FoldersHashStart(context.Context, string, string) (FolderHashJob, error)
- func (c *RemoteHostClient) FoldersList(_ context.Context, _, _ string) ([]FolderEntry, error)
- func (c *RemoteHostClient) FoldersStat(_ context.Context, _, _ string) (FolderEntry, error)
- func (c *RemoteHostClient) KVDelete(ctx context.Context, key string) error
- func (c *RemoteHostClient) KVGet(ctx context.Context, key string) (string, bool, error)
- func (c *RemoteHostClient) KVList(ctx context.Context, prefix string) ([]string, error)
- func (c *RemoteHostClient) KVPut(ctx context.Context, key, value string) error
- func (c *RemoteHostClient) KindDelete(ctx context.Context, kindKey string, externalIDs []string) error
- func (c *RemoteHostClient) KindItems(ctx context.Context, kindKey, cursor string, limit int) (KindPage, error)
- func (c *RemoteHostClient) KindUpsert(ctx context.Context, kindKey string, items []KindItem) (int, error)
- func (c *RemoteHostClient) Log(ctx context.Context, level, message string, attrs map[string]any) error
- func (c *RemoteHostClient) NotifyOwner(ctx context.Context, text string) error
- func (c *RemoteHostClient) ResolveSources(ctx context.Context, q SourceQuery) ([]SourceCandidate, error)
- func (c *RemoteHostClient) SecretGet(_ context.Context, _ string) (string, error)
- func (c *RemoteHostClient) SetWatchState(ctx context.Context, viewerID int64, titleID string, watched bool) error
- func (c *RemoteHostClient) SettingsGet(ctx context.Context) (map[string]any, error)
- func (c *RemoteHostClient) StreamURL(ctx context.Context, viewerID int64, itemRef string) (string, error)
- func (c *RemoteHostClient) UpsertCollection(ctx context.Context, collection map[string]any) error
- func (c *RemoteHostClient) ViewerHistory(ctx context.Context, viewerID int64, limit, offset int) ([]ViewerWatchEntry, error)
- type RemoteHostOptions
- type RouteError
- type Routes
- type RuleConditionMeta
- type RuntimeDecl
- type ScheduleEntry
- type SearchProvider
- type ServeHandle
- type ServeOptions
- type SettingField
- type SettingsGroup
- type SettingsSchema
- type SetupMeta
- type SetupStep
- type SetupTestRequest
- type SetupTestResult
- type SetupTester
- type SlotMeta
- type SourceCandidate
- type SourceMeta
- type SourceQuery
- type StreamEtherExt
- type StreamItem
- type StreamRequest
- type StreamResponse
- type StremioCatalogDecl
- type StremioExtraField
- type StringsCatalog
- type SubtitleDownloadRequest
- type SubtitleDownloadResponse
- type SubtitleItem
- type SubtitlesMeta
- type SubtitlesRequest
- type SubtitlesResponse
- type TemplateOptions
- type TestHarness
- func (h *TestHarness) Action(action string, input map[string]any) (int, ActionResponse, error)
- func (h *TestHarness) Catalog(typ, id string, extra map[string]string) (int, CatalogResponse, error)
- func (h *TestHarness) Configure(settings map[string]any) (int, ConfigureResponse, error)
- func (h *TestHarness) Event(events []EtherEvent) (int, EventResponse, error)
- func (h *TestHarness) File(path, rangeHeader string) RawResponse
- func (h *TestHarness) Health() (int, HealthResponse, error)
- func (h *TestHarness) Manifest() (Manifest, error)
- func (h *TestHarness) Markers(typ, id string) (int, MarkersResponse, error)
- func (h *TestHarness) Meta(typ, id string) (int, MetaResponse, error)
- func (h *TestHarness) Options(field string) (int, []FieldOption, error)
- func (h *TestHarness) Request(req RawRequest) RawResponse
- func (h *TestHarness) Stream(typ, id string, extra map[string]string) (int, StreamResponse, error)
- func (h *TestHarness) Subtitles(typ, id, pickToken string, extra map[string]string) (int, SubtitlesResponse, RawResponse)
- func (h *TestHarness) Test() (int, TestResponse, error)
- func (h *TestHarness) Tool(name string, input map[string]any) (int, ToolResponse, error)
- func (h *TestHarness) View(page string, query map[string]string) (int, ViewResponse, error)
- type TestResponse
- type ToolMeta
- type ToolRequest
- type ToolResponse
- type TunnelError
- type TunnelFrame
- type ViewRequest
- type ViewResponse
- type ViewSpecDocument
- type ViewerPermissions
- type ViewerWatchEntry
- type VolumeRef
Constants ¶
const ( // PairExchangePath accepts a one-time code and returns a credential. PairExchangePath = "/ether/plugins/pair" // TunnelPath is the WebSocket endpoint a paired sidecar dials. TunnelPath = "/ether/plugins/tunnel" )
PairingPaths are the fixed Ether endpoints a sidecar uses to pair.
const ( // TunnelProtocol is the WebSocket subprotocol for Ether remote plugin tunnels. TunnelProtocol = "ether-tunnel-v1" // DefaultMaxChunkBytes is the default chunk size for streamed file responses. DefaultMaxChunkBytes = 64 * 1024 )
const ( KindSyncPull = "pull" KindSyncPush = "push" )
Kind sync modes: pull (Ether walks browse/changes) or push (KindUpsert).
Variables ¶
var ( ErrKindNotFound = &RouteError{Status: http.StatusNotFound, Code: "not_found", Message: "Item not found."} ErrKindNotAvailable = &RouteError{Status: http.StatusOK, Code: "not_available", Message: "No source is available right now."} )
Reserved plugin error codes Ether understands on kind routes.
var Fixtures = struct { PickToken func(itemID string) string Movie func() MetaItem CatalogItem func() CatalogItem PlaybackEvent func(name string) EtherEvent Candidate func() CandidateFacts }{ PickToken: func(itemID string) string { if itemID == "" { itemID = "ether:movie:1" } return "pick-v1:" + itemID + ":sig-test" }, Movie: func() MetaItem { return MetaItem{ CatalogItem: CatalogItem{ ID: "tt0133093", Type: "movie", Name: "The Matrix", ReleaseInfo: "1999", Description: "A computer hacker learns about the true nature of reality.", Genres: []string{"Action", "Sci-Fi"}, IMDBRating: "8.7", }, } }, CatalogItem: func() CatalogItem { return CatalogItem{ ID: "tt0133093", Type: "movie", Name: "The Matrix", ReleaseInfo: "1999", } }, PlaybackEvent: func(name string) EtherEvent { if name == "" { name = "playback.completed" } return EtherEvent{ ID: "evt_01", Name: name, At: "2026-11-02T12:00:00Z", ViewerID: 1, Payload: map[string]any{ "titleId": "tt0133093", "title": "The Matrix", "progress": 0.95, }, } }, Candidate: func() CandidateFacts { return CandidateFacts{ ReleaseID: "rel_01", Name: "The.Matrix.1999.2160p.UHD.BluRay.x265", Resolution: 2160, HDR: []string{"DV", "HDR10"}, VideoCodec: "hevc", Cached: true, Verified: true, } }, }
Fixtures provides sample EPP/1 records for plugin unit tests.
Functions ¶
func AssertValidViewSpec ¶
func AssertValidViewSpec(doc ViewSpecDocument) error
AssertValidViewSpec validates a ViewSpecDocument for structural rules and rejects any `*ClassName` fields.
func DecodeSettings ¶
func DecodeSettings( schema *SettingsSchema, incoming map[string]any, defaults map[string]any, ) (map[string]any, map[string]string)
DecodeSettings applies schema defaults and validates incoming settings, returning the decoded settings map and any JSON-pointer keyed errors.
func LintCopy ¶
LintCopy validates a user-visible string against Ether's copy rules. It returns an empty string when valid, or the plain reason when invalid.
func StateDir ¶
StateDir resolves where the credential file is kept: an explicit dir, else /data when it exists and is writable (a Docker volume), else the OS user config dir under ether-plugins/<plugin id>/.
Types ¶
type ActionProposal ¶
type ActionProposal struct {
Category string `json:"category"`
Description string `json:"description"`
Input map[string]any `json:"input,omitempty"`
}
ActionProposal describes a confirmation proposal returned by an Action handler.
type ActionRequest ¶
ActionRequest is passed to an Action route handler.
type ActionResponse ¶
type ActionResponse struct {
Toast string `json:"toast,omitempty"`
Refresh bool `json:"refresh,omitempty"`
Open string `json:"open,omitempty"`
Proposal *ActionProposal `json:"proposal,omitempty"`
}
ActionResponse is returned by an Action route handler.
type BehaviorHints ¶
type BehaviorHints struct {
Adult bool `json:"adult,omitempty"`
P2P bool `json:"p2p,omitempty"`
Configurable bool `json:"configurable,omitempty"`
ConfigurationRequired bool `json:"configurationRequired,omitempty"`
}
BehaviorHints carries Stremio-compatible behavior hints.
type CandidateFacts ¶
type CandidateFacts struct {
ReleaseID string `json:"releaseId"`
Name string `json:"name"`
Size int64 `json:"size,omitempty"`
Protocol string `json:"protocol,omitempty"`
SourceClass string `json:"sourceClass,omitempty"`
Indexer string `json:"indexer,omitempty"`
Resolution any `json:"resolution,omitempty"`
HDR []string `json:"hdr,omitempty"`
VideoCodec string `json:"videoCodec,omitempty"`
AudioCodecs []string `json:"audioCodecs,omitempty"`
AudioChannels string `json:"audioChannels,omitempty"`
Languages []string `json:"languages,omitempty"`
Subtitles []string `json:"subtitles,omitempty"`
ReleaseType string `json:"releaseType,omitempty"`
Group string `json:"group,omitempty"`
Cached bool `json:"cached,omitempty"`
Verified bool `json:"verified,omitempty"`
ClientCaps *ClientCaps `json:"clientCaps,omitempty"`
}
CandidateFacts is the release candidate structure passed to RankKey and CondMatch.
type Capability ¶
type Capability string
Capability names a capability declared in manifest.ether.capabilities.
const ( CapStreamSource Capability = "stream_source" CapDebridProvider Capability = "debrid_provider" CapListSource Capability = "list_source" CapLiveTV Capability = "livetv_channels" CapSubtitles Capability = "subtitles" CapMarkers Capability = "markers" CapNotify Capability = "notify" CapEvents Capability = "events" CapRankingStep Capability = "ranking_step" CapRuleCondition Capability = "rule_condition" CapTools Capability = "tools" CapUI Capability = "ui" CapCatalogProvider Capability = "catalog_provider" CapKindResolver Capability = "kind_resolver" CapFrontendAdapter Capability = "frontend_adapter" CapMatcher Capability = "matcher" )
type CatalogItem ¶
type CatalogItem struct {
ID string `json:"id"`
Type string `json:"type"`
Name string `json:"name"`
Poster string `json:"poster,omitempty"`
PosterShape string `json:"posterShape,omitempty"`
Background string `json:"background,omitempty"`
Logo string `json:"logo,omitempty"`
Description string `json:"description,omitempty"`
ReleaseInfo string `json:"releaseInfo,omitempty"`
IMDBRating string `json:"imdbRating,omitempty"`
Genres []string `json:"genres,omitempty"`
}
CatalogItem is one item in a catalog response.
type CatalogProvider ¶
type CatalogProvider interface {
Browse(ctx *Context, req KindBrowseRequest) (KindPage, error)
Detail(ctx *Context, kind, id string) (KindItem, error)
}
CatalogProvider serves browse and detail for one kind. Implement ChangesProvider too for delta pull sync; without it Ether re-walks.
type CatalogRequest ¶
type CatalogRequest struct {
Type string `json:"type"`
ID string `json:"id"`
Extra map[string]string `json:"extra"`
Skip int `json:"skip"`
Search string `json:"search,omitempty"`
Genre string `json:"genre,omitempty"`
}
CatalogRequest is passed to a Catalog route handler.
type CatalogResponse ¶
type CatalogResponse struct {
Metas []CatalogItem `json:"metas"`
}
CatalogResponse is returned by a Catalog route handler.
type CatalogTitleSummary ¶
type CatalogTitleSummary struct {
ID any `json:"id"`
Title string `json:"title"`
Type string `json:"type"`
Year int `json:"year,omitempty"`
IMDBID string `json:"imdbId,omitempty"`
TMDBID int `json:"tmdbId,omitempty"`
}
CatalogTitleSummary is a catalog record returned by Host.CatalogSearch or Host.CatalogGet.
type ChangesProvider ¶
type ChangesProvider interface {
Changes(ctx *Context, req KindChangesRequest) (KindChangePage, error)
}
ChangesProvider is the optional delta feed for pull sync.
type ChannelInput ¶
type ChannelInput struct {
URL string `json:"url"`
Name string `json:"name,omitempty"`
Headers map[string]string `json:"headers,omitempty"`
Priority int `json:"priority,omitempty"`
}
ChannelInput is one stream input for a Live TV channel.
type ChannelItem ¶
type ChannelItem struct {
ID string `json:"id"`
Name string `json:"name"`
Number int `json:"number,omitempty"`
Group string `json:"group,omitempty"`
Logo string `json:"logo,omitempty"`
GuideID string `json:"guideId,omitempty"`
Inputs []ChannelInput `json:"inputs"`
}
ChannelItem is one Live TV channel.
type ChannelsMeta ¶
ChannelsMeta describes a Live TV channel contribution.
type ChannelsResponse ¶
type ChannelsResponse struct {
Channels []ChannelItem `json:"channels"`
}
ChannelsResponse is returned by a Channels route handler.
type ClientCaps ¶
type ClientCaps struct {
MaxHeight int `json:"maxHeight,omitempty"`
HDR []string `json:"hdr,omitempty"`
Codecs []string `json:"codecs,omitempty"`
}
ClientCaps describes playback client capabilities passed to hot-path functions.
type CommandMeta ¶
type CommandMeta struct {
Key string `json:"key"`
Label string `json:"label"`
Action string `json:"action"`
}
CommandMeta describes a command contributed by a plugin.
type ConfigureResponse ¶
ConfigureResponse is returned by a Configure route handler.
type ContainerRef ¶
type ContainerRef struct {
Format string `json:"format,omitempty"` // "" (sniff)|rar|7z|zip
Volumes []VolumeRef `json:"volumes"`
Member string `json:"member,omitempty"`
MemberIndex *int `json:"memberIndex,omitempty"`
PasswordSecret string `json:"passwordSecret,omitempty"`
}
ContainerRef describes an archive member inside ordered volumes.
type Context ¶
type Context struct {
context.Context
Manifest Manifest
Settings map[string]any
Locale string
PickToken string
RequestID string
Headers map[string]string
Query map[string]string
Ether Host
I18n *I18n
}
Context is passed to every plugin route handler.
func (*Context) StreamURL ¶
StreamURL mints a short-lived, scoped ticket for one of this plugin's own kind items and returns the Ether stream URL to embed in a frontend adapter response (spec §6.5). The viewer is taken from the request's X-Ether-Viewer header, which Ether injects after authenticating; the plugin never sees a credential. Bytes are served by Ether from the ticket, never by the plugin.
type Contributes ¶
type Contributes struct {
Source *SourceMeta `json:"source,omitempty"`
Channels *ChannelsMeta `json:"channels,omitempty"`
Subtitles *SubtitlesMeta `json:"subtitles,omitempty"`
Markers *MarkersMeta `json:"markers,omitempty"`
Notification *NotificationMeta `json:"notification,omitempty"`
Events *EventsMeta `json:"events,omitempty"`
Integration *IntegrationMeta `json:"integration,omitempty"`
ListSources []ListSourceMeta `json:"listSources,omitempty"`
RankingSteps []RankingStepMeta `json:"rankingSteps,omitempty"`
RuleConditions []RuleConditionMeta `json:"ruleConditions,omitempty"`
Tools []ToolMeta `json:"tools,omitempty"`
Pages []PageMeta `json:"pages,omitempty"`
Slots []SlotMeta `json:"slots,omitempty"`
Commands []CommandMeta `json:"commands,omitempty"`
MediaKinds []MediaKindMeta `json:"mediaKinds,omitempty"`
FrontendAdapters []FrontendAdapterMeta `json:"frontendAdapters,omitempty"`
Setup *SetupMeta `json:"setup,omitempty"`
}
Contributes declares the descriptors a plugin contributes to Ether.
type Definition ¶
type Definition struct {
Manifest Manifest
Routes Routes
DefaultSettings map[string]any
Strings StringsCatalog
DefaultLocale string
Host Host
RemoteHostOptions RemoteHostOptions
}
Definition configures a new Plugin instance.
type EtherEvent ¶
type EtherEvent struct {
ID string `json:"id"`
Name string `json:"name"`
At string `json:"at"`
ViewerID int64 `json:"viewerId,omitempty"`
Payload map[string]any `json:"payload,omitempty"`
}
EtherEvent is one event delivered in a batch to POST /ether/event.
type EtherManifestBlock ¶
type EtherManifestBlock struct {
Protocol int `json:"protocol"`
Kind PluginKind `json:"kind"`
Capabilities []Capability `json:"capabilities,omitempty"`
Summary string `json:"summary"`
Author *PluginAuthor `json:"author,omitempty"`
License string `json:"license,omitempty"`
Repo string `json:"repo,omitempty"`
Icon string `json:"icon,omitempty"`
Runtime RuntimeDecl `json:"runtime"`
Cluster string `json:"cluster,omitempty"`
Health *HealthDecl `json:"health,omitempty"`
Permissions *Permissions `json:"permissions,omitempty"`
Settings *SettingsSchema `json:"settings,omitempty"`
Strings map[string]any `json:"strings,omitempty"`
Schedule []ScheduleEntry `json:"schedule,omitempty"`
Contributes *Contributes `json:"contributes,omitempty"`
}
EtherManifestBlock holds the EPP/1 `ether` manifest block.
type EventResponse ¶
type EventResponse struct {
Ack []string `json:"ack"`
}
EventResponse is returned by an Event route handler.
type EventsMeta ¶
type EventsMeta struct {
Subscribe []string `json:"subscribe"`
}
EventsMeta lists subscribed event names.
type FieldOption ¶
type FieldOption struct {
Value string `json:"value"`
Label string `json:"label"`
Hint string `json:"hint,omitempty"`
}
FieldOption is one selectable option for a select or multiSelect field.
type FieldProblem ¶
FieldProblem describes one schema validation or copy-rule problem.
func LintSettingsSchema ¶
func LintSettingsSchema(schema *SettingsSchema) []FieldProblem
LintSettingsSchema checks a SettingsSchema for forbidden kinds and copy-rule violations.
type FileRangeResponse ¶
type FileRangeResponse struct {
Status int `json:"status,omitempty"`
ContentType string `json:"contentType,omitempty"`
ContentRange string `json:"contentRange,omitempty"`
TotalSize *int64 `json:"totalSize,omitempty"`
Headers map[string]string `json:"headers,omitempty"`
Body []byte `json:"-"`
}
FileRangeResponse is returned by a File route handler.
type FileRequest ¶
type FileRequest struct {
Path string `json:"path"`
Range string `json:"range,omitempty"`
HeadOnly bool `json:"headOnly,omitempty"`
}
FileRequest is passed to a File route handler.
type FolderEntry ¶
type FolderEntry struct {
Name string `json:"name"`
Path string `json:"path"`
Dir bool `json:"dir"`
Size int64 `json:"size,omitempty"`
Mtime int64 `json:"mtime,omitempty"`
}
FolderEntry describes one entry returned by Host.FoldersList or Host.FoldersStat.
type FolderHash ¶
type FolderHash struct {
Size int64 `json:"size"`
ModTime int64 `json:"modTime"`
CRC32 string `json:"crc32"`
MD5 string `json:"md5"`
SHA1 string `json:"sha1"`
}
FolderHash contains digests, never file contents. ModTime is Unix seconds.
type FolderHashJob ¶
type FolderHashJob struct {
ID string `json:"id"`
State string `json:"state"`
Bytes int64 `json:"bytes"`
Result *FolderHash `json:"result,omitempty"`
Error string `json:"error,omitempty"`
}
FolderHashJob is a pollable background hash. Bytes is the progress so far. Terminal states are done, canceled and error. Only done carries Result.
type FrontendAdapter ¶
FrontendAdapter is a plugin-provided protocol surface (OPDS, Subsonic, custom). Ether authenticates the viewer first and forwards the request under /ether/v1/frontend/{key}; the handler sees X-Ether-Viewer headers and never a credential.
type FrontendAdapterMeta ¶
type FrontendAdapterMeta struct {
Key string `json:"key"`
Label string `json:"label"`
ProtocolHint string `json:"protocolHint"` // opds|subsonic|custom
PathPrefix string `json:"pathPrefix"`
DefaultPort int `json:"defaultPort,omitempty"`
Clients []string `json:"clients,omitempty"`
Auth string `json:"auth,omitempty"` // ether_token (default)|basic|none_lan
}
FrontendAdapterMeta declares one plugin-provided protocol surface.
type GuideRequest ¶
type GuideRequest struct {
ChannelID string `json:"channelId"`
From string `json:"from,omitempty"`
To string `json:"to,omitempty"`
}
GuideRequest is passed to a Guide route handler.
type GuideResponse ¶
type GuideResponse struct {
Programmes []ProgrammeItem `json:"programmes"`
}
GuideResponse is returned by a Guide route handler.
type HealthDecl ¶
type HealthDecl struct {
Interval string `json:"interval,omitempty"`
}
HealthDecl configures periodic health checks.
type HealthResponse ¶
type HealthResponse struct {
Status string `json:"status"`
Reason string `json:"reason,omitempty"`
}
HealthResponse is returned by a Health route handler.
type Host ¶
type Host interface {
KVGet(ctx context.Context, key string) (string, bool, error)
KVPut(ctx context.Context, key, value string) error
KVDelete(ctx context.Context, key string) error
KVList(ctx context.Context, prefix string) ([]string, error)
SecretGet(ctx context.Context, name string) (string, error)
Fetch(ctx context.Context, req HostFetchRequest) (HostFetchResponse, error)
CatalogSearch(ctx context.Context, query string, limit, offset int) ([]CatalogTitleSummary, error)
CatalogGet(ctx context.Context, id string) (*CatalogTitleSummary, error)
ViewerHistory(ctx context.Context, viewerID int64, limit, offset int) ([]ViewerWatchEntry, error)
SetWatchState(ctx context.Context, viewerID int64, titleID string, watched bool) error
UpsertCollection(ctx context.Context, collection map[string]any) error
FoldersList(ctx context.Context, root, path string) ([]FolderEntry, error)
FoldersStat(ctx context.Context, root, path string) (FolderEntry, error)
FoldersHash(ctx context.Context, root, path string) (FolderHash, error)
FoldersHashStart(ctx context.Context, root, path string) (FolderHashJob, error)
FoldersHashPoll(ctx context.Context, id string) (FolderHashJob, error)
FoldersHashCancel(ctx context.Context, id string) (FolderHashJob, error)
NotifyOwner(ctx context.Context, text string) error
Log(ctx context.Context, level, message string, attrs map[string]any) error
// Content-kind host services. KindUpsert/KindDelete need a push-mode
// kind; ResolveSources needs permissions.sources.
KindUpsert(ctx context.Context, kindKey string, items []KindItem) (accepted int, err error)
KindDelete(ctx context.Context, kindKey string, externalIDs []string) error
KindItems(ctx context.Context, kindKey, cursor string, limit int) (KindPage, error)
ResolveSources(ctx context.Context, q SourceQuery) ([]SourceCandidate, error)
CachePut(ctx context.Context, libraryKey, name string, data []byte) (blobRef string, err error)
CacheOpen(ctx context.Context, blobRef string) ([]byte, error)
// StreamURL mints a short-lived, scoped ticket for one of this plugin's
// own kind items and returns the Ether stream URL to embed in a
// frontend adapter response (spec §6.5). viewerID is the viewer the
// adapter authenticated.
StreamURL(ctx context.Context, viewerID int64, itemRef string) (string, error)
}
Host provides access to Ether host services (KV, secrets, HTTP, catalog, viewers, collections, folders, owner notifications, and logging).
type HostFetchRequest ¶
type HostFetchRequest struct {
Method string `json:"method,omitempty"`
URL string `json:"url"`
Headers map[string]string `json:"headers,omitempty"`
Body string `json:"body,omitempty"`
}
HostFetchRequest describes an outbound HTTP call via the host service.
type HostFetchResponse ¶
type HostFetchResponse struct {
Status int `json:"status"`
Headers map[string]string `json:"headers"`
Body string `json:"body"`
}
HostFetchResponse is returned by Host.Fetch.
type I18n ¶
type I18n struct {
// contains filtered or unexported fields
}
I18n resolves localized strings with fallback to base language and "en".
func NewI18n ¶
func NewI18n(catalog StringsCatalog, defaultLocale string) *I18n
NewI18n creates a localization helper backed by a StringsCatalog.
func (*I18n) Catalog ¶
func (i *I18n) Catalog() StringsCatalog
Catalog returns the underlying locale catalog.
type IntegrationMeta ¶
type IntegrationMeta struct {
Category string `json:"category"`
Logo string `json:"logo,omitempty"`
Adds []string `json:"adds"`
Connect string `json:"connect"`
Test bool `json:"test,omitempty"`
}
IntegrationMeta describes an external service integration.
type ItemUnavailable ¶
type ItemUnavailable struct {
}
ItemUnavailable explains why an item cannot currently be played.
type JobRequest ¶
type JobRequest struct {
Name string `json:"name"`
}
JobRequest is passed to a Job route handler.
type KindArtRef ¶
type KindArtRef struct {
Role string `json:"role"`
URL string `json:"url"`
Width int `json:"width,omitempty"`
Height int `json:"height,omitempty"`
}
KindArtRef is one artwork reference on a KindItem.
type KindBrowseDecl ¶
type KindBrowseDecl struct {
Sorts []string `json:"sorts,omitempty"`
Facets []string `json:"facets,omitempty"`
Search bool `json:"search"`
SearchFields []string `json:"searchFields,omitempty"`
// LiveSearch: client searches also call the plugin's /search route
// with a short budget; results are upserted and merged (§15.4).
LiveSearch bool `json:"liveSearch,omitempty"`
}
KindBrowseDecl is how a kind library is browsed.
type KindBrowseRequest ¶
type KindBrowseRequest struct {
Kind string `json:"-"` // filled from the route, never on the wire
ParentID string `json:"parentId,omitempty"`
Level string `json:"level,omitempty"`
Cursor string `json:"cursor,omitempty"`
Limit int `json:"limit,omitempty"`
Sort string `json:"sort,omitempty"`
Facets map[string][]string `json:"facets,omitempty"`
Query string `json:"query,omitempty"`
}
KindBrowseRequest is Ether's browse/search request for one kind level.
type KindCacheDecl ¶
type KindCacheDecl struct {
MaxBytes int64 `json:"maxBytes,omitempty"`
TTL string `json:"ttl,omitempty"`
}
KindCacheDecl is the per-library blob cache budget; 0 means server default.
type KindChangePage ¶
type KindChangePage struct {
Upserts []KindItem `json:"upserts,omitempty"`
Deletes []string `json:"deletes,omitempty"`
NextCursor string `json:"nextCursor,omitempty"`
Complete bool `json:"complete"`
}
KindChangePage is one delta page for pull sync.
type KindChangesRequest ¶
type KindChangesRequest struct {
Kind string `json:"-"`
Cursor string `json:"cursor,omitempty"`
Limit int `json:"limit,omitempty"`
}
KindChangesRequest is Ether's delta-feed request.
type KindField ¶
type KindField struct {
Key string `json:"key"`
Type string `json:"type"` // string|int|float|bool|date|duration|enum|strings|people
Label string `json:"label"`
Indexed bool `json:"indexed,omitempty"`
Enum []string `json:"enum,omitempty"`
}
KindField is one declared item field.
type KindItem ¶
type KindItem struct {
ID string `json:"id"`
Level string `json:"level"`
ParentID string `json:"parentId,omitempty"`
Index int `json:"index,omitempty"`
Title string `json:"title"`
SortTitle string `json:"sortTitle,omitempty"`
Summary string `json:"summary,omitempty"`
Year int `json:"year,omitempty"`
Released int64 `json:"released,omitempty"` // unix seconds
Rating float64 `json:"rating,omitempty"`
Playable bool `json:"playable,omitempty"`
ChildCount int `json:"childCount,omitempty"`
LeafCount int `json:"leafCount,omitempty"`
Art []KindArtRef `json:"art,omitempty"`
Fields map[string]json.RawMessage `json:"fields,omitempty"`
Hints json.RawMessage `json:"hints,omitempty"` // opaque JSON object, echoed to the resolver
ETag string `json:"etag,omitempty"`
}
KindItem is the standardised plugin item envelope. Ether assigns the stored identity; the plugin only ever sees its own external ID.
type KindLevel ¶
type KindLevel struct {
Key string `json:"key"`
Label string `json:"label"`
Playable bool `json:"playable,omitempty"`
Container bool `json:"container,omitempty"`
}
KindLevel is one hierarchy level of a kind.
type KindLibraryDecl ¶
KindLibraryDecl is the library created for a kind on install.
type KindMatchDecl ¶
type KindMatchDecl struct {
ThresholdDefault float64 `json:"thresholdDefault,omitempty"`
}
KindMatchDecl holds matcher defaults for a kind.
type KindMatchRequest ¶
type KindMatchRequest struct {
Kind string `json:"-"`
Item KindItem `json:"item"`
Candidates []SourceCandidate `json:"candidates"`
Settings map[string]any `json:"settings,omitempty"`
}
KindMatchRequest asks a matcher to score candidates for one item.
type KindMatchResponse ¶
type KindMatchResponse struct {
Matches []KindMatchScore `json:"matches"`
}
KindMatchResponse is a matcher's answer, best first.
type KindMatchScore ¶
type KindMatchScore struct {
CandidateRef string `json:"candidateRef"`
Score float64 `json:"score"`
Reasons []string `json:"reasons,omitempty"`
}
KindMatchScore is one candidate score (0..1) with plain-language reasons.
type KindMatcher ¶
type KindMatcher interface {
Match(ctx *Context, req KindMatchRequest) (KindMatchResponse, error)
}
KindMatcher scores source candidates for one item.
type KindPage ¶
type KindPage struct {
Items []KindItem `json:"items"`
NextCursor string `json:"nextCursor,omitempty"`
Total *int `json:"total,omitempty"`
}
KindPage is one page of kind items; an empty NextCursor ends the walk.
type KindResolveRequest ¶
type KindResolveRequest struct {
Kind string `json:"-"`
LibraryKey string `json:"libraryKey"`
Item KindItem `json:"item"`
PartIndex *int `json:"partIndex,omitempty"`
Client map[string]any `json:"client,omitempty"`
}
KindResolveRequest asks a resolver for playable sources for one item.
type KindResolveResponse ¶
type KindResolveResponse struct {
Sources []PlayableSource `json:"sources"`
TTLSec int `json:"ttlSec,omitempty"`
}
KindResolveResponse is a resolver's ordered sources.
type KindResolver ¶
type KindResolver interface {
Resolve(ctx *Context, req KindResolveRequest) (KindResolveResponse, error)
}
KindResolver turns a playable item into ordered playable sources.
type KindSyncDecl ¶
type KindSyncDecl struct {
Mode string `json:"mode"` // pull|push
Refresh string `json:"refresh,omitempty"`
}
KindSyncDecl is how a kind's items reach Ether's store.
type ListSourceMeta ¶
type ListSourceMeta struct {
Key string `json:"key"`
Label string `json:"label"`
Hint string `json:"hint,omitempty"`
Catalog string `json:"catalog"`
Params any `json:"params,omitempty"`
MaxItems int `json:"maxItems,omitempty"`
Refresh string `json:"refresh,omitempty"`
}
ListSourceMeta describes a catalog list source.
type Manifest ¶
type Manifest struct {
ID string `json:"id"`
Version string `json:"version"`
Name string `json:"name"`
Description string `json:"description,omitempty"`
Logo string `json:"logo,omitempty"`
Background string `json:"background,omitempty"`
Types []string `json:"types,omitempty"`
Catalogs []StremioCatalogDecl `json:"catalogs,omitempty"`
Resources []any `json:"resources,omitempty"`
IDPrefixes []string `json:"idPrefixes,omitempty"`
BehaviorHints *BehaviorHints `json:"behaviorHints,omitempty"`
Ether *EtherManifestBlock `json:"ether,omitempty"`
}
Manifest is the EPP/1 manifest document served at GET /manifest.json.
type MarkerItem ¶
type MarkerItem struct {
Kind string `json:"kind"`
Start float64 `json:"start"`
End float64 `json:"end"`
Label string `json:"label,omitempty"`
}
MarkerItem is one intro/credits/recap/preview marker.
type MarkersMeta ¶
type MarkersMeta struct {
Kinds []string `json:"kinds"`
}
MarkersMeta describes a playback markers contribution.
type MarkersRequest ¶
MarkersRequest is passed to a Markers route handler.
type MarkersResponse ¶
type MarkersResponse struct {
Markers []MarkerItem `json:"markers"`
}
MarkersResponse is returned by a Markers route handler.
type MediaKindMeta ¶
type MediaKindMeta struct {
Key string `json:"key"`
Label string `json:"label"`
Library KindLibraryDecl `json:"library"`
Levels []KindLevel `json:"levels"`
Fields []KindField `json:"fields,omitempty"`
Art []KindArt `json:"art,omitempty"`
Present Presentations `json:"present"`
Browse KindBrowseDecl `json:"browse"`
Sync KindSyncDecl `json:"sync"`
Cache *KindCacheDecl `json:"cache,omitempty"`
Match *KindMatchDecl `json:"match,omitempty"`
}
MediaKindMeta declares one content kind; each kind becomes its own library.
type MetaItem ¶
type MetaItem struct {
CatalogItem
Runtime string `json:"runtime,omitempty"`
Cast []string `json:"cast,omitempty"`
Director []string `json:"director,omitempty"`
Videos []MetaVideo `json:"videos,omitempty"`
}
MetaItem is a full metadata record returned by a Meta route handler.
type MetaRequest ¶
MetaRequest is passed to a Meta route handler.
type MetaResponse ¶
type MetaResponse struct {
Meta MetaItem `json:"meta"`
}
MetaResponse is returned by a Meta route handler.
type MetaVideo ¶
type MetaVideo struct {
ID string `json:"id"`
Title string `json:"title"`
Released string `json:"released,omitempty"`
Season int `json:"season,omitempty"`
Episode int `json:"episode,omitempty"`
Overview string `json:"overview,omitempty"`
Thumbnail string `json:"thumbnail,omitempty"`
}
MetaVideo describes one episode/video inside a MetaItem.
type MockHost ¶
type MockHost struct {
KV map[string]string
Secrets map[string]string
Catalog map[string]CatalogTitleSummary
History map[int64][]ViewerWatchEntry
WatchState map[string]bool
Collections []map[string]any
Kinds map[string][]KindItem // kindKey -> pushed items, in upsert order
Sources []SourceCandidate // returned by ResolveSources
Blobs map[string][]byte // cache blob ref -> bytes
Folders map[string][]FolderEntry
Notifications []string
Logs []RecordedLog
FetchHandler func(ctx context.Context, req HostFetchRequest) (HostFetchResponse, error)
// LastStreamURLViewer/Item record the most recent StreamURL call.
LastStreamURLViewer int64
LastStreamURLItem string
// contains filtered or unexported fields
}
MockHost is an in-memory Host implementation for unit tests.
func (*MockHost) CatalogGet ¶
CatalogGet returns a title by ID from the in-memory catalog.
func (*MockHost) CatalogSearch ¶
func (m *MockHost) CatalogSearch(_ context.Context, query string, limit, offset int) ([]CatalogTitleSummary, error)
CatalogSearch searches the in-memory catalog by case-insensitive substring.
func (*MockHost) Fetch ¶
func (m *MockHost) Fetch(ctx context.Context, req HostFetchRequest) (HostFetchResponse, error)
Fetch invokes FetchHandler if set, or returns a 200 "{}" response.
func (*MockHost) FoldersHash ¶
func (*MockHost) FoldersHashCancel ¶
func (*MockHost) FoldersHashPoll ¶
func (*MockHost) FoldersHashStart ¶
func (*MockHost) FoldersList ¶
FoldersList returns folder entries for root/path.
func (*MockHost) FoldersStat ¶
FoldersStat returns a FolderEntry for root and path.
func (*MockHost) KindDelete ¶
KindDelete drops recorded items by external id.
func (*MockHost) KindItems ¶
func (m *MockHost) KindItems(_ context.Context, kindKey, cursor string, limit int) (KindPage, error)
KindItems pages recorded items; the cursor is the last item id seen.
func (*MockHost) KindUpsert ¶
KindUpsert records pushed items under their kind, replacing same-id items.
func (*MockHost) NotifyOwner ¶
NotifyOwner appends text to Notifications.
func (*MockHost) ResolveSources ¶
func (m *MockHost) ResolveSources(_ context.Context, _ SourceQuery) ([]SourceCandidate, error)
ResolveSources returns the canned Sources.
func (*MockHost) SetWatchState ¶
func (m *MockHost) SetWatchState(_ context.Context, viewerID int64, titleID string, watched bool) error
SetWatchState records watch state for viewerID:titleID.
func (*MockHost) StreamURL ¶
StreamURL mints a deterministic stand-in URL and records the last call, so a plugin's frontend adapter can be tested without a real ticket issuer.
func (*MockHost) UpsertCollection ¶
UpsertCollection appends the collection to Collections.
func (*MockHost) ViewerHistory ¶
func (m *MockHost) ViewerHistory(_ context.Context, viewerID int64, limit, offset int) ([]ViewerWatchEntry, error)
ViewerHistory returns watch history for viewerID.
type NotificationMeta ¶
type NotificationMeta struct {
Fields any `json:"fields,omitempty"`
SendTest bool `json:"sendTest"`
Formats []string `json:"formats,omitempty"`
MaxLength int `json:"maxLength,omitempty"`
}
NotificationMeta describes a notification channel contribution.
type NotifyRequest ¶
type NotifyRequest struct {
Title string `json:"title,omitempty"`
Message string `json:"message"`
Event string `json:"event,omitempty"`
Settings map[string]any `json:"settings,omitempty"`
}
NotifyRequest is passed to a Notify route handler.
type NotifyResponse ¶
NotifyResponse is returned by a Notify route handler.
type OpenStreamRequest ¶
type OpenStreamRequest struct {
StreamID string `json:"streamId"`
}
OpenStreamRequest is passed to an OpenStream route handler.
type OpenStreamResponse ¶
type OpenStreamResponse struct {
URL string `json:"url,omitempty"`
Headers map[string]string `json:"headers,omitempty"`
ExpiresAt string `json:"expiresAt,omitempty"`
File string `json:"file,omitempty"`
}
OpenStreamResponse is returned by an OpenStream route handler.
type PageMeta ¶
type PageMeta struct {
Key string `json:"key"`
Label string `json:"label"`
Route string `json:"route"`
Group string `json:"group,omitempty"`
Icon string `json:"icon,omitempty"`
}
PageMeta describes a ViewSpec page contributed by a plugin.
type PairingInputs ¶
type PairingInputs struct {
// URL is the server's http(s) base (from ETHER_URL).
URL string
// Code is a one-time pairing code (from ETHER_PAIRING_CODE).
Code string
// Credential is an explicit credential; it always wins.
Credential string
// StateDir overrides where the credential file is kept.
StateDir string
}
PairingInputs are the pairing settings read from options and the environment. Every SDK resolves them in the same order.
type Permissions ¶
type Permissions struct {
Network []string `json:"network,omitempty"`
Catalog string `json:"catalog,omitempty"`
Viewers *ViewerPermissions `json:"viewers,omitempty"`
Collections string `json:"collections,omitempty"`
Folders string `json:"folders,omitempty"`
Secrets []string `json:"secrets,omitempty"`
// Sources lets a kind resolver ask Ether to find bytes: ""|none|search|acquire.
Sources string `json:"sources,omitempty"`
}
Permissions declares the host access a plugin requests.
type PlayableSource ¶
type PlayableSource struct {
Path string `json:"path,omitempty"`
ID string `json:"id"`
Label string `json:"label,omitempty"`
Pattern string `json:"pattern"` // range|download|direct|container|release|file
MIME string `json:"mime"`
Size int64 `json:"size,omitempty"`
DurationSec float64 `json:"durationSec,omitempty"`
URL string `json:"url,omitempty"`
Headers map[string]string `json:"headers,omitempty"`
BlobRef string `json:"blobRef,omitempty"`
SHA256 string `json:"sha256,omitempty"`
MaxBytes int64 `json:"maxBytes,omitempty"`
ExpiresAt int64 `json:"expiresAt,omitempty"`
Container *ContainerRef `json:"container,omitempty"`
Release *ReleaseHint `json:"release,omitempty"`
}
PlayableSource is one candidate way to acquire an item's bytes. URL may carry {itemIndex}, {pageNumber}, {byteStart}, {byteEnd} and {byteRange} placeholders that Ether substitutes.
type Plugin ¶
type Plugin struct {
// contains filtered or unexported fields
}
Plugin is a runnable Ether plugin instance.
func NewCatalogTemplate ¶
func NewCatalogTemplate(opts TemplateOptions) *Plugin
NewCatalogTemplate builds a starter catalog and metadata plugin.
func NewConditionTemplate ¶
func NewConditionTemplate(opts TemplateOptions) *Plugin
NewConditionTemplate builds a starter rule-condition plugin.
func NewRankerTemplate ¶
func NewRankerTemplate(opts TemplateOptions) *Plugin
NewRankerTemplate builds a starter release-ranking step plugin.
func NewScrobblerTemplate ¶
func NewScrobblerTemplate(opts TemplateOptions) *Plugin
NewScrobblerTemplate builds a starter playback event subscriber plugin.
func NewSubtitlesTemplate ¶
func NewSubtitlesTemplate(opts TemplateOptions) *Plugin
NewSubtitlesTemplate builds a starter subtitles provider plugin.
func NewViewTemplate ¶
func NewViewTemplate(opts TemplateOptions) *Plugin
NewViewTemplate builds a starter ViewSpec UI and action plugin.
func (*Plugin) CondMatch ¶
func (p *Plugin) CondMatch(candidate CandidateFacts, operator string, value any) bool
CondMatch invokes the plugin's CondMatch hot-path function.
func (*Plugin) Dispatch ¶
func (p *Plugin) Dispatch(ctx context.Context, req RawRequest) RawResponse
Dispatch routes a RawRequest through the plugin and returns a RawResponse.
func (*Plugin) DispatchTunnelFrame ¶
func (p *Plugin) DispatchTunnelFrame(ctx context.Context, frame TunnelFrame, maxChunkBytes int) []TunnelFrame
DispatchTunnelFrame executes a `"request"` TunnelFrame against a Plugin and returns the outgoing response frames (either a single `"response"` frame or a `"response_start"` / `"response_chunk"` / `"response_end"` sequence for `/ether/file/*` binary responses).
func (*Plugin) GetSettings ¶
GetSettings returns a copy of the plugin's active settings.
func (*Plugin) OnCatalog ¶
func (p *Plugin) OnCatalog(kind string, c CatalogProvider)
OnCatalog registers the catalogue provider for one declared kind.
func (*Plugin) OnFrontend ¶
func (p *Plugin) OnFrontend(key string, a FrontendAdapter)
OnFrontend registers one declared frontend adapter.
func (*Plugin) OnMatch ¶
func (p *Plugin) OnMatch(kind string, m KindMatcher)
OnMatch registers the matcher for one declared kind.
func (*Plugin) OnResolve ¶
func (p *Plugin) OnResolve(kind string, r KindResolver)
OnResolve registers the resolver for one declared kind.
func (*Plugin) OnSetupTest ¶
func (p *Plugin) OnSetupTest(t SetupTester)
OnSetupTest registers the handler for /ether/v1/setup/{step}/test.
func (*Plugin) RankKey ¶
func (p *Plugin) RankKey(candidate CandidateFacts, config map[string]any) int64
RankKey invokes the plugin's RankKey hot-path function.
func (*Plugin) Serve ¶
func (p *Plugin) Serve(ctx context.Context, opts ServeOptions) error
Serve runs the plugin sidecar until ctx is cancelled.
func (*Plugin) ServeHTTP ¶
func (p *Plugin) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP implements net/http.Handler for running a Plugin as an HTTP sidecar.
func (*Plugin) SetSettings ¶
SetSettings validates and updates the plugin's settings.
func (*Plugin) Start ¶
func (p *Plugin) Start(ctx context.Context, opts ServeOptions) (*ServeHandle, error)
Start launches the plugin sidecar in the background (either HTTP or WebSocket tunnel) and returns a ServeHandle that stops it when Close is called or ctx is cancelled.
type PluginAuthor ¶
PluginAuthor identifies the plugin author.
type PluginKind ¶
type PluginKind string
PluginKind identifies the top-level plugin classification in manifest.ether.kind.
const ( KindSource PluginKind = "source" KindIntegration PluginKind = "integration" KindNotificationChannel PluginKind = "notification_channel" KindLiveTVSource PluginKind = "livetv_source" KindExtension PluginKind = "extension" KindContent PluginKind = "content" )
type Presentations ¶
type Presentations struct {
AdapterOnly bool `json:"adapterOnly,omitempty"`
Plex *struct {
Base string `json:"base"` // movie|show|artist|photo
} `json:"plex,omitempty"`
MediaBrowser *struct {
CollectionType string `json:"collectionType"`
ItemTypes map[string]string `json:"itemTypes,omitempty"`
} `json:"mediaBrowser,omitempty"`
Stremio *struct {
Type string `json:"type"`
} `json:"stremio,omitempty"`
Xtream *struct {
Category string `json:"category"`
} `json:"xtream,omitempty"`
Silo *struct {
Type string `json:"type"`
} `json:"silo,omitempty"`
}
Presentations declares how a library is published per protocol.
type ProgrammeItem ¶
type ProgrammeItem struct {
ID string `json:"id,omitempty"`
ChannelID string `json:"channelId,omitempty"`
Title string `json:"title"`
Subtitle string `json:"subtitle,omitempty"`
Description string `json:"description,omitempty"`
Start string `json:"start"`
Stop string `json:"stop"`
Icon string `json:"icon,omitempty"`
Categories []string `json:"categories,omitempty"`
}
ProgrammeItem is one EPG programme entry.
type RankingStepMeta ¶
type RankingStepMeta struct {
Key string `json:"key"`
Label string `json:"label"`
Hint string `json:"hint,omitempty"`
Editor any `json:"editor,omitempty"`
Budget any `json:"budget,omitempty"`
}
RankingStepMeta describes a custom ranking step.
type RawRequest ¶
type RawRequest struct {
PluginID string `json:"pluginId,omitempty"`
Method string `json:"method,omitempty"`
Path string `json:"path"`
Query map[string]string `json:"query,omitempty"`
Headers map[string]string `json:"headers,omitempty"`
Body json.RawMessage `json:"body,omitempty"`
Locale string `json:"locale,omitempty"`
}
RawRequest is the low-level transport-agnostic request passed to Plugin.Dispatch.
type RawResponse ¶
type RawResponse struct {
Status int `json:"status"`
Headers map[string]string `json:"headers,omitempty"`
Body json.RawMessage `json:"body,omitempty"`
BinaryBody []byte `json:"-"`
}
RawResponse is the low-level transport-agnostic response returned by Plugin.Dispatch.
type RecordedLog ¶
RecordedLog is one log message recorded by MockHost.
type ReleaseHint ¶
type ReleaseHint struct {
NZBURL string `json:"nzbUrl,omitempty"`
Magnet string `json:"magnet,omitempty"`
InfoHash string `json:"infoHash,omitempty"`
Candidate *SourceCandidate `json:"candidate,omitempty"`
FileHint string `json:"fileHint,omitempty"`
PasswordSecret string `json:"passwordSecret,omitempty"`
}
ReleaseHint hands a release to Ether's Usenet/debrid/torrent pipeline.
type RemoteHostClient ¶
type RemoteHostClient struct {
// contains filtered or unexported fields
}
RemoteHostClient implements Host by calling `/ether/plugin-host/*` on the Ether server authenticated with `X-Ether-Plugin-Credential`.
func NewRemoteHostClient ¶
func NewRemoteHostClient(opts RemoteHostOptions) *RemoteHostClient
NewRemoteHostClient creates a RemoteHostClient.
func (*RemoteHostClient) CachePut ¶
func (c *RemoteHostClient) CachePut(ctx context.Context, libraryKey, name string, data []byte) (string, error)
CachePut stores one blob in a kind library's cache; the ref is content-addressed.
func (*RemoteHostClient) CatalogGet ¶
func (c *RemoteHostClient) CatalogGet(ctx context.Context, id string) (*CatalogTitleSummary, error)
CatalogGet fetches one title summary from the Ether catalog.
func (*RemoteHostClient) CatalogSearch ¶
func (c *RemoteHostClient) CatalogSearch( ctx context.Context, query string, limit, offset int, ) ([]CatalogTitleSummary, error)
CatalogSearch searches the Ether catalog.
func (*RemoteHostClient) Fetch ¶
func (c *RemoteHostClient) Fetch(ctx context.Context, r HostFetchRequest) (HostFetchResponse, error)
Fetch performs an outbound HTTP request.
func (*RemoteHostClient) FoldersHash ¶
func (*RemoteHostClient) FoldersHash(context.Context, string, string) (FolderHash, error)
func (*RemoteHostClient) FoldersHashCancel ¶
func (*RemoteHostClient) FoldersHashCancel(context.Context, string) (FolderHashJob, error)
func (*RemoteHostClient) FoldersHashPoll ¶
func (*RemoteHostClient) FoldersHashPoll(context.Context, string) (FolderHashJob, error)
func (*RemoteHostClient) FoldersHashStart ¶
func (*RemoteHostClient) FoldersHashStart(context.Context, string, string) (FolderHashJob, error)
func (*RemoteHostClient) FoldersList ¶
func (c *RemoteHostClient) FoldersList(_ context.Context, _, _ string) ([]FolderEntry, error)
FoldersList is only supported in hosted mode; sidecars access local folders directly.
func (*RemoteHostClient) FoldersStat ¶
func (c *RemoteHostClient) FoldersStat(_ context.Context, _, _ string) (FolderEntry, error)
FoldersStat is only supported in hosted mode; sidecars access local folders directly.
func (*RemoteHostClient) KVDelete ¶
func (c *RemoteHostClient) KVDelete(ctx context.Context, key string) error
KVDelete deletes a key from the plugin's KV namespace.
func (*RemoteHostClient) KVList ¶
KVList lists keys matching the given prefix in the plugin's KV namespace.
func (*RemoteHostClient) KVPut ¶
func (c *RemoteHostClient) KVPut(ctx context.Context, key, value string) error
KVPut writes a key-value pair to the plugin's KV namespace.
func (*RemoteHostClient) KindDelete ¶
func (c *RemoteHostClient) KindDelete(ctx context.Context, kindKey string, externalIDs []string) error
KindDelete removes items from a push-mode kind library.
func (*RemoteHostClient) KindItems ¶
func (c *RemoteHostClient) KindItems(ctx context.Context, kindKey, cursor string, limit int) (KindPage, error)
KindItems reads the plugin's own kind library back, keyset-paged.
func (*RemoteHostClient) KindUpsert ¶
func (c *RemoteHostClient) KindUpsert(ctx context.Context, kindKey string, items []KindItem) (int, error)
KindUpsert pushes items into a push-mode kind library.
func (*RemoteHostClient) Log ¶
func (c *RemoteHostClient) Log(ctx context.Context, level, message string, attrs map[string]any) error
Log sends a structured log entry to Ether.
func (*RemoteHostClient) NotifyOwner ¶
func (c *RemoteHostClient) NotifyOwner(ctx context.Context, text string) error
NotifyOwner sends an owner notification through Ether.
func (*RemoteHostClient) ResolveSources ¶
func (c *RemoteHostClient) ResolveSources(ctx context.Context, q SourceQuery) ([]SourceCandidate, error)
ResolveSources asks Ether to find sources through its indexers/debrid.
func (*RemoteHostClient) SecretGet ¶
SecretGet is only available in hosted mode; remote plugins receive secrets via /ether/configure.
func (*RemoteHostClient) SetWatchState ¶
func (c *RemoteHostClient) SetWatchState( ctx context.Context, viewerID int64, titleID string, watched bool, ) error
SetWatchState updates the watch state for a granted viewer.
func (*RemoteHostClient) SettingsGet ¶
SettingsGet reads the current non-secret settings from Ether.
func (*RemoteHostClient) StreamURL ¶
func (c *RemoteHostClient) StreamURL(ctx context.Context, viewerID int64, itemRef string) (string, error)
StreamURL mints a scoped stream ticket and returns the Ether stream URL for one of this plugin's own kind items (spec §6.5).
func (*RemoteHostClient) UpsertCollection ¶
UpsertCollection creates or updates a plugin-managed collection.
func (*RemoteHostClient) ViewerHistory ¶
func (c *RemoteHostClient) ViewerHistory( ctx context.Context, viewerID int64, limit, offset int, ) ([]ViewerWatchEntry, error)
ViewerHistory reads watch history for a granted viewer.
type RemoteHostOptions ¶
RemoteHostOptions configures a RemoteHostClient for sidecar plugins.
type RouteError ¶
RouteError represents a structured HTTP error returned by a plugin handler.
func NewRouteError ¶
func NewRouteError(status int, code, message string) *RouteError
NewRouteError constructs a structured RouteError.
func (*RouteError) Error ¶
func (e *RouteError) Error() string
type Routes ¶
type Routes struct {
Catalog func(ctx *Context, req CatalogRequest) (CatalogResponse, error)
Meta func(ctx *Context, req MetaRequest) (MetaResponse, error)
Stream func(ctx *Context, req StreamRequest) (StreamResponse, error)
OpenStream func(ctx *Context, req OpenStreamRequest) (OpenStreamResponse, error)
Subtitles func(ctx *Context, req SubtitlesRequest) (SubtitlesResponse, error)
SubtitleDownload func(ctx *Context, req SubtitleDownloadRequest) (SubtitleDownloadResponse, error)
Markers func(ctx *Context, req MarkersRequest) (MarkersResponse, error)
Channels func(ctx *Context) (ChannelsResponse, error)
Guide func(ctx *Context, req GuideRequest) (GuideResponse, error)
Configure func(ctx *Context, settings map[string]any) (ConfigureResponse, error)
Test func(ctx *Context) (TestResponse, error)
Options func(ctx *Context, field string) ([]FieldOption, error)
Health func(ctx *Context) (HealthResponse, error)
Notify func(ctx *Context, req NotifyRequest) (NotifyResponse, error)
Event func(ctx *Context, events []EtherEvent) (EventResponse, error)
View func(ctx *Context, req ViewRequest) (ViewResponse, error)
Action func(ctx *Context, req ActionRequest) (ActionResponse, error)
Tool func(ctx *Context, req ToolRequest) (ToolResponse, error)
Job func(ctx *Context, req JobRequest) (JobResponse, error)
File func(ctx *Context, req FileRequest) (FileRangeResponse, error)
RankKey func(candidate CandidateFacts, config map[string]any) int64
CondMatch func(candidate CandidateFacts, operator string, value any) bool
}
Routes holds the capability handlers for a Plugin.
type RuleConditionMeta ¶
type RuleConditionMeta struct {
Key string `json:"key"`
Label string `json:"label"`
Operators []string `json:"operators,omitempty"`
Editor any `json:"editor,omitempty"`
}
RuleConditionMeta describes a custom rule condition.
type RuntimeDecl ¶
type RuntimeDecl struct {
Kind string `json:"kind"`
Entry string `json:"entry,omitempty"`
Module string `json:"module,omitempty"`
}
RuntimeDecl declares how the plugin is executed.
type ScheduleEntry ¶
ScheduleEntry declares a scheduled background job.
type SearchProvider ¶
type SearchProvider interface {
Search(ctx *Context, req KindBrowseRequest) (KindPage, error)
}
SearchProvider is the optional provider-side search route.
type ServeHandle ¶
type ServeHandle struct {
// Done closes when the tunnel supervisor stops (ctx cancellation or Close).
// Transient disconnects reconnect automatically. It is nil for HTTP servers.
Done <-chan struct{}
Mode string
URL string
Port int
Close func() error
}
ServeHandle represents a running HTTP or tunnel sidecar session.
type ServeOptions ¶
type ServeOptions struct {
Mode string
Host string
Port int
TunnelURL string
Credential string
// URL is the server's http(s) base (ETHER_URL). When set, the tunnel URL
// and pair URL are derived from it and the SDK pairs with a code.
URL string
// StateDir overrides where the pairing credential is saved
// (ETHER_PLUGIN_STATE_DIR).
StateDir string
}
ServeOptions configures how Plugin.Serve runs in sidecar mode.
type SettingField ¶
type SettingField struct {
Key string `json:"key"`
Kind string `json:"kind"`
Label string `json:"label,omitempty"`
Hint string `json:"hint,omitempty"`
Required bool `json:"required,omitempty"`
Default any `json:"default,omitempty"`
Options []FieldOption `json:"options,omitempty"`
Fields []SettingField `json:"fields,omitempty"`
Min *float64 `json:"min,omitempty"`
Max *float64 `json:"max,omitempty"`
Placeholder string `json:"placeholder,omitempty"`
}
SettingField describes one leaf or group setting field.
func CollectSettingFields ¶
func CollectSettingFields(schema *SettingsSchema) []SettingField
CollectSettingFields returns all leaf SettingFields from a SettingsSchema.
type SettingsGroup ¶
type SettingsGroup struct {
Key string `json:"key,omitempty"`
Label string `json:"label,omitempty"`
Hint string `json:"hint,omitempty"`
Advanced bool `json:"advanced,omitempty"`
Fields []SettingField `json:"fields"`
}
SettingsGroup groups related settings fields.
type SettingsSchema ¶
type SettingsSchema struct {
Ref string `json:"$ref,omitempty"`
Fields []SettingField `json:"fields,omitempty"`
Groups []SettingsGroup `json:"groups,omitempty"`
}
SettingsSchema describes a plugin's configuration fields.
type SetupMeta ¶
type SetupMeta struct {
Steps []SetupStep `json:"steps"`
}
SetupMeta declares guided setup for any plugin kind.
type SetupStep ¶
type SetupStep struct {
Key string `json:"key"`
Label string `json:"label"`
Hint string `json:"hint,omitempty"`
Fields []string `json:"fields"`
Test string `json:"test"`
Required bool `json:"required"`
}
SetupStep is one setup wizard step; an empty Test means saving is the step.
type SetupTestRequest ¶
type SetupTestRequest struct {
Step string `json:"step"`
Fields map[string]any `json:"fields,omitempty"`
}
SetupTestRequest is Ether's setup-step test call: the step key plus the saved (non-secret) values of the step's fields.
type SetupTestResult ¶
type SetupTestResult struct {
OK bool `json:"ok"`
Detail string `json:"detail,omitempty"`
Fields map[string]string `json:"fields,omitempty"`
}
SetupTestResult is a setup test's answer.
type SetupTester ¶
type SetupTester interface {
TestSetup(ctx *Context, req SetupTestRequest) (SetupTestResult, error)
}
SetupTester answers setup-step test calls.
type SlotMeta ¶
type SlotMeta struct {
Slot string `json:"slot"`
Key string `json:"key"`
Label string `json:"label"`
Route string `json:"route"`
}
SlotMeta describes a UI slot contributed by a plugin.
type SourceCandidate ¶
type SourceCandidate struct {
InfoHash string `json:"infoHash,omitempty"`
Magnet string `json:"magnet,omitempty"`
NZBURL string `json:"nzbUrl,omitempty"`
FileIndex int `json:"fileIndex,omitempty"`
Title string `json:"title,omitempty"`
Size int64 `json:"size,omitempty"`
Seeders int `json:"seeders,omitempty"`
Cached bool `json:"cached,omitempty"`
// Ref names this candidate in match scores. Ether derives it from the
// infohash/NZB when empty; matchers echo it verbatim.
Ref string `json:"-"`
}
SourceCandidate is one Ether-found release for a resolver to rank.
func (SourceCandidate) CandidateRef ¶
func (c SourceCandidate) CandidateRef() string
CandidateRef returns the stable ref matchers report for a candidate.
type SourceMeta ¶
type SourceMeta struct {
Class string `json:"class"`
Abilities []string `json:"abilities,omitempty"`
Limits map[string]any `json:"limits,omitempty"`
}
SourceMeta describes a stream source contribution.
type SourceQuery ¶
type SourceQuery struct {
Kind string `json:"kind"` // indexer_search|debrid_check|debrid_acquire
Query string `json:"query,omitempty"`
Category string `json:"category,omitempty"`
InfoHashes []string `json:"infoHashes,omitempty"`
InfoHash string `json:"infoHash,omitempty"`
Magnet string `json:"magnet,omitempty"`
}
SourceQuery asks Ether to find sources (Host.ResolveSources).
type StreamEtherExt ¶
type StreamEtherExt struct {
ID string `json:"id,omitempty"`
ReleaseName string `json:"releaseName,omitempty"`
Size int64 `json:"size,omitempty"`
Languages []string `json:"languages,omitempty"`
Lazy bool `json:"lazy,omitempty"`
File string `json:"file,omitempty"`
}
StreamEtherExt holds Ether-specific extensions on a StreamItem.
type StreamItem ¶
type StreamItem struct {
Name string `json:"name,omitempty"`
Title string `json:"title,omitempty"`
Description string `json:"description,omitempty"`
URL string `json:"url,omitempty"`
InfoHash string `json:"infoHash,omitempty"`
FileIdx *int `json:"fileIdx,omitempty"`
YtID string `json:"ytId,omitempty"`
ExternalURL string `json:"externalUrl,omitempty"`
Ether *StreamEtherExt `json:"ether,omitempty"`
}
StreamItem is one playable candidate returned by a Stream route handler.
type StreamRequest ¶
type StreamRequest struct {
Type string `json:"type"`
ID string `json:"id"`
Extra map[string]string `json:"extra"`
}
StreamRequest is passed to a Stream route handler.
type StreamResponse ¶
type StreamResponse struct {
Streams []StreamItem `json:"streams"`
}
StreamResponse is returned by a Stream route handler.
type StremioCatalogDecl ¶
type StremioCatalogDecl struct {
Type string `json:"type"`
ID string `json:"id"`
Name string `json:"name,omitempty"`
Extra []StremioExtraField `json:"extra,omitempty"`
}
StremioCatalogDecl declares a Stremio catalog in the manifest.
type StremioExtraField ¶
type StremioExtraField struct {
Name string `json:"name"`
IsRequired bool `json:"isRequired,omitempty"`
Options []string `json:"options,omitempty"`
OptionsLimit int `json:"optionsLimit,omitempty"`
}
StremioExtraField declares a supported extra parameter on a catalog.
type StringsCatalog ¶
StringsCatalog maps locale codes (e.g. "en", "fr-CA") to key-value tables.
type SubtitleDownloadRequest ¶
type SubtitleDownloadRequest struct {
ID string `json:"id"`
Lang string `json:"lang"`
Format string `json:"format"`
}
SubtitleDownloadRequest identifies a viewer-picked subtitle.
type SubtitleDownloadResponse ¶
type SubtitleDownloadResponse struct {
Format string `json:"format"`
Encoding string `json:"encoding"`
Data string `json:"data"`
}
SubtitleDownloadResponse carries subtitle text or base64-encoded bytes.
type SubtitleItem ¶
type SubtitleItem struct {
ID string `json:"id"`
URL string `json:"url,omitempty"`
Name string `json:"name,omitempty"`
Lang string `json:"lang"`
Label string `json:"label,omitempty"`
Format string `json:"format,omitempty"`
HearingImpaired bool `json:"hearingImpaired,omitempty"`
}
SubtitleItem is one subtitle track returned by a Subtitles route handler.
type SubtitlesMeta ¶
type SubtitlesMeta struct {
Languages any `json:"languages,omitempty"`
Formats []string `json:"formats,omitempty"`
}
SubtitlesMeta describes a subtitle provider contribution.
type SubtitlesRequest ¶
type SubtitlesRequest struct {
Type string `json:"type"`
ID string `json:"id"`
Extra map[string]string `json:"extra"`
PickToken string `json:"pickToken"`
VideoHash string `json:"videoHash,omitempty"`
VideoSize int64 `json:"videoSize,omitempty"`
Filename string `json:"filename,omitempty"`
}
SubtitlesRequest is passed to a Subtitles route handler.
type SubtitlesResponse ¶
type SubtitlesResponse struct {
Subtitles []SubtitleItem `json:"subtitles"`
}
SubtitlesResponse is returned by a Subtitles route handler.
type TemplateOptions ¶
type TemplateOptions struct {
ID string
Name string
Version string
Summary string
Description string
}
TemplateOptions configures a capability starter template.
type TestHarness ¶
TestHarness wraps a Plugin and MockHost for ergonomic unit tests.
func NewTestHarness ¶
func NewTestHarness(p *Plugin, host *MockHost) *TestHarness
NewTestHarness constructs a TestHarness for p.
func (*TestHarness) Action ¶
func (h *TestHarness) Action(action string, input map[string]any) (int, ActionResponse, error)
Action calls POST /ether/action/{action}.
func (*TestHarness) Catalog ¶
func (h *TestHarness) Catalog(typ, id string, extra map[string]string) (int, CatalogResponse, error)
Catalog calls GET /catalog/{type}/{id}[/{extra}].json.
func (*TestHarness) Configure ¶
func (h *TestHarness) Configure(settings map[string]any) (int, ConfigureResponse, error)
Configure calls POST /ether/configure.
func (*TestHarness) Event ¶
func (h *TestHarness) Event(events []EtherEvent) (int, EventResponse, error)
Event calls POST /ether/event.
func (*TestHarness) File ¶
func (h *TestHarness) File(path, rangeHeader string) RawResponse
File calls GET /ether/file/{path}.
func (*TestHarness) Health ¶
func (h *TestHarness) Health() (int, HealthResponse, error)
Health calls GET /ether/health.
func (*TestHarness) Manifest ¶
func (h *TestHarness) Manifest() (Manifest, error)
Manifest fetches and decodes GET /manifest.json.
func (*TestHarness) Markers ¶
func (h *TestHarness) Markers(typ, id string) (int, MarkersResponse, error)
Markers calls GET /ether/markers/{type}/{id}.json.
func (*TestHarness) Meta ¶
func (h *TestHarness) Meta(typ, id string) (int, MetaResponse, error)
Meta calls GET /meta/{type}/{id}.json.
func (*TestHarness) Options ¶
func (h *TestHarness) Options(field string) (int, []FieldOption, error)
Options calls GET /ether/options/{field}.
func (*TestHarness) Request ¶
func (h *TestHarness) Request(req RawRequest) RawResponse
Request dispatches a RawRequest against the plugin.
func (*TestHarness) Stream ¶
func (h *TestHarness) Stream(typ, id string, extra map[string]string) (int, StreamResponse, error)
Stream calls GET /stream/{type}/{id}[/{extra}].json.
func (*TestHarness) Subtitles ¶
func (h *TestHarness) Subtitles(typ, id, pickToken string, extra map[string]string) (int, SubtitlesResponse, RawResponse)
Subtitles calls GET /subtitles/{type}/{id}[/{extra}].json with optional pickToken.
func (*TestHarness) Test ¶
func (h *TestHarness) Test() (int, TestResponse, error)
Test calls POST /ether/test.
func (*TestHarness) Tool ¶
func (h *TestHarness) Tool(name string, input map[string]any) (int, ToolResponse, error)
Tool calls POST /ether/tool/{name}.
func (*TestHarness) View ¶
func (h *TestHarness) View(page string, query map[string]string) (int, ViewResponse, error)
View calls GET /ether/view/{page} and validates the returned ViewSpecDocument.
type TestResponse ¶
type TestResponse struct {
OK bool `json:"ok"`
Message string `json:"message,omitempty"`
Details []string `json:"details,omitempty"`
}
TestResponse is returned by a Test route handler.
type ToolMeta ¶
type ToolMeta struct {
Name string `json:"name"`
Title string `json:"title"`
Description string `json:"description"`
InputSchema map[string]any `json:"inputSchema"`
ReadOnly bool `json:"readOnly,omitempty"`
Destructive bool `json:"destructive,omitempty"`
OpenWorld bool `json:"openWorld,omitempty"`
}
ToolMeta describes an agent tool contributed by a plugin.
type ToolRequest ¶
ToolRequest is passed to a Tool route handler.
type ToolResponse ¶
ToolResponse is returned by a Tool route handler.
type TunnelError ¶
TunnelError carries an error payload inside a TunnelFrame.
type TunnelFrame ¶
type TunnelFrame struct {
Type string `json:"type"`
ID string `json:"id,omitempty"`
RequestID string `json:"requestId,omitempty"`
Protocol string `json:"protocol,omitempty"`
Plugin string `json:"plugin,omitempty"`
PluginID string `json:"pluginId,omitempty"`
ConnectionID string `json:"connectionId,omitempty"`
Features []string `json:"features,omitempty"`
MaxChunkBytes int `json:"maxChunkBytes,omitempty"`
Method string `json:"method,omitempty"`
Path string `json:"path,omitempty"`
Query map[string][]string `json:"query,omitempty"`
Headers map[string][]string `json:"headers,omitempty"`
Body string `json:"body,omitempty"`
Data string `json:"data,omitempty"`
Status int `json:"status,omitempty"`
Deadline string `json:"deadline,omitempty"`
Error *TunnelError `json:"error,omitempty"`
}
TunnelFrame is one JSON message sent or received over the `ether-tunnel-v1` WebSocket.
type ViewRequest ¶
ViewRequest is passed to a View route handler.
type ViewResponse ¶
type ViewResponse struct {
Spec ViewSpecDocument `json:"spec"`
Data map[string]any `json:"data"`
}
ViewResponse is returned by a View route handler.
type ViewSpecDocument ¶
type ViewSpecDocument struct {
SpecVersion int `json:"specVersion"`
Layout string `json:"layout"`
Route string `json:"route,omitempty"`
Header []map[string]any `json:"header"`
Body []map[string]any `json:"body"`
}
ViewSpecDocument is a declarative ViewSpec v1 page specification.
type ViewerPermissions ¶
type ViewerPermissions struct {
Identity string `json:"identity,omitempty"`
WatchHistory string `json:"watch_history,omitempty"`
WriteWatchState string `json:"write_watch_state,omitempty"`
}
ViewerPermissions scopes viewer identity and watch-history access.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
kit
|
|
|
archivex
Package archivex lists and reads members of zip-shaped containers (zip, cbz, epub) with the standard library only, so hosted builds stay possible.
|
Package archivex lists and reads members of zip-shaped containers (zip, cbz, epub) with the standard library only, so hosted builds stay possible. |
|
feedparse
Package feedparse turns RSS, Atom and JSON Feed documents into kind items: one feed is usually one root item with entries as leaves.
|
Package feedparse turns RSS, Atom and JSON Feed documents into kind items: one feed is usually one root item with entries as leaves. |
|
hints
Package hints marshals typed resolver hints for KindItem.Hints.
|
Package hints marshals typed resolver hints for KindItem.Hints. |
|
metaparse
Package metaparse reads embedded metadata (EPUB OPF, ComicInfo.xml, ID3v2, FLAC Vorbis comments) into plain maps a provider can copy into KindItem fields.
|
Package metaparse reads embedded metadata (EPUB OPF, ComicInfo.xml, ID3v2, FLAC Vorbis comments) into plain maps a provider can copy into KindItem fields. |
|
scrape
Package scrape fetches pages through Ether's host HTTP service (so the manifest network allowlist applies) and pulls text and links out of simple HTML.
|
Package scrape fetches pages through Ether's host HTTP service (so the manifest network allowlist applies) and pulls text and links out of simple HTML. |