provider

package
v0.1.151 Latest Latest
Warning

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

Go to latest
Published: Jul 19, 2026 License: GPL-2.0, GPL-3.0 Imports: 20 Imported by: 0

Documentation

Overview

Package provider contains the provider registry and retry wrappers.

Index

Constants

View Source
const DownloadRetryAttempts = 3

DownloadRetryAttempts is the maximum number of download attempts per provider.

View Source
const DownloadRetryInitBackoff = 2 * time.Second

DownloadRetryInitBackoff is the initial backoff duration between download retries.

View Source
const HTTPTimeoutExtended = 30 * time.Second

HTTPTimeoutExtended is the timeout for heavier provider APIs that may return larger payloads or have slower backends (opensubtitles, subsource, subdl).

View Source
const HTTPTimeoutStandard = 15 * time.Second

HTTPTimeoutStandard is the default timeout for lightweight provider APIs (hdbits, betaseries, gestdown, animetosho, yifysubtitles).

Variables

This section is empty.

Functions

func ClearProviderCaches

func ClearProviderCaches(providers []api.Provider)

ClearProviderCaches calls ClearCache on any provider that implements api.CacheClearer. Typically called at scan completion to free memory.

func ExtractAndValidate

func ExtractAndValidate(data []byte, season, episode int) ([]byte, error)

ExtractAndValidate attempts to extract a subtitle from an archive (zip/rar), falling back to the raw data if extraction yields nothing. The result is validated for binary content. Returns the usable subtitle bytes or an error.

func NewHTTPClient

func NewHTTPClient(timeout time.Duration) *http.Client

NewHTTPClient returns a *http.Client preconfigured with the SSRF-safe transport, User-Agent injection, redirect policy, the hard response-body ceiling (maxResponseBodyBytes), and the given timeout.

All providers share these defaults: any redirect to a private IP, link-local address, or HTTP-downgrade is rejected; private/link-local DNS resolutions are also blocked at the transport layer. Per-provider tuning (auth headers, caching, rate limiting) layers on top of the *http.Client returned here.

Use this factory instead of constructing &http.Client{} ad-hoc; consistency of SSRF/redirect policy across providers is a security property the factory enforces.

func NewHTTPClientNoClientTimeout

func NewHTTPClientNoClientTimeout(allowedPorts ...uint16) *http.Client

NewHTTPClientNoClientTimeout returns an SSRF-safe *http.Client without a client-level Timeout. Used by providers (e.g. anidb) that fetch large bodies and rely on transport-level dial/response-header timeouts plus per-request context.WithTimeout, where a client-level Timeout would clip mid-stream. NewHTTPClientNoClientTimeout builds the shared SSRF-validated provider client without a client-level timeout (phase timeouts come from SafeTransport). allowedPorts overrides ssrf's default {443} dial-port allowlist — pass it only for a known public endpoint on a non-standard port (e.g. the AniDB HTTP API on 9001); omit it for the https/443 default.

func NormalizeSettings added in v0.1.148

func NormalizeSettings(fields []api.ProviderSchemaField, raw map[string]any) map[string]any

NormalizeSettings returns a copy of the raw settings map with every declared-but-absent field filled from its schema Default, coerced per the declared Type (P14). The registry applies this before invoking a factory, which makes the providerEntries declaration the SINGLE source of a setting's default: factories read the normalized map through FromMap / the typed accessors and never re-encode a default of their own (the use_hash dual-encoding this replaces drifted exactly once already). Undeclared keys pass through untouched, and a declared field the user DID set is never rewritten.

func ParseFlexInt

func ParseFlexInt(data []byte) (int, error)

ParseFlexInt parses a JSON value that may be either a number or a quoted string into an int, as a thin shim over jsonx.Strict(): bare or quoted decimal integers anywhere in int64, null and "" tolerated as 0, everything else an error (wrapped to keep the historical "flexint:" message prefix). The jsonx policy reproduces this decoder's pinned behavior — TestParseFlexInt remains the acceptance spec. Provider-specific FlexInt types that differ in strictness (hdbits, subsource) compose their own jsonx policies directly.

