models

package
v1.32.0 Latest Latest
Warning

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

Go to latest
Published: Oct 13, 2026 License: GPL-2.0 Imports: 33 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DeleteModeNone                        = "none"
	DeleteModeKeepFiles                   = "delete"
	DeleteModeWithFiles                   = "deleteWithFiles"
	DeleteModeWithFilesPreserveCrossSeeds = "deleteWithFilesPreserveCrossSeeds"
	DeleteModeWithFilesIncludeCrossSeeds  = "deleteWithFilesIncludeCrossSeeds"
)

Delete mode constants

View Source
const (
	TagModeFull   = "full"   // Add to matches, remove from non-matches
	TagModeAdd    = "add"    // Only add to matches
	TagModeRemove = "remove" // Only remove from matches
)

Tag mode constants

View Source
const (
	HardlinkScopeNone               = "none"                // No file has link count > 1
	HardlinkScopeTorrentsOnly       = "torrents_only"       // Links exist only between torrents in the set
	HardlinkScopeOutsideQBitTorrent = "outside_qbittorrent" // Links outside the torrent set (stored: outside only; condition: also matches "both")
	HardlinkScopeBoth               = "both"                // Links both inside and outside the torrent set
	HardlinkScopeInsideQBitTorrent  = "inside_qbittorrent"  // Condition-only: linked to other torrents, even if also outside (#1177)
)

Hardlink scope values (wire format - stable API values). The stored per-torrent scope is one of none/torrents_only/outside_qbittorrent/both, a partition of the two independent facts "linked inside the torrent set" and "linked outside it". As condition values, outside_qbittorrent also matches "both" (its historical meaning), and inside_qbittorrent matches torrents_only or "both".

View Source
const (
	SeasonPackStatusPack     = "pack"     // A whole single season
	SeasonPackStatusPacked   = "packed"   // An episode whose season pack of the same release is in the client
	SeasonPackStatusUnpacked = "unpacked" // An episode with no such pack
)

Season pack status values. Empty when the name parses without exactly one season.

View Source
const (
	ActivityActionDeletedRatio        = "deleted_ratio"
	ActivityActionDeletedSeeding      = "deleted_seeding"
	ActivityActionDeletedUnregistered = "deleted_unregistered"
	ActivityActionDeletedCondition    = "deleted_condition" // Expression-based deletion
	ActivityActionDeleteFailed        = "delete_failed"
	ActivityActionLimitFailed         = "limit_failed"
	ActivityActionTagsChanged         = "tags_changed"         // Batch tag operation
	ActivityActionCategoryChanged     = "category_changed"     // Batch category operation
	ActivityActionSpeedLimitsChanged  = "speed_limits_changed" // Batch speed limit operation
	ActivityActionShareLimitsChanged  = "share_limits_changed" // Batch share limit operation
	ActivityActionPaused              = "paused"               // Batch pause operation
	ActivityActionResumed             = "resumed"              // Batch resume operation
	ActivityActionRechecked           = "rechecked"            // Batch force recheck operation
	ActivityActionReannounced         = "reannounced"          // Batch force reannounce operation
	ActivityActionMoved               = "moved"                // Batch move operation
	ActivityActionAutoManaged         = "auto_managed"         // Batch auto management operation
	ActivityActionExportedToInstance  = "exported_to_instance" // Export torrent to another instance
	ActivityActionDryRunNoMatch       = "dry_run_no_match"     // Manual dry-run completed with no matching actions
)

Activity action types

View Source
const (
	ActivityOutcomeSuccess = "success"
	ActivityOutcomeFailed  = "failed"
	ActivityOutcomeDryRun  = "dry-run"
)

Activity outcome types

View Source
const (
	CategoryAffixModePrefix = "prefix"
	CategoryAffixModeSuffix = "suffix"
)

Category affix mode constants.

View Source
const (
	CrossSeedPartialPoolStatusActive  = "active"
	CrossSeedPartialPoolStatusDormant = "dormant"

	CrossSeedPartialPoolModeHardlink = "hardlink"
	CrossSeedPartialPoolModeReflink  = "reflink"

	CrossSeedPartialPoolMemberStatusVerifying  = "verifying"
	CrossSeedPartialPoolMemberStatusWaiting    = "waiting"
	CrossSeedPartialPoolMemberStatusBlocked    = "blocked"
	CrossSeedPartialPoolMemberStatusAcquiring  = "acquiring"
	CrossSeedPartialPoolMemberStatusRechecking = "rechecking"
	CrossSeedPartialPoolMemberStatusComplete   = "complete"
	CrossSeedPartialPoolMemberStatusManual     = "manual"
	CrossSeedPartialPoolMemberStatusRemoved    = "removed"

	CrossSeedPartialPoolFileStatusPresent     = "present"
	CrossSeedPartialPoolFileStatusMissing     = "missing"
	CrossSeedPartialPoolFileStatusAcquiring   = "acquiring"
	CrossSeedPartialPoolFileStatusAvailable   = "available"
	CrossSeedPartialPoolFileStatusPropagating = "propagating"
	CrossSeedPartialPoolFileStatusVerifying   = "verifying"
	CrossSeedPartialPoolFileStatusVerified    = "verified"
	CrossSeedPartialPoolFileStatusManual      = "manual"

	CrossSeedPartialPoolRecheckPending   = "partial pool recheck pending"
	CrossSeedPartialPoolRecheckRequested = "partial pool recheck requested"
)

These constants define persisted partial pool modes, states, and coordination markers.

View Source
const (
	DiscScanStatusPending   = "pending"
	DiscScanStatusScanning  = "scanning"
	DiscScanStatusCompleted = "completed"
	DiscScanStatusFailed    = "failed"
	DiscScanStatusCanceled  = "canceled"
)

Disc scan statuses.

View Source
const (
	ErrorTypeConnection     = "connection"
	ErrorTypeAuthentication = "authentication"
	ErrorTypeBan            = "ban"
	ErrorTypeAPI            = "api"
)

Error types for categorization

View Source
const (
	LicenseStatusActive  = "active"
	LicenseStatusInvalid = "invalid"
)

LicenseStatus constants

View Source
const (
	ThemeSlotDefault = "default"
	ThemeSlotMobile  = "mobile"
)
View Source
const DefaultAutoResumeMaxDownloadMB = 50

DefaultAutoResumeMaxDownloadMB is the default auto-resume budget for new cross-seed additions: resume only when missing data is 50 MiB or less.

View Source
const (
	LicenseProviderDodo = "dodo"
)

LicenseProvider constants

View Source
const MaxCompletionDelaySeconds = 600

MaxCompletionDelaySeconds caps the per-instance completion delay (10 minutes).

Variables

View Source
var (
	ErrSSHHostKeyNotPinned     = errors.New("ssh host key is not pinned")
	ErrSSHEndpointChanged      = errors.New("ssh endpoint changed while pinning the host key")
	ErrSSHHostKeyAlreadyPinned = errors.New("ssh host key is already pinned")
	ErrSSHKeyNotConfigured     = errors.New("ssh private key is not configured")
	// ErrInvalidSSHCredentials marks what the submitter can fix, so a caller can
	// tell it apart from the cipher and database faults SetSSHCredentials also
	// returns and which are nobody's to act on.
	ErrInvalidSSHCredentials = errors.New("invalid ssh credentials")
)
View Source
var (
	ErrTorznabIndexerNotFound   = errors.New("torznab indexer not found")
	ErrTorznabIndexerIDRequired = errors.New("indexer_id is required for prowlarr backends")
)
View Source
var DefaultSectionOrder = []string{"server-stats", "tracker-breakdown", "global-stats", "instances"}

Default section order

View Source
var DefaultSectionVisibility = map[string]bool{
	"server-stats":      true,
	"tracker-breakdown": true,
	"global-stats":      true,
	"instances":         true,
}

Default section visibility (all visible)

View Source
var ErrAPIKeyNotFound = errors.New("api key not found")
View Source
var (
	ErrArrInstanceNotFound = errors.New("arr instance not found")
)
View Source
var (
	// ErrBasicAuthPasswordRequired is returned when a basic auth username is provided but the password is missing.
	ErrBasicAuthPasswordRequired = errors.New("basic_password is required when basic auth is enabled")
)
View Source
var ErrClientAPIKeyNotFound = errors.New("client api key not found")
View Source
var ErrDirScanRunAlreadyActive = errors.New("an active scan run already exists for this directory")

ErrDirScanRunAlreadyActive is returned when attempting to create a run while one is active.

View Source
var ErrDirectoryNotFound = errors.New("directory not found")

ErrDirectoryNotFound is returned when a directory is not found.

View Source
var ErrDuplicateDirScanDirectoryPath = errors.New("duplicate dir scan directory path")

ErrDuplicateDirScanDirectoryPath is returned when another directory already uses the same cleaned path.

View Source
var ErrDuplicateFilterViewName = errors.New("duplicate filter view name")

ErrDuplicateFilterViewName is returned when a user already has a view with the same name.

View Source
var ErrExternalProgramNotFound = errors.New("external program not found")
View Source
var ErrInstanceNotFound = errors.New("instance not found")
View Source
var ErrInvalidAPIKey = errors.New("invalid api key")
View Source
var (
	ErrLicenseNotFound = errors.New("license not found")
)
View Source
var ErrNotificationTargetNotFound = errors.New("notification target not found")
View Source
var ErrRunAlreadyActive = errors.New("an active run already exists for this instance")

ErrRunAlreadyActive is returned when attempting to create a run while one is already active.

View Source
var ErrUserAlreadyExists = errors.New("user already exists")
View Source
var ErrUserNotFound = errors.New("user not found")

Functions

func BoolToSQLite added in v1.10.0

func BoolToSQLite(v bool) int

BoolToSQLite converts a bool to SQLite integer representation (0 or 1).

func ComputeTitleHash added in v1.12.0

func ComputeTitleHash(title string) string

ComputeTitleHash computes a SHA256 hash of the normalized title for cache lookup

func DecodeStringSliceJSON added in v1.10.0

func DecodeStringSliceJSON(raw sql.NullString) ([]string, error)

DecodeStringSliceJSON unmarshals a JSON string to a sanitized string slice. Returns an empty slice for NULL or empty database values.

func EncodeStringSliceJSON added in v1.10.0

func EncodeStringSliceJSON(values []string) (string, error)

EncodeStringSliceJSON marshals a string slice to JSON. Returns "[]" for empty/nil slices.

func GenerateAPIKey

func GenerateAPIKey() (string, error)

GenerateAPIKey generates a new API key

func HashAPIKey

func HashAPIKey(key string) string

HashAPIKey creates a SHA256 hash of the API key

func ResolveTrackerDisplayName added in v1.12.0

func ResolveTrackerDisplayName(domain string, indexerName string, customizations []*TrackerCustomization) string

ResolveTrackerDisplayName resolves a tracker domain to its display name using customizations. Fallback chain: customization display name → indexerName → domain.

The domain should be extracted from the tracker announce URL (lowercase, no port). indexerName is typically from the cross-seed request and serves as a fallback.

func SQLiteIntToBool added in v1.15.0

func SQLiteIntToBool(v int) bool

SQLiteIntToBool converts SQLite/Postgres integer-backed boolean columns to bool.

func SanitizeCommaSeparatedStringSlice added in v1.13.0

func SanitizeCommaSeparatedStringSlice(values []string) []string

SanitizeCommaSeparatedStringSlice splits values on comma, trims whitespace, removes empty strings, lowercases entries, and deduplicates case-insensitively.

func SanitizeStringSlice added in v1.10.0

func SanitizeStringSlice(values []string) []string

SanitizeStringSlice trims whitespace, removes empty strings, and deduplicates case-insensitively. Original casing is preserved for the first occurrence of each unique value.

Types

type APIKey

type APIKey struct {
	ID         int        `json:"id"`
	KeyHash    string     `json:"-"`
	Name       string     `json:"name"`
	CreatedAt  time.Time  `json:"createdAt"`
	LastUsedAt *time.Time `json:"lastUsedAt,omitempty"`
}

type APIKeyStore

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

func NewAPIKeyStore

func NewAPIKeyStore(db dbinterface.Querier) *APIKeyStore

func (*APIKeyStore) Create

func (s *APIKeyStore) Create(ctx context.Context, name string) (string, *APIKey, error)

func (*APIKeyStore) Delete

func (s *APIKeyStore) Delete(ctx context.Context, id int) error

func (*APIKeyStore) GetByHash

func (s *APIKeyStore) GetByHash(ctx context.Context, keyHash string) (*APIKey, error)

func (*APIKeyStore) List

func (s *APIKeyStore) List(ctx context.Context) ([]*APIKey, error)

func (*APIKeyStore) UpdateLastUsed

func (s *APIKeyStore) UpdateLastUsed(ctx context.Context, id int) error

func (*APIKeyStore) ValidateAPIKey

func (s *APIKeyStore) ValidateAPIKey(ctx context.Context, rawKey string) (*APIKey, error)

ValidateAPIKey validates a raw API key and returns the associated APIKey if valid

type ActionCondition added in v1.31.0

type ActionCondition struct {
	Path      string // JSON pointer to the condition, for example "/conditions/move/condition"
	Enabled   bool
	Condition *RuleCondition
}

ActionCondition is one configured action's condition, as ActionConditions.Conditions yields it.

type ActionConditions added in v1.12.0

type ActionConditions struct {
	SchemaVersion    string                  `json:"schemaVersion" doc:"Must be '1'."`
	Grouping         *GroupingConfig         `json:"grouping,omitempty" doc:"Group definitions for group-aware actions and conditions."`
	SpeedLimits      *SpeedLimitAction       `json:"speedLimits,omitempty" doc:"Set upload and download speed limits."`
	ShareLimits      *ShareLimitsAction      `json:"shareLimits,omitempty" doc:"Set ratio and seeding time limits."`
	Pause            *PauseAction            `json:"pause,omitempty" doc:"Pause matching torrents."`
	Resume           *ResumeAction           `json:"resume,omitempty" doc:"Resume matching torrents."`
	Recheck          *RecheckAction          `json:"recheck,omitempty" doc:"Force a recheck of matching torrents."`
	Reannounce       *ReannounceAction       `json:"reannounce,omitempty" doc:"Force a reannounce of matching torrents."`
	Delete           *DeleteAction           `json:"delete,omitempty" doc:"Delete matching torrents. A rule with 'delete' has no other action."`
	Tag              *TagAction              `json:"tag,omitempty" doc:"-"` // Legacy single-tag action (backward compatible alias for first entry in Tags)
	Tags             []*TagAction            `json:"tags,omitempty" doc:"Tag actions. Each entry manages its own set of tags."`
	Category         *CategoryAction         `json:"category,omitempty" doc:"Set the category of matching torrents."`
	Move             *MoveAction             `json:"move,omitempty" doc:"Move matching torrents to a different save path."`
	ExternalProgram  *ExternalProgramAction  `json:"externalProgram,omitempty" doc:"Run an external program for each matching torrent."`
	AutoManagement   *AutoManagementAction   `json:"autoManagement,omitempty" doc:"Turn automatic torrent management on or off."`
	ExportToInstance *ExportToInstanceAction `json:"exportToInstance,omitempty" doc:"Add matching torrents to a different qBittorrent instance."`
}

ActionConditions holds per-action conditions with action configuration. This is the top-level structure stored in the `conditions` JSON column.

func (*ActionConditions) Conditions added in v1.31.0

func (ac *ActionConditions) Conditions() iter.Seq[ActionCondition]

Conditions yields every configured action with its condition, which can be nil. Each caller decides whether a disabled action counts. An AutoManagement action counts as enabled whenever it exists, because its Enabled field is the ATM value that it sets.

func (*ActionConditions) IsEmpty added in v1.12.0

func (ac *ActionConditions) IsEmpty() bool

IsEmpty returns true if no actions are configured.

func (*ActionConditions) Normalize added in v1.14.0

func (ac *ActionConditions) Normalize()

Normalize normalizes legacy/new action fields for in-memory use.

func (*ActionConditions) TagActions added in v1.14.0

func (ac *ActionConditions) TagActions() []*TagAction

TagActions returns all configured tag actions (multi-tag aware).

type ArrIDCacheEntry added in v1.12.0

type ArrIDCacheEntry struct {
	ID            int64       `json:"id"`
	TitleHash     string      `json:"title_hash"`
	ContentType   string      `json:"content_type"`
	ArrInstanceID *int        `json:"arr_instance_id,omitempty"`
	ExternalIDs   ExternalIDs `json:"external_ids"`
	Titles        []string    `json:"titles,omitempty"`
	HasTitles     bool        `json:"has_titles"`
	EpisodeMap    *EpisodeMap `json:"episode_map,omitempty"`
	// HasEpisodeMap reports that the row was written by a lookup that read the
	// episode map. A positive row without it predates the map and refetches once.
	HasEpisodeMap bool      `json:"has_episode_map"`
	IsNegative    bool      `json:"is_negative"`
	CachedAt      time.Time `json:"cached_at"`
	ExpiresAt     time.Time `json:"expires_at"`
}

ArrIDCacheEntry represents a cached ID lookup result

type ArrIDCacheStore added in v1.12.0

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

ArrIDCacheStore manages the ARR ID cache in the database

func NewArrIDCacheStore added in v1.12.0

func NewArrIDCacheStore(db dbinterface.Querier) *ArrIDCacheStore

NewArrIDCacheStore creates a new ArrIDCacheStore

func (*ArrIDCacheStore) CleanupExpired added in v1.12.0

func (s *ArrIDCacheStore) CleanupExpired(ctx context.Context) (int64, error)

CleanupExpired removes all expired cache entries

func (*ArrIDCacheStore) Get added in v1.12.0

func (s *ArrIDCacheStore) Get(ctx context.Context, titleHash, contentType string) (*ArrIDCacheEntry, error)

Get retrieves a cached ID entry if it exists and hasn't expired.

Expiry is compared against a bound UTC time parameter rather than SQL's CURRENT_TIMESTAMP. expires_at is stored by binding a Go time.Time, which the SQLite driver serializes as a string; CURRENT_TIMESTAMP returns its own UTC string in a different format, so a lexical comparison of the two only behaves chronologically when the process runs in UTC. Binding the comparison value through the same driver path (and storing expires_at in UTC, see SetWithTitles) makes the comparison timezone-independent on both SQLite and Postgres (#1961).

func (*ArrIDCacheStore) Set added in v1.12.0

func (s *ArrIDCacheStore) Set(ctx context.Context, titleHash, contentType string, arrInstanceID *int, ids *ExternalIDs, isNegative bool, ttl time.Duration) error

Set creates or updates a cache entry (upsert) without titles or an episode map, recording neither as known. The service uses it for negative rows.

func (*ArrIDCacheStore) SetWithTitles added in v1.19.0

func (s *ArrIDCacheStore) SetWithTitles(ctx context.Context, titleHash, contentType string, arrInstanceID *int, ids *ExternalIDs, titles []string, episodeMap *EpisodeMap, episodeMapKnown, isNegative bool, ttl time.Duration) error

