models

package
v1.13.1 Latest Latest
Warning

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

Go to latest
Published: Jan 28, 2026 License: GPL-2.0 Imports: 25 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 non-matches
)

Tag mode constants

View Source
const (
	HardlinkScopeNone               = "none"                // No file has link count > 1
	HardlinkScopeTorrentsOnly       = "torrents_only"       // All links are within qBittorrent's torrent set
	HardlinkScopeOutsideQBitTorrent = "outside_qbittorrent" // At least one file has links outside the torrent set
)

Hardlink scope values (wire format - stable API values)

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
	ActivityActionMoved               = "moved"                // Batch move operation
)

Activity action types

View Source
const (
	ActivityOutcomeSuccess = "success"
	ActivityOutcomeFailed  = "failed"
)

Activity outcome types

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

Category affix mode constants.

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

Error types for categorization

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

LicenseStatus constants

Variables

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 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 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 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 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 ActionConditions added in v1.12.0

type ActionConditions struct {
	SchemaVersion string             `json:"schemaVersion"`
	SpeedLimits   *SpeedLimitAction  `json:"speedLimits,omitempty"`
	ShareLimits   *ShareLimitsAction `json:"shareLimits,omitempty"`
	Pause         *PauseAction       `json:"pause,omitempty"`
	Delete        *DeleteAction      `json:"delete,omitempty"`
	Tag           *TagAction         `json:"tag,omitempty"`
	Category      *CategoryAction    `json:"category,omitempty"`
	Move          *MoveAction        `json:"move,omitempty"`
}

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

func (*ActionConditions) IsEmpty added in v1.12.0

func (ac *ActionConditions) IsEmpty() bool

IsEmpty returns true if no actions are configured.

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"`
	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) Count added in v1.12.0

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

Count returns the total number of cache entries

func (*ArrIDCacheStore) CountValid added in v1.12.0

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

CountValid returns the number of non-expired cache entries

func (*ArrIDCacheStore) Delete added in v1.12.0

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

Delete removes a specific cache entry

func (*ArrIDCacheStore) DeleteByArrInstance added in v1.12.0

func (s *ArrIDCacheStore) DeleteByArrInstance(ctx context.Context, arrInstanceID int) error

DeleteByArrInstance removes all cache entries for a specific ARR instance

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

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)

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"`
	APIKeyEncrypted 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) (*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, 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) 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) 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
	Enabled        *bool
	Priority       *int
	TimeoutSeconds *int
}

ArrInstanceUpdateParams captures optional fields for updating an ARR instance.

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"`
	TrackerDomains  []string          `json:"trackerDomains,omitempty"`
	Conditions      *ActionConditions `json:"conditions"`
	FreeSpaceSource *FreeSpaceSource  `json:"freeSpaceSource,omitempty"` // nil = default qBittorrent free space
	Enabled         bool              `json:"enabled"`
	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) 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 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) 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) 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"`
	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"`
	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) CountBlobReferences added in v1.5.0

func (s *BackupStore) CountBlobReferences(ctx context.Context, relPath string) (int, error)

func (*BackupStore) CountBlobReferencesBatch added in v1.8.0

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

func (*BackupStore) CountRunsByKind added in v1.5.0

func (s *BackupStore) CountRunsByKind(ctx context.Context, instanceID int, kind BackupRunKind) (int, error)

func (*BackupStore) CreateRun added in v1.5.0

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

func (*BackupStore) DeleteItemsByRunIDs added in v1.5.0

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

func (*BackupStore) DeleteRun added in v1.5.0

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

func (*BackupStore) DeleteRunsByIDs added in v1.5.0

func (s *BackupStore) DeleteRunsByIDs(ctx context.Context, runIDs []int64) 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

func (*BackupStore) LatestRunByKind added in v1.5.0

func (s *BackupStore) LatestRunByKind(ctx context.Context, instanceID int, kind BackupRunKind) (*BackupRun, error)

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) RemoveFailedRunsBefore added in v1.5.0

func (s *BackupStore) RemoveFailedRunsBefore(ctx context.Context, cutoff time.Time) (int64, error)

RemoveFailedRunsBefore deletes failed runs older than the provided cutoff and returns the number of rows affected.

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"`
	Category          string `json:"category"`                    // Target category name
	IncludeCrossSeeds bool   `json:"includeCrossSeeds,omitempty"` // Also move cross-seeds to same category
	// 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"`
	Condition                    *RuleCondition `json:"condition,omitempty"`
}

CategoryAction configures category assignment with optional conditions.

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) DeleteByInstanceID added in v1.0.0