func ResolveShowCounter

func ResolveShowCounter(providers []api.Provider) api.ShowSubtitleCounter

ResolveShowCounter finds the first provider implementing ShowSubtitleCounter. Called at the composition root to inject the resolved counter into LiveState.

func SettingBool

func SettingBool(settings map[string]any, key SettingKey, def bool) bool

SettingBool returns the boolean value for key in settings. Accepts native bool or string "true"/"false". Returns def if the key is missing or the value is not a recognized boolean.

func SettingFloat

func SettingFloat(settings map[string]any, key SettingKey, def float64) float64

SettingFloat returns the float64 value for key in settings. Accepts native float64/int/int64 or numeric string. Returns def if the key is missing or the value is not convertible to float64.

func SettingInt

func SettingInt(settings map[string]any, key SettingKey, def int) int

SettingInt returns the integer value for key in settings. Accepts native int/int64/float64 (whole YAML numeric) or numeric string. Returns def if the key is missing or the value is not convertible to int. Non-whole float64 values return def.

func SettingString

func SettingString(settings map[string]any, key SettingKey) string

SettingString returns the string value for key in settings. Returns "" if the key is missing or the value is not a string.

func WrapRetry

func WrapRetry(p api.Provider, maxAttempts int, initBackoff time.Duration) api.Provider

WrapRetry wraps a provider with download retry logic. If the inner provider implements ShowSubtitleCounter, the wrapper preserves that interface.

func WrapRetryAll

func WrapRetryAll(providers []api.Provider, maxAttempts int, initBackoff time.Duration) []api.Provider

WrapRetryAll wraps each provider with download retry logic.

Types

type FactoryFunc

type FactoryFunc func(ctx context.Context, settings map[string]any) (api.Provider, error)

FactoryFunc creates a provider from config settings. The context parameter enables cancellation during provider initialization (e.g. credential validation, API pings) and respects shutdown signals.

type Registry

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

Registry holds provider factories keyed by name.

func NewRegistry

func NewRegistry() *Registry

NewRegistry creates an empty provider registry.

func (*Registry) LoadAll

func (r *Registry) LoadAll(ctx context.Context, providers map[api.ProviderID]api.ProviderCfg) ([]api.Provider, error)

LoadAll creates all enabled providers from config. Providers are loaded in parallel for reduced startup latency when factories perform network validation. Results are sorted by name for deterministic ordering. Unknown provider names are skipped with a warning (a typo in config should not prevent all other providers from loading). Providers are returned unwrapped; download retry wrapping (WrapRetryAll) is applied by the composition root (main.go wiring).

LoadAll reads only cfg.Enabled and cfg.Settings from each entry. Other ProviderCfg fields (if added) will not affect provider loading.

Zero providers loading is NOT an error: a config with no enabled acquisition providers is a valid "embedded detection and coverage only" setup. The counts are WARN-logged so operators can still distinguish a typo (unknown>0) from a deliberate all-disabled state.

func (*Registry) ProviderNames

func (r *Registry) ProviderNames() []api.ProviderID

ProviderNames returns all registered provider names in sorted order.

func (*Registry) Register

func (r *Registry) Register(name api.ProviderID, f FactoryFunc)

Register adds a provider factory to the registry.

func (*Registry) RegisterSchema

func (r *Registry) RegisterSchema(name api.ProviderID, label string, fields []api.ProviderSchemaField)

RegisterSchema adds UI metadata for a provider.

func (*Registry) Schema

func (r *Registry) Schema(name api.ProviderID) (string, []api.ProviderSchemaField)

Schema returns the label and settings fields for a provider.

type RegistryError

type RegistryError struct {
	Err      error          // underlying error for ErrProviderInit
	Provider api.ProviderID // non-empty for ErrProviderInit
	Kind     RegistryErrorKind
}

RegistryError is a typed error returned by LoadAll.

func (*RegistryError) Error

func (e *RegistryError) Error() string

func (*RegistryError) Unwrap

