Documentation
¶
Index ¶
- Constants
- func SaveToFile(config *Config, filename string) error
- type APIConfig
- type ArrsConfig
- type ArrsInstanceConfig
- type AuthConfig
- type ChangeCallback
- type Config
- func (c *Config) DeepCopy() *Config
- func (c *Config) GetCheckAllSegments() bool
- func (c *Config) GetCheckBatchSize() int
- func (c *Config) GetCheckInterval() time.Duration
- func (c *Config) GetDownloadClientBaseURL() string
- func (c *Config) GetFuseMountPath() string
- func (c *Config) GetHealthDeleteOnCorruption() bool
- func (c *Config) GetHealthEnabled() bool
- func (c *Config) GetHealthExcludedCategories() []string
- func (c *Config) GetHealthReadTimeout() time.Duration
- func (c *Config) GetImportDamagePolicyTolerant() bool
- func (c *Config) GetIsoAnalyzeTimeout() time.Duration
- func (c *Config) GetLibrarySyncConcurrency() int
- func (c *Config) GetLibrarySyncInterval() time.Duration
- func (c *Config) GetMaxConcurrentImports() int
- func (c *Config) GetMaxConcurrentJobs() int
- func (c *Config) GetMaxConnectionsForHealthChecks() int
- func (c *Config) GetMaxDownloadPrefetch() int
- func (c *Config) GetMaxRepairRetries() int
- func (c *Config) GetMaxRetries() int
- func (c *Config) GetMetadataBackupKeep() int
- func (c *Config) GetReadTimeoutSeconds() int
- func (c *Config) GetRepairEnabled() bool
- func (c *Config) GetRepairExponentialBackoff() bool
- func (c *Config) GetRepairInterval() time.Duration
- func (c *Config) GetRepairMaxCoolDown() time.Duration
- func (c *Config) GetSegmentSamplePercentage() int
- func (c *Config) GetVerifyData() bool
- func (c *Config) GetWebhookBaseURL() string
- func (c *Config) ProvidersDiff(other *Config) []ProviderChange
- func (c *Config) ProvidersEqual(other *Config) bool
- func (c *Config) ProvidersOrderChanged(other *Config) bool
- func (c *Config) ToNNTPProviders() []nntppool.Provider
- func (c *Config) TotalProviderConnections() int
- func (c *Config) Validate() error
- func (c *Config) ValidateDirectories() error
- type ConfigGetter
- type DatabaseConfig
- type FailureMaskingConfig
- type FuseConfig
- type HealthConfig
- type IgnoredMessage
- type ImportConfig
- type ImportStrategy
- type LogConfig
- type Manager
- func (m *Manager) ClearLibrarySyncFlag()
- func (m *Manager) GetConfig() *Config
- func (m *Manager) GetConfigGetter() ConfigGetter
- func (m *Manager) GetPreviousMountPath() string
- func (m *Manager) NeedsLibrarySync() bool
- func (m *Manager) OnConfigChange(callback ChangeCallback)
- func (m *Manager) ReloadConfig() error
- func (m *Manager) SaveConfig() error
- func (m *Manager) UpdateConfig(config *Config) error
- func (m *Manager) ValidateConfig(config *Config) error
- func (m *Manager) ValidateConfigUpdate(newConfig *Config) error
- type MetadataBackupConfig
- type MetadataConfig
- type MountType
- type NetworkConfig
- type NzblnkConfig
- type ProviderChange
- type ProviderChangeType
- type ProviderConfig
- type ProwlarrConfig
- type RCloneConfig
- type RepairConfig
- type SABnzbdCategory
- type SABnzbdConfig
- type SegmentCacheConfig
- type StreamingConfig
- type StremioConfig
- type StuckCleanupRule
- type WebDAVConfig
Constants ¶
const ( // StuckActionRemove removes the item from the queue only (no blocklist, no // re-search) — for transient/environmental errors or already-satisfied files. StuckActionRemove = "remove" // StuckActionBlocklist removes the item and blocklists the release so the same // NZB is not grabbed again, but does NOT trigger a new search. StuckActionBlocklist = "blocklist" // StuckActionBlocklistSearch blocklists the release and triggers the *arr to // search for a replacement. StuckActionBlocklistSearch = "blocklist_search" )
Stuck cleanup actions decide what happens to a matched stuck import.
const DefaultCategoryDir = "complete"
const DefaultCategoryName = "Default"
const MountProvider = "altmount"
Variables ¶
This section is empty.
Functions ¶
func SaveToFile ¶
SaveToFile saves a configuration to a YAML file
Types ¶
type APIConfig ¶
type APIConfig struct {
Prefix string `yaml:"prefix" mapstructure:"prefix" json:"prefix"`
KeyOverride string `yaml:"key_override" mapstructure:"key_override" json:"key_override,omitempty"`
AllowedOrigins []string `yaml:"allowed_origins" mapstructure:"allowed_origins" json:"allowed_origins,omitempty"`
}
APIConfig represents REST API configuration
type ArrsConfig ¶
type ArrsConfig struct {
Enabled *bool `yaml:"enabled" mapstructure:"enabled" json:"enabled"`
MaxWorkers int `yaml:"max_workers" mapstructure:"max_workers" json:"max_workers,omitempty"`
WebhookBaseURL string `yaml:"webhook_base_url" mapstructure:"webhook_base_url" json:"webhook_base_url,omitempty"`
RadarrInstances []ArrsInstanceConfig `yaml:"radarr_instances" mapstructure:"radarr_instances" json:"radarr_instances"`
SonarrInstances []ArrsInstanceConfig `yaml:"sonarr_instances" mapstructure:"sonarr_instances" json:"sonarr_instances"`
LidarrInstances []ArrsInstanceConfig `yaml:"lidarr_instances" mapstructure:"lidarr_instances" json:"lidarr_instances"`
ReadarrInstances []ArrsInstanceConfig `yaml:"readarr_instances" mapstructure:"readarr_instances" json:"readarr_instances"`
WhisparrInstances []ArrsInstanceConfig `yaml:"whisparr_instances" mapstructure:"whisparr_instances" json:"whisparr_instances"`
SportarrInstances []ArrsInstanceConfig `yaml:"sportarr_instances" mapstructure:"sportarr_instances" json:"sportarr_instances"`
QueueCleanupEnabled *bool `yaml:"queue_cleanup_enabled" mapstructure:"queue_cleanup_enabled" json:"queue_cleanup_enabled,omitempty"`
QueueCleanupIntervalSeconds int `` /* 131-byte string literal not displayed */
QueueCleanupGracePeriodMinutes int `` /* 143-byte string literal not displayed */
// QueueCleanupMaxFailures is the per-target failure circuit breaker. After
// AltMount has acted on the same target (a Radarr movie or Sonarr/Whisparr
// episode that keeps failing import) this many times — via queue cleanup,
// health-repair re-searches or the partial-pack reconcile — it gives up:
// it blocklists without re-searching and unmonitors the item in the *arr so it
// stops being automatically re-grabbed. 0 (the default) disables the breaker.
QueueCleanupMaxFailures int `yaml:"queue_cleanup_max_failures" mapstructure:"queue_cleanup_max_failures" json:"queue_cleanup_max_failures,omitempty"`
// QueueCleanupRules matches an *arr status message for a stuck/failed import and
// decides the action (remove / blocklist / blocklist+search). This is the single
// message-rule list for queue cleanup; ghost/empty-folder detection runs alongside
// it in the same pass. Only items owned by AltMount's download client are touched
// (see issue #523).
QueueCleanupRules []StuckCleanupRule `yaml:"queue_cleanup_rules,omitempty" mapstructure:"queue_cleanup_rules" json:"queue_cleanup_rules,omitempty"`
// Deprecated: the fields below are read from existing config files for one-time
// migration into the unified queue-cleanup model (see migrateArrsCleanup) and are
// cleared afterwards. They are hidden from the API (json:"-") and dropped from
// saved YAML once empty (yaml omitempty). Do not use in new code.
QueueCleanupAllowlist []IgnoredMessage `yaml:"queue_cleanup_allowlist,omitempty" mapstructure:"queue_cleanup_allowlist" json:"-"`
StuckCleanupEnabled *bool `yaml:"stuck_cleanup_enabled,omitempty" mapstructure:"stuck_cleanup_enabled" json:"-"`
StuckCleanupGracePeriodMinutes int `yaml:"stuck_cleanup_grace_period_minutes,omitempty" mapstructure:"stuck_cleanup_grace_period_minutes" json:"-"`
StuckCleanupRules []StuckCleanupRule `yaml:"stuck_cleanup_rules,omitempty" mapstructure:"stuck_cleanup_rules" json:"-"`
// Deprecated: the hardcoded "automatic import is not possible" purge has been
// folded into the unified QueueCleanupRules (see migrateArrsCleanup). Read for
// one-time migration only, then cleared. Do not use in new code.
CleanupAutomaticImportFailure *bool `yaml:"cleanup_automatic_import_failure,omitempty" mapstructure:"cleanup_automatic_import_failure" json:"-"`
}
ArrsConfig represents arrs configuration
type ArrsInstanceConfig ¶
type ArrsInstanceConfig struct {
Name string `yaml:"name" mapstructure:"name" json:"name"`
URL string `yaml:"url" mapstructure:"url" json:"url"`
APIKey string `yaml:"api_key" mapstructure:"api_key" json:"api_key"`
Category string `yaml:"category" mapstructure:"category" json:"category,omitempty"`
Enabled *bool `yaml:"enabled" mapstructure:"enabled" json:"enabled,omitempty"`
SyncIntervalHours *int `yaml:"sync_interval_hours" mapstructure:"sync_interval_hours" json:"sync_interval_hours,omitempty"`
}
ArrsInstanceConfig represents a single arrs instance configuration
type AuthConfig ¶
type AuthConfig struct {
LoginRequired *bool `yaml:"login_required" mapstructure:"login_required" json:"login_required"`
}
AuthConfig represents authentication configuration
type ChangeCallback ¶
type ChangeCallback func(oldConfig, newConfig *Config)
ChangeCallback represents a function called when configuration changes
type Config ¶
type Config struct {
WebDAV WebDAVConfig `yaml:"webdav" mapstructure:"webdav" json:"webdav"`
API APIConfig `yaml:"api" mapstructure:"api" json:"api"`
Auth AuthConfig `yaml:"auth" mapstructure:"auth" json:"auth"`
Database DatabaseConfig `yaml:"database" mapstructure:"database" json:"database"`
Metadata MetadataConfig `yaml:"metadata" mapstructure:"metadata" json:"metadata"`
Streaming StreamingConfig `yaml:"streaming" mapstructure:"streaming" json:"streaming"`
Health HealthConfig `yaml:"health" mapstructure:"health" json:"health"`
RClone RCloneConfig `yaml:"rclone" mapstructure:"rclone" json:"rclone"`
Import ImportConfig `yaml:"import" mapstructure:"import" json:"import"`
Log LogConfig `yaml:"log" mapstructure:"log" json:"log"`
SABnzbd SABnzbdConfig `yaml:"sabnzbd" mapstructure:"sabnzbd" json:"sabnzbd"`
Arrs ArrsConfig `yaml:"arrs" mapstructure:"arrs" json:"arrs"`
Stremio StremioConfig `yaml:"stremio" mapstructure:"stremio" json:"stremio"`
Fuse FuseConfig `yaml:"fuse" mapstructure:"fuse" json:"fuse"`
SegmentCache SegmentCacheConfig `yaml:"segment_cache" mapstructure:"segment_cache" json:"segment_cache"`
Providers []ProviderConfig `yaml:"providers" mapstructure:"providers" json:"providers"`
Nzblnk NzblnkConfig `yaml:"nzblnk" mapstructure:"nzblnk" json:"nzblnk"`
Network NetworkConfig `yaml:"network" mapstructure:"network" json:"network"`
MountPath string `yaml:"mount_path" mapstructure:"mount_path" json:"mount_path"`
MountType MountType `yaml:"mount_type" mapstructure:"mount_type" json:"mount_type"`
ProfilerEnabled bool `yaml:"profiler_enabled" mapstructure:"profiler_enabled" json:"profiler_enabled" default:"false"`
}
Config represents the complete application configuration
func DefaultConfig ¶
DefaultConfig returns a config with default values If configDir is provided, it will be used for database and log file paths
func LoadConfig ¶
LoadConfig loads configuration from file and merges with defaults
func (*Config) DeepCopy ¶
DeepCopy returns a deep copy of the configuration using the copier library. This handles all pointer fields, slices, and maps automatically.
func (*Config) GetCheckAllSegments ¶
GetCheckAllSegments returns whether to check all segments during health checks.
func (*Config) GetCheckBatchSize ¶ added in v0.3.0
GetCheckBatchSize returns how many due files each health cycle fetches and sweeps together in one cross-file StatMany call, with a default fallback. Distinct from GetMaxConnectionsForHealthChecks: this bounds how many FILES are batched into one sweep, while that bounds how many segment checks run concurrently within a sweep.
func (*Config) GetCheckInterval ¶
GetCheckInterval returns the health check interval with a default fallback.
func (*Config) GetDownloadClientBaseURL ¶ added in v0.2.0
GetDownloadClientBaseURL returns the configured download client base URL or a default one based on the current port.
func (*Config) GetFuseMountPath ¶
GetFuseMountPath returns the FUSE mount path, falling back to the root mount_path if not set.
func (*Config) GetHealthDeleteOnCorruption ¶ added in v0.3.0
GetHealthDeleteOnCorruption reports whether confirmed corruption should delete the file instead of triggering an Arr repair (health.corruption_action == "delete").
func (*Config) GetHealthEnabled ¶
GetHealthEnabled returns whether health checking is enabled (defaults to true)
func (*Config) GetHealthExcludedCategories ¶ added in v0.3.2
GetHealthExcludedCategories returns the SABnzbd category names whose files must not be registered for health checking by the library-sync pass.
func (*Config) GetHealthReadTimeout ¶
GetHealthReadTimeout returns the health check read timeout as a duration with a default fallback.
func (*Config) GetImportDamagePolicyTolerant ¶ added in v0.3.0
GetImportDamagePolicyTolerant reports whether small confirmed damage on a standalone video file should import as degraded (true, the default) instead of failing the import (false, "strict").
func (*Config) GetIsoAnalyzeTimeout ¶ added in v0.3.0
GetIsoAnalyzeTimeout returns the per-ISO analyse deadline with a 120s default fallback. This bounds the entire iso.AnalyzeISO walk so a degraded NNTP provider cannot stall the importer indefinitely.
Sentinel handling:
- nil (config field unset) → 120s default
- 0 or negative (explicit "none") → 120s default; users cannot disable the cap — the whole purpose of this knob is to prevent unbounded waits. To approximate "unlimited", set a very large value (e.g. 86400 for a one-day budget).
func (*Config) GetLibrarySyncConcurrency ¶
GetLibrarySyncConcurrency returns the library sync concurrency with a default fallback.
func (*Config) GetLibrarySyncInterval ¶
GetLibrarySyncInterval returns the library sync interval with a default fallback.
func (*Config) GetMaxConcurrentImports ¶ added in v0.3.0
GetMaxConcurrentImports returns the global cap on concurrent NZB imports. 0 means unlimited (the default).
func (*Config) GetMaxConcurrentJobs ¶
GetMaxConcurrentJobs returns max concurrent health check jobs with a default fallback.
func (*Config) GetMaxConnectionsForHealthChecks ¶
GetMaxConnectionsForHealthChecks returns max connections for health checks with a default fallback.
func (*Config) GetMaxDownloadPrefetch ¶
GetMaxDownloadPrefetch returns max download prefetch with a default fallback.
func (*Config) GetMaxRepairRetries ¶
GetMaxRepairRetries returns the maximum number of repair notification retries.
func (*Config) GetMaxRetries ¶
GetMaxRetries returns the maximum number of health check retries.
func (*Config) GetMetadataBackupKeep ¶
GetMetadataBackupKeep returns the number of metadata backups to keep with a default fallback.
func (*Config) GetReadTimeoutSeconds ¶
GetReadTimeoutSeconds returns read timeout in seconds with a default fallback.
func (*Config) GetRepairEnabled ¶
GetRepairEnabled returns whether automatic repair is enabled (defaults to true)
func (*Config) GetRepairExponentialBackoff ¶
GetRepairExponentialBackoff returns whether exponential backoff is enabled for repairs
func (*Config) GetRepairInterval ¶
GetRepairInterval returns the repair check interval
func (*Config) GetRepairMaxCoolDown ¶
GetRepairMaxCoolDown returns the maximum cooldown for repairs
func (*Config) GetSegmentSamplePercentage ¶
GetSegmentSamplePercentage returns segment sample percentage with a default fallback. Returns a value between 1 and 100.
func (*Config) GetVerifyData ¶
GetVerifyData returns whether to verify data during health checks.
func (*Config) GetWebhookBaseURL ¶ added in v0.2.0
GetWebhookBaseURL returns the configured webhook base URL or a default one based on the current port.
func (*Config) ProvidersDiff ¶
func (c *Config) ProvidersDiff(other *Config) []ProviderChange
ProvidersDiff computes the set of provider changes between this config and another. Returns nil if providers are identical (same set and same field values).
func (*Config) ProvidersEqual ¶
ProvidersEqual compares the providers in this config with another config for equality
func (*Config) ProvidersOrderChanged ¶
ProvidersOrderChanged returns true if the provider order differs between this config and another, even if the set of providers is unchanged.
func (*Config) ToNNTPProviders ¶
ToNNTPProviders converts ProviderConfig slice to nntppool.Provider slice (enabled only)
func (*Config) TotalProviderConnections ¶ added in v0.3.0
TotalProviderConnections returns the pool's total connection capacity: the sum of MaxConnections across enabled, non-backup providers. When no primary providers are configured it falls back to the enabled backup providers' sum so the capacity is not zero while a usable pool exists. Returns 0 when no providers are configured at all.
func (*Config) ValidateDirectories ¶
ValidateDirectories validates that all configured directories are writable This performs actual filesystem checks and may create directories if needed
type ConfigGetter ¶
type ConfigGetter func() *Config
ConfigGetter represents a function that returns the current configuration
type DatabaseConfig ¶
type DatabaseConfig struct {
// Type selects the database backend: "sqlite" (default) or "postgres".
Type string `yaml:"type" mapstructure:"type" json:"type"`
// Path is the SQLite database file path (sqlite only).
Path string `yaml:"path" mapstructure:"path" json:"path"`
// DSN is the PostgreSQL connection string (postgres only).
// Example: "postgres://user:password@localhost:5432/altmount?sslmode=disable"
DSN string `yaml:"dsn" mapstructure:"dsn" json:"dsn,omitempty"`
}
DatabaseConfig represents database configuration
type FailureMaskingConfig ¶
type FailureMaskingConfig struct {
Enabled *bool `yaml:"enabled" mapstructure:"enabled" json:"enabled"`
Threshold int `yaml:"threshold" mapstructure:"threshold" json:"threshold"`
}
FailureMaskingConfig represents failure masking configuration
type FuseConfig ¶
type FuseConfig struct {
MountPath string `yaml:"mount_path" mapstructure:"mount_path" json:"mount_path"`
Enabled *bool `yaml:"enabled" mapstructure:"enabled" json:"enabled"`
AllowOther bool `yaml:"allow_other" mapstructure:"allow_other" json:"allow_other"`
Debug bool `yaml:"debug" mapstructure:"debug" json:"debug"`
AttrTimeoutSeconds int `yaml:"attr_timeout_seconds" mapstructure:"attr_timeout_seconds" json:"attr_timeout_seconds"`
EntryTimeoutSeconds int `yaml:"entry_timeout_seconds" mapstructure:"entry_timeout_seconds" json:"entry_timeout_seconds"`
MaxCacheSizeMB int `yaml:"max_cache_size_mb" mapstructure:"max_cache_size_mb" json:"max_cache_size_mb"`
MaxReadAheadMB int `yaml:"max_read_ahead_mb" mapstructure:"max_read_ahead_mb" json:"max_read_ahead_mb"`
// AsyncBufferSizeMB is the per-open-file read-ahead buffer size (MB). A
// background goroutine fills it ahead of the player so reads are served
// from memory instead of blocking on the network, mirroring the buffering
// rclone's VFS provides over WebDAV. 0 disables read-ahead (every read is a
// direct passthrough — the previous behavior).
AsyncBufferSizeMB int `yaml:"async_buffer_size_mb" mapstructure:"async_buffer_size_mb" json:"async_buffer_size_mb"`
// AsyncBufferMaxTotalMB caps total read-ahead memory across all open files
// (MB). Buffers reserve their size only while actively streaming; over the
// cap, additional streams run unbuffered. 0 = unlimited.
AsyncBufferMaxTotalMB int `yaml:"async_buffer_max_total_mb" mapstructure:"async_buffer_max_total_mb" json:"async_buffer_max_total_mb"`
Backend string `yaml:"backend" mapstructure:"backend" json:"backend"` // "hanwen" or "cgo" (empty = platform default)
// NoModTime reports epoch for all timestamps (mtime, ctime, atime); prevents
// media servers re-scanning on unstable VFS mtimes. Note: tools like find -atime
// will not see meaningful access times on this mount.
NoModTime bool `yaml:"no_mod_time" mapstructure:"no_mod_time" json:"no_mod_time"`
}
FuseConfig represents FUSE mount configuration
type HealthConfig ¶
type HealthConfig struct {
Enabled *bool `yaml:"enabled" mapstructure:"enabled" json:"enabled,omitempty"`
LibraryDir *string `yaml:"library_dir" mapstructure:"library_dir" json:"library_dir,omitempty"`
CleanupOrphanedMetadata *bool `yaml:"cleanup_orphaned_metadata" mapstructure:"cleanup_orphaned_metadata" json:"cleanup_orphaned_metadata,omitempty"`
CheckIntervalSeconds int `yaml:"check_interval_seconds" mapstructure:"check_interval_seconds" json:"check_interval_seconds,omitempty"`
MaxConnectionsForHealthChecks int `` /* 140-byte string literal not displayed */
CheckBatchSize int `yaml:"check_batch_size" mapstructure:"check_batch_size" json:"check_batch_size,omitempty"`
MaxConcurrentJobs int `yaml:"max_concurrent_jobs" mapstructure:"max_concurrent_jobs" json:"max_concurrent_jobs,omitempty"`
SegmentSamplePercentage int `yaml:"segment_sample_percentage" mapstructure:"segment_sample_percentage" json:"segment_sample_percentage,omitempty"`
MaxRetries int `yaml:"max_retries" mapstructure:"max_retries" json:"max_retries"`
LibrarySyncIntervalMinutes int `` /* 128-byte string literal not displayed */
LibrarySyncConcurrency int `yaml:"library_sync_concurrency" mapstructure:"library_sync_concurrency" json:"library_sync_concurrency,omitempty"`
ResolveRepairOnImport *bool `yaml:"resolve_repair_on_import" mapstructure:"resolve_repair_on_import" json:"resolve_repair_on_import,omitempty"`
VerifyData *bool `yaml:"verify_data" mapstructure:"verify_data" json:"verify_data,omitempty"`
CheckAllSegments *bool `yaml:"check_all_segments" mapstructure:"check_all_segments" json:"check_all_segments,omitempty"`
ReadTimeoutSeconds int `yaml:"read_timeout_seconds" mapstructure:"read_timeout_seconds" json:"read_timeout_seconds,omitempty"`
AcceptableMissingSegmentsPercentage float64 `` /* 145-byte string literal not displayed */
// ExcludedCategories lists SABnzbd category names whose files must never be
// registered for health checking by the library-sync discovery pass. Matching
// is by the category's configured directory under CompleteDir and is
// case-insensitive. Empty means no categories are excluded.
ExcludedCategories []string `yaml:"excluded_categories" mapstructure:"excluded_categories" json:"excluded_categories,omitempty"`
Repair RepairConfig `yaml:"repair" mapstructure:"repair" json:"repair"`
// CorruptionAction controls what happens when the health checker or a streaming read
// confirms real (non-degraded) corruption: "repair" (default) triggers an Arr rescan;
// "delete" removes the file's metadata/NZB/health record and cleans up now-empty
// parent directories instead. Degraded files are never affected either way.
CorruptionAction string `yaml:"corruption_action" mapstructure:"corruption_action" json:"corruption_action,omitempty"`
}
HealthConfig represents health checker configuration
type IgnoredMessage ¶
type IgnoredMessage struct {
Message string `yaml:"message" mapstructure:"message" json:"message"`
Enabled bool `yaml:"enabled" mapstructure:"enabled" json:"enabled"`
}
IgnoredMessage represents an error message to ignore during queue cleanup
type ImportConfig ¶
type ImportConfig struct {
MaxProcessorWorkers int `yaml:"max_processor_workers" mapstructure:"max_processor_workers" json:"max_processor_workers"`
QueueProcessingIntervalSeconds int `` /* 130-byte string literal not displayed */
AllowedFileExtensions []string `yaml:"allowed_file_extensions" mapstructure:"allowed_file_extensions" json:"allowed_file_extensions"`
// MaxConcurrentImports caps the number of NZB imports that may run
// end-to-end at the same time. 0 = unlimited. NNTP connection use is
// balanced automatically: imports share the pool's full capacity and
// yield to streams (priority lane + adaptive connection budget).
MaxConcurrentImports int `yaml:"max_concurrent_imports" mapstructure:"max_concurrent_imports" json:"max_concurrent_imports"`
MaxDownloadPrefetch int `yaml:"max_download_prefetch" mapstructure:"max_download_prefetch" json:"max_download_prefetch"`
SegmentSamplePercentage int `yaml:"segment_sample_percentage" mapstructure:"segment_sample_percentage" json:"segment_sample_percentage"`
ReadTimeoutSeconds int `yaml:"read_timeout_seconds" mapstructure:"read_timeout_seconds" json:"read_timeout_seconds"`
IsoAnalyzeTimeoutSeconds *int `yaml:"iso_analyze_timeout_seconds" mapstructure:"iso_analyze_timeout_seconds" json:"iso_analyze_timeout_seconds,omitempty"`
ImportStrategy ImportStrategy `yaml:"import_strategy" mapstructure:"import_strategy" json:"import_strategy"`
ImportDir *string `yaml:"import_dir" mapstructure:"import_dir" json:"import_dir,omitempty"`
WatchDir *string `yaml:"watch_dir" mapstructure:"watch_dir" json:"watch_dir,omitempty"`
WatchIntervalSeconds *int `yaml:"watch_interval_seconds" mapstructure:"watch_interval_seconds" json:"watch_interval_seconds,omitempty"`
AllowNestedRarExtraction *bool `yaml:"allow_nested_rar_extraction" mapstructure:"allow_nested_rar_extraction" json:"allow_nested_rar_extraction,omitempty"`
ExpandBlurayIso *bool `yaml:"expand_bluray_iso" mapstructure:"expand_bluray_iso" json:"expand_bluray_iso,omitempty"`
RenameToNzbName *bool `yaml:"rename_to_nzb_name" mapstructure:"rename_to_nzb_name" json:"rename_to_nzb_name,omitempty"`
FilterSampleFiles *bool `yaml:"filter_sample_files" mapstructure:"filter_sample_files" json:"filter_sample_files,omitempty"`
FailedItemRetentionHours *int `yaml:"failed_item_retention_hours" mapstructure:"failed_item_retention_hours" json:"failed_item_retention_hours,omitempty"`
HistoryRetentionDays *int `yaml:"history_retention_days" mapstructure:"history_retention_days" json:"history_retention_days,omitempty"`
// DamagePolicy governs standalone video files whose fast-fail sweep finds
// SMALL confirmed damage (within the playback padding caps, see
// internal/holes): "tolerant" (default) imports them as degraded so
// streaming zero-fills the gaps; "strict" fails the import so an ARR can
// grab a different release. Damage beyond the caps, archive-set members
// and non-video files fail either way.
DamagePolicy string `yaml:"damage_policy" mapstructure:"damage_policy" json:"damage_policy,omitempty"`
}
ImportConfig represents import processing configuration
type ImportStrategy ¶
type ImportStrategy string
ImportStrategy represents the import strategy type
const ( ImportStrategyNone ImportStrategy = "NONE" ImportStrategySYMLINK ImportStrategy = "SYMLINK" ImportStrategySTRM ImportStrategy = "STRM" )
type LogConfig ¶
type LogConfig struct {
File string `yaml:"file" mapstructure:"file" json:"file,omitempty"` // Log file path (empty = console only)
Level string `yaml:"level" mapstructure:"level" json:"level,omitempty"` // Log level (debug, info, warn, error)
MaxSize int `yaml:"max_size" mapstructure:"max_size" json:"max_size,omitempty"` // Max size in MB before rotation
MaxAge int `yaml:"max_age" mapstructure:"max_age" json:"max_age,omitempty"` // Max age in days to keep files
MaxBackups int `yaml:"max_backups" mapstructure:"max_backups" json:"max_backups,omitempty"` // Max number of old files to keep
Compress bool `yaml:"compress" mapstructure:"compress" json:"compress,omitempty"` // Compress old log files
}
LogConfig represents logging configuration with rotation support
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager manages configuration state and persistence
func NewManager ¶
NewManager creates a new configuration manager
func (*Manager) ClearLibrarySyncFlag ¶
func (m *Manager) ClearLibrarySyncFlag()
ClearLibrarySyncFlag clears the library sync needed flag
func (*Manager) GetConfigGetter ¶
func (m *Manager) GetConfigGetter() ConfigGetter
GetConfigGetter returns a function that provides the current configuration
func (*Manager) GetPreviousMountPath ¶
GetPreviousMountPath returns the previous mount path before the last change
func (*Manager) NeedsLibrarySync ¶
NeedsLibrarySync returns whether a library sync is needed due to configuration changes
func (*Manager) OnConfigChange ¶
func (m *Manager) OnConfigChange(callback ChangeCallback)
OnConfigChange registers a callback to be called when configuration changes
func (*Manager) ReloadConfig ¶
ReloadConfig reloads configuration from file
func (*Manager) SaveConfig ¶
SaveConfig saves the current configuration to file
func (*Manager) UpdateConfig ¶
UpdateConfig updates the current configuration (thread-safe)
func (*Manager) ValidateConfig ¶
ValidateConfig validates the configuration using existing validation logic
func (*Manager) ValidateConfigUpdate ¶
ValidateConfigUpdate validates configuration updates with additional restrictions
type MetadataBackupConfig ¶
type MetadataBackupConfig struct {
Enabled *bool `yaml:"enabled" mapstructure:"enabled" json:"enabled"`
Schedule string `yaml:"schedule" mapstructure:"schedule" json:"schedule"` // cron expression (UTC)
KeepBackups int `yaml:"keep_backups" mapstructure:"keep_backups" json:"keep_backups"`
Path string `yaml:"path" mapstructure:"path" json:"path"`
}
MetadataBackupConfig represents metadata backup configuration
type MetadataConfig ¶
type MetadataConfig struct {
RootPath string `yaml:"root_path" mapstructure:"root_path" json:"root_path"`
DeleteSourceNzbOnRemoval *bool `yaml:"delete_source_nzb_on_removal" mapstructure:"delete_source_nzb_on_removal" json:"delete_source_nzb_on_removal,omitempty"`
Backup MetadataBackupConfig `yaml:"backup" mapstructure:"backup" json:"backup"`
}
MetadataConfig represents metadata filesystem configuration
func (MetadataConfig) ShouldDeleteSourceNzb ¶
func (m MetadataConfig) ShouldDeleteSourceNzb() bool
ShouldDeleteSourceNzb returns whether source NZB files should be deleted on removal.
type NetworkConfig ¶ added in v0.3.0
type NetworkConfig struct {
HTTPProxy string `yaml:"http_proxy" mapstructure:"http_proxy" json:"http_proxy,omitempty"`
HTTPSProxy string `yaml:"https_proxy" mapstructure:"https_proxy" json:"https_proxy,omitempty"`
NoProxy string `yaml:"no_proxy" mapstructure:"no_proxy" json:"no_proxy,omitempty"`
}
NetworkConfig holds outbound HTTP routing options applied to every external client (indexers, arrs, SABnzbd fallback, NZBLNK resolver). Internal endpoints (RC server, self-loopback) are unaffected.
Semantics mirror Go's standard HTTP_PROXY/HTTPS_PROXY/NO_PROXY env vars. Empty strings disable proxying for that scheme.
func (NetworkConfig) GetHTTPProxy ¶ added in v0.3.0
func (n NetworkConfig) GetHTTPProxy() string
GetHTTPProxy returns the configured HTTP proxy URL. Implements the httpclient.NetworkProxyConfig interface to avoid config↔httpclient import cycles.
func (NetworkConfig) GetHTTPSProxy ¶ added in v0.3.0
func (n NetworkConfig) GetHTTPSProxy() string
GetHTTPSProxy returns the configured HTTPS proxy URL.
func (NetworkConfig) GetNoProxy ¶ added in v0.3.0
func (n NetworkConfig) GetNoProxy() string
GetNoProxy returns the comma-separated bypass list.
type NzblnkConfig ¶ added in v0.3.0
type NzblnkConfig struct {
// UserAgent is the HTTP User-Agent sent to indexers when resolving nzblnk:// links.
// Defaults to a browser-like string. Leave empty to use the default.
UserAgent string `yaml:"user_agent" mapstructure:"user_agent" json:"user_agent,omitempty"`
}
NzblnkConfig configures the NZBLNK resolver (used for nzblnk:// link resolution via public indexers).
type ProviderChange ¶
type ProviderChange struct {
Type ProviderChangeType
ProviderID string
OldProvider *ProviderConfig // nil for Added
NewProvider *ProviderConfig // nil for Removed
}
ProviderChange describes a single provider change between two configurations.
type ProviderChangeType ¶
type ProviderChangeType int
ProviderChangeType describes the kind of provider change detected by ProvidersDiff.
const ( ProviderAdded ProviderChangeType = iota ProviderRemoved ProviderModified )
type ProviderConfig ¶
type ProviderConfig struct {
ID string `yaml:"id" mapstructure:"id" json:"id"`
Name string `yaml:"name" mapstructure:"name" json:"name,omitempty"`
Host string `yaml:"host" mapstructure:"host" json:"host"`
Port int `yaml:"port" mapstructure:"port" json:"port"`
Username string `yaml:"username" mapstructure:"username" json:"username"`
Password string `yaml:"password" mapstructure:"password" json:"-"`
MaxConnections int `yaml:"max_connections" mapstructure:"max_connections" json:"max_connections"`
InflightRequests int `yaml:"inflight_requests" mapstructure:"inflight_requests" json:"inflight_requests"`
StatInflightRequests int `yaml:"stat_inflight_requests" mapstructure:"stat_inflight_requests" json:"stat_inflight_requests"`
TLS bool `yaml:"tls" mapstructure:"tls" json:"tls"`
InsecureTLS bool `yaml:"insecure_tls" mapstructure:"insecure_tls" json:"insecure_tls"`
ProxyURL string `yaml:"proxy_url" mapstructure:"proxy_url" json:"proxy_url,omitempty"`
Enabled *bool `yaml:"enabled" mapstructure:"enabled" json:"enabled,omitempty"`
IsBackupProvider *bool `yaml:"is_backup_provider" mapstructure:"is_backup_provider" json:"is_backup_provider,omitempty"`
SkipPing bool `yaml:"skip_ping" mapstructure:"skip_ping" json:"skip_ping,omitempty"`
KeepaliveIntervalSeconds int `yaml:"keepalive_interval_seconds" mapstructure:"keepalive_interval_seconds" json:"keepalive_interval_seconds,omitempty"`
KeepaliveCommand string `yaml:"keepalive_command" mapstructure:"keepalive_command" json:"keepalive_command,omitempty"`
UserAgent string `yaml:"user_agent" mapstructure:"user_agent" json:"user_agent,omitempty"`
QuotaBytes int64 `yaml:"quota_bytes" mapstructure:"quota_bytes" json:"quota_bytes,omitempty"`
QuotaPeriodHours int `yaml:"quota_period_hours" mapstructure:"quota_period_hours" json:"quota_period_hours,omitempty"`
LastRTTMs int64 `yaml:"last_rtt_ms" mapstructure:"last_rtt_ms" json:"last_rtt_ms,omitempty"`
LastSpeedTestMbps float64 `yaml:"last_speed_test_mbps" mapstructure:"last_speed_test_mbps" json:"last_speed_test_mbps,omitempty"`
LastSpeedTestTime *time.Time `yaml:"last_speed_test_time" mapstructure:"last_speed_test_time" json:"last_speed_test_time,omitempty"`
AccountExpirationDate string `yaml:"account_expiration_date" mapstructure:"account_expiration_date" json:"account_expiration_date,omitempty"`
}
ProviderConfig represents a single NNTP provider configuration
func (*ProviderConfig) NNTPPoolName ¶
func (p *ProviderConfig) NNTPPoolName() string
NNTPPoolName returns the name nntppool v4 uses to identify this provider. Format: "host:port" or "host:port+username" when username is set.
func (*ProviderConfig) ToNNTPProvider ¶
func (p *ProviderConfig) ToNNTPProvider() nntppool.Provider
ToNNTPProvider converts a single ProviderConfig to an nntppool.Provider. Does not check the Enabled flag — caller is responsible for that.
type ProwlarrConfig ¶
type ProwlarrConfig struct {
// Enabled controls whether Prowlarr search is active for the Stremio addon.
Enabled *bool `yaml:"enabled" mapstructure:"enabled" json:"enabled"`
// Host is the Prowlarr base URL (e.g. "http://localhost:9696").
Host string `yaml:"host" mapstructure:"host" json:"host,omitempty"`
// APIKey is the Prowlarr API key.
APIKey string `yaml:"api_key" mapstructure:"api_key" json:"api_key,omitempty"`
// Categories filters search results by Newznab category IDs.
// Defaults to 5000 (Movies), 5010 (Movies/Foreign), 5030 (TV), 5040 (TV/HD).
Categories []int `yaml:"categories" mapstructure:"categories" json:"categories,omitempty"`
// Languages is an optional list of keywords; releases must contain at least one to pass.
// Empty = no filtering. Examples: ["Esp", "🇪🇸", "Spanish", "DUAL"]
Languages []string `yaml:"languages" mapstructure:"languages" json:"languages,omitempty"`
// Qualities is an optional list of keywords; releases must contain at least one to pass.
// Empty = no filtering. Examples: ["1080p", "HD", "4K", "3D"]
Qualities []string `yaml:"qualities" mapstructure:"qualities" json:"qualities,omitempty"`
}
ProwlarrConfig configures the Prowlarr indexer integration for Stremio addon searches.
type RCloneConfig ¶
type RCloneConfig struct {
// RClone Path
Path string `yaml:"path" mapstructure:"path" json:"path"`
// Encryption
Password string `yaml:"password" mapstructure:"password" json:"-"`
Salt string `yaml:"salt" mapstructure:"salt" json:"-"`
// RC (Remote Control) Configuration
RCEnabled *bool `yaml:"rc_enabled" mapstructure:"rc_enabled" json:"rc_enabled"`
RCUrl string `yaml:"rc_url" mapstructure:"rc_url" json:"rc_url"`
RCPort int `yaml:"rc_port" mapstructure:"rc_port" json:"rc_port"`
RCUser string `yaml:"rc_user" mapstructure:"rc_user" json:"rc_user"`
RCPass string `yaml:"rc_pass" mapstructure:"rc_pass" json:"rc_pass,omitempty"`
RCOptions map[string]string `yaml:"rc_options" mapstructure:"rc_options" json:"rc_options"`
// Mount Configuration
MountEnabled *bool `yaml:"mount_enabled" mapstructure:"mount_enabled" json:"mount_enabled"`
VFSName string `yaml:"vfs_name" mapstructure:"vfs_name" json:"vfs_name"`
MountOptions map[string]string `yaml:"mount_options" mapstructure:"mount_options" json:"mount_options"`
LogLevel string `yaml:"log_level" mapstructure:"log_level" json:"log_level"`
UID int `yaml:"uid" mapstructure:"uid" json:"uid"`
GID int `yaml:"gid" mapstructure:"gid" json:"gid"`
Umask string `yaml:"umask" mapstructure:"umask" json:"umask"`
BufferSize string `yaml:"buffer_size" mapstructure:"buffer_size" json:"buffer_size"`
AttrTimeout string `yaml:"attr_timeout" mapstructure:"attr_timeout" json:"attr_timeout"`
Transfers int `yaml:"transfers" mapstructure:"transfers" json:"transfers"`
// VFS Cache Settings
CacheDir string `yaml:"cache_dir" mapstructure:"cache_dir" json:"cache_dir"`
VFSCacheMode string `yaml:"vfs_cache_mode" mapstructure:"vfs_cache_mode" json:"vfs_cache_mode"`
VFSCachePollInterval string `yaml:"vfs_cache_poll_interval" mapstructure:"vfs_cache_poll_interval" json:"vfs_cache_poll_interval"`
VFSReadChunkSize string `yaml:"vfs_read_chunk_size" mapstructure:"vfs_read_chunk_size" json:"vfs_read_chunk_size"`
VFSReadChunkSizeLimit string `yaml:"vfs_read_chunk_size_limit" mapstructure:"vfs_read_chunk_size_limit" json:"vfs_read_chunk_size_limit"`
VFSCacheMaxSize string `yaml:"vfs_cache_max_size" mapstructure:"vfs_cache_max_size" json:"vfs_cache_max_size"`
VFSCacheMaxAge string `yaml:"vfs_cache_max_age" mapstructure:"vfs_cache_max_age" json:"vfs_cache_max_age"`
VFSReadAhead string `yaml:"vfs_read_ahead" mapstructure:"vfs_read_ahead" json:"vfs_read_ahead"`
DirCacheTime string `yaml:"dir_cache_time" mapstructure:"dir_cache_time" json:"dir_cache_time"`
VFSCacheMinFreeSpace string `yaml:"vfs_cache_min_free_space" mapstructure:"vfs_cache_min_free_space" json:"vfs_cache_min_free_space"`
VFSDiskSpaceTotal string `yaml:"vfs_disk_space_total" mapstructure:"vfs_disk_space_total" json:"vfs_disk_space_total"`
VFSReadChunkStreams int `yaml:"vfs_read_chunk_streams" mapstructure:"vfs_read_chunk_streams" json:"vfs_read_chunk_streams"`
// Mount-Specific Settings
AllowOther bool `yaml:"allow_other" mapstructure:"allow_other" json:"allow_other"`
AllowNonEmpty bool `yaml:"allow_non_empty" mapstructure:"allow_non_empty" json:"allow_non_empty"`
ReadOnly bool `yaml:"read_only" mapstructure:"read_only" json:"read_only"`
Timeout string `yaml:"timeout" mapstructure:"timeout" json:"timeout"`
Syslog bool `yaml:"syslog" mapstructure:"syslog" json:"syslog"`
// Advanced Settings
NoModTime bool `yaml:"no_mod_time" mapstructure:"no_mod_time" json:"no_mod_time"`
NoChecksum bool `yaml:"no_checksum" mapstructure:"no_checksum" json:"no_checksum"`
AsyncRead bool `yaml:"async_read" mapstructure:"async_read" json:"async_read"`
VFSFastFingerprint bool `yaml:"vfs_fast_fingerprint" mapstructure:"vfs_fast_fingerprint" json:"vfs_fast_fingerprint"`
UseMmap bool `yaml:"use_mmap" mapstructure:"use_mmap" json:"use_mmap"`
Links bool `yaml:"links" mapstructure:"links" json:"links"`
}
RCloneConfig represents rclone configuration
type RepairConfig ¶
type RepairConfig struct {
Enabled *bool `yaml:"enabled" mapstructure:"enabled" json:"enabled,omitempty"`
IntervalMinutes int `yaml:"interval_minutes" mapstructure:"interval_minutes" json:"interval_minutes,omitempty"`
MaxCoolDownHours int `yaml:"max_cooldown_hours" mapstructure:"max_cooldown_hours" json:"max_cooldown_hours,omitempty"`
MaxRepairRetries int `yaml:"max_repair_retries" mapstructure:"max_repair_retries" json:"max_repair_retries"`
ExponentialBackoff *bool `yaml:"exponential_backoff" mapstructure:"exponential_backoff" json:"exponential_backoff,omitempty"`
}
RepairConfig represents repair behavior configuration
type SABnzbdCategory ¶
type SABnzbdCategory struct {
Name string `yaml:"name" mapstructure:"name" json:"name"`
Order int `yaml:"order" mapstructure:"order" json:"order"`
Priority int `yaml:"priority" mapstructure:"priority" json:"priority"`
Dir string `yaml:"dir" mapstructure:"dir" json:"dir"`
Type string `yaml:"type" mapstructure:"type" json:"type"` // "sonarr" or "radarr"
}
SABnzbdCategory represents a SABnzbd category configuration
type SABnzbdConfig ¶
type SABnzbdConfig struct {
Enabled *bool `yaml:"enabled" mapstructure:"enabled" json:"enabled"`
CompleteDir string `yaml:"complete_dir" mapstructure:"complete_dir" json:"complete_dir"`
DownloadClientBaseURL string `yaml:"download_client_base_url" mapstructure:"download_client_base_url" json:"download_client_base_url,omitempty"`
Categories []SABnzbdCategory `yaml:"categories" mapstructure:"categories" json:"categories"`
// HistoryRetentionMinutes controls how far back the SABnzbd-emulating history
// endpoint looks into import_history when *arr clients poll without a specific
// nzo_id filter. Older entries are still returned when *arr asks for them by
// nzo_id. Defaults to 10080 (7 days).
HistoryRetentionMinutes int `yaml:"history_retention_minutes" mapstructure:"history_retention_minutes" json:"history_retention_minutes,omitempty"`
// Fallback configuration for sending failed imports to external SABnzbd
FallbackHost string `yaml:"fallback_host" mapstructure:"fallback_host" json:"fallback_host"`
FallbackAPIKey string `yaml:"fallback_api_key" mapstructure:"fallback_api_key" json:"fallback_api_key"` // Masked in API responses
}
SABnzbdConfig represents SABnzbd-compatible API configuration
type SegmentCacheConfig ¶
type SegmentCacheConfig struct {
Enabled *bool `yaml:"enabled" mapstructure:"enabled" json:"enabled"`
CachePath string `yaml:"cache_path" mapstructure:"cache_path" json:"cache_path"`
MaxSizeGB int `yaml:"max_size_gb" mapstructure:"max_size_gb" json:"max_size_gb"`
ExpiryHours int `yaml:"expiry_hours" mapstructure:"expiry_hours" json:"expiry_hours"`
}
SegmentCacheConfig configures the segment-aligned disk cache shared by FUSE and WebDAV. When enabled, this cache replaces the FUSE VFS disk cache and additionally benefits WebDAV. Cache key: Usenet message ID. Cache unit: ~750KB decoded segment (matches one NNTP article).
type StreamingConfig ¶
type StreamingConfig struct {
MaxPrefetch int `yaml:"max_prefetch" mapstructure:"max_prefetch" json:"max_prefetch"`
FailureMasking FailureMaskingConfig `yaml:"failure_masking" mapstructure:"failure_masking" json:"failure_masking"`
}
StreamingConfig represents streaming and chunking configuration
type StremioConfig ¶
type StremioConfig struct {
// Enabled controls whether the endpoint is active. Disabled by default.
// When false, the endpoint returns 404 Not Found.
Enabled *bool `yaml:"enabled" mapstructure:"enabled" json:"enabled"`
// NzbTTLHours controls how long a completed NZB result is cached before
// the same NZB is re-processed on the next request.
// Set to 0 to disable expiry (cache forever). Defaults to 24 hours.
NzbTTLHours int `yaml:"nzb_ttl_hours" mapstructure:"nzb_ttl_hours" json:"nzb_ttl_hours,omitempty"`
// BaseURL is the public base URL used when building Stremio stream links
// (e.g. "https://altmount.example.com"). Falls back to the auto-detected
// request origin when not set.
BaseURL string `yaml:"base_url" mapstructure:"base_url" json:"base_url,omitempty"`
// Prowlarr configures the Prowlarr indexer used by the Stremio addon to search for NZBs.
Prowlarr ProwlarrConfig `yaml:"prowlarr" mapstructure:"prowlarr" json:"prowlarr"`
}
StremioConfig configures the Stremio NZB stream endpoint (POST /api/nzb/streams).
type StuckCleanupRule ¶ added in v0.3.0
type StuckCleanupRule struct {
Message string `yaml:"message" mapstructure:"message" json:"message"`
Enabled bool `yaml:"enabled" mapstructure:"enabled" json:"enabled"`
Action string `yaml:"action" mapstructure:"action" json:"action"`
}
StuckCleanupRule matches a stuck-import status message and decides the action (one of StuckActionRemove, StuckActionBlocklist, StuckActionBlocklistSearch).
type WebDAVConfig ¶
type WebDAVConfig struct {
Port int `yaml:"port" mapstructure:"port" json:"port"`
User string `yaml:"user" mapstructure:"user" json:"user"`
Password string `yaml:"password" mapstructure:"password" json:"password"`
Host string `yaml:"host" mapstructure:"host" json:"host,omitempty"`
}
WebDAVConfig represents WebDAV server configuration