config

package
v0.1.147 Latest Latest
Warning

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

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

Documentation

Overview

Package config loads, validates, and hot-reloads the subflux YAML configuration.

Index

Constants

View Source
const (
	// DefaultConfigPath is the container-internal config file path.
	DefaultConfigPath = "/config/config.yaml"
	// DefaultDBPath is the container-internal bbolt database file path.
	// Core and auth buckets live in the same file; no separate auth path.
	DefaultDBPath = "/config/subflux.bolt"
)

Container-internal path constants (single source of truth).

View Source
const DefaultSessionAbsoluteTimeout = defaults.DefaultSessionAbsoluteTimeout

DefaultSessionAbsoluteTimeout is the session absolute timeout when not configured.

View Source
const DefaultSessionIdleTimeout = defaults.DefaultSessionIdleTimeout

DefaultSessionIdleTimeout is the session idle timeout when not configured.

View Source
const ServerPort = 8374

ServerPort is the fixed HTTP server port.

Variables

View Source
var (
	// ErrNoProvider indicates no subtitle provider is enabled.
	ErrNoProvider = errors.New("at least one provider must be enabled")

	// ErrNoArr indicates neither Sonarr nor Radarr is configured.
	ErrNoArr = errors.New("at least one of sonarr or radarr must be configured")

	// ErrNoDefaultLang indicates the languages.default section is empty.
	ErrNoDefaultLang = errors.New("languages.default must contain at least one subtitle target; every item must have a fallback set of subtitles to look for")

	// ErrDuplicateAudioRule indicates a duplicate audio language rule was found.
	ErrDuplicateAudioRule = errors.New("duplicate audio language rule")

	// ErrSearchConfig indicates an invalid search configuration.
	ErrSearchConfig = errors.New("invalid search configuration")

	// ErrAdaptiveConfig indicates an invalid adaptive configuration.
	ErrAdaptiveConfig = errors.New("invalid adaptive configuration")

	// ErrLoggingConfig indicates an invalid logging configuration.
	ErrLoggingConfig = errors.New("invalid logging configuration")

	// ErrPostProcessConfig indicates an invalid post-processing configuration.
	ErrPostProcessConfig = errors.New("invalid post-processing configuration")

	// ErrMissingAPIKey indicates a required API key is not configured.
	ErrMissingAPIKey = errors.New("API key required")
)

Sentinel errors for the most common config validation failures. These enable errors.Is dispatch instead of string matching.

View Source
var ErrConfigTooLarge = errors.New("config too large")

ErrConfigTooLarge indicates the config file or data exceeds the maximum allowed size.

View Source
var ErrPathNotAllowed = errors.New("path not under any configured media_roots")

ErrPathNotAllowed is returned when a path is not under any configured media_roots.

View Source
var ErrVariantConflict = errors.New("cannot set both variant and variants")

ErrVariantConflict indicates both "variant" and "variants" are set on the same target.

Functions

func ParseDuration

func ParseDuration(s string) (time.Duration, error)

ParseDuration extends time.ParseDuration with D, M, and Y suffixes.

func ValidLogFormat

func ValidLogFormat(f LogFormat) bool

ValidLogFormat returns true if the format is a recognized value, judged by slogx.ParseFormat — the same case-insensitive, trimming normalization setupLogging applies when it consumes the value — so validation and consumption cannot drift. The empty string is "unset" (the caller falls back to the default), not a valid value.

func ValidLogLevel

func ValidLogLevel(l LogLevel) bool

ValidLogLevel returns true if the level is a recognized value.

Types

type AudioRule

type AudioRule struct {
	Audio     string               `yaml:"audio"`     // ISO 639-1 audio to match
	Subtitles []yamlSubtitleTarget `yaml:"subtitles"` // What to download
}

AudioRule maps a detected audio language to subtitle targets.

type Config