func (e *RegistryError) Unwrap() error

type RegistryErrorKind

type RegistryErrorKind int

RegistryErrorKind categorizes registry loading failures.

const ErrProviderInit RegistryErrorKind = iota + 1

ErrProviderInit indicates a provider factory returned an error.

func (RegistryErrorKind) String

func (k RegistryErrorKind) String() string

String returns a human-readable name for the error kind.

type SettingKey

type SettingKey string

SettingKey is a typed constant for provider setting keys, preventing typos and enabling IDE navigation.

const (
	KeyAPIKey          SettingKey = "api_key"
	KeyUsername        SettingKey = "username"
	KeyPassword        SettingKey = "password"
	KeyPasskey         SettingKey = "passkey"
	KeyToken           SettingKey = "token"
	KeyUseHash         SettingKey = "use_hash"
	KeyIncludeAI       SettingKey = "include_ai_translated"
	KeyAniDBClientKey  SettingKey = "anidb_client_key"
	KeyMode            SettingKey = "mode"
	KeyErrorMessage    SettingKey = "error_message"
	KeyDownloadError   SettingKey = "download_error"
	KeySubtitleContent SettingKey = "subtitle_content"
	KeyIncludeHash     SettingKey = "include_hash"
	KeyHearingImpaired SettingKey = "hearing_impaired"
	KeyForced          SettingKey = "forced"
	KeyResultCount     SettingKey = "result_count"
	KeyFlakyRate       SettingKey = "flaky_rate"
	KeyDelayMs         SettingKey = "delay_ms"
)

Common provider setting keys.

type Settings

type Settings struct {
	Custom   map[string]any // provider-specific extras
	APIKey   string
	Username string
	Password string
	Passkey  string
	Token    string
	UseHash  bool
}

Settings provides typed access to common provider configuration fields. Every common field has migrated here (FromMap gives compile-time safety); Custom carries only genuinely provider-specific extras.

func FromMap

func FromMap(settings map[string]any) Settings

FromMap constructs a Settings from the raw settings map, extracting common fields with type-safe accessors and preserving remaining entries in Custom for provider-specific use.

Directories

Path Synopsis
Package anidb provides TVDB → AniDB mapping using the community-maintained anime-list.xml from https://github.com/Anime-Lists/anime-lists.
Package anidb provides TVDB → AniDB mapping using the community-maintained anime-list.xml from https://github.com/Anime-Lists/anime-lists.
Package animetosho implements the AnimeTosho subtitle provider.
Package animetosho implements the AnimeTosho subtitle provider.
Package archive provides subtitle extraction from ZIP and RAR archives.
Package archive provides subtitle extraction from ZIP and RAR archives.
Package betaseries implements the BetaSeries subtitle provider.
Package betaseries implements the BetaSeries subtitle provider.
Package classify provides subtitle classification (forced/HI) and language resolution utilities consumed by provider sub-packages.
Package classify provides subtitle classification (forced/HI) and language resolution utilities consumed by provider sub-packages.
Package dlcache provides a generic LRU download-data cache with heap-based eviction.
Package dlcache provides a generic LRU download-data cache with heap-based eviction.
Package gestdown implements the Gestdown subtitle provider.
Package gestdown implements the Gestdown subtitle provider.
Package hdbits implements the HDBits.org subtitle provider.
Package hdbits implements the HDBits.org subtitle provider.
Package mock provides a configurable mock subtitle provider for functional testing.
Package mock provides a configurable mock subtitle provider for functional testing.
Package opensubtitles implements the OpenSubtitles.com REST API provider.
Package opensubtitles implements the OpenSubtitles.com REST API provider.
Package subdl implements the SubDL subtitle provider.
Package subdl implements the SubDL subtitle provider.
Package subsource implements the SubSource subtitle provider.
Package subsource implements the SubSource subtitle provider.
Package yifysubtitles implements the YIFY Subtitles provider.
Package yifysubtitles implements the YIFY Subtitles provider.

Jump to

Keyboard shortcuts

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