func (s *ClientAPIKeyStore) DeleteByInstanceID(ctx context.Context, instanceID 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 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"
	FieldCategory    ConditionField = "CATEGORY"
	FieldTags        ConditionField = "TAGS"
	FieldSavePath    ConditionField = "SAVE_PATH"
	FieldContentPath ConditionField = "CONTENT_PATH"
	FieldState       ConditionField = "STATE"
	FieldTracker     ConditionField = "TRACKER"
	FieldComment     ConditionField = "COMMENT"

	// Numeric fields (bytes)
	FieldSize       ConditionField = "SIZE"
	FieldTotalSize  ConditionField = "TOTAL_SIZE"
	FieldDownloaded ConditionField = "DOWNLOADED"
	FieldUploaded   ConditionField = "UPLOADED"
	FieldAmountLeft ConditionField = "AMOUNT_LEFT"
	FieldFreeSpace  ConditionField = "FREE_SPACE"

	// Numeric fields (timestamps/seconds)
	FieldAddedOn      ConditionField = "ADDED_ON"
	FieldCompletionOn ConditionField = "COMPLETION_ON"
	FieldLastActivity ConditionField = "LAST_ACTIVITY"
	FieldSeedingTime  ConditionField = "SEEDING_TIME"
	FieldTimeActive   ConditionField = "TIME_ACTIVE"

	// Age fields (time since timestamp - 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"
	FieldProgress     ConditionField = "PROGRESS"
	FieldAvailability ConditionField = "AVAILABILITY"

	// Numeric fields (speeds)
	FieldDlSpeed ConditionField = "DL_SPEED"
	FieldUpSpeed ConditionField = "UP_SPEED"

	// Numeric fields (counts)
	FieldNumSeeds      ConditionField = "NUM_SEEDS"
	FieldNumLeechs     ConditionField = "NUM_LEECHS"
	FieldNumComplete   ConditionField = "NUM_COMPLETE"
	FieldNumIncomplete ConditionField = "NUM_INCOMPLETE"
	FieldTrackersCount ConditionField = "TRACKERS_COUNT"

	// Boolean fields
	FieldPrivate         ConditionField = "PRIVATE"
	FieldIsUnregistered  ConditionField = "IS_UNREGISTERED"
	FieldHasMissingFiles ConditionField = "HAS_MISSING_FILES"

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

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 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)
	StartPaused        bool    `json:"startPaused"`        // RSS: start added torrents paused
	Category           *string `json:"category,omitempty"` // RSS: category for added torrents
	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
	SizeMismatchTolerancePercent float64 `json:"sizeMismatchTolerancePercent"` // Size tolerance for matching (default: 5%)
	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

	// 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
	SkipPieceBoundarySafetyCheck bool `json:"skipPieceBoundarySafetyCheck"` // Skip piece boundary safety check (risky: may corrupt existing seeded data)

	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 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 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"`
	TorrentsAdded   int                  `json:"torrentsAdded"`
	TorrentsFailed  int                  `json:"torrentsFailed"`
	TorrentsSkipped int                  `json:"torrentsSkipped"`
	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"`
	Added        bool      `json:"added"`
	Message      string    `json:"message,omitempty"`
	ProcessedAt  time.Time `json:"processedAt"`
}

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

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"`
	TorrentsAdded   int                      `json:"torrentsAdded"`
	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) *CrossSeedStore

NewCrossSeedStore constructs a new automation store.

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) GetLatestRun added in v1.8.0

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

GetLatestRun returns the most recent automation run.

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) 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) 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) 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) 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) (*CrossSeedSearchRun, error)

UpdateSearchRun updates persisted metadata for a search run.

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"`
	Mode             string         `json:"mode"`                       // "delete", "deleteWithFiles", "deleteWithFilesPreserveCrossSeeds", "deleteWithFilesIncludeCrossSeeds"
	IncludeHardlinks bool           `json:"includeHardlinks,omitempty"` // Only valid when mode is "deleteWithFilesIncludeCrossSeeds" and instance has local filesystem access
	Condition        *RuleCondition `json:"condition,omitempty"`
}

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"`
	Enabled             bool       `json:"enabled"`
	ArrInstanceID       *int       `json:"arrInstanceId,omitempty"`
	TargetInstanceID    int        `json:"targetInstanceId"`
	ScanIntervalMinutes int        `json:"scanIntervalMinutes"`
	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
	Enabled             *bool
	ArrInstanceID       *int // Use -1 to clear
	TargetInstanceID    *int
	ScanIntervalMinutes *int
}

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, vol+idx on Windows)
	Status             DirScanFileStatus `json:"status"`
	MatchedTorrentHash string            `json:"matchedTorrentHash,omitempty"`
	MatchedIndexerID   *int              `json:"matchedIndexerId,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"`
	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"`
	AllowPartial                 bool      `json:"allowPartial"`
	SkipPieceBoundarySafetyCheck bool      `json:"skipPieceBoundarySafetyCheck"`
	StartPaused                  bool      `json:"startPaused"`
	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) CountFilesByStatus added in v1.13.0