SetWithTitles creates or updates a cache entry from a full lookup result with the ARR title aliases recorded as known. episodeMapKnown records that the lookup read the episode map (nil when it found none); a parse that never answered leaves it false so the row refetches. A negative write never replaces a live positive row: concurrent lookups of the same title can race, and a slower no-ID result must not hide freshly resolved IDs for the negative TTL (#2300). Positive writes always win.

type ArrInstance added in v1.12.0

type ArrInstance struct {
	ID                     int             `json:"id"`
	Type                   ArrInstanceType `json:"type"`
	Name                   string          `json:"name"`
	BaseURL                string          `json:"base_url"`
	BasicUsername          *string         `json:"basic_username,omitempty"`
	APIKeyEncrypted        string          `json:"-"`
	BasicPasswordEncrypted *string         `json:"-"`
	Enabled                bool            `json:"enabled"`
	Priority               int             `json:"priority"`
	TimeoutSeconds         int             `json:"timeout_seconds"`
	LastTestAt             *time.Time      `json:"last_test_at,omitempty"`
	LastTestStatus         string          `json:"last_test_status"`
	LastTestError          *string         `json:"last_test_error,omitempty"`
	CreatedAt              time.Time       `json:"created_at"`
	UpdatedAt              time.Time       `json:"updated_at"`
}

ArrInstance represents a Sonarr or Radarr instance used for ID lookups

type ArrInstanceStore added in v1.12.0

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

ArrInstanceStore manages ARR instances in the database

func NewArrInstanceStore added in v1.12.0

func NewArrInstanceStore(db dbinterface.Querier, encryptionKey []byte, opts ...CredentialCipherOption) (*ArrInstanceStore, error)

NewArrInstanceStore creates a new ArrInstanceStore

func (*ArrInstanceStore) Create added in v1.12.0

func (s *ArrInstanceStore) Create(ctx context.Context, instanceType ArrInstanceType, name, baseURL, apiKey string, basicUsername, basicPassword *string, enabled bool, priority, timeoutSeconds int) (*ArrInstance, error)

Create creates a new ARR instance

func (*ArrInstanceStore) Delete added in v1.12.0

func (s *ArrInstanceStore) Delete(ctx context.Context, id int) error

Delete deletes an ARR instance String pool cleanup is handled by the centralized CleanupUnusedStrings() function

func (*ArrInstanceStore) Get added in v1.12.0

func (s *ArrInstanceStore) Get(ctx context.Context, id int) (*ArrInstance, error)

Get retrieves an ARR instance by ID using the view

func (*ArrInstanceStore) GetDecryptedAPIKey added in v1.12.0

func (s *ArrInstanceStore) GetDecryptedAPIKey(instance *ArrInstance) (string, error)

GetDecryptedAPIKey returns the decrypted API key for an ARR instance

func (*ArrInstanceStore) GetDecryptedBasicPassword added in v1.14.0

func (s *ArrInstanceStore) GetDecryptedBasicPassword(instance *ArrInstance) (string, error)

GetDecryptedBasicPassword returns the decrypted basic auth password for an ARR instance.

func (*ArrInstanceStore) List added in v1.12.0

func (s *ArrInstanceStore) List(ctx context.Context) ([]*ArrInstance, error)

List retrieves all ARR instances using the view, ordered by type, priority (descending), and name

func (*ArrInstanceStore) ListEnabled added in v1.12.0

func (s *ArrInstanceStore) ListEnabled(ctx context.Context) ([]*ArrInstance, error)

ListEnabled retrieves all enabled ARR instances, ordered by type, priority (descending), and name

func (*ArrInstanceStore) ListEnabledByType added in v1.12.0

func (s *ArrInstanceStore) ListEnabledByType(ctx context.Context, instanceType ArrInstanceType) ([]*ArrInstance, error)

ListEnabledByType retrieves all enabled ARR instances of a specific type, ordered by priority (descending)

func (*ArrInstanceStore) RewriteLegacyCredentials added in v1.29.0

func (s *ArrInstanceStore) RewriteLegacyCredentials(ctx context.Context) (int, error)

RewriteLegacyCredentials re-encrypts stored *arr instance credentials that still carry the pre-HKDF format and reports how many rows it rewrote.

func (*ArrInstanceStore) Update added in v1.12.0

Update updates an existing ARR instance

func (*ArrInstanceStore) UpdateTestStatus added in v1.12.0

func (s *ArrInstanceStore) UpdateTestStatus(ctx context.Context, id int, status string, errorMsg *string) error

UpdateTestStatus updates the test status of an ARR instance

type ArrInstanceType added in v1.12.0

type ArrInstanceType string

ArrInstanceType represents the type of ARR instance (sonarr or radarr)

const (
	ArrInstanceTypeSonarr ArrInstanceType = "sonarr"
	ArrInstanceTypeRadarr ArrInstanceType = "radarr"
)

func ParseArrInstanceType added in v1.12.0

func ParseArrInstanceType(value string) (ArrInstanceType, error)

ParseArrInstanceType validates and normalizes an ARR instance type string.

type ArrInstanceUpdateParams added in v1.12.0

type ArrInstanceUpdateParams struct {
	Name           *string
	BaseURL        *string
	APIKey         *string
	BasicUsername  *string
	BasicPassword  *string
	Enabled        *bool
	Priority       *int
	TimeoutSeconds *int
}

ArrInstanceUpdateParams captures optional fields for updating an ARR instance.

type AutoManagementAction added in v1.16.0

type AutoManagementAction struct {
	Enabled   bool           `json:"enabled" doc:"'true' turns automatic torrent management on, 'false' turns it off."`
	Condition *RuleCondition `json:"condition,omitempty" doc:"Optional. When set, the action applies only to torrents that also match this condition."`
}

AutoManagementAction configures automatic torrent management (ATM) with optional conditions.

type Automation added in v1.12.0

type Automation struct {
	ID              int               `json:"id"`
	InstanceID      int               `json:"instanceId"`
	Name            string            `json:"name"`
	TrackerPattern  string            `json:"trackerPattern"`
	Conditions      *ActionConditions `json:"conditions"`
	FreeSpaceSource *FreeSpaceSource  `json:"freeSpaceSource,omitempty"` // nil = default qBittorrent free space
	SortingConfig   *SortingConfig    `json:"sortingConfig,omitempty"`   // nil = default sorting (oldest first)
	Enabled         bool              `json:"enabled"`
	DryRun          bool              `json:"dryRun"`
	Notify          bool              `json:"notify"`
	SortOrder       int               `json:"sortOrder"`
	IntervalSeconds *int              `json:"intervalSeconds,omitempty"` // nil = use DefaultRuleInterval (15m)
	CreatedAt       time.Time         `json:"createdAt"`
	UpdatedAt       time.Time         `json:"updatedAt"`
}

type AutomationActivity added in v1.12.0

type AutomationActivity struct {
	ID            int             `json:"id"`
	InstanceID    int             `json:"instanceId"`
	Hash          string          `json:"hash"`
	TorrentName   string          `json:"torrentName,omitempty"`
	TrackerDomain string          `json:"trackerDomain,omitempty"`
	Action        string          `json:"action"`
	RuleID        *int            `json:"ruleId,omitempty"`
	RuleName      string          `json:"ruleName,omitempty"`
	Outcome       string          `json:"outcome"`
	Reason        string          `json:"reason,omitempty"`
	Details       json.RawMessage `json:"details,omitempty"`
	CreatedAt     time.Time       `json:"createdAt"`
}

type AutomationActivityStore added in v1.12.0

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

func NewAutomationActivityStore added in v1.12.0

func NewAutomationActivityStore(db dbinterface.Querier) *AutomationActivityStore

func (*AutomationActivityStore) Create added in v1.12.0

func (*AutomationActivityStore) CreateWithID added in v1.14.0

func (s *AutomationActivityStore) CreateWithID(ctx context.Context, activity *AutomationActivity) (int, error)

func (*AutomationActivityStore) DeleteOlderThan added in v1.12.0

func (s *AutomationActivityStore) DeleteOlderThan(ctx context.Context, instanceID int, days int) (int64, error)

func (*AutomationActivityStore) ListByInstance added in v1.12.0

func (s *AutomationActivityStore) ListByInstance(ctx context.Context, instanceID int, limit int) ([]*AutomationActivity, error)

func (*AutomationActivityStore) Prune added in v1.12.0

func (s *AutomationActivityStore) Prune(ctx context.Context, retentionDays int) (int64, error)

type AutomationReference added in v1.14.0

type AutomationReference struct {
	ID         int    `json:"id"`
	InstanceID int    `json:"instanceId"`
	Name       string `json:"name"`
}

AutomationReference represents a minimal automation reference for cascade delete warnings.

type AutomationStore added in v1.12.0

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

func NewAutomationStore added in v1.12.0

func NewAutomationStore(db dbinterface.Querier) *AutomationStore

func (*AutomationStore) ClearExternalProgramAction added in v1.14.0

func (s *AutomationStore) ClearExternalProgramAction(ctx context.Context, programID int) (int64, error)

ClearExternalProgramAction removes the external program action from all automations that reference the given program ID. This is used for cascade delete. Clears references regardless of whether the action is enabled or disabled.

func (*AutomationStore) Create added in v1.12.0

func (s *AutomationStore) Create(ctx context.Context, automation *Automation) (*Automation, error)

func (*AutomationStore) Delete added in v1.12.0

func (s *AutomationStore) Delete(ctx context.Context, instanceID int, id int) error

func (*AutomationStore) FindByExternalProgramID added in v1.14.0

func (s *AutomationStore) FindByExternalProgramID(ctx context.Context, programID int) ([]*AutomationReference, error)

FindByExternalProgramID returns automations that reference the given external program ID. Returns all automations referencing the program, regardless of whether the action is enabled.

func (*AutomationStore) Get added in v1.12.0

func (s *AutomationStore) Get(ctx context.Context, instanceID, id int) (*Automation, error)

func (*AutomationStore) ListByInstance added in v1.12.0

func (s *AutomationStore) ListByInstance(ctx context.Context, instanceID int) ([]*Automation, error)

func (*AutomationStore) Reorder added in v1.12.0

func (s *AutomationStore) Reorder(ctx context.Context, instanceID int, orderedIDs []int) error

func (*AutomationStore) Update added in v1.12.0

func (s *AutomationStore) Update(ctx context.Context, automation *Automation) (*Automation, error)

type BackupItem added in v1.5.0

type BackupItem struct {
	ID              int64     `json:"id"`
	RunID           int64     `json:"runId"`
	TorrentHash     string    `json:"torrentHash"`
	Name            string    `json:"name"`
	Category        *string   `json:"category,omitempty"`
	SizeBytes       int64     `json:"sizeBytes"`
	ArchiveRelPath  *string   `json:"archiveRelPath,omitempty"`
	InfoHashV1      *string   `json:"infohashV1,omitempty"`
	InfoHashV2      *string   `json:"infohashV2,omitempty"`
	Tags            *string   `json:"tags,omitempty"`
	TorrentBlobPath *string   `json:"torrentBlobPath,omitempty"`
	SavePath        *string   `json:"savePath,omitempty"`
	CreatedAt       time.Time `json:"createdAt"`
}

type BackupRun added in v1.5.0

type BackupRun struct {
	ID             int64                       `json:"id"`
	InstanceID     int                         `json:"instanceId"`
	Kind           BackupRunKind               `json:"kind"`
	Status         BackupRunStatus             `json:"status"`
	RequestedBy    string                      `json:"requestedBy"`
	RequestedAt    time.Time                   `json:"requestedAt"`
	StartedAt      *time.Time                  `json:"startedAt,omitempty"`
	CompletedAt    *time.Time                  `json:"completedAt,omitempty"`
	ArchivePath    *string                     `json:"archivePath,omitempty"`
	ManifestPath   *string                     `json:"manifestPath,omitempty"`
	TotalBytes     int64                       `json:"totalBytes"`
	TorrentCount   int                         `json:"torrentCount"`
	CategoryCounts map[string]int              `json:"categoryCounts,omitempty"`
	ErrorMessage   *string                     `json:"errorMessage,omitempty"`
	Categories     map[string]CategorySnapshot `json:"categories,omitempty"`
	Tags           []string                    `json:"tags,omitempty"`
	// contains filtered or unexported fields
}

type BackupRunKind added in v1.5.0

type BackupRunKind string
const (
	BackupRunKindManual  BackupRunKind = "manual"
	BackupRunKindHourly  BackupRunKind = "hourly"
	BackupRunKindDaily   BackupRunKind = "daily"
	BackupRunKindWeekly  BackupRunKind = "weekly"
	BackupRunKindMonthly BackupRunKind = "monthly"
)

type BackupRunStatus added in v1.5.0

type BackupRunStatus string
const (
	BackupRunStatusPending  BackupRunStatus = "pending"
	BackupRunStatusRunning  BackupRunStatus = "running"
	BackupRunStatusSuccess  BackupRunStatus = "success"
	BackupRunStatusFailed   BackupRunStatus = "failed"
	BackupRunStatusCanceled BackupRunStatus = "canceled"
)

type BackupSettings added in v1.5.0

type BackupSettings struct {
	InstanceID        int       `json:"instanceId"`
	Enabled           bool      `json:"enabled"`
	HourlyEnabled     bool      `json:"hourlyEnabled"`
	DailyEnabled      bool      `json:"dailyEnabled"`
	WeeklyEnabled     bool      `json:"weeklyEnabled"`
	MonthlyEnabled    bool      `json:"monthlyEnabled"`
	KeepHourly        int       `json:"keepHourly"`
	KeepDaily         int       `json:"keepDaily"`
	KeepWeekly        int       `json:"keepWeekly"`
	KeepMonthly       int       `json:"keepMonthly"`
	IncludeCategories bool      `json:"includeCategories"`
	IncludeTags       bool      `json:"includeTags"`
	IncludeSavePaths  bool      `json:"includeSavePaths"`
	CustomPath        *string   `json:"customPath,omitempty"`
	CreatedAt         time.Time `json:"createdAt"`
	UpdatedAt         time.Time `json:"updatedAt"`
}

func DefaultBackupSettings added in v1.5.0

func DefaultBackupSettings(instanceID int) *BackupSettings

type BackupStore added in v1.5.0

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

func NewBackupStore added in v1.5.0

func NewBackupStore(db dbinterface.Querier) *BackupStore

func (*BackupStore) CleanupRun added in v1.5.0

func (s *BackupStore) CleanupRun(ctx context.Context, runID int64) error

func (*BackupStore) CleanupRuns added in v1.8.0

func (s *BackupStore) CleanupRuns(ctx context.Context, runIDs []int64) error

func (*BackupStore) CountBlobReferencesBatch added in v1.8.0

func (s *BackupStore) CountBlobReferencesBatch(ctx context.Context, relPaths []string) (map[string]int, error)

CountBlobReferencesBatch counts stored rows. The count is correct because CleanupRuns deletes each row that no remaining run covers, in the same transaction as its runs.

func (*BackupStore) CreateRun added in v1.5.0

func (s *BackupStore) CreateRun(ctx context.Context, run *BackupRun) error

func (*BackupStore) DeleteRunsOlderThan added in v1.5.0

func (s *BackupStore) DeleteRunsOlderThan(ctx context.Context, instanceID int, kind BackupRunKind, keep int) ([]int64, error)

func (*BackupStore) FindCachedTorrentBlob added in v1.5.0

func (s *BackupStore) FindCachedTorrentBlob(ctx context.Context, instanceID int, hash string) (*string, error)

func (*BackupStore) FindIncompleteRuns added in v1.6.0

func (s *BackupStore) FindIncompleteRuns(ctx context.Context) ([]*BackupRun, error)

FindIncompleteRuns returns all backup runs that are in pending or running status. These are runs that were interrupted by a restart or crash.

func (*BackupStore) GetInstanceName added in v1.5.0

func (s *BackupStore) GetInstanceName(ctx context.Context, instanceID int) (string, error)

func (*BackupStore) GetItemByHash added in v1.5.0

func (s *BackupStore) GetItemByHash(ctx context.Context, runID int64, hash string) (*BackupItem, error)

func (*BackupStore) GetRun added in v1.5.0

func (s *BackupStore) GetRun(ctx context.Context, runID int64) (*BackupRun, error)

func (*BackupStore) GetRuns added in v1.8.0

func (s *BackupStore) GetRuns(ctx context.Context, runIDs []int64) ([]*BackupRun, error)

func (*BackupStore) GetSettings added in v1.5.0

func (s *BackupStore) GetSettings(ctx context.Context, instanceID int) (*BackupSettings, error)

func (*BackupStore) InsertItems added in v1.5.0

func (s *BackupStore) InsertItems(ctx context.Context, runID int64, items []BackupItem) error

InsertItems records runID's snapshot. Torrents whose state matches the instance's current rows extend those rows to this run without a write; only new or changed torrents insert a row, and states the run no longer has are closed at this run's sequence number.

func (*BackupStore) ListEnabledSettings added in v1.5.0

func (s *BackupStore) ListEnabledSettings(ctx context.Context) ([]*BackupSettings, error)

func (*BackupStore) ListItems added in v1.5.0

func (s *BackupStore) ListItems(ctx context.Context, runID int64) ([]*BackupItem, error)

func (*BackupStore) ListItemsForRuns added in v1.8.0

func (s *BackupStore) ListItemsForRuns(ctx context.Context, runIDs []int64) ([]*BackupItem, error)

func (*BackupStore) ListRunIDs added in v1.5.0

func (s *BackupStore) ListRunIDs(ctx context.Context, instanceID int) ([]int64, error)

func (*BackupStore) ListRuns added in v1.5.0

func (s *BackupStore) ListRuns(ctx context.Context, instanceID int, limit, offset int) ([]*BackupRun, error)

func (*BackupStore) ListRunsByKind added in v1.5.0

func (s *BackupStore) ListRunsByKind(ctx context.Context, instanceID int, kind BackupRunKind, limit int) ([]*BackupRun, error)

func (*BackupStore) ListTorrentBlobPaths added in v1.24.0

func (s *BackupStore) ListTorrentBlobPaths(ctx context.Context) ([]string, error)

ListTorrentBlobPaths returns every distinct blob path referenced by any backup item across all runs and instances.

func (*BackupStore) UpdateMultipleRunsStatus added in v1.7.0

func (s *BackupStore) UpdateMultipleRunsStatus(ctx context.Context, runIDs []int64, status BackupRunStatus, completedAt *time.Time, errorMessage *string) error

UpdateMultipleRunsStatus updates the status of multiple backup runs in a single transaction

func (*BackupStore) UpdateRunMetadata added in v1.5.0

func (s *BackupStore) UpdateRunMetadata(ctx context.Context, runID int64, updateFn func(*BackupRun) error) error

func (*BackupStore) UpsertSettings added in v1.5.0

func (s *BackupStore) UpsertSettings(ctx context.Context, settings *BackupSettings) error

type CategoryAction added in v1.12.0

type CategoryAction struct {
	Enabled           bool   `json:"enabled" doc:"Whether the action runs."`
	Category          string `json:"category" doc:"The category to set. An empty string removes the category."`
	IncludeCrossSeeds bool   `json:"includeCrossSeeds,omitempty" doc:"Also move the cross-seeds of each matching torrent to the category."`
	GroupID           string `` /* 189-byte string literal not displayed */
	// BlockIfCrossSeedInCategories prevents category changes when any other cross-seed torrent
	// (same ContentPath + SavePath) is found in one of the listed categories.
	BlockIfCrossSeedInCategories []string       `json:"blockIfCrossSeedInCategories,omitempty" doc:"Skip a torrent when one of its cross-seeds is in one of these categories."`
	Condition                    *RuleCondition `json:"condition,omitempty" doc:"Optional. When set, the action applies only to torrents that also match this condition."`
}

CategoryAction configures category assignment with optional conditions.

type CategoryMappingRule added in v1.26.0

type CategoryMappingRule struct {
	Categories  []string `json:"categories"`  // qBittorrent category names, exact match
	ContentType string   `json:"contentType"` // movie, tv, music, audiobook, book, comic, game, app
}

CategoryMappingRule forces the cross-seed search category for torrents in any of a set of qBittorrent categories (discussion #1734). A category must match exactly; a matching rule wins over both the name parse and the file-extension signal.

type CategorySnapshot added in v1.5.0

type CategorySnapshot struct {
	SavePath string `json:"savePath,omitempty"`
}

type ClientAPIKey added in v1.0.0

type ClientAPIKey struct {
	ID         int        `json:"id"`
	KeyHash    string     `json:"-"`
	ClientName string     `json:"clientName"`
	InstanceID int        `json:"instanceId"`
	CreatedAt  time.Time  `json:"createdAt"`
	LastUsedAt *time.Time `json:"lastUsedAt,omitempty"`
}

type ClientAPIKeyStore added in v1.0.0

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

func NewClientAPIKeyStore added in v1.0.0

func NewClientAPIKeyStore(db dbinterface.Querier) *ClientAPIKeyStore

func (*ClientAPIKeyStore) Create added in v1.0.0

func (s *ClientAPIKeyStore) Create(ctx context.Context, clientName string, instanceID int) (string, *ClientAPIKey, error)

func (*ClientAPIKeyStore) Delete added in v1.0.0

func (s *ClientAPIKeyStore) Delete(ctx context.Context, id int) error

func (*ClientAPIKeyStore) GetAll added in v1.0.0

func (s *ClientAPIKeyStore) GetAll(ctx context.Context) ([]*ClientAPIKey, error)

func (*ClientAPIKeyStore) GetByKeyHash added in v1.0.0

func (s *ClientAPIKeyStore) GetByKeyHash(ctx context.Context, keyHash string) (*ClientAPIKey, error)

func (*ClientAPIKeyStore) UpdateLastUsed added in v1.0.0

func (s *ClientAPIKeyStore) UpdateLastUsed(ctx context.Context, keyHash string) error

func (*ClientAPIKeyStore) ValidateKey added in v1.0.0

func (s *ClientAPIKeyStore) ValidateKey(ctx context.Context, rawKey string) (*ClientAPIKey, error)

type ClientSettingsStore added in v1.27.0

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

ClientSettingsStore persists frontend user settings as an opaque key-value map. Values are raw strings the backend never parses; the frontend owns the encoding of every key.

func NewClientSettingsStore added in v1.27.0

func NewClientSettingsStore(db dbinterface.Querier) *ClientSettingsStore

func (*ClientSettingsStore) GetAll added in v1.27.0

func (s *ClientSettingsStore) GetAll(ctx context.Context) (map[string]string, error)

GetAll returns every stored setting. An empty map means nothing is stored.

func (*ClientSettingsStore) SetMany added in v1.27.0

func (s *ClientSettingsStore) SetMany(ctx context.Context, settings map[string]string) error

SetMany upserts the given settings atomically, leaving keys not in the map untouched.

type CompletionFilterProvider added in v1.10.0

type CompletionFilterProvider interface {
	GetCategories() []string
	GetTags() []string
	GetExcludeCategories() []string
	GetExcludeTags() []string
}

CompletionFilterProvider defines the interface for types that provide completion filter fields. Used by InstanceCrossSeedCompletionSettings for per-instance completion configuration.

type ConditionField added in v1.12.0

type ConditionField string

ConditionField represents a field from the qBittorrent Torrent struct that can be filtered on.

const (
	// String fields
	FieldName          ConditionField = "NAME"
	FieldHash          ConditionField = "HASH"
	FieldInfohashV1    ConditionField = "INFOHASH_V1"
	FieldInfohashV2    ConditionField = "INFOHASH_V2"
	FieldMagnetURI     ConditionField = "MAGNET_URI"
	FieldCategory      ConditionField = "CATEGORY"
	FieldTags          ConditionField = "TAGS"
	FieldSavePath      ConditionField = "SAVE_PATH"
	FieldContentPath   ConditionField = "CONTENT_PATH"
	FieldDownloadPath  ConditionField = "DOWNLOAD_PATH"
	FieldCreatedBy     ConditionField = "CREATED_BY"
	FieldTrackers      ConditionField = "TRACKERS"
	FieldContentType   ConditionField = "CONTENT_TYPE"
	FieldEffectiveName ConditionField = "EFFECTIVE_NAME"

	// RLS-derived specifiers (from torrent name parsing)
	FieldRlsSource      ConditionField = "RLS_SOURCE"
	FieldRlsResolution  ConditionField = "RLS_RESOLUTION"
	FieldRlsCodec       ConditionField = "RLS_CODEC"
	FieldRlsHDR         ConditionField = "RLS_HDR"
	FieldRlsAudio       ConditionField = "RLS_AUDIO"
	FieldRlsChannels    ConditionField = "RLS_CHANNELS"
	FieldRlsGroup       ConditionField = "RLS_GROUP"
	FieldRlsYear        ConditionField = "RLS_YEAR"
	FieldState          ConditionField = "STATE"
	FieldTracker        ConditionField = "TRACKER"
	FieldTrackerStatus  ConditionField = "TRACKER_STATUS"
	FieldTrackerMessage ConditionField = "TRACKER_MESSAGE"
	FieldComment        ConditionField = "COMMENT"

	// Numeric fields (bytes)
	FieldSize              ConditionField = "SIZE"
	FieldTotalSize         ConditionField = "TOTAL_SIZE"
	FieldCompleted         ConditionField = "COMPLETED"
	FieldDownloaded        ConditionField = "DOWNLOADED"
	FieldDownloadedSession ConditionField = "DOWNLOADED_SESSION"
	FieldUploaded          ConditionField = "UPLOADED"
	FieldUploadedSession   ConditionField = "UPLOADED_SESSION"
	FieldAmountLeft        ConditionField = "AMOUNT_LEFT"
	FieldFreeSpace         ConditionField = "FREE_SPACE"

	// Time fields (timestamp-backed ages + duration seconds)
	FieldAddedOn                  ConditionField = "ADDED_ON"
	FieldCompletionOn             ConditionField = "COMPLETION_ON"
	FieldLastActivity             ConditionField = "LAST_ACTIVITY"
	FieldSeenComplete             ConditionField = "SEEN_COMPLETE"
	FieldETA                      ConditionField = "ETA"
	FieldReannounce               ConditionField = "REANNOUNCE"
	FieldSeedingTime              ConditionField = "SEEDING_TIME"
	FieldTimeActive               ConditionField = "TIME_ACTIVE"
	FieldMaxSeedingTime           ConditionField = "MAX_SEEDING_TIME"
	FieldMaxInactiveSeedingTime   ConditionField = "MAX_INACTIVE_SEEDING_TIME"
	FieldSeedingTimeLimit         ConditionField = "SEEDING_TIME_LIMIT"
	FieldInactiveSeedingTimeLimit ConditionField = "INACTIVE_SEEDING_TIME_LIMIT"

	// Legacy age aliases (computed as nowUnix - timestamp)
	FieldAddedOnAge      ConditionField = "ADDED_ON_AGE"
	FieldCompletionOnAge ConditionField = "COMPLETION_ON_AGE"
	FieldLastActivityAge ConditionField = "LAST_ACTIVITY_AGE"

	// Numeric fields (float64)
	FieldRatio            ConditionField = "RATIO"
	FieldRatioLimit       ConditionField = "RATIO_LIMIT"
	FieldMaxRatio         ConditionField = "MAX_RATIO"
	FieldUploadedOverSize ConditionField = "UPLOADED_OVER_SIZE"
	FieldProgress         ConditionField = "PROGRESS"
	FieldAvailability     ConditionField = "AVAILABILITY"
	FieldPopularity       ConditionField = "POPULARITY"

	// Numeric fields (speeds)
	FieldDlSpeed ConditionField = "DL_SPEED"
	FieldUpSpeed ConditionField = "UP_SPEED"
	FieldDlLimit ConditionField = "DL_LIMIT"
	FieldUpLimit ConditionField = "UP_LIMIT"

	// Numeric fields (counts/misc)
	FieldNumSeeds      ConditionField = "NUM_SEEDS"
	FieldNumLeechs     ConditionField = "NUM_LEECHS"
	FieldNumComplete   ConditionField = "NUM_COMPLETE"
	FieldNumIncomplete ConditionField = "NUM_INCOMPLETE"
	FieldTrackersCount ConditionField = "TRACKERS_COUNT"
	FieldPriority      ConditionField = "PRIORITY"
	FieldGroupSize     ConditionField = "GROUP_SIZE"

	// Boolean fields
	FieldPrivate                ConditionField = "PRIVATE"
	FieldAutoManaged            ConditionField = "AUTO_MANAGED"
	FieldFirstLastPiecePrio     ConditionField = "FIRST_LAST_PIECE_PRIO"
	FieldForceStart             ConditionField = "FORCE_START"
	FieldSequentialDownload     ConditionField = "SEQUENTIAL_DOWNLOAD"
	FieldSuperSeeding           ConditionField = "SUPER_SEEDING"
	FieldIsUnregistered         ConditionField = "IS_UNREGISTERED"
	FieldHasMissingFiles        ConditionField = "HAS_MISSING_FILES"
	FieldHasSkippedFiles        ConditionField = "HAS_SKIPPED_FILES"
	FieldIsGrouped              ConditionField = "IS_GROUPED"
	FieldExistsOnOtherInstance  ConditionField = "EXISTS_ON_OTHER_INSTANCE"
	FieldSeedingOnOtherInstance ConditionField = "SEEDING_ON_OTHER_INSTANCE"
	FieldExistsOnSameInstance   ConditionField = "EXISTS_ON_SAME_INSTANCE"
	FieldSeedingOnSameInstance  ConditionField = "SEEDING_ON_SAME_INSTANCE"
	FieldCrossSeedTags          ConditionField = "CROSS_SEED_TAGS"

	// Season pack fields
	FieldSeasonPackStatus            ConditionField = "SEASON_PACK_STATUS"
	FieldSeasonPackStatusAnyInstance ConditionField = "SEASON_PACK_STATUS_ANY_INSTANCE"

	// System time fields
	FieldSystemHour      ConditionField = "SYSTEM_HOUR"
	FieldSystemMinute    ConditionField = "SYSTEM_MINUTE"
	FieldSystemDayOfWeek ConditionField = "SYSTEM_DAY_OF_WEEK"
	FieldSystemDay       ConditionField = "SYSTEM_DAY"
	FieldSystemMonth     ConditionField = "SYSTEM_MONTH"
	FieldSystemYear      ConditionField = "SYSTEM_YEAR"

	// Enum-like fields
	FieldHardlinkScope      ConditionField = "HARDLINK_SCOPE"
	FieldHardlinkScopeCross ConditionField = "HARDLINK_SCOPE_CROSS"
)

func (ConditionField) IsNumeric added in v1.15.0

func (f ConditionField) IsNumeric() bool

func (ConditionField) IsString added in v1.15.0

func (f ConditionField) IsString() bool

func (ConditionField) WrapsBetween added in v1.29.0

func (f ConditionField) WrapsBetween() bool

WrapsBetween reports whether a BETWEEN range on this field wraps when the minimum is greater than the maximum. Clock fields cycle, so 20 to 6 on the hour means the night that crosses midnight. A wrapped range stops before its maximum, see matchesBetween. SYSTEM_DAY and SYSTEM_YEAR do not wrap: a month boundary depends on the month length, and years do not cycle.

type ConditionOperator added in v1.12.0

type ConditionOperator string

ConditionOperator represents operators for comparing field values.

const (
	// Logical operators (for groups)
	OperatorAnd ConditionOperator = "AND"
	OperatorOr  ConditionOperator = "OR"

	// Comparison operators
	OperatorEqual              ConditionOperator = "EQUAL"
	OperatorNotEqual           ConditionOperator = "NOT_EQUAL"
	OperatorContains           ConditionOperator = "CONTAINS"
	OperatorNotContains        ConditionOperator = "NOT_CONTAINS"
	OperatorStartsWith         ConditionOperator = "STARTS_WITH"
	OperatorEndsWith           ConditionOperator = "ENDS_WITH"
	OperatorGreaterThan        ConditionOperator = "GREATER_THAN"
	OperatorGreaterThanOrEqual ConditionOperator = "GREATER_THAN_OR_EQUAL"
	OperatorLessThan           ConditionOperator = "LESS_THAN"
	OperatorLessThanOrEqual    ConditionOperator = "LESS_THAN_OR_EQUAL"
	OperatorBetween            ConditionOperator = "BETWEEN"
	OperatorMatches            ConditionOperator = "MATCHES" // regex

	// Cross-category lookup operators (NAME field only)
	OperatorExistsIn   ConditionOperator = "EXISTS_IN"   // exact name match in target category
	OperatorContainsIn ConditionOperator = "CONTAINS_IN" // partial name match in target category
)

type ConditionalScoreRule added in v1.15.0

type ConditionalScoreRule struct {
	Condition *RuleCondition `json:"condition" doc:"When the torrent matches this condition, score is added."`
	Score     float64        `json:"score" doc:"The score to add."`
}

ConditionalScoreRule adds a flat score if a condition is met.

type CredentialCipher added in v1.29.0

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

CredentialCipher seals the credentials the stores keep in the database. It writes under the current key and can still read values written under the pre-HKDF key when one is configured.

func NewCredentialCipher added in v1.29.0

func NewCredentialCipher(key []byte, opts ...CredentialCipherOption) (*CredentialCipher, error)

NewCredentialCipher builds a cipher around a 32-byte key.

func (*CredentialCipher) Decrypt added in v1.29.0

func (c *CredentialCipher) Decrypt(ciphertext string, aad []byte) (string, error)

Decrypt opens a value written by Encrypt, or an unprefixed legacy value under the legacy key when one is configured.

func (*CredentialCipher) Encrypt added in v1.29.0

func (c *CredentialCipher) Encrypt(plaintext string, aad []byte) (string, error)

Encrypt seals plaintext under the current key. aad is bound into the tag and must be passed again to Decrypt.

type CredentialCipherOption added in v1.29.0

type CredentialCipherOption func(*CredentialCipher) error

CredentialCipherOption configures a CredentialCipher at construction.

func WithLegacyEncryptionKey added in v1.29.0

func WithLegacyEncryptionKey(key []byte) CredentialCipherOption

WithLegacyEncryptionKey lets the cipher read values written before the key was derived with HKDF.

type CrossSeedAutomationSettings added in v1.8.0

type CrossSeedAutomationSettings struct {
	// RSS Automation settings
	Enabled            bool  `json:"enabled"`            // Enable/disable RSS automation
	RunIntervalMinutes int   `json:"runIntervalMinutes"` // RSS: interval between RSS feed polls (min: 30 minutes, default: 120)
	TargetInstanceIDs  []int `json:"targetInstanceIds"`  // RSS: instances to add cross-seeds to
	TargetIndexerIDs   []int `json:"targetIndexerIds"`   // RSS: indexers to poll for RSS feeds
	MaxResultsPerRun   int   `json:"maxResultsPerRun"`   // Deprecated: automation processes full feeds; retained for backward compatibility

	// RSS source filtering: filter which LOCAL torrents are considered when checking RSS feeds.
	// Empty arrays mean "all" (no filtering).
	RSSSourceCategories        []string `json:"rssSourceCategories"`        // Only match against torrents in these categories
	RSSSourceTags              []string `json:"rssSourceTags"`              // Only match against torrents with these tags
	RSSSourceExcludeCategories []string `json:"rssSourceExcludeCategories"` // Skip torrents in these categories
	RSSSourceExcludeTags       []string `json:"rssSourceExcludeTags"`       // Skip torrents with these tags

	// Webhook source filtering: filter which LOCAL torrents are considered when checking webhook requests.
	// Empty arrays mean "all" (no filtering).
	WebhookSourceCategories        []string `json:"webhookSourceCategories"`        // Only match against torrents in these categories
	WebhookSourceTags              []string `json:"webhookSourceTags"`              // Only match against torrents with these tags
	WebhookSourceExcludeCategories []string `json:"webhookSourceExcludeCategories"` // Skip torrents in these categories
	WebhookSourceExcludeTags       []string `json:"webhookSourceExcludeTags"`       // Skip torrents with these tags

	// Global cross-seed settings (apply to both RSS Automation and Seeded Torrent Search)
	FindIndividualEpisodes         bool `json:"findIndividualEpisodes"`         // Match season packs with individual episodes
	AutoResumeMaxDownloadMB        int  `json:"autoResumeMaxDownloadMb"`        // Max missing data (MiB) to still auto-resume a new cross-seed; 0 = only complete torrents (default: 50)
	PooledPartialCompletionEnabled bool `json:"pooledPartialCompletionEnabled"` // Coordinate partial hardlink/reflink completion pools
	UseCategoryFromIndexer         bool `json:"useCategoryFromIndexer"`         // Use indexer name as category for cross-seeds
	RunExternalProgramID           *int `json:"runExternalProgramId"`           // Optional external program to run after successful cross-seed injection

	// Category mapping rules force the search category for torrents in a
	// qBittorrent category; a matching rule wins over content type detection.
	CategoryMappingRules []CategoryMappingRule `json:"categoryMappingRules"`

	// Source-specific tagging: tags applied based on how the cross-seed was discovered.
	// Each defaults to ["cross-seed"]. Users can add source-specific tags like "rss", "seeded-search", etc.
	RSSAutomationTags    []string `json:"rssAutomationTags"`    // Tags for RSS automation results
	SeededSearchTags     []string `json:"seededSearchTags"`     // Tags for seeded torrent search results
	CompletionSearchTags []string `json:"completionSearchTags"` // Tags for completion-triggered search results
	WebhookTags          []string `json:"webhookTags"`          // Tags for /apply webhook results
	InheritSourceTags    bool     `json:"inheritSourceTags"`    // Also copy tags from the matched source torrent

	// Category affix: add prefix or suffix to the original category name
	UseCrossCategoryAffix bool   `json:"useCrossCategoryAffix"` // Enable category affix
	CategoryAffixMode     string `json:"categoryAffixMode"`     // "prefix" or "suffix"
	CategoryAffix         string `json:"categoryAffix"`         // The affix value (default: ".cross")
	// Custom category: use exact user-specified category without any suffixing
	UseCustomCategory bool   `json:"useCustomCategory"` // Use custom category instead of affix or indexer name
	CustomCategory    string `json:"customCategory"`    // Custom category name when UseCustomCategory is true

	// Skip auto-resume settings per source mode.
	// When enabled, torrents remain paused after hash check instead of auto-resuming.
	SkipAutoResumeRSS            bool `json:"skipAutoResumeRss"`            // Skip auto-resume for RSS automation results
	SkipAutoResumeSeededSearch   bool `json:"skipAutoResumeSeededSearch"`   // Skip auto-resume for seeded torrent search results
	SkipAutoResumeCompletion     bool `json:"skipAutoResumeCompletion"`     // Skip auto-resume for completion-triggered search results
	SkipAutoResumeWebhook        bool `json:"skipAutoResumeWebhook"`        // Skip auto-resume for /apply webhook results
	SkipRecheck                  bool `json:"skipRecheck"`                  // Skip cross-seed matches that require a recheck
	RescueTitleMismatches        bool `json:"rescueTitleMismatches"`        // This setting tries exact-size results when only the title differs.
	SkipPieceBoundarySafetyCheck bool `json:"skipPieceBoundarySafetyCheck"` // Skip piece boundary safety check (risky: may corrupt existing seeded data)

	// Season pack settings
	SeasonPackSkipRepackCompare  bool                     `json:"seasonPackSkipRepackCompare"`
	SeasonPackSimplifyHDRCompare bool                     `json:"seasonPackSimplifyHdrCompare"`
	SeasonPackSimplifyWEBCompare bool                     `json:"seasonPackSimplifyWebCompare"`
	SeasonPackSkipYearCompare    bool                     `json:"seasonPackSkipYearCompare"`
	SeasonPackEnabled            bool                     `json:"seasonPackEnabled"`           // Enable season pack webhook flow
	SeasonPackAutomationEnabled  bool                     `json:"seasonPackAutomationEnabled"` // Allow qui to assemble season packs on its own initiative (RSS/automation)
	SeasonPackCoverageThreshold  float64                  `json:"seasonPackCoverageThreshold"` // Minimum episode coverage to trigger (0..1, default 0.75)
	SeasonPackTags               []string                 `json:"seasonPackTags"`              // Tags for season pack results
	SeasonPackCategory           string                   `json:"seasonPackCategory"`          // Fallback category for season pack adds ("Anything else")
	SeasonPackCategoryRules      []SeasonPackCategoryRule `json:"seasonPackCategoryRules"`     // Per-quality routing rules; first match wins, else SeasonPackCategory
	SeasonPackTVDBAPIKey         string                   `json:"seasonPackTvdbApiKey,omitempty"`
	SeasonPackTVDBPIN            string                   `json:"seasonPackTvdbPin,omitempty"`

	// Gazelle (OPS/RED) cross-seed settings.
	// When enabled, qui uses the tracker JSON APIs to find matches for OPS/RED torrents
	// instead of Torznab. Keys are stored encrypted and are redacted in API responses.
	GazelleEnabled bool   `json:"gazelleEnabled"`
	RedactedAPIKey string `json:"redactedApiKey,omitempty"`
	OrpheusAPIKey  string `json:"orpheusApiKey,omitempty"`

	CreatedAt time.Time `json:"createdAt"`
	UpdatedAt time.Time `json:"updatedAt"`
}

CrossSeedAutomationSettings controls automatic cross-seed behaviour. Contains both RSS Automation-specific settings and global cross-seed settings.

func DefaultCrossSeedAutomationSettings added in v1.8.0

func DefaultCrossSeedAutomationSettings() *CrossSeedAutomationSettings

DefaultCrossSeedAutomationSettings returns sensible defaults for RSS automation. RSS automation is disabled by default with a 2-hour interval.

type CrossSeedBlocklistEntry added in v1.14.0

type CrossSeedBlocklistEntry struct {
	InstanceID int       `json:"instanceId"`
	InfoHash   string    `json:"infoHash"`
	Note       string    `json:"note,omitempty"`
	CreatedAt  time.Time `json:"createdAt"`
}

CrossSeedBlocklistEntry represents a per-instance cross-seed blocklist item.

type CrossSeedBlocklistStore added in v1.14.0

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

func NewCrossSeedBlocklistStore added in v1.14.0

func NewCrossSeedBlocklistStore(db dbinterface.Querier) *CrossSeedBlocklistStore

func (*CrossSeedBlocklistStore) Delete added in v1.14.0

func (s *CrossSeedBlocklistStore) Delete(ctx context.Context, instanceID int, infoHash string) error

func (*CrossSeedBlocklistStore) FindBlocked added in v1.14.0

func (s *CrossSeedBlocklistStore) FindBlocked(ctx context.Context, instanceID int, hashes []string) (string, bool, error)

FindBlocked returns the first blocked infohash from the provided list.

func (*CrossSeedBlocklistStore) Get added in v1.14.0

func (s *CrossSeedBlocklistStore) Get(ctx context.Context, instanceID int, infoHash string) (*CrossSeedBlocklistEntry, error)

func (*CrossSeedBlocklistStore) List added in v1.14.0

func (*CrossSeedBlocklistStore) Upsert added in v1.14.0

type CrossSeedFeedItem added in v1.8.0

type CrossSeedFeedItem struct {
	GUID        string                  `json:"guid"`
	IndexerID   int                     `json:"indexerId"`
	Title       string                  `json:"title"`
	FirstSeenAt time.Time               `json:"firstSeenAt"`
	LastSeenAt  time.Time               `json:"lastSeenAt"`
	LastStatus  CrossSeedFeedItemStatus `json:"lastStatus"`
	LastRunID   *int64                  `json:"lastRunId,omitempty"`
	InfoHash    *string                 `json:"infoHash,omitempty"`
}

CrossSeedFeedItem tracks GUIDs pulled from indexers to avoid duplicates.

type CrossSeedFeedItemStatus added in v1.8.0

type CrossSeedFeedItemStatus string

CrossSeedFeedItemStatus tracks processing state for feed items.

const (
	CrossSeedFeedItemStatusPending   CrossSeedFeedItemStatus = "pending"
	CrossSeedFeedItemStatusProcessed CrossSeedFeedItemStatus = "processed"
	CrossSeedFeedItemStatusSkipped   CrossSeedFeedItemStatus = "skipped"
	CrossSeedFeedItemStatusFailed    CrossSeedFeedItemStatus = "failed"
)

type CrossSeedPartialPool added in v1.28.0

type CrossSeedPartialPool struct {
	ID               int64
	SourceInstanceID int
	SourceTorrentKey string
	Status           string
	CreatedAt        time.Time
	UpdatedAt        time.Time
	Members          []*CrossSeedPartialPoolMember
}

CrossSeedPartialPool groups partial link-mode torrents by their original source.

type CrossSeedPartialPoolMember added in v1.28.0

type CrossSeedPartialPoolMember struct {
	ID                  int64
	PoolID              int64
	InstanceID          int
	TorrentKey          string
	InfoHashV1          string
	InfoHashV2          string
	Mode                string
	RootPath            string
	Status              string
	MissingBytes        int64
	StartedByPool       bool
	LastDownloadedBytes *int64
	LastProgressAt      *time.Time
	RetryAfter          *time.Time
	ReviewPausePending  bool
	ResumeAttempts      *int64
	RecoveryAttempts    *int64
	LastError           string
	CreatedAt           time.Time
	UpdatedAt           time.Time
	Files               []*CrossSeedPartialPoolMemberFile
}

CrossSeedPartialPoolMember is one qBittorrent torrent managed by a partial pool. Review and retry fields persist coordinator sub-state separately from LastError diagnostics.

type CrossSeedPartialPoolMemberFile added in v1.28.0

type CrossSeedPartialPoolMemberFile struct {
	ID                int64
	MemberID          int64
	FileIndex         int
	RelativePath      string
	SizeBytes         int64
	PiecesRoot        string
	WantedAtAdmission bool
	MaterializedAtAdd bool
	// ReplaceableAtAdd records that no target path existed immediately before the qBittorrent add.
	ReplaceableAtAdd bool
	Status           string
	SourceFileID     *int64
	LastError        string
	CreatedAt        time.Time
	UpdatedAt        time.Time
}

CrossSeedPartialPoolMemberFile is durable per-file completion state.

type CrossSeedPartialPoolRegistration added in v1.28.0

type CrossSeedPartialPoolRegistration struct {
	SourceInstanceID int
	SourceTorrentKey string
	SourceAliases    []string

	MatchedInstanceID int
	MatchedTorrentKey string
	MatchedAliases    []string

	Member CrossSeedPartialPoolMember
	Files  []CrossSeedPartialPoolMemberFile
}

CrossSeedPartialPoolRegistration contains the source-resolution evidence and the member/files inserted in one transaction.

type CrossSeedRun added in v1.8.0

type CrossSeedRun struct {
	ID                int64                `json:"id"`
	TriggeredBy       string               `json:"triggeredBy"`
	Mode              CrossSeedRunMode     `json:"mode"`
	Status            CrossSeedRunStatus   `json:"status"`
	StartedAt         time.Time            `json:"startedAt"`
	CompletedAt       *time.Time           `json:"completedAt,omitempty"`
	TotalFeedItems    int                  `json:"totalFeedItems"`
	CandidatesFound   int                  `json:"candidatesFound"`
	CrossSeedsAdded   int                  `json:"crossSeedsAdded"`
	CandidatesFailed  int                  `json:"candidatesFailed"`
	CandidatesSkipped int                  `json:"candidatesSkipped"`
	Message           *string              `json:"message,omitempty"`
	ErrorMessage      *string              `json:"errorMessage,omitempty"`
	Results           []CrossSeedRunResult `json:"results,omitempty"`
	CreatedAt         time.Time            `json:"createdAt"`
}

CrossSeedRun stores the persisted automation run metadata.

type CrossSeedRunMode added in v1.8.0

type CrossSeedRunMode string

CrossSeedRunMode indicates how the run was triggered.

const (
	CrossSeedRunModeAuto   CrossSeedRunMode = "auto"
	CrossSeedRunModeManual CrossSeedRunMode = "manual"
)

type CrossSeedRunResult added in v1.8.0

type CrossSeedRunResult struct {
	InstanceID         int     `json:"instanceId"`
	InstanceName       string  `json:"instanceName"`
	IndexerName        string  `json:"indexerName,omitempty"`
	Success            bool    `json:"success"`
	Status             string  `json:"status"`
	Message            string  `json:"message,omitempty"`
	MatchedTorrentHash *string `json:"matchedTorrentHash,omitempty"`
	MatchedTorrentName *string `json:"matchedTorrentName,omitempty"`
}

CrossSeedRunResult summarises the outcome for a single instance.

type CrossSeedRunStatus added in v1.8.0

type CrossSeedRunStatus string

CrossSeedRunStatus indicates the outcome of an automation run.

const (
	CrossSeedRunStatusPending CrossSeedRunStatus = "pending"
	CrossSeedRunStatusRunning CrossSeedRunStatus = "running"
	CrossSeedRunStatusSuccess CrossSeedRunStatus = "success"
	CrossSeedRunStatusPartial CrossSeedRunStatus = "partial"
	CrossSeedRunStatusFailed  CrossSeedRunStatus = "failed"
)

type CrossSeedSearchFilters added in v1.8.0

type CrossSeedSearchFilters struct {
	Categories []string `json:"categories"`
	Tags       []string `json:"tags"`
}

CrossSeedSearchFilters capture how torrents are selected for automated search runs.

type CrossSeedSearchResult added in v1.8.0

type CrossSeedSearchResult struct {
	TorrentHash  string                      `json:"torrentHash"`
	TorrentName  string                      `json:"torrentName"`
	IndexerName  string                      `json:"indexerName"`
	ReleaseTitle string                      `json:"releaseTitle"`
	Status       CrossSeedSearchResultStatus `json:"status"`
	Message      string                      `json:"message,omitempty"`
	ProcessedAt  time.Time                   `json:"processedAt"`
}

CrossSeedSearchResult records the outcome of processing a single torrent during a search run.

type CrossSeedSearchResultStatus added in v1.20.0

type CrossSeedSearchResultStatus string

CrossSeedSearchResultStatus records the add outcome for one searched torrent.

const (
	// CrossSeedSearchResultStatusAdded means the match was added to qBittorrent.
	CrossSeedSearchResultStatusAdded CrossSeedSearchResultStatus = "added"
	// CrossSeedSearchResultStatusSkipped means the match did not require or permit an add.
	CrossSeedSearchResultStatusSkipped CrossSeedSearchResultStatus = "skipped"
	// CrossSeedSearchResultStatusFailed means the match hit an add or preparation error.
	CrossSeedSearchResultStatusFailed CrossSeedSearchResultStatus = "failed"
)

type CrossSeedSearchRun added in v1.8.0

type CrossSeedSearchRun struct {
	ID                     int64                    `json:"id"`
	InstanceID             int                      `json:"instanceId"`
	Status                 CrossSeedSearchRunStatus `json:"status"`
	StartedAt              time.Time                `json:"startedAt"`
	CompletedAt            *time.Time               `json:"completedAt,omitempty"`
	TotalTorrents          int                      `json:"totalTorrents"`
	Processed              int                      `json:"processed"`
	TorrentsWithCrossSeeds int                      `json:"torrentsWithCrossSeeds"`
	CrossSeedsAdded        int                      `json:"crossSeedsAdded"`
	TorrentsFailed         int                      `json:"torrentsFailed"`
	TorrentsSkipped        int                      `json:"torrentsSkipped"`
	Message                *string                  `json:"message,omitempty"`
	ErrorMessage           *string                  `json:"errorMessage,omitempty"`
	Filters                CrossSeedSearchFilters   `json:"filters"`
	IndexerIDs             []int                    `json:"indexerIds"`
	IntervalSeconds        int                      `json:"intervalSeconds"`
	CooldownMinutes        int                      `json:"cooldownMinutes"`
	Results                []CrossSeedSearchResult  `json:"results"`
	CreatedAt              time.Time                `json:"createdAt"`
}

CrossSeedSearchRun stores metadata for library search automation runs.

type CrossSeedSearchRunStatus added in v1.8.0

type CrossSeedSearchRunStatus string

CrossSeedSearchRunStatus represents the lifecycle state of an automated search pass.

const (
	CrossSeedSearchRunStatusRunning  CrossSeedSearchRunStatus = "running"
	CrossSeedSearchRunStatusSuccess  CrossSeedSearchRunStatus = "success"
	CrossSeedSearchRunStatusFailed   CrossSeedSearchRunStatus = "failed"
	CrossSeedSearchRunStatusCanceled CrossSeedSearchRunStatus = "canceled"
)

type CrossSeedSearchSettings added in v1.8.0

type CrossSeedSearchSettings struct {
	InstanceID      *int      `json:"instanceId"`
	Categories      []string  `json:"categories"`
	Tags            []string  `json:"tags"`
	IndexerIDs      []int     `json:"indexerIds"`
	IntervalSeconds int       `json:"intervalSeconds"`
	CooldownMinutes int       `json:"cooldownMinutes"`
	CreatedAt       time.Time `json:"createdAt"`
	UpdatedAt       time.Time `json:"updatedAt"`
}

CrossSeedSearchSettings stores defaults for manual seeded torrent searches.

func DefaultCrossSeedSearchSettings added in v1.8.0

func DefaultCrossSeedSearchSettings() *CrossSeedSearchSettings

DefaultCrossSeedSearchSettings returns defaults for seeded torrent searches.

type CrossSeedStore added in v1.8.0

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

CrossSeedStore persists automation settings, runs, and feed items.

func NewCrossSeedStore added in v1.8.0

func NewCrossSeedStore(db dbinterface.Querier, encryptionKey []byte, opts ...CredentialCipherOption) (*CrossSeedStore, error)

NewCrossSeedStore constructs a new automation store.

func (*CrossSeedStore) ClaimPartialPoolDownloader added in v1.28.0

func (s *CrossSeedStore) ClaimPartialPoolDownloader(ctx context.Context, memberID, downloadedBytes int64, admittedAt, now, admissionCutoff time.Time) (bool, error)

ClaimPartialPoolDownloader locks the pool row before inspecting current pool membership, then claims at most one eligible downloader whose admission generation matches admittedAt.

func (*CrossSeedStore) CreateRun added in v1.8.0

func (s *CrossSeedStore) CreateRun(ctx context.Context, run *CrossSeedRun) (*CrossSeedRun, error)

CreateRun inserts a new automation run record.

func (*CrossSeedStore) CreateSearchRun added in v1.8.0

func (s *CrossSeedStore) CreateSearchRun(ctx context.Context, run *CrossSeedSearchRun) (*CrossSeedSearchRun, error)

CreateSearchRun inserts a new record for a search automation run.

func (*CrossSeedStore) GetDecryptedGazelleAPIKey added in v1.14.0

func (s *CrossSeedStore) GetDecryptedGazelleAPIKey(ctx context.Context, host string) (string, bool, error)

GetDecryptedGazelleAPIKey returns the decrypted Gazelle API key for the given host. Supported hosts: redacted.sh, orpheus.network.

func (*CrossSeedStore) GetDecryptedSeasonPackTVDBCredentials added in v1.19.0

func (s *CrossSeedStore) GetDecryptedSeasonPackTVDBCredentials(ctx context.Context) (apiKey, pin string, err error)

GetDecryptedSeasonPackTVDBCredentials returns the decrypted TVDB API key and PIN for season pack metadata resolution.

func (*CrossSeedStore) GetIndexerSearchHistory added in v1.25.0

func (s *CrossSeedStore) GetIndexerSearchHistory(ctx context.Context, instanceID int, torrentHash string) (map[int]time.Time, error)

GetIndexerSearchHistory returns the last search time per indexer for a torrent. Indexers with no row have never searched this torrent.

func (*CrossSeedStore) GetLatestRun added in v1.8.0

func (s *CrossSeedStore) GetLatestRun(ctx context.Context) (*CrossSeedRun, error)

GetLatestRun returns the most recent automation run.

func (*CrossSeedStore) GetLatestSearchHistory added in v1.25.0

func (s *CrossSeedStore) GetLatestSearchHistory(ctx context.Context, torrentHash string) (time.Time, bool, error)

GetLatestSearchHistory returns the most recent search timestamp for a key across all instances. Used for pseudo-keys whose verdict is global, like season-pack diversion failures.

func (*CrossSeedStore) GetPartialPool added in v1.28.0

func (s *CrossSeedStore) GetPartialPool(ctx context.Context, poolID int64) (*CrossSeedPartialPool, error)

GetPartialPool loads a pool and all of its members/files.

func (*CrossSeedStore) GetRun added in v1.8.0

func (s *CrossSeedStore) GetRun(ctx context.Context, id int64) (*CrossSeedRun, error)

GetRun fetches a single run by ID.

func (*CrossSeedStore) GetSearchHistory added in v1.8.0

func (s *CrossSeedStore) GetSearchHistory(ctx context.Context, instanceID int, torrentHash string) (time.Time, bool, error)

GetSearchHistory returns the last time a torrent was searched.

func (*CrossSeedStore) GetSearchRun added in v1.8.0

func (s *CrossSeedStore) GetSearchRun(ctx context.Context, id int64) (*CrossSeedSearchRun, error)

GetSearchRun loads a specific search run by ID.

func (*CrossSeedStore) GetSearchSettings added in v1.8.0

func (s *CrossSeedStore) GetSearchSettings(ctx context.Context) (*CrossSeedSearchSettings, error)

GetSearchSettings returns the stored seeded search defaults, or defaults when unset.

func (*CrossSeedStore) GetSeasonPackTVDBCredentialsUpdatedAt added in v1.19.0

func (s *CrossSeedStore) GetSeasonPackTVDBCredentialsUpdatedAt(ctx context.Context) (time.Time, error)

GetSeasonPackTVDBCredentialsUpdatedAt returns the row revision used to avoid decrypting unchanged TVDB credentials on every metadata lookup.

func (*CrossSeedStore) GetSettings added in v1.8.0

GetSettings returns the current automation settings or defaults.

func (*CrossSeedStore) HasProcessedFeedItem added in v1.8.0

func (s *CrossSeedStore) HasProcessedFeedItem(ctx context.Context, guid string, indexerID int) (bool, CrossSeedFeedItemStatus, error)

HasProcessedFeedItem reports whether a GUID/indexer pair has been handled.

func (*CrossSeedStore) ListActivePartialPoolsForReconciliation added in v1.28.0

func (s *CrossSeedStore) ListActivePartialPoolsForReconciliation(ctx context.Context) ([]*CrossSeedPartialPool, error)

ListActivePartialPoolsForReconciliation loads scheduled pools with a non-removed member.

func (*CrossSeedStore) ListPartialPoolMembersAwaitingRecheckObservation added in v1.28.0

func (s *CrossSeedStore) ListPartialPoolMembersAwaitingRecheckObservation(ctx context.Context) ([]*CrossSeedPartialPoolMember, error)

ListPartialPoolMembersAwaitingRecheckObservation loads only members whose requested piece check has not yet been observed.

func (*CrossSeedStore) ListPartialPoolsForReconciliation added in v1.28.0

func (s *CrossSeedStore) ListPartialPoolsForReconciliation(ctx context.Context) ([]*CrossSeedPartialPool, error)

ListPartialPoolsForReconciliation loads every pool with a non-removed member. Manual and complete members remain observable for completion/removal.

func (*CrossSeedStore) ListRuns added in v1.8.0

func (s *CrossSeedStore) ListRuns(ctx context.Context, limit, offset int) ([]*CrossSeedRun, error)

ListRuns returns automation run history.

func (*CrossSeedStore) ListSearchRuns added in v1.8.0

func (s *CrossSeedStore) ListSearchRuns(ctx context.Context, instanceID, limit, offset int) ([]*CrossSeedSearchRun, error)

ListSearchRuns returns search automation history for an instance.

func (*CrossSeedStore) MarkFeedItem added in v1.8.0

func (s *CrossSeedStore) MarkFeedItem(ctx context.Context, item *CrossSeedFeedItem) error

MarkFeedItem updates the state of a feed item.

func (*CrossSeedStore) MarkInterruptedAutomationRuns added in v1.12.0

func (s *CrossSeedStore) MarkInterruptedAutomationRuns(ctx context.Context, completedAt time.Time, message string) (int64, error)

MarkInterruptedAutomationRuns marks any automation runs still in 'running' status as failed. This should be called at startup to reconcile runs interrupted by a crash/restart.

func (*CrossSeedStore) MarkInterruptedSearchRuns added in v1.12.0

func (s *CrossSeedStore) MarkInterruptedSearchRuns(ctx context.Context, completedAt time.Time, message string) (int64, error)

MarkInterruptedSearchRuns marks any search runs still in 'running' status as failed. This should be called at startup to reconcile runs interrupted by a crash/restart.

func (*CrossSeedStore) MarkPartialPoolMemberRemoved added in v1.28.0

func (s *CrossSeedStore) MarkPartialPoolMemberRemoved(ctx context.Context, poolID, memberID int64, admittedAt time.Time, reason string) error

MarkPartialPoolMemberRemoved records qBittorrent removal only while the member's pool and admission timestamp still match, then deletes an empty pool.

func (*CrossSeedStore) PruneEmptyPartialPools added in v1.28.0

func (s *CrossSeedStore) PruneEmptyPartialPools(ctx context.Context) error

PruneEmptyPartialPools removes source anchors left after instance cascades.

func (*CrossSeedStore) PruneFeedItems added in v1.8.0

func (s *CrossSeedStore) PruneFeedItems(ctx context.Context, olderThan time.Time) (int64, error)

PruneFeedItems removes processed feed items older than the provided cutoff.

func (*CrossSeedStore) RegisterPartialPoolMember added in v1.28.0

RegisterPartialPoolMember atomically resolves or creates the source pool and persists one member plus every file. An alias-equivalent re-admission keeps the member identity but replaces its stale admission and file state.

func (*CrossSeedStore) ResolvePartialPoolMember added in v1.28.0

func (s *CrossSeedStore) ResolvePartialPoolMember(ctx context.Context, instanceID int, aliases ...string) (*CrossSeedPartialPool, *CrossSeedPartialPoolMember, error)

ResolvePartialPoolMember finds a member by any hash alias and reactivates its pool.

func (*CrossSeedStore) RewriteLegacyCredentials added in v1.29.0

func (s *CrossSeedStore) RewriteLegacyCredentials(ctx context.Context) (int, error)

RewriteLegacyCredentials re-encrypts stored cross-seed credentials that still carry the pre-HKDF format and reports how many rows it rewrote.

func (*CrossSeedStore) SetPartialPoolStatus added in v1.28.0

func (s *CrossSeedStore) SetPartialPoolStatus(ctx context.Context, poolID int64, status string) error

SetPartialPoolStatus changes pool scheduling state.

func (*CrossSeedStore) SetPartialPoolStatusIfUnchanged added in v1.28.0

func (s *CrossSeedStore) SetPartialPoolStatusIfUnchanged(ctx context.Context, poolID int64, updatedAt time.Time, status string) (bool, error)

SetPartialPoolStatusIfUnchanged changes scheduling state only when the pool has not been updated since it was loaded.

func (*CrossSeedStore) TouchFeedItem added in v1.30.0

func (s *CrossSeedStore) TouchFeedItem(ctx context.Context, guid string, indexerID int, seenAt time.Time) error

TouchFeedItem advances last_seen_at to seenAt's UTC day so PruneFeedItems keeps an item that is still in the feed. Unlike an ON CONFLICT upsert, a plain UPDATE whose WHERE fails takes no row lock, so same-day polls write no WAL.

func (*CrossSeedStore) TransitionPartialPoolFile added in v1.28.0

func (s *CrossSeedStore) TransitionPartialPoolFile(ctx context.Context, fileID int64, admittedAt time.Time, expected []string, status string, mutation PartialPoolFileMutation) (bool, error)

TransitionPartialPoolFile applies an expected-state and admission compare-and-set.

func (*CrossSeedStore) TransitionPartialPoolHardlinkRollback added in v1.28.0

func (s *CrossSeedStore) TransitionPartialPoolHardlinkRollback(ctx context.Context, memberID, fileID int64, memberAdmittedAt, fileAdmittedAt time.Time, memberStatus string) (bool, error)

TransitionPartialPoolHardlinkRollback atomically marks a verifying file missing, clears its source, and records the member's pending follow-up check. It returns false without committing when either compare-and-set no longer matches, and returns an error for invalid input or database failures.

func (*CrossSeedStore) TransitionPartialPoolMember added in v1.28.0

func (s *CrossSeedStore) TransitionPartialPoolMember(ctx context.Context, memberID int64, admittedAt time.Time, expected []string, status string, mutation PartialPoolMemberMutation) (bool, error)

TransitionPartialPoolMember applies an expected-state and admission compare-and-set.

func (*CrossSeedStore) UpdateRun added in v1.8.0

func (s *CrossSeedStore) UpdateRun(ctx context.Context, run *CrossSeedRun) (*CrossSeedRun, error)

UpdateRun updates an existing run with final statistics.

func (*CrossSeedStore) UpdateSearchRun added in v1.8.0

func (s *CrossSeedStore) UpdateSearchRun(ctx context.Context, run *CrossSeedSearchRun) error

UpdateSearchRun persists the full row of a search run, results blob included. UpdateSearchRunProgress is the cheap per-candidate write.

func (*CrossSeedStore) UpdateSearchRunProgress added in v1.29.0

func (s *CrossSeedStore) UpdateSearchRunProgress(ctx context.Context, run *CrossSeedSearchRun) error

UpdateSearchRunProgress writes the live counters of a search run and leaves results_json alone. The hot per-candidate path uses it so the bytes written per candidate stay constant; UpdateSearchRun persists the full row.

func (*CrossSeedStore) UpsertIndexerSearchHistory added in v1.25.0

func (s *CrossSeedStore) UpsertIndexerSearchHistory(ctx context.Context, instanceID int, torrentHash string, indexerIDs []int, searchedAt time.Time) error

UpsertIndexerSearchHistory stamps a search on each covered indexer for a torrent.

func (*CrossSeedStore) UpsertSearchHistory added in v1.8.0

func (s *CrossSeedStore) UpsertSearchHistory(ctx context.Context, instanceID int, torrentHash string, searchedAt time.Time) error

UpsertSearchHistory updates the last searched timestamp for a torrent on an instance.

func (*CrossSeedStore) UpsertSearchSettings added in v1.8.0

func (s *CrossSeedStore) UpsertSearchSettings(ctx context.Context, settings *CrossSeedSearchSettings) (*CrossSeedSearchSettings, error)

UpsertSearchSettings saves seeded search defaults.

func (*CrossSeedStore) UpsertSettings added in v1.8.0

UpsertSettings saves automation settings and returns the updated value.

type DashboardSettings added in v1.9.0

type DashboardSettings struct {
	ID                           int             `json:"id"`
	UserID                       int             `json:"userId"`
	SectionVisibility            map[string]bool `json:"sectionVisibility"`
	SectionOrder                 []string        `json:"sectionOrder"`
	SectionCollapsed             map[string]bool `json:"sectionCollapsed"`
	TrackerBreakdownSortColumn   string          `json:"trackerBreakdownSortColumn"`
	TrackerBreakdownSortDir      string          `json:"trackerBreakdownSortDirection"`
	TrackerBreakdownItemsPerPage int             `json:"trackerBreakdownItemsPerPage"`
	CreatedAt                    time.Time       `json:"createdAt"`
	UpdatedAt                    time.Time       `json:"updatedAt"`
}

type DashboardSettingsInput added in v1.9.0

type DashboardSettingsInput struct {
	SectionVisibility            map[string]bool `json:"sectionVisibility,omitempty"`
	SectionOrder                 []string        `json:"sectionOrder,omitempty"`
	SectionCollapsed             map[string]bool `json:"sectionCollapsed,omitempty"`
	TrackerBreakdownSortColumn   string          `json:"trackerBreakdownSortColumn,omitempty"`
	TrackerBreakdownSortDir      string          `json:"trackerBreakdownSortDirection,omitempty"`
	TrackerBreakdownItemsPerPage int             `json:"trackerBreakdownItemsPerPage,omitempty"`
}

type DashboardSettingsStore added in v1.9.0

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

func NewDashboardSettingsStore added in v1.9.0

func NewDashboardSettingsStore(db dbinterface.Querier) *DashboardSettingsStore

func (*DashboardSettingsStore) GetByUserID added in v1.9.0

func (s *DashboardSettingsStore) GetByUserID(ctx context.Context, userID int) (*DashboardSettings, error)

GetByUserID returns settings for a user, creating defaults if none exist

func (*DashboardSettingsStore) Update added in v1.9.0

Update updates settings for a user (partial update - merges with existing)

type DeleteAction added in v1.12.0

type DeleteAction struct {
	Enabled          bool           `json:"enabled" doc:"Whether the action runs."`
	Mode             string         `` /* 178-byte string literal not displayed */
	IncludeHardlinks bool           `` /* 182-byte string literal not displayed */
	GroupID          string         `` /* 198-byte string literal not displayed */
	Atomic           string         `json:"atomic,omitempty" doc:"With 'groupId': 'all' deletes the group only when every torrent in it matches."`
	Condition        *RuleCondition `` /* 127-byte string literal not displayed */
}

DeleteAction configures deletion with mode and conditions.

type DirScanDirectory added in v1.13.0

type DirScanDirectory struct {
	ID                     int        `json:"id"`
	Path                   string     `json:"path"`
	QbitPathPrefix         string     `json:"qbitPathPrefix,omitempty"`
	Category               string     `json:"category,omitempty"`
	Tags                   []string   `json:"tags"`
	AllowedDownloadClients []string   `json:"allowedDownloadClients"`
	Enabled                bool       `json:"enabled"`
	ArrInstanceID          *int       `json:"arrInstanceId,omitempty"`
	TargetInstanceID       int        `json:"targetInstanceId"`
	ScanIntervalMinutes    int        `json:"scanIntervalMinutes"`
	SkipIndividualEpisodes bool       `json:"skipIndividualEpisodes"`
	LastScanAt             *time.Time `json:"lastScanAt,omitempty"`
	CreatedAt              time.Time  `json:"createdAt"`
	UpdatedAt              time.Time  `json:"updatedAt"`
}

DirScanDirectory represents a configured scan directory.

type DirScanDirectoryUpdateParams added in v1.13.0

type DirScanDirectoryUpdateParams struct {
	Path                   *string
	QbitPathPrefix         *string
	Category               *string
	Tags                   *[]string
	AllowedDownloadClients *[]string
	Enabled                *bool
	ArrInstanceID          *int // Use -1 to clear
	TargetInstanceID       *int
	ScanIntervalMinutes    *int
	SkipIndividualEpisodes *bool
}

DirScanDirectoryUpdateParams holds optional fields for updating a directory.

type DirScanFile added in v1.13.0

type DirScanFile struct {
	ID                 int64             `json:"id"`
	DirectoryID        int               `json:"directoryId"`
	FilePath           string            `json:"filePath"`
	FileSize           int64             `json:"fileSize"`
	FileModTime        time.Time         `json:"fileModTime"`
	FileID             []byte            `json:"-"` // Platform-neutral FileID (dev+ino on Unix, volume serial+128-bit ID on Windows)
	Status             DirScanFileStatus `json:"status"`
	MatchedTorrentHash string            `json:"matchedTorrentHash,omitempty"`
	MatchedIndexerID   *int              `json:"matchedIndexerId,omitempty"`
	// SearchedIndexerIDs lists the indexers that the search covered when the row
	// was stamped no_match. A nil value means the search set is unknown (legacy
	// rows); such rows stay final.
	SearchedIndexerIDs []int      `json:"searchedIndexerIds,omitempty"`
	LastProcessedAt    *time.Time `json:"lastProcessedAt,omitempty"`
}

DirScanFile represents a scanned file tracking entry.

type DirScanFileStatus added in v1.13.0

type DirScanFileStatus string

DirScanFileStatus defines the status of a scanned file.

const (
	DirScanFileStatusPending        DirScanFileStatus = "pending" //nolint:goconst // type-safe enum values intentionally share strings with other status types
	DirScanFileStatusMatched        DirScanFileStatus = "matched"
	DirScanFileStatusNoMatch        DirScanFileStatus = "no_match"
	DirScanFileStatusError          DirScanFileStatus = "error"
	DirScanFileStatusAlreadySeeding DirScanFileStatus = "already_seeding"
	DirScanFileStatusInQBittorrent  DirScanFileStatus = "in_qbittorrent"
)

Status constants are type-safe enums; duplicate string values across types are intentional.

type DirScanRun added in v1.13.0

type DirScanRun struct {
	ID            int64            `json:"id"`
	DirectoryID   int              `json:"directoryId"`
	Status        DirScanRunStatus `json:"status"`
	TriggeredBy   string           `json:"triggeredBy"`
	ScanRoot      string           `json:"scanRoot,omitempty"`
	FilesFound    int              `json:"filesFound"`
	FilesSkipped  int              `json:"filesSkipped"`
	MatchesFound  int              `json:"matchesFound"`
	TorrentsAdded int              `json:"torrentsAdded"`
	ErrorMessage  string           `json:"errorMessage,omitempty"`
	StartedAt     time.Time        `json:"startedAt"`
	CompletedAt   *time.Time       `json:"completedAt,omitempty"`
}

DirScanRun represents a scan run history entry.

type DirScanRunInjection added in v1.13.0

type DirScanRunInjection struct {
	ID                 int64                     `json:"id"`
	RunID              int64                     `json:"runId"`
	DirectoryID        int                       `json:"directoryId"`
	Status             DirScanRunInjectionStatus `json:"status"`
	SearcheeName       string                    `json:"searcheeName"`
	TorrentName        string                    `json:"torrentName"`
	InfoHash           string                    `json:"infoHash"`
	ContentType        string                    `json:"contentType"`
	IndexerName        string                    `json:"indexerName,omitempty"`
	TrackerDomain      string                    `json:"trackerDomain,omitempty"`
	TrackerDisplayName string                    `json:"trackerDisplayName,omitempty"`
	LinkMode           string                    `json:"linkMode,omitempty"`
	SavePath           string                    `json:"savePath,omitempty"`
	Category           string                    `json:"category,omitempty"`
	Tags               []string                  `json:"tags"`
	ErrorMessage       string                    `json:"errorMessage,omitempty"`
	CreatedAt          time.Time                 `json:"createdAt"`
}

DirScanRunInjection represents a successful or failed injection attempt for a scan run.

type DirScanRunInjectionStatus added in v1.13.0

type DirScanRunInjectionStatus string

DirScanRunInjectionStatus defines the status of an injection attempt.

const (
	DirScanRunInjectionStatusAdded  DirScanRunInjectionStatus = "added"
	DirScanRunInjectionStatusFailed DirScanRunInjectionStatus = "failed" //nolint:goconst // type-safe enum values intentionally share strings with other status types
)

type DirScanRunStatus added in v1.13.0

type DirScanRunStatus string

DirScanRunStatus defines the status of a scan run.

const (
	DirScanRunStatusQueued    DirScanRunStatus = "queued"
	DirScanRunStatusScanning  DirScanRunStatus = "scanning"
	DirScanRunStatusSearching DirScanRunStatus = "searching"
	DirScanRunStatusInjecting DirScanRunStatus = "injecting"
	DirScanRunStatusSuccess   DirScanRunStatus = "success"  //nolint:goconst // type-safe enum values intentionally share strings with other status types
	DirScanRunStatusFailed    DirScanRunStatus = "failed"   //nolint:goconst // type-safe enum values intentionally share strings with other status types
	DirScanRunStatusCanceled  DirScanRunStatus = "canceled" //nolint:goconst // type-safe enum values intentionally share strings with other status types
)

Run status constants are type-safe enums; duplicate string values across types are intentional.

type DirScanSettings added in v1.13.0

type DirScanSettings struct {
	ID                           int       `json:"id"`
	Enabled                      bool      `json:"enabled"`
	MatchMode                    MatchMode `json:"matchMode"`
	SizeTolerancePercent         float64   `json:"sizeTolerancePercent"`
	MinPieceRatio                float64   `json:"minPieceRatio"`
	MaxSearcheesPerRun           int       `json:"maxSearcheesPerRun"`
	MaxSearcheeAgeDays           int       `json:"maxSearcheeAgeDays"`
	AllowPartial                 bool      `json:"allowPartial"`
	SkipPieceBoundarySafetyCheck bool      `json:"skipPieceBoundarySafetyCheck"`
	StartPaused                  bool      `json:"startPaused"`
	DownloadMissingFiles         bool      `json:"downloadMissingFiles"`
	Category                     string    `json:"category"`
	Tags                         []string  `json:"tags"`
	CreatedAt                    time.Time `json:"createdAt"`
	UpdatedAt                    time.Time `json:"updatedAt"`
}

DirScanSettings represents global directory scanner settings.

type DirScanStore added in v1.13.0

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

DirScanStore handles database operations for directory scanner.

func NewDirScanStore added in v1.13.0

func NewDirScanStore(db dbinterface.Querier) *DirScanStore

NewDirScanStore creates a new DirScanStore.

func (*DirScanStore) CancelQueuedRuns added in v1.15.0

func (s *DirScanStore) CancelQueuedRuns(ctx context.Context, directoryID int) error

CancelQueuedRuns marks all queued runs for a directory as canceled.

func (*DirScanStore) CreateDirectory added in v1.13.0

func (s *DirScanStore) CreateDirectory(ctx context.Context, dir *DirScanDirectory) (*DirScanDirectory, error)

CreateDirectory creates a new scan directory.

func (*DirScanStore) CreateRun added in v1.13.0

func (s *DirScanStore) CreateRun(ctx context.Context, directoryID int, triggeredBy, scanRoot string) (int64, error)

CreateRun creates a new scan run.

func (*DirScanStore) CreateRunIfNoActive added in v1.13.0

func (s *DirScanStore) CreateRunIfNoActive(ctx context.Context, directoryID int, triggeredBy, scanRoot string) (int64, error)

CreateRunIfNoActive atomically checks for active runs and creates a new one if none exist.

func (*DirScanStore) CreateRunInjection added in v1.13.0

func (s *DirScanStore) CreateRunInjection(ctx context.Context, injection *DirScanRunInjection) error

CreateRunInjection records a successful or failed injection attempt for a run.

func (*DirScanStore) DeleteDirectory added in v1.13.0

func (s *DirScanStore) DeleteDirectory(ctx context.Context, id int) error

DeleteDirectory deletes a scan directory.

func (*DirScanStore) DeleteFilesForDirectory added in v1.13.0

func (s *DirScanStore) DeleteFilesForDirectory(ctx context.Context, directoryID int) error

DeleteFilesForDirectory deletes all tracked files for a directory.

func (*DirScanStore) GetActiveRun added in v1.13.0

func (s *DirScanStore) GetActiveRun(ctx context.Context, directoryID int) (*DirScanRun, error)

GetActiveRun returns the active run for a directory, if any.

func (*DirScanStore) GetDirectory added in v1.13.0

func (s *DirScanStore) GetDirectory(ctx context.Context, id int) (*DirScanDirectory, error)

GetDirectory retrieves a directory by ID.

func (*DirScanStore) GetQueuedRun added in v1.15.0

func (s *DirScanStore) GetQueuedRun(ctx context.Context, directoryID int) (*DirScanRun, error)

GetQueuedRun returns the most recent queued run for a directory, if any.

func (*DirScanStore) GetRun added in v1.13.0

func (s *DirScanStore) GetRun(ctx context.Context, runID int64) (*DirScanRun, error)

GetRun retrieves a run by ID.

func (*DirScanStore) GetSettings added in v1.13.0

func (s *DirScanStore) GetSettings(ctx context.Context) (*DirScanSettings, error)

GetSettings retrieves the global directory scanner settings.

func (*DirScanStore) ListDirectories added in v1.13.0

func (s *DirScanStore) ListDirectories(ctx context.Context) ([]*DirScanDirectory, error)

ListDirectories retrieves all scan directories.

func (*DirScanStore) ListDirectoryIDs added in v1.16.0

func (s *DirScanStore) ListDirectoryIDs(ctx context.Context) ([]int, error)

ListDirectoryIDs retrieves all scan directory IDs.

func (*DirScanStore) ListEnabledDirectories added in v1.13.0

func (s *DirScanStore) ListEnabledDirectories(ctx context.Context) ([]*DirScanDirectory, error)

ListEnabledDirectories returns all enabled directories.

func (*DirScanStore) ListFiles added in v1.13.0

func (s *DirScanStore) ListFiles(ctx context.Context, directoryID int, status *DirScanFileStatus, limit, offset int) ([]*DirScanFile, error)

ListFiles lists files for a directory with optional status filter.

func (*DirScanStore) ListRunInjections added in v1.13.0

func (s *DirScanStore) ListRunInjections(ctx context.Context, directoryID int, runID int64, limit, offset int) ([]*DirScanRunInjection, error)

ListRunInjections returns injection attempts for a run (newest first).

func (*DirScanStore) ListRuns added in v1.13.0

func (s *DirScanStore) ListRuns(ctx context.Context, directoryID, limit int) ([]*DirScanRun, error)

ListRuns lists recent runs for a directory.

func (*DirScanStore) MarkActiveRunsFailed added in v1.13.0

func (s *DirScanStore) MarkActiveRunsFailed(ctx context.Context, errorMessage string) (int64, error)

MarkActiveRunsFailed marks any in-progress runs as failed (typically after a restart).

func (*DirScanStore) PruneMissingFiles added in v1.29.0

func (s *DirScanStore) PruneMissingFiles(ctx context.Context, directoryID int) (int64, error)

PruneMissingFiles removes rows whose file was absent from the last dirScanPruneGraceRuns successful scans of the directory and returns how many it removed. It removes nothing when the directory has too little successful scan history to judge, or when the latest scan refreshed too few rows to be trusted.

func (*DirScanStore) PruneRunHistory added in v1.16.0

func (s *DirScanStore) PruneRunHistory(ctx context.Context) error

PruneRunHistory trims each directory to the most recent retained runs.

func (*DirScanStore) RequeueNoMatchFiles added in v1.25.0

func (s *DirScanStore) RequeueNoMatchFiles(ctx context.Context, directoryID int) (int64, error)

RequeueNoMatchFiles resets no_match rows for a directory to pending so the next scan searches them again. Matched and already-seeding rows are kept.

It deliberately leaves last_processed_at alone: that column records when a scan last saw the file on disk, and a requeue never visits the filesystem. Writing it here would let a requeue racing a scan pass off untouched rows as freshly seen, which is what PruneMissingFiles reads to judge whether a scan had real coverage.

func (*DirScanStore) UpdateDirectory added in v1.13.0

func (s *DirScanStore) UpdateDirectory(ctx context.Context, id int, params *DirScanDirectoryUpdateParams) (*DirScanDirectory, error)

UpdateDirectory updates a scan directory.

func (*DirScanStore) UpdateDirectoryLastScan added in v1.13.0

func (s *DirScanStore) UpdateDirectoryLastScan(ctx context.Context, id int) error

UpdateDirectoryLastScan updates the last scan timestamp.

func (*DirScanStore) UpdateRunCanceled added in v1.13.0

func (s *DirScanStore) UpdateRunCanceled(ctx context.Context, runID int64) error

UpdateRunCanceled marks a run as canceled.

func (*DirScanStore) UpdateRunCompleted added in v1.13.0

func (s *DirScanStore) UpdateRunCompleted(ctx context.Context, runID int64, matchesFound, torrentsAdded int) error

UpdateRunCompleted marks a run as completed successfully.

func (*DirScanStore) UpdateRunFailed added in v1.13.0

func (s *DirScanStore) UpdateRunFailed(ctx context.Context, runID int64, errorMessage string) error

UpdateRunFailed marks a run as failed.

func (*DirScanStore) UpdateRunScanRoot added in v1.15.0

func (s *DirScanStore) UpdateRunScanRoot(ctx context.Context, runID int64, scanRoot string) error

UpdateRunScanRoot updates the scan root of a run.

func (*DirScanStore) UpdateRunStats added in v1.13.0

func (s *DirScanStore) UpdateRunStats(ctx context.Context, runID int64, filesFound, filesSkipped, matchesFound, torrentsAdded int) error

UpdateRunStats updates the stats of a run.

func (*DirScanStore) UpdateRunStatus added in v1.13.0

func (s *DirScanStore) UpdateRunStatus(ctx context.Context, runID int64, status DirScanRunStatus) error

UpdateRunStatus updates the status of a run.

func (*DirScanStore) UpdateRunStatusIfCurrent added in v1.15.0

func (s *DirScanStore) UpdateRunStatusIfCurrent(ctx context.Context, runID int64, currentStatus, nextStatus DirScanRunStatus) (bool, error)

UpdateRunStatusIfCurrent updates the status of a run only when it is still in the expected state.

func (*DirScanStore) UpdateSettings added in v1.13.0

func (s *DirScanStore) UpdateSettings(ctx context.Context, settings *DirScanSettings) (*DirScanSettings, error)

UpdateSettings updates the global directory scanner settings.

func (*DirScanStore) UpsertFile added in v1.13.0

func (s *DirScanStore) UpsertFile(ctx context.Context, file *DirScanFile) error

UpsertFile inserts or updates a scanned file.

type DiscScanRun added in v1.29.0

type DiscScanRun struct {
	ID             int64      `json:"id"`
	InstanceID     int        `json:"instanceId"`
	TorrentHash    string     `json:"torrentHash"`
	DiscPath       string     `json:"discPath"`
	ResolvedPath   string     `json:"resolvedPath"`
	Status         string     `json:"status"`
	ErrorMessage   string     `json:"errorMessage,omitempty"`
	ProcessedBytes int64      `json:"processedBytes"`
	TotalBytes     int64      `json:"totalBytes"`
	QueuePosition  int        `json:"queuePosition,omitempty"`
	Report         string     `json:"report,omitempty"`
	QuickSummary   string     `json:"quickSummary,omitempty"`
	ForumsBlock    string     `json:"forumsBlock,omitempty"`
	CreatedAt      time.Time  `json:"createdAt"`
	StartedAt      *time.Time `json:"startedAt,omitempty"`
	CompletedAt    *time.Time `json:"completedAt,omitempty"`
}

DiscScanRun is one queued or running BDInfo job on one Disc, and after completion its cached Disc report.

func (*DiscScanRun) Active added in v1.29.0

func (r *DiscScanRun) Active() bool

Active reports whether the run is still queued or running.

type DiscScanStore added in v1.29.0

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

DiscScanStore handles database operations for Disc scans.

func NewDiscScanStore added in v1.29.0

func NewDiscScanStore(db dbinterface.Querier) *DiscScanStore

NewDiscScanStore creates a new DiscScanStore.

func (*DiscScanStore) Create added in v1.29.0

func (s *DiscScanStore) Create(ctx context.Context, instanceID int, torrentHash, discPath, resolvedPath string) (int64, error)

Create inserts a pending run and returns its id.

func (*DiscScanStore) GetByInstance added in v1.29.0

func (s *DiscScanStore) GetByInstance(ctx context.Context, instanceID int, runID int64) (*DiscScanRun, error)

GetByInstance returns one run scoped to an instance, or nil.

func (*DiscScanStore) Latest added in v1.29.0

func (s *DiscScanStore) Latest(ctx context.Context, instanceID int, resolvedPath string) (*DiscScanRun, error)

Latest returns the newest run for the cache key (instance, resolved path), or nil.

func (*DiscScanStore) ListNewestForTorrent added in v1.29.0

func (s *DiscScanStore) ListNewestForTorrent(ctx context.Context, instanceID int, torrentHash string) ([]*DiscScanRun, error)

ListNewestForTorrent returns the newest run per Disc path for one torrent.

func (*DiscScanStore) MarkCanceled added in v1.29.0

func (s *DiscScanStore) MarkCanceled(ctx context.Context, runID int64) (bool, error)

MarkCanceled cancels a pending or scanning run. Returns false when the run had already finished.

func (*DiscScanStore) MarkCompleted added in v1.29.0

func (s *DiscScanStore) MarkCompleted(ctx context.Context, runID int64, report, quickSummary, forumsBlock string) (bool, error)

MarkCompleted stores the report on a scanning run.

func (*DiscScanStore) MarkFailed added in v1.29.0

func (s *DiscScanStore) MarkFailed(ctx context.Context, runID int64, errorMessage string) (bool, error)

MarkFailed fails a scanning run with a message.

func (*DiscScanStore) MarkInterrupted added in v1.29.0

func (s *DiscScanStore) MarkInterrupted(ctx context.Context, errorMessage string) error

MarkInterrupted fails every scanning run. Called once at startup, because a scan does not survive a process restart.

func (*DiscScanStore) MarkScanning added in v1.29.0

func (s *DiscScanStore) MarkScanning(ctx context.Context, runID int64) (bool, error)

MarkScanning moves a pending run to scanning. Returns false when the run was no longer pending, for example because it was canceled meanwhile.

func (*DiscScanStore) NextPending added in v1.29.0

func (s *DiscScanStore) NextPending(ctx context.Context) (*DiscScanRun, error)

NextPending returns the oldest pending run, or nil when the queue is empty.

func (*DiscScanStore) UpdateProgress added in v1.29.0

func (s *DiscScanStore) UpdateProgress(ctx context.Context, runID int64, processed, total int64) error

UpdateProgress stores the byte counters of a running scan.

type EpisodeMap added in v1.29.0

type EpisodeMap struct {
	Season   int `json:"season"`
	Episode  int `json:"episode"`
	Absolute int `json:"absolute"`
}

EpisodeMap is the Sonarr-sourced (season, episode, absolute) triple for the one episode a release name resolves to. It lets a seasoned and an absolute-numbered release count as the same episode.

type ExportToInstanceAction added in v1.19.0

type ExportToInstanceAction struct {
	Enabled          bool           `json:"enabled" doc:"Whether the action runs."`
	TargetInstanceID int            `` /* 132-byte string literal not displayed */
	SavePath         string         `json:"savePath" doc:"The save path on the target instance. Supports Go templates."`
	Category         string         `json:"category,omitempty" doc:"The category on the target instance."`
	Tags             []string       `json:"tags,omitempty" doc:"The tags on the target instance."`
	Paused           bool           `json:"paused,omitempty" doc:"Add the torrent paused."`
	SkipChecking     *bool          `json:"skipChecking,omitempty" doc:"Skip the hash check on the target instance. Default 'true'."`
	ContentLayout    string         `` /* 142-byte string literal not displayed */
	Condition        *RuleCondition `json:"condition,omitempty" doc:"Optional. When set, the action applies only to torrents that also match this condition."`
}

ExportToInstanceAction configures exporting a torrent to a different qBittorrent instance.

func (*ExportToInstanceAction) SkipCheckingEnabled added in v1.19.0

func (a *ExportToInstanceAction) SkipCheckingEnabled() bool

SkipCheckingEnabled returns the effective skip_checking value (defaults true).

func (*ExportToInstanceAction) Validate added in v1.19.0

func (a *ExportToInstanceAction) Validate() error

Validate checks that the ExportToInstanceAction has valid configuration.

type ExternalIDs added in v1.12.0

type ExternalIDs struct {
	IMDbID   string `json:"imdb_id,omitempty"`
	TMDbID   int    `json:"tmdb_id,omitempty"`
	TVDbID   int    `json:"tvdb_id,omitempty"`
	TVMazeID int    `json:"tvmaze_id,omitempty"`
}

ExternalIDs represents the external IDs resolved from ARR instances

func (*ExternalIDs) IsEmpty added in v1.12.0

func (e *ExternalIDs) IsEmpty() bool

IsEmpty returns true if no IDs are set

type ExternalProgram added in v1.7.0

type ExternalProgram struct {
	ID           int           `json:"id"`
	Name         string        `json:"name"`
	Path         string        `json:"path"`
	ArgsTemplate string        `json:"args_template"`
	Enabled      bool          `json:"enabled"`
	UseTerminal  bool          `json:"use_terminal"`
	PathMappings []PathMapping `json:"path_mappings"`
	CreatedAt    time.Time     `json:"created_at"`
	UpdatedAt    time.Time     `json:"updated_at"`
}

ExternalProgram represents a configured external program that can be executed from the torrent context menu

type ExternalProgramAction added in v1.14.0

type ExternalProgramAction struct {
	Enabled   bool           `json:"enabled" doc:"Whether the action runs."`
	ProgramID int            `json:"programId" doc:"The ID of the external program in this qui. An export keeps the ID of the qui that made it."` // FK to external_programs table
	Condition *RuleCondition `json:"condition,omitempty" doc:"Optional. When set, the action applies only to torrents that also match this condition."`
}

ExternalProgramAction configures external program execution with optional conditions.

func (*ExternalProgramAction) Validate added in v1.14.0

func (a *ExternalProgramAction) Validate() error

Validate checks that the ExternalProgramAction has valid configuration.

type ExternalProgramCreate added in v1.7.0

type ExternalProgramCreate struct {
	Name         string        `json:"name"`
	Path         string        `json:"path"`
	ArgsTemplate string        `json:"args_template"`
	Enabled      bool          `json:"enabled"`
	UseTerminal  bool          `json:"use_terminal"`
	PathMappings []PathMapping `json:"path_mappings"`
}

ExternalProgramCreate represents the data needed to create a new external program

type ExternalProgramExecute added in v1.7.0

type ExternalProgramExecute struct {
	ProgramID  int      `json:"program_id"`
	InstanceID int      `json:"instance_id"`
	Hashes     []string `json:"hashes"`
}

ExternalProgramExecute represents a request to execute an external program with torrent data

type ExternalProgramStore added in v1.7.0

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

func NewExternalProgramStore added in v1.7.0

func NewExternalProgramStore(db dbinterface.Querier) *ExternalProgramStore

func (*ExternalProgramStore) Create added in v1.7.0

func (*ExternalProgramStore) Delete added in v1.7.0

func (s *ExternalProgramStore) Delete(ctx context.Context, id int) error

func (*ExternalProgramStore) GetByID added in v1.7.0

func (s *ExternalProgramStore) GetByID(ctx context.Context, id int) (*ExternalProgram, error)

func (*ExternalProgramStore) List added in v1.7.0

func (*ExternalProgramStore) ListEnabled added in v1.7.0

func (s *ExternalProgramStore) ListEnabled(ctx context.Context) ([]*ExternalProgram, error)

func (*ExternalProgramStore) Update added in v1.7.0

type ExternalProgramUpdate added in v1.7.0

type ExternalProgramUpdate struct {
	Name         string        `json:"name"`
	Path         string        `json:"path"`
	ArgsTemplate string        `json:"args_template"`
	Enabled      bool          `json:"enabled"`
	UseTerminal  bool          `json:"use_terminal"`
	PathMappings []PathMapping `json:"path_mappings"`
}

ExternalProgramUpdate represents the data needed to update an external program

type FieldMultiplierScoreRule added in v1.15.0

type FieldMultiplierScoreRule struct {
	Field      ConditionField `json:"field" doc:"The condition field whose value is multiplied."`
	Multiplier float64        `json:"multiplier" doc:"The number to multiply the field value by. The result is added to the score."`
}

FieldMultiplierScoreRule applies a multiplier to a numeric field.

type FilesystemCapabilities added in v1.31.0

type FilesystemCapabilities struct {
	Read     bool `json:"read"`
	Identity bool `json:"identity"`
	Write    bool `json:"write"`
	Content  bool `json:"content"`
}

FilesystemCapabilities is what qui can do with one instance's files.

func FilesystemCapabilitiesOf added in v1.31.0

func FilesystemCapabilitiesOf(inst *Instance) FilesystemCapabilities

FilesystemCapabilitiesOf is the one place that maps an instance's filesystem mode to what qui may do with its files. A remote instance gets Write with #2942, once the SFTP writes from #2725 are in, and Identity with the exec tier (#2726).

func (FilesystemCapabilities) Has added in v1.31.0

type FilesystemCapability added in v1.31.0

type FilesystemCapability string

FilesystemCapability names one thing qui can do with an instance's files.

const (
	// CapabilityRead is listing, stat, and walking paths.
	CapabilityRead FilesystemCapability = "read"
	// CapabilityIdentity is trusting a file's identity (device and inode) to
	// find hardlinks. Only a kernel-attested identity counts.
	CapabilityIdentity FilesystemCapability = "identity"
	// CapabilityWrite is creating and removing link trees.
	CapabilityWrite FilesystemCapability = "write"
	// CapabilityContent is reading file bytes.
	CapabilityContent FilesystemCapability = "content"
)

type FilesystemMode added in v1.30.0

type FilesystemMode string

FilesystemMode describes how qui reaches an instance's torrent data.

const (
	FilesystemModeNone   FilesystemMode = "none"
	FilesystemModeLocal  FilesystemMode = "local"
	FilesystemModeRemote FilesystemMode = "remote"
)

func FilesystemAccessMode added in v1.30.0

func FilesystemAccessMode(inst *Instance) FilesystemMode

FilesystemAccessMode: local takes precedence over remote, and remote requires a confirmed host-key pin — an SSH host with credentials but no pin is a connection the user has not trusted yet, and no filesystem operation may run over it.

This routes, it does not authorize. A row whose pin has been tampered with still reads as remote here; the connection layer is what must treat GetHostKeyPin's error as fatal.

type FilterView added in v1.25.0

type FilterView struct {
	ID        int             `json:"id"`
	Name      string          `json:"name"`
	Filters   json.RawMessage `json:"filters"`
	CreatedAt time.Time       `json:"createdAt"`
	UpdatedAt time.Time       `json:"updatedAt"`
}

FilterView is a named snapshot of the frontend's TorrentFilters object. Filters is opaque to the backend: it is stored and returned verbatim.

type FilterViewStore added in v1.25.0

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

func NewFilterViewStore added in v1.25.0

func NewFilterViewStore(db dbinterface.Querier) *FilterViewStore

func (*FilterViewStore) Create added in v1.25.0

func (s *FilterViewStore) Create(ctx context.Context, userID int, name string, filters json.RawMessage) (*FilterView, error)

func (*FilterViewStore) Delete added in v1.25.0

func (s *FilterViewStore) Delete(ctx context.Context, userID, id int) error

func (*FilterViewStore) List added in v1.25.0

func (s *FilterViewStore) List(ctx context.Context, userID int) ([]*FilterView, error)

func (*FilterViewStore) Update added in v1.25.0

func (s *FilterViewStore) Update(ctx context.Context, userID, id int, name string, filters json.RawMessage) (*FilterView, error)

type FreeSpaceSource added in v1.13.0

type FreeSpaceSource struct {
	Type FreeSpaceSourceType `json:"type" doc:"'qbittorrent' uses the free space that qBittorrent reports. 'path' reads the free space at 'path'."`
	Path string              `json:"path,omitempty" doc:"With type 'path': the path to read. Needs filesystem access on the instance."`
}

FreeSpaceSource configures how FREE_SPACE conditions obtain available disk space.

type FreeSpaceSourceType added in v1.13.0

type FreeSpaceSourceType string

FreeSpaceSourceType defines the source for free space checks in workflows.

const (
	// FreeSpaceSourceQBittorrent uses qBittorrent's reported free space (default download dir).
	FreeSpaceSourceQBittorrent FreeSpaceSourceType = "qbittorrent"
	// FreeSpaceSourcePath reads free space at a path through the instance's
	// filesystem backend, local or SSH.
	FreeSpaceSourcePath FreeSpaceSourceType = "path"
)

type GroupDefinition added in v1.14.0

type GroupDefinition struct {
	ID                    string   `json:"id" doc:"The group ID. Conditions and actions refer to the group by this ID."`
	Keys                  []string `json:"keys" doc:"Torrents with equal values for all these keys are in the same group."`
	AmbiguousPolicy       string   `` /* 335-byte string literal not displayed */
	MinFileOverlapPercent int      `json:"minFileOverlapPercent,omitempty" doc:"With 'verify_overlap': the percentage of files that must overlap. Default '90'."`
}

GroupDefinition defines a single grouping strategy.

type GroupingConfig added in v1.14.0

type GroupingConfig struct {
	DefaultGroupID string            `` /* 177-byte string literal not displayed */
	Groups         []GroupDefinition `json:"groups,omitempty" doc:"Custom group definitions."`
}

GroupingConfig defines how torrents can be grouped for group-aware actions and conditions. Group definitions are per-rule (stored inside the rule's conditions JSON).

type Instance

type Instance struct {
	ID                       int     `json:"id"`
	Name                     string  `json:"name"`
	Host                     string  `json:"host"`
	Username                 string  `json:"username"`
	PasswordEncrypted        string  `json:"-"`
	APIKeyEncrypted          string  `json:"-"`
	BasicUsername            *string `json:"basic_username,omitempty"`
	BasicPasswordEncrypted   *string `json:"-"`
	TLSSkipVerify            bool    `json:"tlsSkipVerify"`
	SortOrder                int     `json:"sortOrder"`
	IsActive                 bool    `json:"isActive"`
	HasLocalFilesystemAccess bool    `json:"hasLocalFilesystemAccess"`
	// Hardlink mode settings (per-instance)
	UseHardlinks      bool   `json:"useHardlinks"`
	HardlinkBaseDir   string `json:"hardlinkBaseDir"`
	HardlinkDirPreset string `json:"hardlinkDirPreset"` // "flat", "by-tracker", "by-instance"
	// Reflink mode (copy-on-write clones) - mutually exclusive with hardlink mode
	UseReflinks bool `json:"useReflinks"`
	// Fallback to regular mode when reflink/hardlink fails
	FallbackToRegularMode bool `json:"fallbackToRegularMode"`

	// SSH access for instances whose torrent data lives on another host.
	// Not part of the JSON contract yet: the API shape lands with the
	// ssh-test/credentials endpoints, which are also what first writes these.
	SSHHost     string `json:"-"`
	SSHPort     int    `json:"-"`
	SSHUsername string `json:"-"`
	// Both ciphertexts are AEAD-bound to this row; see instance_ssh.go.
	SSHKeyEncrypted string `json:"-"`
	// Marshaled host public key, empty until the user confirms it.
	SSHHostKeyEncrypted string `json:"-"`
}

func (Instance) MarshalJSON added in v1.0.0

func (i Instance) MarshalJSON() ([]byte, error)

func (*Instance) UnmarshalJSON added in v1.0.0

func (i *Instance) UnmarshalJSON(data []byte) error

type InstanceCrossSeedCompletionSettings added in v1.10.0

type InstanceCrossSeedCompletionSettings struct {
	InstanceID         int       `json:"instanceId"`
	Enabled            bool      `json:"enabled"`
	Categories         []string  `json:"categories"`
	Tags               []string  `json:"tags"`
	ExcludeCategories  []string  `json:"excludeCategories"`
	ExcludeTags        []string  `json:"excludeTags"`
	IndexerIDs         []int     `json:"indexerIds"`
	BypassTorznabCache bool      `json:"bypassTorznabCache"`
	DelaySeconds       int       `json:"delaySeconds"`
	UpdatedAt          time.Time `json:"updatedAt"`
}

InstanceCrossSeedCompletionSettings stores per-instance cross-seed completion configuration.

func DefaultInstanceCrossSeedCompletionSettings added in v1.10.0

func DefaultInstanceCrossSeedCompletionSettings(instanceID int) *InstanceCrossSeedCompletionSettings

DefaultInstanceCrossSeedCompletionSettings returns default values for a new instance. Completion is disabled by default for safety.

func (*InstanceCrossSeedCompletionSettings) GetCategories added in v1.10.0

func (s *InstanceCrossSeedCompletionSettings) GetCategories() []string

GetCategories returns the categories filter.

func (*InstanceCrossSeedCompletionSettings) GetExcludeCategories added in v1.10.0

func (s *InstanceCrossSeedCompletionSettings) GetExcludeCategories() []string

GetExcludeCategories returns the excluded categories filter.

func (*InstanceCrossSeedCompletionSettings) GetExcludeTags added in v1.10.0

func (s *InstanceCrossSeedCompletionSettings) GetExcludeTags() []string

GetExcludeTags returns the excluded tags filter.

func (*InstanceCrossSeedCompletionSettings) GetTags added in v1.10.0

GetTags returns the tags filter.

type InstanceCrossSeedCompletionStore added in v1.10.0

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

InstanceCrossSeedCompletionStore manages persistence for InstanceCrossSeedCompletionSettings.

func NewInstanceCrossSeedCompletionStore added in v1.10.0

func NewInstanceCrossSeedCompletionStore(db dbinterface.Querier) *InstanceCrossSeedCompletionStore

NewInstanceCrossSeedCompletionStore creates a new store.

func (*InstanceCrossSeedCompletionStore) Get added in v1.10.0

Get returns settings for an instance, falling back to defaults if missing.

func (*InstanceCrossSeedCompletionStore) List added in v1.10.0

List returns settings for all instances that have overrides. Instances without overrides are omitted.

func (*InstanceCrossSeedCompletionStore) Upsert added in v1.10.0

Upsert saves settings for an instance, creating or updating as needed.

type InstanceError added in v1.0.0

type InstanceError struct {
	ID           int       `json:"id"`
	InstanceID   int       `json:"instanceId"`
	ErrorType    string    `json:"errorType"`
	ErrorMessage string    `json:"errorMessage"`
	OccurredAt   time.Time `json:"occurredAt"`
}

type InstanceErrorStore added in v1.0.0

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

func NewInstanceErrorStore added in v1.0.0

func NewInstanceErrorStore(db dbinterface.Querier) *InstanceErrorStore

func (*InstanceErrorStore) ClearErrors added in v1.0.0

func (s *InstanceErrorStore) ClearErrors(ctx context.Context, instanceID int) error

ClearErrors removes all errors for an instance (called on successful connection)

func (*InstanceErrorStore) GetRecentErrors added in v1.0.0

func (s *InstanceErrorStore) GetRecentErrors(ctx context.Context, instanceID int, limit int) ([]InstanceError, error)

GetRecentErrors retrieves the last N errors for an instance

func (*InstanceErrorStore) RecordError added in v1.0.0

func (s *InstanceErrorStore) RecordError(ctx context.Context, instanceID int, err error) error

RecordError stores an error for an instance with simple deduplication

type InstanceReannounceSettings added in v1.8.0

type InstanceReannounceSettings struct {
	InstanceID                int       `json:"instanceId"`
	Enabled                   bool      `json:"enabled"`
	InitialWaitSeconds        int       `json:"initialWaitSeconds"`
	ReannounceIntervalSeconds int       `json:"reannounceIntervalSeconds"`
	MaxAgeSeconds             int       `json:"maxAgeSeconds"`
	MaxRetries                int       `json:"maxRetries"`
	Aggressive                bool      `json:"aggressive"`
	MonitorAll                bool      `json:"monitorAll"`
	ExcludeCategories         bool      `json:"excludeCategories"`
	Categories                []string  `json:"categories"`
	ExcludeTags               bool      `json:"excludeTags"`
	Tags                      []string  `json:"tags"`
	ExcludeTrackers           bool      `json:"excludeTrackers"`
	Trackers                  []string  `json:"trackers"`
	UpdatedAt                 time.Time `json:"updatedAt"`
}

InstanceReannounceSettings stores per-instance tracker reannounce configuration.

func DefaultInstanceReannounceSettings added in v1.8.0

func DefaultInstanceReannounceSettings(instanceID int) *InstanceReannounceSettings

DefaultInstanceReannounceSettings returns default values for a new instance.

func (*InstanceReannounceSettings) CanMatchTorrents added in v1.28.0

func (s *InstanceReannounceSettings) CanMatchTorrents() bool

CanMatchTorrents reports whether any torrent can match these settings: the feature is on, and the scope is either MonitorAll or at least one inclusion list. A scope that matches nothing lets callers skip the client fetch.

type InstanceReannounceStore added in v1.8.0

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

InstanceReannounceStore manages persistence for InstanceReannounceSettings.

func NewInstanceReannounceStore added in v1.8.0

func NewInstanceReannounceStore(db dbinterface.Querier) *InstanceReannounceStore

NewInstanceReannounceStore creates a new store.

func (*InstanceReannounceStore) Get added in v1.8.0

Get returns settings for an instance, falling back to defaults if missing.

func (*InstanceReannounceStore) List added in v1.8.0

List returns settings for all instances that have overrides. Instances without overrides are omitted.

func (*InstanceReannounceStore) Upsert added in v1.8.0

Upsert saves settings for an instance, creating or updating as needed.

type InstanceStore

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

func NewInstanceStore

func NewInstanceStore(db dbinterface.Querier, encryptionKey []byte, opts ...CredentialCipherOption) (*InstanceStore, error)

func (*InstanceStore) ClearSSHCredentials added in v1.30.0

func (s *InstanceStore) ClearSSHCredentials(ctx context.Context, instanceID int) error

ClearSSHCredentials removes the credentials but keeps the pin: the pin belongs to the host, not to whoever last authenticated against it.

func (*InstanceStore) Create

func (s *InstanceStore) Create(ctx context.Context, name, rawHost, username, password string, basicUsername, basicPassword *string, tlsSkipVerify bool, hasLocalFilesystemAccess *bool, apiKey ...string) (*Instance, error)

func (*InstanceStore) Delete

func (s *InstanceStore) Delete(ctx context.Context, id int) error

func (*InstanceStore) Get

func (s *InstanceStore) Get(ctx context.Context, id int) (*Instance, error)

func (*InstanceStore) GetDecryptedAPIKey added in v1.19.0

func (s *InstanceStore) GetDecryptedAPIKey(instance *Instance) (string, error)

GetDecryptedAPIKey returns the decrypted API key for an instance.

func (*InstanceStore) GetDecryptedBasicPassword

func (s *InstanceStore) GetDecryptedBasicPassword(instance *Instance) (*string, error)

GetDecryptedBasicPassword returns the decrypted basic auth password for an instance

func (*InstanceStore) GetDecryptedPassword

func (s *InstanceStore) GetDecryptedPassword(instance *Instance) (string, error)

GetDecryptedPassword returns the decrypted password for an instance

func (*InstanceStore) GetDecryptedSSHKey added in v1.30.0

func (s *InstanceStore) GetDecryptedSSHKey(instance *Instance) (string, error)

GetDecryptedSSHKey returns the private key for an instance, or ErrSSHKeyNotConfigured when the instance has none: an empty key is not a credential, and returning one would let a dial try an empty-key auth.

func (*InstanceStore) GetHostKeyPin added in v1.30.0

func (s *InstanceStore) GetHostKeyPin(instance *Instance) ([]byte, error)

GetHostKeyPin returns the marshaled host public key confirmed for this instance. A decryption failure is returned as-is and never degrades to "unpinned": falling back to trust-on-first-use here would hand an attacker who can write the database exactly the re-pin the mismatch flow refuses.

func (*InstanceStore) List

func (s *InstanceStore) List(ctx context.Context) ([]*Instance, error)

func (*InstanceStore) ReplaceHostKeyPin added in v1.30.0

func (s *InstanceStore) ReplaceHostKeyPin(ctx context.Context, instanceID int, host string, port int, marshaledKey []byte) error

ReplaceHostKeyPin overwrites the pin after the user confirmed a mismatch. It is the mirror of SetHostKeyPin: an instance with nothing pinned is refused with ErrSSHHostKeyNotPinned, since a replacement the user never compared against an existing pin is just a silent TOFU by another name.

func (*InstanceStore) RewriteLegacyCredentials added in v1.29.0

func (s *InstanceStore) RewriteLegacyCredentials(ctx context.Context) (int, error)

RewriteLegacyCredentials re-encrypts stored qBittorrent instance credentials that still carry the pre-HKDF format and reports how many rows it rewrote.

func (*InstanceStore) SetActiveState added in v1.8.0

func (s *InstanceStore) SetActiveState(ctx context.Context, id int, active bool) (*Instance, error)

func (*InstanceStore) SetHostKeyPin added in v1.30.0

func (s *InstanceStore) SetHostKeyPin(ctx context.Context, instanceID int, host string, port int, marshaledKey []byte) error

SetHostKeyPin pins the marshaled host public key the caller confirmed for host and port. The endpoint comes from the caller, not the stored row: a key confirmed for one host must not be pinned to whatever host the row carries by the time the confirmation lands, so a row whose endpoint no longer matches is refused with ErrSSHEndpointChanged.

Pinning an already-pinned instance is refused: overwriting a live pin is exactly the silent re-pin the mismatch flow exists to prevent, so replacing one has to be asked for by name rather than fallen into.

func (*InstanceStore) SetSSHCredentials added in v1.30.0

func (s *InstanceStore) SetSSHCredentials(ctx context.Context, instanceID int, host string, port int, username, privateKey string) error

SetSSHCredentials stores the SSH endpoint and private key for an instance. Changing the host or port drops any existing pin: the pin was confirmed for one endpoint, and the new one has never been seen before.

func (*InstanceStore) Update

func (s *InstanceStore) Update(ctx context.Context, id int, name, rawHost, username, password string, basicUsername, basicPassword *string, params *InstanceUpdateParams, apiKey ...*string) (*Instance, error)

func (*InstanceStore) UpdateOrder added in v1.7.0

func (s *InstanceStore) UpdateOrder(ctx context.Context, instanceIDs []int) error

type InstanceUpdateParams added in v1.12.0

type InstanceUpdateParams struct {
	TLSSkipVerify            *bool
	HasLocalFilesystemAccess *bool
	UseHardlinks             *bool
	HardlinkBaseDir          *string
	HardlinkDirPreset        *string
	UseReflinks              *bool
	FallbackToRegularMode    *bool
}

InstanceUpdateParams contains optional fields for updating an instance.

type LicenseInfo added in v1.0.0

type LicenseInfo struct {
	Key          string     `json:"key"`
	ProductName  string     `json:"productName"`
	CustomerID   string     `json:"customerId"`
	ProductID    string     `json:"productId"`
	ExpiresAt    *time.Time `json:"expiresAt,omitempty"`
	Valid        bool       `json:"valid"`
	ErrorMessage string     `json:"errorMessage,omitempty"`
}

LicenseInfo contains license validation information

type LogExclusions added in v1.12.0

type LogExclusions struct {
	ID        int       `json:"id"`
	Patterns  []string  `json:"patterns"`
	CreatedAt time.Time `json:"createdAt"`
	UpdatedAt time.Time `json:"updatedAt"`
}

type LogExclusionsInput added in v1.12.0

type LogExclusionsInput struct {
	Patterns []string `json:"patterns"`
}

type LogExclusionsStore added in v1.12.0

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

func NewLogExclusionsStore added in v1.12.0

func NewLogExclusionsStore(db dbinterface.Querier) *LogExclusionsStore

func (*LogExclusionsStore) Get added in v1.12.0

Get returns log exclusions, creating defaults if none exist

func (*LogExclusionsStore) Update added in v1.12.0

Update replaces patterns

type MatchMode added in v1.13.0

type MatchMode string

MatchMode defines how files are matched to torrent files.

const (
	// MatchModeStrict requires files to match by name AND size.
	MatchModeStrict MatchMode = "strict"
	// MatchModeFlexible matches files by size only, ignoring filename differences.
	MatchModeFlexible MatchMode = "flexible"
)

type MediaIDCacheEntry added in v1.27.0

type MediaIDCacheEntry struct {
	TorrentKey       string    `json:"torrent_key"`
	ContentType      string    `json:"content_type"`
	ExtractorVersion int       `json:"extractor_version"`
	IDType           string    `json:"id_type,omitempty"`
	IDValue          string    `json:"id_value,omitempty"`
	CachedAt         time.Time `json:"cached_at"`
}

MediaIDCacheEntry is one cached MediaInfo external-ID extraction for a torrent. An entry with an empty IDType records a successful scan that found no usable ID, so later searches skip the file read.

type MediaIDCacheStore added in v1.27.0

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

MediaIDCacheStore manages the media_id_cache table.

func NewMediaIDCacheStore added in v1.27.0

func NewMediaIDCacheStore(db dbinterface.Querier) *MediaIDCacheStore

NewMediaIDCacheStore creates a new MediaIDCacheStore.

func (*MediaIDCacheStore) Get added in v1.27.0

func (s *MediaIDCacheStore) Get(ctx context.Context, torrentKey, contentType string) (*MediaIDCacheEntry, error)

Get returns the cached entry for a torrent key and content type, or nil when no entry exists.

func (*MediaIDCacheStore) Set added in v1.27.0

Set upserts a cache entry. An empty IDType stores a no-ID result (both ID columns NULL, enforced by a table constraint).

type MoveAction added in v1.13.0

type MoveAction struct {
	Enabled          bool           `json:"enabled" doc:"Whether the action runs."`
	Path             string         `json:"path" doc:"The new save path."`
	BlockIfCrossSeed bool           `` /* 142-byte string literal not displayed */
	GroupID          string         `` /* 171-byte string literal not displayed */
	Atomic           string         `json:"atomic,omitempty" doc:"With 'groupId': 'all' moves the group only when every torrent in it matches."`
	Condition        *RuleCondition `json:"condition,omitempty" doc:"Optional. When set, the action applies only to torrents that also match this condition."`
}

type NotificationTarget added in v1.14.0

type NotificationTarget struct {
	ID         int       `json:"id"`
	Name       string    `json:"name"`
	URL        string    `json:"url"`
	Enabled    bool      `json:"enabled"`
	EventTypes []string  `json:"eventTypes"`
	CreatedAt  time.Time `json:"createdAt"`
	UpdatedAt  time.Time `json:"updatedAt"`
}

NotificationTarget represents a configured notification destination.

type NotificationTargetCreate added in v1.14.0

type NotificationTargetCreate struct {
	Name       string   `json:"name"`
	URL        string   `json:"url"`
	Enabled    bool     `json:"enabled"`
	EventTypes []string `json:"eventTypes"`
}

NotificationTargetCreate represents data needed to create a notification target.

type NotificationTargetStore added in v1.14.0

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

NotificationTargetStore manages persistence for notification targets.

func NewNotificationTargetStore added in v1.14.0

func NewNotificationTargetStore(db dbinterface.Querier) *NotificationTargetStore

func (*NotificationTargetStore) Create added in v1.14.0

func (*NotificationTargetStore) Delete added in v1.14.0

func (s *NotificationTargetStore) Delete(ctx context.Context, id int) error

func (*NotificationTargetStore) GetByID added in v1.14.0

func (*NotificationTargetStore) List added in v1.14.0

func (*NotificationTargetStore) ListEnabled added in v1.14.0

func (*NotificationTargetStore) Update added in v1.14.0

type NotificationTargetUpdate added in v1.14.0

type NotificationTargetUpdate struct {
	Name       string   `json:"name"`
	URL        string   `json:"url"`
	Enabled    bool     `json:"enabled"`
	EventTypes []string `json:"eventTypes"`
}

NotificationTargetUpdate represents data needed to update a notification target.

type NullableInt64Update added in v1.28.0

type NullableInt64Update struct {
	Set   bool
	Value *int64
}

NullableInt64Update distinguishes no update from setting a value or NULL.

type NullableTimeUpdate added in v1.28.0

type NullableTimeUpdate struct {
	Set   bool
	Value *time.Time
}

NullableTimeUpdate distinguishes no update from setting a value or NULL.

type OrphanScanFile added in v1.12.0

type OrphanScanFile struct {
	ID             int64      `json:"id"`
	RunID          int64      `json:"runId"`
	FilePath       string     `json:"filePath"`
	FileSize       int64      `json:"fileSize"`
	IsAbandonedDir bool       `json:"isAbandonedDir"`
	ModifiedAt     *time.Time `json:"modifiedAt,omitempty"`
	Status         string     `json:"status"` // pending, deleted, skipped, failed
	ErrorMessage   string     `json:"errorMessage,omitempty"`
}

OrphanScanFile represents an orphan file found in a scan.

type OrphanScanRun added in v1.12.0

type OrphanScanRun struct {
	ID             int64      `json:"id"`
	InstanceID     int        `json:"instanceId"`
	Status         string     `json:"status"` // pending, scanning, preview_ready, deleting, completed, failed, canceled
	TriggeredBy    string     `json:"triggeredBy"`
	ScanPaths      []string   `json:"scanPaths"`
	FilesFound     int        `json:"filesFound"`
	FilesDeleted   int        `json:"filesDeleted"`
	FoldersDeleted int        `json:"foldersDeleted"`
	BytesReclaimed int64      `json:"bytesReclaimed"`
	Truncated      bool       `json:"truncated"`
	Partial        bool       `json:"partial,omitzero"`
	ErrorMessage   string     `json:"errorMessage,omitempty"`
	StartedAt      time.Time  `json:"startedAt"`
	CompletedAt    *time.Time `json:"completedAt,omitempty"`
	// FilesystemMode is the mode the preview was walked under, not the instance's current one.
	FilesystemMode FilesystemMode `json:"filesystemMode"`
}

OrphanScanRun represents an orphan scan run.

type OrphanScanSettings added in v1.12.0

type OrphanScanSettings struct {
	ID                  int64     `json:"id"`
	InstanceID          int       `json:"instanceId"`
	Enabled             bool      `json:"enabled"`
	GracePeriodMinutes  int       `json:"gracePeriodMinutes"`
	IgnorePaths         []string  `json:"ignorePaths"`
	ScanIntervalHours   int       `json:"scanIntervalHours"`
	PreviewSort         string    `json:"previewSort"`
	MaxFilesPerRun      int       `json:"maxFilesPerRun"`
	AutoCleanupEnabled  bool      `json:"autoCleanupEnabled"`
	AutoCleanupMaxFiles int       `json:"autoCleanupMaxFiles"`
	ScanDefaultSavePath bool      `json:"scanDefaultSavePath"`
	ScanCategoryPaths   bool      `json:"scanCategoryPaths"`
	DeleteAbandonedDirs bool      `json:"deleteAbandonedDirs"`
	CreatedAt           time.Time `json:"createdAt"`
	UpdatedAt           time.Time `json:"updatedAt"`
}

OrphanScanSettings represents orphan scan settings for an instance.

type OrphanScanStore added in v1.12.0

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

OrphanScanStore handles database operations for orphan scan.

func NewOrphanScanStore added in v1.12.0

func NewOrphanScanStore(db dbinterface.Querier) *OrphanScanStore

NewOrphanScanStore creates a new OrphanScanStore.

func (*OrphanScanStore) CreateRunIfNoActive added in v1.12.0

func (s *OrphanScanStore) CreateRunIfNoActive(ctx context.Context, instanceID int, triggeredBy string) (int64, error)

CreateRunIfNoActive atomically checks for active runs and creates a new one if none exist. This prevents race conditions between HasActiveRun and CreateRun. A preview walked over SSH can never be confirmed, so the new run cancels it instead of being blocked by it.

func (*OrphanScanStore) FailPreviewReadyRun added in v1.31.0

func (s *OrphanScanStore) FailPreviewReadyRun(ctx context.Context, runID int64, errorMessage string) (bool, error)

FailPreviewReadyRun marks a run failed only while it is still preview_ready, and reports whether it did.

func (*OrphanScanStore) GetFilesForDeletion added in v1.12.0

func (s *OrphanScanStore) GetFilesForDeletion(ctx context.Context, runID int64) ([]*OrphanScanFile, error)

GetFilesForDeletion returns all pending files for a run. Note: loads all files into memory. If memory usage becomes a concern with very large orphan sets, consider adding batched retrieval here.

func (*OrphanScanStore) GetLastCompletedRun added in v1.12.0

func (s *OrphanScanStore) GetLastCompletedRun(ctx context.Context, instanceID int) (*OrphanScanRun, error)

GetLastCompletedRun returns the last completed run for an instance.

func (*OrphanScanStore) GetLastFinishedScan added in v1.31.0

func (s *OrphanScanStore) GetLastFinishedScan(ctx context.Context, instanceID int) (*OrphanScanRun, error)

GetLastFinishedScan returns the newest completed run or preview still awaiting review, the runs whose walk finished. A preview over SSH never completes, so a schedule paced by completed runs alone would rescan it on every tick. A preview has no completed_at, so it is ordered by when it started.

func (*OrphanScanStore) GetMostRecentActiveRun added in v1.13.0

func (s *OrphanScanStore) GetMostRecentActiveRun(ctx context.Context, instanceID int) (*OrphanScanRun, error)

GetMostRecentActiveRun returns the most recent run that blocks CreateRunIfNoActive.

func (*OrphanScanStore) GetRun added in v1.12.0

func (s *OrphanScanStore) GetRun(ctx context.Context, runID int64) (*OrphanScanRun, error)

GetRun retrieves an orphan scan run by ID.

func (*OrphanScanStore) GetRunByInstance added in v1.12.0

func (s *OrphanScanStore) GetRunByInstance(ctx context.Context, instanceID int, runID int64) (*OrphanScanRun, error)

GetRunByInstance retrieves a specific run for an instance.

func (*OrphanScanStore) GetSettings added in v1.12.0

func (s *OrphanScanStore) GetSettings(ctx context.Context, instanceID int) (*OrphanScanSettings, error)

GetSettings retrieves orphan scan settings for an instance. Returns nil if no settings exist.

func (*OrphanScanStore) InsertFiles added in v1.12.0

func (s *OrphanScanStore) InsertFiles(ctx context.Context, runID int64, files []OrphanScanFile) error

InsertFiles inserts orphan files for a run in batches.

func (*OrphanScanStore) ListFiles added in v1.12.0

func (s *OrphanScanStore) ListFiles(ctx context.Context, runID int64, limit, offset int, sortMode string) ([]*OrphanScanFile, error)

func (*OrphanScanStore) ListRuns added in v1.12.0

func (s *OrphanScanStore) ListRuns(ctx context.Context, instanceID, limit int) ([]*OrphanScanRun, error)

ListRuns lists recent runs for an instance.

func (*OrphanScanStore) MarkDeletingRunsFailed added in v1.13.0

func (s *OrphanScanStore) MarkDeletingRunsFailed(ctx context.Context, errorMessage string) error

MarkDeletingRunsFailed marks any runs currently in "deleting" as failed. This is intended to run at service startup so interrupted deletions don't remain stuck in a non-terminal state after a restart.

func (*OrphanScanStore) MarkStuckRunsFailed added in v1.12.0

func (s *OrphanScanStore) MarkStuckRunsFailed(ctx context.Context, threshold time.Duration, statuses []string) error

MarkStuckRunsFailed marks old pending/scanning runs as failed.

func (*OrphanScanStore) StartRunDeletion added in v1.31.0

func (s *OrphanScanStore) StartRunDeletion(ctx context.Context, runID int64) (bool, error)

StartRunDeletion moves a run from preview_ready to deleting, and reports whether it did.

func (*OrphanScanStore) UpdateFileStatus added in v1.12.0

func (s *OrphanScanStore) UpdateFileStatus(ctx context.Context, fileID int64, status string, errorMessage string) error

UpdateFileStatus updates the status of a single file.

func (*OrphanScanStore) UpdateRunCompleted added in v1.12.0

func (s *OrphanScanStore) UpdateRunCompleted(ctx context.Context, runID int64, filesDeleted, foldersDeleted int, bytesReclaimed int64, warningMessage string) error

UpdateRunCompleted saves completion, stats, and the warning in one update.

func (*OrphanScanStore) UpdateRunFailed added in v1.12.0

func (s *OrphanScanStore) UpdateRunFailed(ctx context.Context, runID int64, errorMessage string) error

UpdateRunFailed marks a run as failed with an error message.

func (*OrphanScanStore) UpdateRunFilesystemMode added in v1.31.0

func (s *OrphanScanStore) UpdateRunFilesystemMode(ctx context.Context, runID int64, mode FilesystemMode) error

UpdateRunFilesystemMode records the filesystem mode a run is walked under.

func (*OrphanScanStore) UpdateRunFoundStats added in v1.12.0

func (s *OrphanScanStore) UpdateRunFoundStats(ctx context.Context, runID int64, filesFound int, truncated bool, bytesFound int64) error

UpdateRunFoundStats updates the files found count, truncated flag, and preview bytes. bytesFound should represent the total size of orphan files found during the scan.

func (*OrphanScanStore) UpdateRunPartial added in v1.29.0

func (s *OrphanScanStore) UpdateRunPartial(ctx context.Context, runID int64, warningMessage string) error

UpdateRunPartial records incomplete scan coverage and its warning.

func (*OrphanScanStore) UpdateRunScanPaths added in v1.12.0

func (s *OrphanScanStore) UpdateRunScanPaths(ctx context.Context, runID int64, scanPaths []string) error

UpdateRunScanPaths updates the scan paths for a run.

func (*OrphanScanStore) UpdateRunStatus added in v1.12.0

func (s *OrphanScanStore) UpdateRunStatus(ctx context.Context, runID int64, status string) error

UpdateRunStatus updates the status of a run.

func (*OrphanScanStore) UpdateRunWarning added in v1.12.0

func (s *OrphanScanStore) UpdateRunWarning(ctx context.Context, runID int64, warningMessage string) error

UpdateRunWarning sets a warning message on a run without changing its status.

func (*OrphanScanStore) UpsertSettings added in v1.12.0

func (s *OrphanScanStore) UpsertSettings(ctx context.Context, settings *OrphanScanSettings) (*OrphanScanSettings, error)

UpsertSettings creates or updates orphan scan settings for an instance.

type PartialPoolFileMutation added in v1.28.0

type PartialPoolFileMutation struct {
	SourceFileID NullableInt64Update
	LastError    *string
}

PartialPoolFileMutation contains fields changed with a file status claim.

type PartialPoolMemberMutation added in v1.28.0

type PartialPoolMemberMutation struct {
	MissingBytes        *int64
	StartedByPool       *bool
	LastDownloadedBytes NullableInt64Update
	LastProgressAt      NullableTimeUpdate
	RetryAfter          NullableTimeUpdate
	ReviewPausePending  *bool
	ResumeAttempts      NullableInt64Update
	RecoveryAttempts    NullableInt64Update
	LastError           *string
}

PartialPoolMemberMutation contains fields changed with a member status claim.

type PathMapping added in v1.7.0

type PathMapping struct {
	From string `json:"from"` // Remote path prefix
	To   string `json:"to"`   // Local path prefix
}

PathMapping represents a path mapping from remote to local

type PauseAction added in v1.12.0

type PauseAction struct {
	Enabled   bool           `json:"enabled" doc:"Whether the action runs."`
	Condition *RuleCondition `json:"condition,omitempty" doc:"Optional. When set, the action applies only to torrents that also match this condition."`
}

PauseAction configures pause action with conditions.

type ProductLicense added in v1.0.0

type ProductLicense struct {
	ID             int        `json:"id"`
	LicenseKey     string     `json:"licenseKey"`
	ProductName    string     `json:"productName"`
	Status         string     `json:"status"`
	ActivatedAt    time.Time  `json:"activatedAt"`
	ExpiresAt      *time.Time `json:"expiresAt,omitempty"`
	LastValidated  time.Time  `json:"lastValidated"`
	Provider       string     `json:"provider,omitempty"`
	DodoInstanceID string     `json:"dodoInstanceId,omitempty"`
	Username       string     `json:"username"`
	CreatedAt      time.Time  `json:"createdAt"`
	UpdatedAt      time.Time  `json:"updatedAt"`
}

ProductLicense represents a product license in the database

type ReannounceAction added in v1.14.0

type ReannounceAction struct {
	Enabled   bool           `json:"enabled" doc:"Whether the action runs."`
	Condition *RuleCondition `json:"condition,omitempty" doc:"Optional. When set, the action applies only to torrents that also match this condition."`
}

ReannounceAction configures force reannounce action with optional conditions.

type RecheckAction added in v1.14.0

type RecheckAction struct {
	Enabled   bool           `json:"enabled" doc:"Whether the action runs."`
	Condition *RuleCondition `json:"condition,omitempty" doc:"Optional. When set, the action applies only to torrents that also match this condition."`
}

RecheckAction configures force recheck action with optional conditions.

type ResumeAction added in v1.14.0

type ResumeAction struct {
	Enabled   bool           `json:"enabled" doc:"Whether the action runs."`
	Condition *RuleCondition `json:"condition,omitempty" doc:"Optional. When set, the action applies only to torrents that also match this condition."`
}

ResumeAction configures resume action with conditions.

type RuleCondition added in v1.12.0

type RuleCondition struct {
	Field      ConditionField    `json:"field,omitempty" doc:"The condition field to test. Leave it out on an 'AND' or 'OR' group."`
	Operator   ConditionOperator `json:"operator" doc:"An operator that the field allows, or 'AND' or 'OR' for a group."`
	GroupID    string            `` /* 197-byte string literal not displayed */
	Value      string            `` /* 136-byte string literal not displayed */
	MinValue   *float64          `json:"minValue,omitempty" doc:"For 'BETWEEN': the lower end of the range, as a JSON number."`
	MaxValue   *float64          `` /* 231-byte string literal not displayed */
	Regex      bool              `` /* 144-byte string literal not displayed */
	Negate     bool              `json:"negate,omitempty" doc:"When 'true', the condition matches when the test is false."`
	Conditions []*RuleCondition  `json:"conditions,omitempty" doc:"For an 'AND' or 'OR' group: the child conditions."`
	Compiled   *regexp.Regexp    `json:"-"` // compiled regex, not serialized
}

RuleCondition represents a condition or group of conditions for filtering torrents.

func (*RuleCondition) CompileRegex added in v1.12.0

func (c *RuleCondition) CompileRegex() error

CompileRegex compiles the regex pattern if needed. Safe to call multiple times.

func (*RuleCondition) IsGroup added in v1.12.0

func (c *RuleCondition) IsGroup() bool

IsGroup returns true if this condition is an AND/OR group containing child conditions.

type ScoreRule added in v1.15.0

type ScoreRule struct {
	Type            ScoreRuleType             `json:"type" doc:"The kind of rule."`
	FieldMultiplier *FieldMultiplierScoreRule `json:"fieldMultiplier,omitempty" doc:"With type 'field_multiplier': the field and multiplier."`
	Conditional     *ConditionalScoreRule     `json:"conditional,omitempty" doc:"With type 'conditional': the condition and score."`
}

ScoreRule defines a single weighted rule for scoring torrents.

type ScoreRuleType added in v1.15.0

type ScoreRuleType string

ScoreRuleType defines the type of score rule.

const (
	ScoreRuleTypeFieldMultiplier ScoreRuleType = "field_multiplier"
	ScoreRuleTypeConditional     ScoreRuleType = "conditional"
)

type SeasonPackCategoryRule added in v1.20.0

type SeasonPackCategoryRule struct {
	Resolution string `json:"resolution"` // Canonical lowercase rls value, e.g. "1080p", "2160p"
	Source     string `json:"source"`     // "" = any; else canonical uppercase: WEB, BLURAY, REMUX, HDTV
	Category   string `json:"category"`   // qBittorrent category to file the add under
}

SeasonPackCategoryRule routes a season pack add to a category based on its release quality. The first matching rule wins; otherwise the add falls back to CrossSeedAutomationSettings.SeasonPackCategory ("Anything else").

type SeasonPackRun added in v1.19.0

type SeasonPackRun struct {
	ID              int64     `json:"id"`
	TorrentName     string    `json:"torrentName"`
	Phase           string    `json:"phase"`
	Status          string    `json:"status"`
	Reason          string    `json:"reason"`
	Message         string    `json:"message"`
	InstanceID      *int      `json:"instanceId,omitempty"`
	MatchedEpisodes int       `json:"matchedEpisodes"`
	TotalEpisodes   int       `json:"totalEpisodes"`
	Coverage        float64   `json:"coverage"`
	LinkMode        string    `json:"linkMode"`
	CreatedAt       time.Time `json:"createdAt"`
}

SeasonPackRun records one season-pack webhook processing attempt.

type SeasonPackRunStore added in v1.19.0

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

SeasonPackRunStore persists season-pack run activity.

func NewSeasonPackRunStore added in v1.19.0

func NewSeasonPackRunStore(db dbinterface.Querier) *SeasonPackRunStore

NewSeasonPackRunStore constructs a new season-pack run store.

func (*SeasonPackRunStore) Create added in v1.19.0

Create inserts a new season-pack run and returns it with the generated ID and timestamp.

func (*SeasonPackRunStore) List added in v1.19.0

func (s *SeasonPackRunStore) List(ctx context.Context, limit int) ([]*SeasonPackRun, error)

List returns the most recent season-pack runs, ordered newest first.

type ShareLimitsAction added in v1.12.0

type ShareLimitsAction struct {
	Enabled            bool           `json:"enabled" doc:"Whether the action runs."`
	RatioLimit         *float64       `` /* 137-byte string literal not displayed */
	SeedingTimeMinutes *int64         `` /* 163-byte string literal not displayed */
	ShareLimitAction   *string        `` /* 161-byte string literal not displayed */
	ShareLimitsMode    *string        `` /* 162-byte string literal not displayed */
	Condition          *RuleCondition `json:"condition,omitempty" doc:"Optional. When set, the action applies only to torrents that also match this condition."`
}

ShareLimitsAction configures share limit (ratio/seeding time) application with optional conditions.

type SortDirection added in v1.15.0

type SortDirection string
const (
	SortDirectionASC  SortDirection = "ASC"
	SortDirectionDESC SortDirection = "DESC"
)

type SortingConfig added in v1.15.0

type SortingConfig struct {
	SchemaVersion string         `json:"schemaVersion" doc:"Must be '1'."`
	Type          SortingType    `json:"type" doc:"'simple' sorts by one field. 'score' sorts by the sum of 'scoreRules'."`
	Direction     SortDirection  `json:"direction" doc:"'ASC' or 'DESC'."`
	Field         ConditionField `json:"field,omitempty" doc:"With type 'simple': the condition field to sort by."`
	ScoreRules    []ScoreRule    `json:"scoreRules,omitempty" doc:"With type 'score': the rules that add up to the score of each torrent."`
}

SortingConfig defines how torrents are sorted before processing. This is the top-level structure stored in the `sorting_config` JSON column.

func (*SortingConfig) Validate added in v1.15.0

func (c *SortingConfig) Validate() error

type SortingType added in v1.15.0

type SortingType string
const (
	SortingTypeSimple SortingType = "simple"
	SortingTypeScore  SortingType = "score"
)

type SpeedLimitAction added in v1.12.0

type SpeedLimitAction struct {
	Enabled     bool           `json:"enabled" doc:"Whether the action runs."`
	UploadKiB   *int64         `json:"uploadKiB,omitempty" doc:"Upload limit in KiB/s. '0' removes the limit. Leave it out to keep the current limit."`
	DownloadKiB *int64         `json:"downloadKiB,omitempty" doc:"Download limit in KiB/s. '0' removes the limit. Leave it out to keep the current limit."`
	Condition   *RuleCondition `json:"condition,omitempty" doc:"Optional. When set, the action applies only to torrents that also match this condition."`
}

SpeedLimitAction configures speed limit application with optional conditions.

type TagAction added in v1.12.0

type TagAction struct {
	Enabled          bool           `json:"enabled" doc:"Whether the action runs."`
	Tags             []string       `` /* 128-byte string literal not displayed */
	Mode             string         `` /* 161-byte string literal not displayed */
	DeleteFromClient bool           `` /* 135-byte string literal not displayed */
	UseTrackerAsTag  bool           `json:"useTrackerAsTag,omitempty" doc:"Use the tracker domain of each torrent as its tag."`
	UseDisplayName   bool           `json:"useDisplayName,omitempty" doc:"With 'useTrackerAsTag': use the tracker display name in place of the domain."`
	Condition        *RuleCondition `json:"condition,omitempty" doc:"Optional. When set, the action applies only to torrents that also match this condition."`
}

TagAction configures tagging with smart add/remove logic.

type ThemeSettings added in v1.27.0

type ThemeSettings struct {
	ThemeID   string `json:"themeId"`
	Mode      string `json:"mode"`
	Variation string `json:"variation,omitempty"`
}

ThemeSettings is one stored theme selection (a theme slot).

type ThemeSettingsStore added in v1.27.0

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

func NewThemeSettingsStore added in v1.27.0

func NewThemeSettingsStore(db dbinterface.Querier) *ThemeSettingsStore

func (*ThemeSettingsStore) Delete added in v1.31.0

func (s *ThemeSettingsStore) Delete(ctx context.Context, slot string) error

Delete removes one slot.

func (*ThemeSettingsStore) GetAll added in v1.31.0

GetAll returns every stored theme slot.

func (*ThemeSettingsStore) Set added in v1.27.0

Set stores the theme selection of one slot, replacing any previous one.

type ThemeSlots added in v1.31.0

type ThemeSlots struct {
	Default *ThemeSettings `json:"default,omitempty"`
	Mobile  *ThemeSettings `json:"mobile,omitempty"`
}

ThemeSlots holds every stored theme slot. A nil Mobile means the mobile layout uses the default slot.

type TorznabBackend added in v1.8.0

type TorznabBackend string

TorznabBackend represents the backend implementation used to access a Torznab indexer.

const (
	// TorznabBackendJackett routes requests through a Jackett instance.
	TorznabBackendJackett TorznabBackend = "jackett"
	// TorznabBackendProwlarr routes requests through a Prowlarr instance.
	TorznabBackendProwlarr TorznabBackend = "prowlarr"
	// TorznabBackendNative talks directly to a tracker-provided Torznab/Newznab endpoint.
	TorznabBackendNative TorznabBackend = "native"
)

func ParseTorznabBackend added in v1.8.0

func ParseTorznabBackend(value string) (TorznabBackend, error)

ParseTorznabBackend validates and normalizes a backend string.

type TorznabIndexer added in v1.8.0

type TorznabIndexer struct {
	ID                     int                      `json:"id"`
	Name                   string                   `json:"name"`
	BaseURL                string                   `json:"base_url"`
	IndexerID              string                   `json:"indexer_id"` // Jackett/Prowlarr indexer ID (e.g., "aither")
	BasicUsername          *string                  `json:"basic_username,omitempty"`
	Backend                TorznabBackend           `json:"backend"`
	APIKeyEncrypted        string                   `json:"-"`
	BasicPasswordEncrypted *string                  `json:"-"`
	Enabled                bool                     `json:"enabled"`
	Priority               int                      `json:"priority"`
	TimeoutSeconds         int                      `json:"timeout_seconds"`
	LimitDefault           int                      `json:"limit_default"`
	LimitMax               int                      `json:"limit_max"`
	Capabilities           []string                 `json:"capabilities"`
	Categories             []TorznabIndexerCategory `json:"categories"`
	LastTestAt             *time.Time               `json:"last_test_at,omitempty"`
	LastTestStatus         string                   `json:"last_test_status"`
	LastTestError          *string                  `json:"last_test_error,omitempty"`
	CreatedAt              time.Time                `json:"created_at"`
	UpdatedAt              time.Time                `json:"updated_at"`
}

TorznabIndexer represents a Torznab API indexer (Jackett, Prowlarr, etc.)

type TorznabIndexerCategory added in v1.8.0

type TorznabIndexerCategory struct {
	IndexerID      int    `json:"indexer_id"`
	CategoryID     int    `json:"category_id"`
	CategoryName   string `json:"category_name"`
	ParentCategory *int   `json:"parent_category_id,omitempty"`
}

TorznabIndexerCategory represents a category supported by an indexer

type TorznabIndexerError added in v1.8.0

type TorznabIndexerError struct {
	ID           int        `json:"id"`
	IndexerID    int        `json:"indexer_id"`
	ErrorMessage string     `json:"error_message"`
	ErrorCode    string     `json:"error_code"`
	OccurredAt   time.Time  `json:"occurred_at"`
	ResolvedAt   *time.Time `json:"resolved_at,omitempty"`
	ErrorCount   int        `json:"error_count"`
}

TorznabIndexerError represents an error that occurred with an indexer

type TorznabIndexerHealth added in v1.8.0

type TorznabIndexerHealth struct {
	IndexerID        int        `json:"indexer_id"`
	IndexerName      string     `json:"indexer_name"`
	Enabled          bool       `json:"enabled"`
	LastTestStatus   string     `json:"last_test_status"`
	ErrorsLast24h    int        `json:"errors_last_24h"`
	UnresolvedErrors int        `json:"unresolved_errors"`
	AvgLatencyMs     *float64   `json:"avg_latency_ms,omitempty"`
	SuccessRatePct   *float64   `json:"success_rate_pct,omitempty"`
	RequestsLast7d   *int       `json:"requests_last_7d,omitempty"`
	LastMeasuredAt   *time.Time `json:"last_measured_at,omitempty"`
}

TorznabIndexerHealth represents the health status of an indexer

type TorznabIndexerLatencyStats added in v1.8.0

type TorznabIndexerLatencyStats struct {
	IndexerID          int       `json:"indexer_id"`
	OperationType      string    `json:"operation_type"`
	TotalRequests      int       `json:"total_requests"`
	SuccessfulRequests int       `json:"successful_requests"`
	AvgLatencyMs       *float64  `json:"avg_latency_ms,omitempty"`
	MinLatencyMs       *int      `json:"min_latency_ms,omitempty"`
	MaxLatencyMs       *int      `json:"max_latency_ms,omitempty"`
	SuccessRatePct     float64   `json:"success_rate_pct"`
	LastMeasuredAt     time.Time `json:"last_measured_at"`
}

TorznabIndexerLatencyStats represents aggregated latency statistics

type TorznabIndexerStore added in v1.8.0

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

TorznabIndexerStore manages Torznab indexers in the database

func NewTorznabIndexerStore added in v1.8.0

func NewTorznabIndexerStore(db dbinterface.Querier, encryptionKey []byte, opts ...CredentialCipherOption) (*TorznabIndexerStore, error)

NewTorznabIndexerStore creates a new TorznabIndexerStore

func (*TorznabIndexerStore) CleanupOldLatency added in v1.8.0

func (s *TorznabIndexerStore) CleanupOldLatency(ctx context.Context, olderThan time.Duration) (int64, error)

CleanupOldLatency removes latency records older than the specified duration

func (*TorznabIndexerStore) Create added in v1.8.0

func (s *TorznabIndexerStore) Create(ctx context.Context, name, baseURL, apiKey string, basicUsername, basicPassword *string, enabled bool, priority, timeoutSeconds int) (*TorznabIndexer, error)

Create creates a new Torznab indexer

func (*TorznabIndexerStore) CreateWithIndexerID added in v1.8.0

func (s *TorznabIndexerStore) CreateWithIndexerID(ctx context.Context, name, baseURL, indexerID, apiKey string, basicUsername, basicPassword *string, enabled bool, priority, timeoutSeconds int, backend TorznabBackend) (*TorznabIndexer, error)

func (*TorznabIndexerStore) Delete added in v1.8.0

func (s *TorznabIndexerStore) Delete(ctx context.Context, id int) error

Delete deletes a Torznab indexer String pool cleanup is handled by the centralized CleanupUnusedStrings() function

func (*TorznabIndexerStore) Get added in v1.8.0

Get retrieves a Torznab indexer by ID using the view

func (*TorznabIndexerStore) GetAllHealth added in v1.8.0

func (s *TorznabIndexerStore) GetAllHealth(ctx context.Context) ([]TorznabIndexerHealth, error)

GetAllHealth retrieves health information for all indexers

func (*TorznabIndexerStore) GetCapabilities added in v1.8.0

func (s *TorznabIndexerStore) GetCapabilities(ctx context.Context, indexerID int) ([]string, error)

GetCapabilities retrieves all capabilities for an indexer

func (*TorznabIndexerStore) GetCategories added in v1.8.0

func (s *TorznabIndexerStore) GetCategories(ctx context.Context, indexerID int) ([]TorznabIndexerCategory, error)

GetCategories retrieves all categories for an indexer

func (*TorznabIndexerStore) GetDecryptedAPIKey added in v1.8.0

func (s *TorznabIndexerStore) GetDecryptedAPIKey(indexer *TorznabIndexer) (string, error)

GetDecryptedAPIKey returns the decrypted API key for an indexer

func (*TorznabIndexerStore) GetDecryptedBasicPassword added in v1.14.0

func (s *TorznabIndexerStore) GetDecryptedBasicPassword(indexer *TorznabIndexer) (string, error)

GetDecryptedBasicPassword returns the decrypted basic auth password for an indexer.

func (*TorznabIndexerStore) GetHealth added in v1.8.0

func (s *TorznabIndexerStore) GetHealth(ctx context.Context, indexerID int) (*TorznabIndexerHealth, error)

GetHealth retrieves health information for an indexer

func (*TorznabIndexerStore) GetLatencyStats added in v1.8.0

func (s *TorznabIndexerStore) GetLatencyStats(ctx context.Context, indexerID int) ([]TorznabIndexerLatencyStats, error)

GetLatencyStats retrieves aggregated latency statistics for an indexer

func (*TorznabIndexerStore) GetRecentErrors added in v1.8.0

func (s *TorznabIndexerStore) GetRecentErrors(ctx context.Context, indexerID int, limit int) ([]TorznabIndexerError, error)

GetRecentErrors retrieves recent errors for an indexer

func (*TorznabIndexerStore) List added in v1.8.0

List retrieves all Torznab indexers using the view, ordered by priority (descending) and name

func (*TorznabIndexerStore) ListEnabled added in v1.8.0

func (s *TorznabIndexerStore) ListEnabled(ctx context.Context) ([]*TorznabIndexer, error)

ListEnabled retrieves all enabled Torznab indexers using the view, ordered by priority

func (*TorznabIndexerStore) RecordError added in v1.8.0

func (s *TorznabIndexerStore) RecordError(ctx context.Context, indexerID int, errorMessage, errorCode string) error

RecordError records an error for an indexer

func (*TorznabIndexerStore) RecordLatency added in v1.8.0

func (s *TorznabIndexerStore) RecordLatency(ctx context.Context, indexerID int, operationType string, latencyMs int, success bool) error

RecordLatency records a latency measurement for an indexer

func (*TorznabIndexerStore) RewriteLegacyCredentials added in v1.29.0

func (s *TorznabIndexerStore) RewriteLegacyCredentials(ctx context.Context) (int, error)

RewriteLegacyCredentials re-encrypts stored Torznab indexer credentials that still carry the pre-HKDF format and reports how many rows it rewrote.

func (*TorznabIndexerStore) SetCapabilities added in v1.8.0

func (s *TorznabIndexerStore) SetCapabilities(ctx context.Context, indexerID int, capabilities []string) error

SetCapabilities replaces all capabilities for an indexer

func (*TorznabIndexerStore) SetCategories added in v1.8.0

func (s *TorznabIndexerStore) SetCategories(ctx context.Context, indexerID int, categories []TorznabIndexerCategory) error

SetCategories replaces all categories for an indexer

func (*TorznabIndexerStore) SetLimits added in v1.13.0

func (s *TorznabIndexerStore) SetLimits(ctx context.Context, indexerID, limitDefault, limitMax int) error

SetLimits updates the limit_default and limit_max values for an indexer

func (*TorznabIndexerStore) Update added in v1.8.0

Update updates a Torznab indexer

func (*TorznabIndexerStore) UpdateTestStatus added in v1.8.0

func (s *TorznabIndexerStore) UpdateTestStatus(ctx context.Context, id int, status string, errorMsg *string) error

UpdateTestStatus updates the test status of an indexer

type TorznabIndexerUpdateParams added in v1.8.0

type TorznabIndexerUpdateParams struct {
	Name           string
	BaseURL        string
	IndexerID      *string
	Backend        *TorznabBackend
	APIKey         string
	BasicUsername  *string
	BasicPassword  *string
	Enabled        *bool
	Priority       *int
	TimeoutSeconds *int
}

TorznabIndexerUpdateParams captures optional fields for updating an indexer.

type TorznabRecentSearch added in v1.8.0

type TorznabRecentSearch struct {
	CacheKey     string     `json:"cacheKey"`
	Scope        string     `json:"scope"`
	Query        string     `json:"query"`
	Categories   []int      `json:"categories"`
	IndexerIDs   []int      `json:"indexerIds"`
	TotalResults int        `json:"totalResults"`
	CachedAt     time.Time  `json:"cachedAt"`
	LastUsedAt   *time.Time `json:"lastUsedAt,omitempty"`
	ExpiresAt    time.Time  `json:"expiresAt"`
	HitCount     int64      `json:"hitCount"`
}

TorznabRecentSearch captures metadata about a cached search request for UI consumption.

type TorznabSearchCacheEntry added in v1.8.0

type TorznabSearchCacheEntry struct {
	ID                 int64
	CacheKey           string
	Scope              string
	Query              string
	Categories         []int
	IndexerIDs         []int
	RequestFingerprint string
	ResponseData       []byte
	TotalResults       int
	CachedAt           time.Time
	LastUsedAt         time.Time
	ExpiresAt          time.Time
	HitCount           int64
}

TorznabSearchCacheEntry captures a cached Torznab search response.

type TorznabSearchCacheSettings added in v1.8.0

type TorznabSearchCacheSettings struct {
	TTLMinutes int
	UpdatedAt  *time.Time
}

TorznabSearchCacheSettings tracks persisted cache configuration.

type TorznabSearchCacheStats added in v1.8.0

type TorznabSearchCacheStats struct {
	Entries         int64      `json:"entries"`
	TotalHits       int64      `json:"totalHits"`
	ApproxSizeBytes int64      `json:"approxSizeBytes"`
	OldestCachedAt  *time.Time `json:"oldestCachedAt,omitempty"`
	NewestCachedAt  *time.Time `json:"newestCachedAt,omitempty"`
	LastUsedAt      *time.Time `json:"lastUsedAt,omitempty"`
	Enabled         bool       `json:"enabled"`
	TTLMinutes      int        `json:"ttlMinutes"`
}

TorznabSearchCacheStats provides aggregated cache metrics for observability.

type TorznabSearchCacheStore added in v1.8.0

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

TorznabSearchCacheStore persists search cache entries.

func NewTorznabSearchCacheStore added in v1.8.0

func NewTorznabSearchCacheStore(db dbinterface.Querier) *TorznabSearchCacheStore

NewTorznabSearchCacheStore constructs a new search cache store.

func (*TorznabSearchCacheStore) CleanupExpired added in v1.8.0

func (s *TorznabSearchCacheStore) CleanupExpired(ctx context.Context) (int64, error)

CleanupExpired removes all expired cache rows.

func (*TorznabSearchCacheStore) Fetch added in v1.8.0

Fetch returns a cached search response by cache key.

func (*TorznabSearchCacheStore) FindActiveByScopeAndQuery added in v1.8.0

func (s *TorznabSearchCacheStore) FindActiveByScopeAndQuery(ctx context.Context, scope string, query string) ([]*TorznabSearchCacheEntry, error)

FindActiveByScopeAndQuery returns matching, non-expired cache entries for a scope/query pair.

func (*TorznabSearchCacheStore) Flush added in v1.8.0

Flush removes every cache entry.

func (*TorznabSearchCacheStore) GetSettings added in v1.8.0

GetSettings returns the current cache settings (if any).

func (*TorznabSearchCacheStore) InvalidateByIndexerIDs added in v1.8.0

func (s *TorznabSearchCacheStore) InvalidateByIndexerIDs(ctx context.Context, indexerIDs []int) (int64, error)

InvalidateByIndexerIDs removes cache entries referencing any of the provided indexers.

func (*TorznabSearchCacheStore) RebaseTTL added in v1.8.0

func (s *TorznabSearchCacheStore) RebaseTTL(ctx context.Context, ttlMinutes int) (int64, error)

RebaseTTL recalculates expires_at for all cached entries using the provided TTL minutes.

func (*TorznabSearchCacheStore) RecentSearches added in v1.8.0

func (s *TorznabSearchCacheStore) RecentSearches(ctx context.Context, scope string, limit int) ([]*TorznabRecentSearch, error)

RecentSearches returns the most recently used cached search queries.

func (*TorznabSearchCacheStore) Stats added in v1.8.0

Stats returns summary metrics for the search cache table.

func (*TorznabSearchCacheStore) Store added in v1.8.0

Store inserts or updates a cached search response.

func (*TorznabSearchCacheStore) Touch added in v1.8.0

func (s *TorznabSearchCacheStore) Touch(ctx context.Context, id int64)

Touch updates last_used_at and hit_count for a cache entry.

func (*TorznabSearchCacheStore) UpdateSettings added in v1.8.0

func (s *TorznabSearchCacheStore) UpdateSettings(ctx context.Context, ttlMinutes int) (*TorznabSearchCacheSettings, error)

UpdateSettings persists TTL minutes and returns the updated settings.

type TorznabTorrentCacheEntry added in v1.8.0

type TorznabTorrentCacheEntry struct {
	IndexerID   int
	CacheKey    string
	GUID        string
	DownloadURL string
	InfoHash    string
	Title       string
	SizeBytes   int64
	TorrentData []byte
}

TorznabTorrentCacheEntry represents a cached torrent payload downloaded from an indexer.

type TorznabTorrentCacheStore added in v1.8.0

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

TorznabTorrentCacheStore manages cached Torznab torrent files.

func NewTorznabTorrentCacheStore added in v1.8.0

func NewTorznabTorrentCacheStore(db dbinterface.Querier) *TorznabTorrentCacheStore

NewTorznabTorrentCacheStore constructs a new cache store.

func (*TorznabTorrentCacheStore) Cleanup added in v1.8.0

func (s *TorznabTorrentCacheStore) Cleanup(ctx context.Context, olderThan time.Duration) (int64, error)

Cleanup removes entries older than the provided age, returning the number of deleted rows.

func (*TorznabTorrentCacheStore) Fetch added in v1.8.0

func (s *TorznabTorrentCacheStore) Fetch(ctx context.Context, indexerID int, cacheKey string, maxAge time.Duration) ([]byte, bool, error)

Fetch returns cached torrent data when available and not expired. maxAge <= 0 disables expiration checks.

func (*TorznabTorrentCacheStore) Store added in v1.8.0

Store inserts or updates a cached torrent payload.

type TrackerCustomization added in v1.9.0

type TrackerCustomization struct {
	ID              int       `json:"id"`
	DisplayName     string    `json:"displayName"`
	Domains         []string  `json:"domains"`
	IncludedInStats []string  `json:"includedInStats,omitempty"`
	CreatedAt       time.Time `json:"createdAt"`
	UpdatedAt       time.Time `json:"updatedAt"`
}

type TrackerCustomizationStore added in v1.9.0

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

func NewTrackerCustomizationStore added in v1.9.0

func NewTrackerCustomizationStore(db dbinterface.Querier) *TrackerCustomizationStore

func (*TrackerCustomizationStore) Create added in v1.9.0

func (*TrackerCustomizationStore) Delete added in v1.9.0

func (s *TrackerCustomizationStore) Delete(ctx context.Context, id int) error

func (*TrackerCustomizationStore) Get added in v1.9.0

func (*TrackerCustomizationStore) List added in v1.9.0

func (*TrackerCustomizationStore) Update added in v1.9.0

type User

type User struct {
	ID           int    `json:"id"`
	Username     string `json:"username"`
	PasswordHash string `json:"-"`
}

type UserStore

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

func NewUserStore

func NewUserStore(db dbinterface.Querier) *UserStore

func (*UserStore) Create

func (s *UserStore) Create(ctx context.Context, username, passwordHash string) (*User, error)

func (*UserStore) Exists

func (s *UserStore) Exists(ctx context.Context) (bool, error)

func (*UserStore) Get

func (s *UserStore) Get(ctx context.Context) (*User, error)

func (*UserStore) GetByUsername

func (s *UserStore) GetByUsername(ctx context.Context, username string) (*User, error)

func (*UserStore) UpdatePassword

func (s *UserStore) UpdatePassword(ctx context.Context, passwordHash string) error

Jump to

Keyboard shortcuts

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