type Config struct {
	Providers map[api.ProviderID]yamlProviderCfg `yaml:"providers"`
	Scoring   ScoringConfig                      `yaml:"scoring"`

	Sonarr    yamlArrConfig `yaml:"sonarr"`
	Radarr    yamlArrConfig `yaml:"radarr"`
	Logging   LoggingConfig `yaml:"logging"`
	Languages LanguageRules `yaml:"languages"`

	MediaRootDirs []string `yaml:"media_roots"`
	// TrustedProxies lists reverse-proxy CIDR ranges (or single IPs as /32)
	// whose X-Forwarded-For may be trusted for client-IP resolution. Empty
	// (the default) trusts nothing: the socket peer is used and XFF ignored.
	TrustedProxies []string `yaml:"trusted_proxies"`

	Auth            yamlAuthConfig        `yaml:"auth"`
	Backup          yamlBackupConfig      `yaml:"backup"`
	SearchCfg       yamlSearchConfig      `yaml:"search"`
	AdaptiveCfg     yamlAdaptiveConfig    `yaml:"adaptive"`
	PostProcessing  yamlPostProcessConfig `yaml:"post_processing"`
	PollIntervalCfg Duration              `yaml:"poll_interval"`
	// contains filtered or unexported fields
}

Config is the top-level configuration.

func Load

func Load(ctx context.Context, path string) (*Config, error)

Load reads and validates a config file. The context enables cancellation during file I/O and validation (e.g. media_roots stat loop).

func LoadFromBytes

func LoadFromBytes(ctx context.Context, data []byte) (*Config, error)

LoadFromBytes parses config from raw YAML bytes.

func (*Config) Adaptive

func (c *Config) Adaptive() api.AdaptiveConfig

Adaptive returns the adaptive search config.

func (*Config) AuthDisabled

func (c *Config) AuthDisabled() bool

AuthDisabled returns whether authentication is completely bypassed. This is an undocumented escape hatch; not part of the ConfigProvider interface.

func (*Config) AuthEnabled

func (c *Config) AuthEnabled() bool

AuthEnabled returns true once setup is complete (any user exists). The actual check is done at the middleware level; config always returns true.

func (*Config) BackupEnabled

func (c *Config) BackupEnabled() bool

BackupEnabled reports whether scheduled database backups are enabled.

func (*Config) BackupFrequency

func (c *Config) BackupFrequency() time.Duration

BackupFrequency returns how often a backup is taken.

func (*Config) BackupPath

func (c *Config) BackupPath() string

BackupPath returns the backup directory override. Empty means backups are written next to the database file.

func (*Config) BackupRetention

func (c *Config) BackupRetention() int

BackupRetention returns how many backup files to keep on disk.

func (*Config) BasicAuthEnabled

func (c *Config) BasicAuthEnabled() bool

BasicAuthEnabled returns whether password login is enabled. Defaults to true if not explicitly set.

func (*Config) CheckBreachedPasswords

func (c *Config) CheckBreachedPasswords() bool

CheckBreachedPasswords returns whether to check passwords against HIBP. Defaults to true if not explicitly set.

func (*Config) Close

func (c *Config) Close() error

Close releases all cached os.Root handles. Call at shutdown.

func (*Config) LanguageCodes

func (c *Config) LanguageCodes() []string

LanguageCodes returns a deduplicated list of all subtitle language codes across all rules and the default. Used for full library scans where audio language isn't known upfront.

func (*Config) LanguageRulesForUI

func (c *Config) LanguageRulesForUI() api.LanguageRulesJSON

LanguageRulesForUI returns the raw (unexpanded) language rules for the UI.

func (*Config) LoggingFormat

func (c *Config) LoggingFormat() api.LogFormat

LoggingFormat returns the configured log format.

func (*Config) LoggingLevel

func (c *Config) LoggingLevel() api.LogLevel

LoggingLevel returns the configured log level.

func (*Config) MediaRoots

func (c *Config) MediaRoots() []string

MediaRoots returns the configured media root directories.

func (*Config) MinScoreForTarget

func (c *Config) MinScoreForTarget(t *api.SubtitleTarget, _ api.MediaType) int

MinScoreForTarget returns the minimum score for a target, falling back to the global min_score. The mediaType parameter is part of the ConfigProvider interface for future per-media-type score overrides; currently unused.

func (*Config) OIDCConfig

func (c *Config) OIDCConfig() auth.OIDCConfig