func (s *DirScanStore) CountFilesByStatus(ctx context.Context, directoryID int) (map[DirScanFileStatus]int, error)

CountFilesByStatus returns counts of files by status for a directory.

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 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 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) GetFileByFileID added in v1.13.0

func (s *DirScanStore) GetFileByFileID(ctx context.Context, directoryID int, fileID []byte) (*DirScanFile, error)

GetFileByFileID retrieves a file by its FileID within a directory.

func (*DirScanStore) GetFileByPath added in v1.13.0

func (s *DirScanStore) GetFileByPath(ctx context.Context, directoryID int, filePath string) (*DirScanFile, error)

GetFileByPath retrieves a file by its path within a directory.

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) HasActiveRun added in v1.13.0

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

HasActiveRun checks if there's an active run for a directory.

func (*DirScanStore) ListDirectories added in v1.13.0

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

ListDirectories retrieves all scan directories.

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) 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) UpdateFileMatch added in v1.13.0

func (s *DirScanStore) UpdateFileMatch(ctx context.Context, fileID int64, torrentHash string, indexerID int) error

UpdateFileMatch updates the match info for a file.

func (*DirScanStore) UpdateFileStatus added in v1.13.0

func (s *DirScanStore) UpdateFileStatus(ctx context.Context, fileID int64, status DirScanFileStatus) error

UpdateFileStatus updates the status of a file.

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) 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) 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 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 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 FreeSpaceSource added in v1.13.0

type FreeSpaceSource struct {
	Type FreeSpaceSourceType `json:"type"`           // "qbittorrent" or "path"
	Path string              `json:"path,omitempty"` // Required when Type == "path"
}

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 from a local filesystem path.
	FreeSpaceSourcePath FreeSpaceSourceType = "path"
)

type Instance

type Instance struct {
	ID                       int     `json:"id"`
	Name                     string  `json:"name"`
	Host                     string  `json:"host"`
	Username                 string  `json:"username"`
	PasswordEncrypted        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"`
}

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"`
	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.

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) (*InstanceStore, error)

func (*InstanceStore) Create

func (s *InstanceStore) Create(ctx context.Context, name, rawHost, username, password string, basicUsername, basicPassword *string, tlsSkipVerify bool, hasLocalFilesystemAccess *bool) (*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) 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) List

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

func (*InstanceStore) SetActiveState added in v1.8.0

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

func (*InstanceStore) Update

func (s *InstanceStore) Update(ctx context.Context, id int, name, rawHost, username, password string, basicUsername, basicPassword *string, params *InstanceUpdateParams) (*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 MoveAction added in v1.13.0

type MoveAction struct {
	Enabled          bool           `json:"enabled"`
	Path             string         `json:"path"`
	BlockIfCrossSeed bool           `json:"blockIfCrossSeed,omitempty"`
	Condition        *RuleCondition `json:"condition,omitempty"`
}

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"`
	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"`
	ErrorMessage   string     `json:"errorMessage,omitempty"`
	StartedAt      time.Time  `json:"startedAt"`
	CompletedAt    *time.Time `json:"completedAt,omitempty"`
}

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"`
	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) CountFiles added in v1.12.0

func (s *OrphanScanStore) CountFiles(ctx context.Context, runID int64) (int, error)

CountFiles returns the total number of files for a run.

func (*OrphanScanStore) CreateRun added in v1.12.0

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

CreateRun creates a new orphan scan run.

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.

func (*OrphanScanStore) DeleteRun added in v1.12.0

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

DeleteRun deletes a run and its files (cascade).

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) GetMostRecentActiveRun added in v1.13.0

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

GetMostRecentActiveRun returns the most recent active run for an instance. "Active" matches the same definition used by 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) HasActiveRun added in v1.12.0

func (s *OrphanScanStore) HasActiveRun(ctx context.Context, instanceID int) (bool, error)

HasActiveRun checks if there's an active run for an instance. Note: preview_ready with files_found=0 is excluded (legacy "clean" scans that should have been marked completed).

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) 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) error

UpdateRunCompleted marks a run as completed with stats.

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) UpdateRunFilesFound added in v1.12.0

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

UpdateRunFilesFound updates the files found count and truncated flag.

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) 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 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"`
	Condition *RuleCondition `json:"condition,omitempty"`
}

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"`
	PolarCustomerID   *string    `json:"polarCustomerId,omitempty"`
	PolarProductID    *string    `json:"polarProductId,omitempty"`
	PolarActivationID string     `json:"polarActivationId,omitempty"`
	Username          string     `json:"username"`
	CreatedAt         time.Time  `json:"createdAt"`
	UpdatedAt         time.Time  `json:"updatedAt"`
}

ProductLicense represents a product license in the database

type RuleCondition added in v1.12.0

type RuleCondition struct {
	Field      ConditionField    `json:"field,omitempty"`
	Operator   ConditionOperator `json:"operator"`
	Value      string            `json:"value,omitempty"`
	MinValue   *float64          `json:"minValue,omitempty"`
	MaxValue   *float64          `json:"maxValue,omitempty"`
	Regex      bool              `json:"regex,omitempty"`
	Negate     bool              `json:"negate,omitempty"`
	Conditions []*RuleCondition  `json:"conditions,omitempty"`
	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 ShareLimitsAction added in v1.12.0

type ShareLimitsAction struct {
	Enabled            bool           `json:"enabled"`
	RatioLimit         *float64       `json:"ratioLimit,omitempty"`
	SeedingTimeMinutes *int64         `json:"seedingTimeMinutes,omitempty"`
	Condition          *RuleCondition `json:"condition,omitempty"`
}

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

type SpeedLimitAction added in v1.12.0

type SpeedLimitAction struct {
	Enabled     bool           `json:"enabled"`
	UploadKiB   *int64         `json:"uploadKiB,omitempty"`
	DownloadKiB *int64         `json:"downloadKiB,omitempty"`
	Condition   *RuleCondition `json:"condition,omitempty"`
}

SpeedLimitAction configures speed limit application with optional conditions.

type TagAction added in v1.12.0

type TagAction struct {
	Enabled         bool           `json:"enabled"`
	Tags            []string       `json:"tags"`                      // Tags to manage (fallback if UseTrackerAsTag has no domains)
	Mode            string         `json:"mode"`                      // "full", "add", "remove"
	UseTrackerAsTag bool           `json:"useTrackerAsTag,omitempty"` // Derive tag from torrent's tracker domain
	UseDisplayName  bool           `json:"useDisplayName,omitempty"`  // Use tracker customization display name instead of raw domain
	Condition       *RuleCondition `json:"condition,omitempty"`
}

TagAction configures tagging with smart add/remove logic.

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 MustTorznabBackend added in v1.8.0

func MustTorznabBackend(value string) TorznabBackend

MustTorznabBackend parses backend and panics on error (useful for defaults).

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")
	Backend         TorznabBackend           `json:"backend"`
	APIKeyEncrypted 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 TorznabIndexerCapability added in v1.8.0

type TorznabIndexerCapability struct {
	IndexerID      int    `json:"indexer_id"`
	CapabilityType string `json:"capability_type"`
}

TorznabIndexerCapability represents a search capability

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 TorznabIndexerCooldown added in v1.8.0

type TorznabIndexerCooldown struct {
	IndexerID int           `json:"indexer_id"`
	ResumeAt  time.Time     `json:"resume_at"`
	Cooldown  time.Duration `json:"cooldown"`
	Reason    string        `json:"reason,omitempty"`
}

TorznabIndexerCooldown captures a persisted rate-limit suspension window for 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 TorznabIndexerLatency added in v1.8.0

type TorznabIndexerLatency struct {
	ID            int       `json:"id"`
	IndexerID     int       `json:"indexer_id"`
	OperationType string    `json:"operation_type"`
	LatencyMs     int       `json:"latency_ms"`
	Success       bool      `json:"success"`
	MeasuredAt    time.Time `json:"measured_at"`
}

TorznabIndexerLatency represents a latency measurement

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) (*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, 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, 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) DeleteRateLimitCooldown added in v1.8.0

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

DeleteRateLimitCooldown removes any persisted cooldown for the provided indexer ID.

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) 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) ListRateLimitCooldowns added in v1.8.0

func (s *TorznabIndexerStore) ListRateLimitCooldowns(ctx context.Context) ([]TorznabIndexerCooldown, error)

ListRateLimitCooldowns returns any persisted cooldown windows for Torznab indexers.

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) ResolveErrors added in v1.8.0

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

ResolveErrors marks all unresolved errors for an indexer as resolved

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) Test added in v1.8.0

func (s *TorznabIndexerStore) Test(ctx context.Context, baseURL, apiKey string) error

Test tests the connection to a Torznab indexer by querying its capabilities

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

func (*TorznabIndexerStore) UpsertRateLimitCooldown added in v1.8.0

func (s *TorznabIndexerStore) UpsertRateLimitCooldown(ctx context.Context, indexerID int, resumeAt time.Time, cooldown time.Duration, reason string) error

UpsertRateLimitCooldown stores or updates the cooldown window for an indexer.

type TorznabIndexerUpdateParams added in v1.8.0

type TorznabIndexerUpdateParams struct {
	Name           string
	BaseURL        string
	IndexerID      *string
	Backend        *TorznabBackend
	APIKey         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