OIDCConfig returns the OIDC provider settings.

func (*Config) OIDCEnabled

func (c *Config) OIDCEnabled() bool

OIDCEnabled returns whether OIDC login is enabled.

func (*Config) PollInterval

func (c *Config) PollInterval() time.Duration

PollInterval returns the configured arr history poll interval.

func (*Config) PostProcessConfig

func (c *Config) PostProcessConfig() api.PostProcessConfig

PostProcessConfig returns the post-processing configuration.

func (*Config) ProviderConfigs

func (c *Config) ProviderConfigs() map[api.ProviderID]api.ProviderCfg

ProviderConfigs returns the provider configuration map.

func (*Config) ProviderPriority

func (c *Config) ProviderPriority(name api.ProviderID) int

ProviderPriority returns the priority for a provider (lower = higher trust). Returns api.DefaultProviderPriority for unconfigured or zero-priority providers.

func (*Config) ProvidersForTarget

func (c *Config) ProvidersForTarget(t *api.SubtitleTarget, allProviders []api.ProviderID) []api.ProviderID

ProvidersForTarget returns which providers to use for a subtitle target.

func (*Config) RadarrConfig

func (c *Config) RadarrConfig() api.ArrConfig

RadarrConfig returns the Radarr connection config. Returns empty config when disabled.

func (*Config) RemoveUnderRoot

func (c *Config) RemoveUnderRoot(ctx context.Context, path string) error

RemoveUnderRoot deletes a file atomically through an os.Root handle, eliminating the TOCTOU window between path validation and removal. Returns nil if the file was removed or did not exist.

If no media_roots are configured the operation is refused — earlier versions fell back to a bare os.Remove(path), but that gave callers implicit superuser-style FS access that bypassed the os.Root containment guarantee. The fallback also tripped CodeQL's go/path-injection rule for code paths where row.Path originates from the database (and ultimately from a filesystem scan that itself ran outside any safety envelope). Refusing is the safe default; admins who want subtitle deletion to work must configure media_roots.

func (*Config) ResolveTargetsWithFallback

func (c *Config) ResolveTargetsWithFallback(originalLang string, audioLangs []string) []api.SubtitleTarget

ResolveTargetsWithFallback implements the full language resolution chain: 1. Match originalLanguage against rules 2. If no match, try each audio track language against rules 3. If still no match, return default targets

func (*Config) Scores

func (c *Config) Scores() api.Scores

Scores returns custom weights or the defaults.

func (*Config) Search

func (c *Config) Search() api.SearchConfig

Search returns the search config.

func (*Config) ServerPort

func (c *Config) ServerPort() int

ServerPort returns the fixed HTTP server port.

func (*Config) SessionAbsoluteTimeout

func (c *Config) SessionAbsoluteTimeout() time.Duration

SessionAbsoluteTimeout returns the session absolute timeout. Defaults to 7 days if not configured.

func (*Config) SessionIdleTimeout

func (c *Config) SessionIdleTimeout() time.Duration

SessionIdleTimeout returns the session idle timeout. Defaults to 24 hours if not configured.

func (*Config) SonarrConfig

func (c *Config) SonarrConfig() api.ArrConfig

SonarrConfig returns the Sonarr connection config. Returns empty config when disabled.

func (*Config) SyncConfig

func (c *Config) SyncConfig() api.SyncConfig

SyncConfig returns the sync configuration.

func (*Config) TrustedProxyNets added in v0.1.92

func (c *Config) TrustedProxyNets() []*net.IPNet

TrustedProxyNets returns the parsed trusted reverse-proxy CIDR set used for spoof-safe client-IP resolution. It is empty when trusted_proxies is unset (the default), in which case the client IP resolves to the unspoofable socket peer and X-Forwarded-For is ignored. Not part of the ConfigProvider interface; consumed directly by the composition root (like AuthDisabled).

func (*Config) Validate

func (c *Config) Validate() error

Validate checks that the Config has the minimum required configuration.

func (*Config) ValidatePath

func (c *Config) ValidatePath(ctx context.Context, path string) error

ValidatePath checks that a file path is under one of the configured media roots using pre-opened os.Root handles for symlink-safe containment. Returns an error if the path escapes all roots. If no media roots are configured, all paths are allowed.

func (*Config) WebAuthnRPID

func (c *Config) WebAuthnRPID() string

WebAuthnRPID returns the configured WebAuthn Relying Party ID. Returns empty string if not set (auto-detected from hostname at runtime).

type Duration

type Duration struct {
	D time.Duration
}

Duration wraps time.Duration with extended YAML parsing that supports day (D), month (M), and year (Y) suffixes in addition to Go's standard duration units (ns, us, ms, s, m, h). Only single-unit values are supported for extended units (e.g. "7D", "3M", "1Y").

Conversions: 1D = 24h, 1M = 730h (30.4 days), 1Y = 8760h (365 days).

func (*Duration) UnmarshalYAML

func (d *Duration) UnmarshalYAML(value *yaml.Node) error

UnmarshalYAML parses a duration string, extending time.ParseDuration with D (days), M (months), and Y (years) suffixes.

type FieldDependencyError

type FieldDependencyError struct {
	Field     string // the field that has the constraint
	DependsOn string // the field it depends on
	Reason    string // human-readable explanation
}

FieldDependencyError is a typed error for config field-requires-field constraint violations. Callers can use errors.As to programmatically identify which field combinations are invalid.

func (*FieldDependencyError) Error

func (e *FieldDependencyError) Error() string

type LanguageRules

type LanguageRules struct {
	// Rules maps an audio language (ISO 639-1) to subtitle targets.
	// Example: audio "en" -> download "fr" normal + "fr" forced
	Rules []AudioRule `yaml:"rules"`

	// Default applies when the audio language doesn't match any rule.
	// If empty, no subtitles are downloaded for unmatched audio.
	Default []yamlSubtitleTarget `yaml:"default,omitempty"`
}

LanguageRules maps detected audio languages to desired subtitle downloads.

type LogFormat

type LogFormat = api.LogFormat

LogFormat is a typed string for log output formats.

const (
	LogFormatJSON LogFormat = "json"
	LogFormatText LogFormat = "text"
)

LogFormat constants for the supported log output formats.

type LogLevel

type LogLevel = api.LogLevel

LogLevel is a typed string for log verbosity levels.

const (
	LogLevelError LogLevel = "error"
	LogLevelWarn  LogLevel = "warn"
	LogLevelInfo  LogLevel = "info"
	LogLevelDebug LogLevel = "debug"
)

LogLevel constants for the supported log verbosity levels.

type LoggingConfig

type LoggingConfig struct {
	Level  LogLevel  `yaml:"level"`
	Format LogFormat `yaml:"format"`
}

LoggingConfig controls log output.

type ScoringConfig

type ScoringConfig struct {
	Weights *api.Scores `yaml:"weights,omitempty"`
}

ScoringConfig allows users to customize scoring weights.

type ValidationError

type ValidationError struct {
	Field   string // e.g. "search.min_score", "sonarr.api_key"
	Message string
}

ValidationError is a structured validation error that identifies the offending config field. Callers can use errors.As to extract the field name for targeted UI display or programmatic handling.

func (*ValidationError) Error

func (e *ValidationError) Error() string

type ValidationErrors

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

ValidationErrors accumulates multiple validation errors from config checking. Sub-validators append directly via Add, eliminating the repeated if-err-append boilerplate.

func (*ValidationErrors) Add

func (ve *ValidationErrors) Add(err error)

Add appends a non-nil error to the accumulator.

func (*ValidationErrors) Err

func (ve *ValidationErrors) Err() error

Err returns the accumulated errors joined, or nil if none.

type Validator

type Validator interface {
	Validate() error
}

Validator is satisfied by types that can self-validate after loading.

Directories

Path Synopsis
Package defaults provides shared configuration constants and helpers used by both config/ and config/schema/.
Package defaults provides shared configuration constants and helpers used by both config/ and config/schema/.
Package schema generates the UI configuration schema for the web frontend.
Package schema generates the UI configuration schema for the web frontend.

Jump to

Keyboard shortcuts

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