jackett

package
v1.14.1 Latest Latest
Warning

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

Go to latest
Published: Feb 23, 2026 License: GPL-2.0 Imports: 28 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// Movies
	CategoryMovies   = 2000
	CategoryMoviesSD = 2030
	CategoryMoviesHD = 2040
	CategoryMovies4K = 2045
	CategoryMovies3D = 2050

	// TV
	CategoryTV            = 5000
	CategoryTVSD          = 5030
	CategoryTVHD          = 5040
	CategoryTV4K          = 5045
	CategoryTVSport       = 5060
	CategoryTVAnime       = 5070
	CategoryTVDocumentary = 5080

	// XXX
	CategoryXXX         = 6000
	CategoryXXXDVD      = 6010
	CategoryXXXWMV      = 6020
	CategoryXXXXviD     = 6030
	CategoryXXXx264     = 6040
	CategoryXXXPack     = 6050
	CategoryXXXImageSet = 6060
	CategoryXXXOther    = 6070

	// Audio
	CategoryAudio = 3000

	// PC
	CategoryPC = 4000

	// Books
	CategoryBooks       = 7000
	CategoryBooksEbook  = 7020
	CategoryBooksComics = 7030

	CacheModeDefault = ""
	CacheModeBypass  = "bypass"
)

Torznab category constants

View Source
const (
	DefaultSearchCacheTTL        = defaultSearchCacheTTL
	MinSearchCacheTTL            = minSearchCacheTTL
	MinSearchCacheTTLMinutes     = int(minSearchCacheTTL / time.Minute)
	DefaultSearchCacheTTLMinutes = int(defaultSearchCacheTTL / time.Minute)
)

Exported constants for cache settings.

Variables

View Source
var ErrMissingIndexerIdentifier = errors.New("torznab indexer identifier is required for caps sync")

ErrMissingIndexerIdentifier signals that the Torznab backend requires an indexer ID to fetch caps.

Functions

func GetIndexerDomainFromInfo

func GetIndexerDomainFromInfo(indexerInfo map[int]EnabledIndexerInfo, indexerID int) string

GetIndexerDomainFromInfo returns the indexer domain for a given ID using cached indexer info

func GetIndexerNameFromInfo

func GetIndexerNameFromInfo(indexerInfo map[int]EnabledIndexerInfo, indexerID int) string

GetIndexerNameFromInfo returns the indexer name for a given ID using cached indexer info

func WithSearchPriority

func WithSearchPriority(ctx context.Context, priority RateLimitPriority) context.Context

WithSearchPriority annotates a context with a desired search priority for scheduling.

Types

type ActivityStatus

type ActivityStatus struct {
	Scheduler        *SchedulerStatus        `json:"scheduler,omitempty"`
	CooldownIndexers []IndexerCooldownStatus `json:"cooldownIndexers"`
}

ActivityStatus represents the current activity state of the indexer service

type CategoryInfo

type CategoryInfo struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
}

CategoryInfo represents a Torznab category

type Client

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

Client wraps the Torznab backend client implementation

func NewClient

func NewClient(baseURL, apiKey string, basicUsername, basicPassword *string, backend models.TorznabBackend, timeoutSeconds int) *Client

NewClient creates a new Torznab client for the desired backend

func (*Client) Download

func (c *Client) Download(ctx context.Context, downloadURL string) ([]byte, error)

Download retrieves the raw torrent bytes for the provided download URL.

func (*Client) FetchCaps

func (c *Client) FetchCaps(ctx context.Context, indexerID string) (*torznabCaps, error)

FetchCaps retrieves the Torznab caps document for the configured backend/indexer.

func (*Client) GetCapabilitiesDirect

func (c *Client) GetCapabilitiesDirect() (*gojackett.Indexers, error)

GetCapabilitiesDirect gets capabilities from a direct Torznab endpoint

func (*Client) Search

func (c *Client) Search(ctx context.Context, indexer string, params map[string]string) ([]Result, error)

Search performs a search on a specific indexer or "all"

func (*Client) SearchAll

func (c *Client) SearchAll(ctx context.Context, params map[string]string) ([]Result, error)

SearchAll searches across all indexers when supported by the backend

func (*Client) SearchDirect

func (c *Client) SearchDirect(ctx context.Context, params map[string]string) ([]Result, error)

SearchDirect searches a direct Torznab endpoint (not through Jackett/Prowlarr aggregator) Uses the native SearchDirectCtx method from go-jackett library

type DiscoveryResult added in v1.9.0

type DiscoveryResult struct {
	Indexers []JackettIndexer `json:"indexers"`
	Warnings []string         `json:"warnings,omitempty"`
}

DiscoveryResult contains discovered indexers and any warnings from partial failures

func DiscoverJackettIndexers

func DiscoverJackettIndexers(ctx context.Context, baseURL, apiKey string, basicUsername, basicPassword *string) (DiscoveryResult, error)

DiscoverJackettIndexers discovers all configured indexers from a Jackett instance. The context is used to cancel in-flight capability fetches if the request is cancelled. Returns a DiscoveryResult containing indexers and any warnings about partial failures.

type DownloadError added in v1.9.0

type DownloadError struct {
	StatusCode int
	URL        string
}

DownloadError represents an HTTP error during torrent download. It preserves the status code for rate-limit detection and retry logic.

func (*DownloadError) Error added in v1.9.0

func (e *DownloadError) Error() string

func (*DownloadError) Is added in v1.9.0

func (e *DownloadError) Is(target error) bool

func (*DownloadError) IsRateLimited added in v1.9.0

func (e *DownloadError) IsRateLimited() bool

IsRateLimited returns true if this error indicates rate limiting (HTTP 429).

type DownloadRateLimitError added in v1.9.0

type DownloadRateLimitError struct {
	IndexerID   int
	IndexerName string
	ResumeAt    time.Time
	// Queued indicates whether the request was queued for automatic retry.
	// TODO: Set to true when download retry queue is implemented.
	Queued bool
}

DownloadRateLimitError indicates that a download was blocked due to rate limiting. It includes retry information to help callers decide whether to queue for later.

func (*DownloadRateLimitError) Error added in v1.9.0

func (e *DownloadRateLimitError) Error() string

func (*DownloadRateLimitError) Is added in v1.9.0

func (e *DownloadRateLimitError) Is(target error) bool

type EnabledIndexerInfo

type EnabledIndexerInfo struct {
	ID     int
	Name   string
	Domain string
}

EnabledIndexerInfo holds both name and domain information for an enabled indexer

type HistoryRecorder

type HistoryRecorder interface {
	Record(entry SearchHistoryEntry)
}

HistoryRecorder is the interface for recording search history.

func NewHistoryRecorder

func NewHistoryRecorder(buffer *SearchHistoryBuffer) HistoryRecorder

NewHistoryRecorder creates a new history recorder with the given buffer.

type IndexerCooldownStatus

type IndexerCooldownStatus struct {
	IndexerID   int       `json:"indexerId"`
	IndexerName string    `json:"indexerName"`
	CooldownEnd time.Time `json:"cooldownEnd"`
	Reason      string    `json:"reason,omitempty"`
}

IndexerCooldownStatus represents an indexer in cooldown

type IndexerInfo

type IndexerInfo struct {
	// ID of the indexer
	ID string `json:"id"`
	// Name of the indexer
	Name string `json:"name"`
	// Description
	Description string `json:"description,omitempty"`
	// Type (public, semi-private, private)
	Type string `json:"type"`
	// Configured (whether the indexer is configured)
	Configured bool `json:"configured"`
	// Supported categories
	Categories []CategoryInfo `json:"categories,omitempty"`
}

IndexerInfo represents information about a Jackett indexer

type IndexerOutcome

type IndexerOutcome struct {
	Outcome    string    `json:"outcome"`              // "added", "failed", "no_match", ""
	AddedCount int       `json:"addedCount,omitempty"` // Number of torrents added from this indexer
	Message    string    `json:"message,omitempty"`
	RecordedAt time.Time `json:"recordedAt"`
}

IndexerOutcome represents the cross-seed outcome for a specific indexer's search results.

type IndexerOutcomeStore

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

IndexerOutcomeStore tracks cross-seed outcomes per (JobID, IndexerID). Uses a bounded map with a ring buffer for FIFO eviction.

func NewIndexerOutcomeStore

func NewIndexerOutcomeStore(maxSize int) *IndexerOutcomeStore

NewIndexerOutcomeStore creates a new outcome store with the given capacity.

func (*IndexerOutcomeStore) Count

func (s *IndexerOutcomeStore) Count() int

Count returns the current number of outcomes stored.

func (*IndexerOutcomeStore) Get

func (s *IndexerOutcomeStore) Get(jobID uint64, indexerID int) (IndexerOutcome, bool)

Get retrieves the outcome for a specific (jobID, indexerID) pair.

func (*IndexerOutcomeStore) Record

func (s *IndexerOutcomeStore) Record(jobID uint64, indexerID int, outcome string, addedCount int, message string)

Record stores an outcome for a specific (jobID, indexerID) pair.

type IndexerStore

type IndexerStore interface {
	Get(ctx context.Context, id int) (*models.TorznabIndexer, error)
	List(ctx context.Context) ([]*models.TorznabIndexer, error)
	ListEnabled(ctx context.Context) ([]*models.TorznabIndexer, error)
	GetDecryptedAPIKey(indexer *models.TorznabIndexer) (string, error)
	GetDecryptedBasicPassword(indexer *models.TorznabIndexer) (string, error)
	GetCapabilities(ctx context.Context, indexerID int) ([]string, error)
	SetCapabilities(ctx context.Context, indexerID int, capabilities []string) error
	SetCategories(ctx context.Context, indexerID int, categories []models.TorznabIndexerCategory) error
	SetLimits(ctx context.Context, indexerID, limitDefault, limitMax int) error
	RecordLatency(ctx context.Context, indexerID int, operationType string, latencyMs int, success bool) error
	RecordError(ctx context.Context, indexerID int, errorMessage, errorCode string) error
	ListRateLimitCooldowns(ctx context.Context) ([]models.TorznabIndexerCooldown, error)
	UpsertRateLimitCooldown(ctx context.Context, indexerID int, resumeAt time.Time, cooldown time.Duration, reason string) error
	DeleteRateLimitCooldown(ctx context.Context, indexerID int) error
}

IndexerStore defines the interface for indexer storage operations

type IndexersResponse

type IndexersResponse struct {
	Indexers []IndexerInfo `json:"indexers"`
}

IndexersResponse represents the list of available indexers

type JackettIndexer

type JackettIndexer struct {
	ID          string                          `json:"id"`
	Name        string                          `json:"name"`
	Description string                          `json:"description"`
	Type        string                          `json:"type"`
	Configured  bool                            `json:"configured"`
	Backend     models.TorznabBackend           `json:"backend"`
	Caps        []string                        `json:"caps,omitempty"`
	Categories  []models.TorznabIndexerCategory `json:"categories,omitempty"`
}

JackettIndexer represents an indexer from Jackett's indexer list

type JobCallbacks

type JobCallbacks struct {
	// OnComplete fires for each indexer when it finishes (success or error).
	// Called in a goroutine - safe to do blocking work.
	OnComplete func(jobID uint64, indexer *models.TorznabIndexer, results []Result, coverage []int, err error)
	// OnJobDone fires once after ALL indexers complete (optional, can be nil).
	// Called in a goroutine - safe to do blocking work.
	OnJobDone func(jobID uint64)
}

JobCallbacks defines the callbacks for async job completion.

type MagnetDownloadError added in v1.13.0

type MagnetDownloadError struct {
	MagnetURL string
}

MagnetDownloadError indicates that the download endpoint redirected to a magnet URL. Callers should add the magnet directly to the torrent client.

func (*MagnetDownloadError) Error added in v1.13.0

func (e *MagnetDownloadError) Error() string

type RateLimitOptions

type RateLimitOptions struct {
	Priority    RateLimitPriority
	MinInterval time.Duration
	MaxWait     time.Duration
}

type RateLimitPriority

type RateLimitPriority string
const (
	RateLimitPriorityInteractive RateLimitPriority = "interactive"
	RateLimitPriorityRSS         RateLimitPriority = "rss"
	RateLimitPriorityCompletion  RateLimitPriority = "completion"
	RateLimitPriorityBackground  RateLimitPriority = "background"
)

func SearchPriority added in v1.13.0

func SearchPriority(ctx context.Context) (RateLimitPriority, bool)

SearchPriority returns the desired scheduler priority embedded in ctx via WithSearchPriority.

type RateLimitWaitError

type RateLimitWaitError struct {
	IndexerID   int
	IndexerName string
	Wait        time.Duration
	MaxWait     time.Duration
	Priority    RateLimitPriority
}

func (*RateLimitWaitError) Error

func (e *RateLimitWaitError) Error() string

func (*RateLimitWaitError) Is

func (e *RateLimitWaitError) Is(target error) bool

type RateLimiter

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

RateLimiter tracks per-indexer request timing and computes wait times. It does not block; the scheduler queries it to make dispatch decisions.

func NewRateLimiter

func NewRateLimiter(minInterval time.Duration) *RateLimiter

func (*RateLimiter) ClearCooldown

func (r *RateLimiter) ClearCooldown(indexerID int)

func (*RateLimiter) GetCooldownIndexers

func (r *RateLimiter) GetCooldownIndexers() map[int]time.Time

GetCooldownIndexers returns a list of indexer IDs that are currently in cooldown

func (*RateLimiter) IsInCooldown

func (r *RateLimiter) IsInCooldown(indexerID int) (bool, time.Time)

IsInCooldown checks if an indexer is currently in cooldown without blocking

func (*RateLimiter) LoadCooldowns

func (r *RateLimiter) LoadCooldowns(cooldowns map[int]time.Time)

LoadCooldowns seeds the rate limiter with pre-existing cooldown windows.

func (*RateLimiter) NextWait

func (r *RateLimiter) NextWait(indexer *models.TorznabIndexer, opts *RateLimitOptions) time.Duration

NextWait returns the amount of time the caller would need to wait before a request could be made against the provided indexer using the supplied options. This is a non-blocking helper used by the job scheduler to decide if a request can run immediately.

func (*RateLimiter) RecordFailure

func (r *RateLimiter) RecordFailure(indexerID int) time.Duration

RecordFailure increments the escalation level and sets a cooldown based on the new level. This implements Prowlarr-style escalating backoff for rate limit failures.

func (*RateLimiter) RecordRequest

func (r *RateLimiter) RecordRequest(indexerID int, ts time.Time)

func (*RateLimiter) RecordSuccess

func (r *RateLimiter) RecordSuccess(indexerID int)

RecordSuccess resets the escalation level to 0 on successful request.

func (*RateLimiter) SetCooldown

func (r *RateLimiter) SetCooldown(indexerID int, until time.Time)

func (*RateLimiter) WaitForMinInterval added in v1.13.0

func (r *RateLimiter) WaitForMinInterval(ctx context.Context, indexer *models.TorznabIndexer, opts *RateLimitOptions) error

WaitForMinInterval blocks until a new request slot is available for the given indexer according to the configured min interval and priority multiplier, then reserves the slot by recording the request time.

Note: this intentionally does NOT wait for cooldown windows. Callers that care about cooldowns should check IsInCooldown separately (downloads typically return immediately when in cooldown).

type Result

type Result struct {
	Tracker              string
	IndexerID            int
	Title                string
	Link                 string
	Details              string
	GUID                 string
	PublishDate          time.Time
	Category             string
	Size                 int64
	Seeders              int
	Peers                int
	DownloadVolumeFactor float64
	UploadVolumeFactor   float64
	Imdb                 string
	// Attributes stores every Torznab attribute with lowercase keys from RSS item attr entries (see convertRssToResults normalization).
	Attributes map[string]string
}

Result represents a single search result (simplified format)

type SchedulerJobStatus

type SchedulerJobStatus struct {
	JobID          uint64 `json:"jobId"`
	TotalTasks     int    `json:"totalTasks"`
	CompletedTasks int    `json:"completedTasks"`
}

SchedulerJobStatus represents a job's completion status

type SchedulerStatus

type SchedulerStatus struct {
	QueuedTasks   []SchedulerTaskStatus `json:"queuedTasks"`
	InFlightTasks []SchedulerTaskStatus `json:"inFlightTasks"`
	ActiveJobs    []SchedulerJobStatus  `json:"activeJobs"`
	QueueLength   int                   `json:"queueLength"`
	WorkerCount   int                   `json:"workerCount"`
	WorkersInUse  int                   `json:"workersInUse"`
}

SchedulerStatus represents the current state of the scheduler

type SchedulerTaskStatus

type SchedulerTaskStatus struct {
	JobID       uint64    `json:"jobId"`
	TaskID      uint64    `json:"taskId"`
	IndexerID   int       `json:"indexerId"`
	IndexerName string    `json:"indexerName"`
	Priority    string    `json:"priority"`
	CreatedAt   time.Time `json:"createdAt"`
	IsRSS       bool      `json:"isRss"`
}

SchedulerTaskStatus represents a single task's status

type SearchCacheConfig

type SearchCacheConfig struct {
	TTL time.Duration
}

SearchCacheConfig defines caching behaviour for Torznab search queries.

type SearchCacheMetadata

type SearchCacheMetadata struct {
	Hit       bool       `json:"hit"`
	Scope     string     `json:"scope"`
	Source    string     `json:"source"`
	CachedAt  time.Time  `json:"cachedAt"`
	ExpiresAt time.Time  `json:"expiresAt"`
	LastUsed  *time.Time `json:"lastUsed,omitempty"`
}

SearchCacheMetadata describes how the response was sourced.

type SearchHistoryBuffer

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

SearchHistoryBuffer is a thread-safe ring buffer for live search history.

func NewSearchHistoryBuffer

func NewSearchHistoryBuffer(capacity int) *SearchHistoryBuffer

NewSearchHistoryBuffer creates a new ring buffer with the given capacity.

func (*SearchHistoryBuffer) Count

func (b *SearchHistoryBuffer) Count() int

Count returns the current number of entries in the buffer.

func (*SearchHistoryBuffer) GetByIndexer

func (b *SearchHistoryBuffer) GetByIndexer(indexerID int, limit int) []SearchHistoryEntry

GetByIndexer returns recent entries for a specific indexer.

func (*SearchHistoryBuffer) GetRecent

func (b *SearchHistoryBuffer) GetRecent(limit int) []SearchHistoryEntry

GetRecent returns the most recent entries, up to the specified limit. Entries are returned in reverse chronological order (newest first).

func (*SearchHistoryBuffer) Push

Push adds an entry to the buffer and returns its assigned ID.

func (*SearchHistoryBuffer) Stats

type SearchHistoryEntry

type SearchHistoryEntry struct {
	ID     uint64 `json:"id"`
	JobID  uint64 `json:"jobId"`
	TaskID uint64 `json:"taskId"`

	// Indexer details
	IndexerID   int    `json:"indexerId"`
	IndexerName string `json:"indexerName"`

	// Search parameters
	Query       string            `json:"query,omitempty"`
	ReleaseName string            `json:"releaseName,omitempty"` // Original full release name
	Params      map[string]string `json:"params,omitempty"`      // Raw params sent to indexer
	Categories  []int             `json:"categories,omitempty"`
	ContentType string            `json:"contentType,omitempty"`
	Priority    string            `json:"priority"`
	SearchMode  string            `json:"searchMode,omitempty"`

	// Results
	Status      string `json:"status"` // success, error, skipped, rate_limited
	ResultCount int    `json:"resultCount"`

	// Timing
	StartedAt   time.Time `json:"startedAt"`
	CompletedAt time.Time `json:"completedAt"`
	DurationMs  int       `json:"durationMs"`

	// Error details (if applicable)
	ErrorMessage string `json:"errorMessage,omitempty"`
}

SearchHistoryEntry captures details of a completed search task.

type SearchHistoryEntryWithOutcome

type SearchHistoryEntryWithOutcome struct {
	SearchHistoryEntry
	Outcome    string `json:"outcome,omitempty"`    // "added", "failed", "no_match", ""
	AddedCount int    `json:"addedCount,omitempty"` // Torrents added from this indexer
}

SearchHistoryEntryWithOutcome extends SearchHistoryEntry with outcome data for API responses.

type SearchHistoryResponse

type SearchHistoryResponse struct {
	Entries []SearchHistoryEntry `json:"entries"`
	Total   int                  `json:"total"`
	Source  string               `json:"source"` // "memory" or "database"
}

SearchHistoryResponse is the API response for search history queries.

type SearchHistoryResponseWithOutcome

type SearchHistoryResponseWithOutcome struct {
	Entries []SearchHistoryEntryWithOutcome `json:"entries"`
	Total   int                             `json:"total"`
	Source  string                          `json:"source"` // "memory" or "database"
}

SearchHistoryResponseWithOutcome is the API response that includes outcome data.

type SearchHistoryStats

type SearchHistoryStats struct {
	Count       int            `json:"count"`
	Capacity    int            `json:"capacity"`
	ByStatus    map[string]int `json:"byStatus"`
	ByPriority  map[string]int `json:"byPriority"`
	AvgDuration float64        `json:"avgDurationMs"`
}

Stats returns basic statistics about the buffer.

type SearchResponse

type SearchResponse struct {
	Results []SearchResult       `json:"results"`
	Total   int                  `json:"total"`
	Cache   *SearchCacheMetadata `json:"cache,omitempty"`
	Partial bool                 `json:"partial,omitempty"`
	// JobID identifies this search for outcome tracking (cross-seed)
	JobID uint64 `json:"jobId,omitempty"`
}

type SearchResult

type SearchResult struct {
	// Indexer name
	Indexer string `json:"indexer"`
	// Indexer identifier
	IndexerID int `json:"indexer_id"`
	// Title of the release
	Title string `json:"title"`
	// Download URL for the torrent
	DownloadURL string `json:"download_url"`
	// Info URL (details page)
	InfoURL string `json:"info_url,omitempty"`
	// Size in bytes
	Size int64 `json:"size"`
	// Seeders count
	Seeders int `json:"seeders"`
	// Leechers count
	Leechers int `json:"leechers"`
	// Category ID
	CategoryID int `json:"category_id"`
	// Category name
	CategoryName string `json:"category_name"`
	// Published date
	PublishDate time.Time `json:"publish_date"`
	// Download volume factor (0.0 = free, 1.0 = normal)
	DownloadVolumeFactor float64 `json:"download_volume_factor"`
	// Upload volume factor
	UploadVolumeFactor float64 `json:"upload_volume_factor"`
	// GUID (unique identifier)
	GUID string `json:"guid"`
	// InfoHashV1 if available
	InfoHashV1 string `json:"infohash_v1,omitempty"`
	// InfoHashV2 if available
	InfoHashV2 string `json:"infohash_v2,omitempty"`
	// IMDb ID if available
	IMDbID string `json:"imdb_id,omitempty"`
	// TVDb ID if available
	TVDbID string `json:"tvdb_id,omitempty"`
	// Source parsed from release name (e.g., "WEB-DL", "BluRay", "HDTV")
	Source string `json:"source,omitempty"`
	// Collection/streaming service parsed from release name (e.g., "AMZN", "NF", "HULU", "MAX")
	Collection string `json:"collection,omitempty"`
	// Release group parsed from release name
	Group string `json:"group,omitempty"`
}

SearchResult represents a single search result from Jackett

type Service

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

Service provides Jackett integration for Torznab searching

func NewService

func NewService(indexerStore IndexerStore, opts ...ServiceOption) *Service

NewService creates a new Jackett service

func (*Service) DownloadTorrent

func (s *Service) DownloadTorrent(ctx context.Context, req TorrentDownloadRequest) ([]byte, error)

DownloadTorrent fetches the raw torrent bytes for a specific indexer result. It respects rate limits, retries on transient failures, and records 429 responses in the shared rate limiter to prevent hammering indexers.

func (*Service) FilterIndexersForCapabilities

func (s *Service) FilterIndexersForCapabilities(ctx context.Context, requested []int, requiredCaps []string, categories []int) ([]int, error)

FilterIndexersForCapabilities restricts requested indexers to those matching required caps/categories.

func (*Service) FlushSearchCache

func (s *Service) FlushSearchCache(ctx context.Context) (int64, error)

FlushSearchCache removes all cached search responses.

func (*Service) GetActivityStatus

func (s *Service) GetActivityStatus(ctx context.Context) (*ActivityStatus, error)

GetActivityStatus returns the current activity status including scheduler state and cooldowns

func (*Service) GetEnabledIndexersInfo

func (s *Service) GetEnabledIndexersInfo(ctx context.Context) (map[int]EnabledIndexerInfo, error)

GetEnabledIndexersInfo retrieves both names and domains for all enabled indexers in a single operation

func (*Service) GetEnabledTrackerDomains

func (s *Service) GetEnabledTrackerDomains(ctx context.Context) ([]string, error)

GetEnabledTrackerDomains extracts domain names from enabled indexers only

func (*Service) GetIndexerDomain

func (s *Service) GetIndexerDomain(ctx context.Context, indexerName string) (string, error)

GetIndexerDomain gets the tracker domain for a specific indexer by name

func (*Service) GetIndexerName

func (s *Service) GetIndexerName(ctx context.Context, id int) string

GetIndexerName resolves a Torznab indexer ID to its configured name.

func (*Service) GetIndexers

func (s *Service) GetIndexers(ctx context.Context) (*IndexersResponse, error)

GetIndexers retrieves all configured Torznab indexers

func (*Service) GetOptimalCategoriesForIndexers

func (s *Service) GetOptimalCategoriesForIndexers(ctx context.Context, requestedCategories []int, indexerIDs []int) []int

GetOptimalCategoriesForIndexers returns categories optimized for the given indexers based on their capabilities

func (*Service) GetRecentSearches

func (s *Service) GetRecentSearches(ctx context.Context, scope string, limit int) ([]*models.TorznabRecentSearch, error)

GetRecentSearches returns the most recently cached search queries for UI hints.

func (*Service) GetSearchCacheStats

func (s *Service) GetSearchCacheStats(ctx context.Context) (*models.TorznabSearchCacheStats, error)

GetSearchCacheStats returns summary stats for the cache table.

func (*Service) GetSearchHistory

func (s *Service) GetSearchHistory(_ context.Context, limit int) (*SearchHistoryResponseWithOutcome, error)

GetSearchHistory returns recent search history entries from the in-memory buffer, merged with any recorded cross-seed outcomes.

func (*Service) GetSearchHistoryStats

func (s *Service) GetSearchHistoryStats(_ context.Context) (*SearchHistoryStats, error)

GetSearchHistoryStats returns statistics about search history.

func (*Service) GetTrackerDomainDetails

func (s *Service) GetTrackerDomainDetails(ctx context.Context) ([]TrackerDomainInfo, error)

GetTrackerDomainDetails returns detailed information about tracker domains from all indexers

func (*Service) GetTrackerDomains

func (s *Service) GetTrackerDomains(ctx context.Context) ([]string, error)

GetTrackerDomains extracts domain names from all configured indexers

func (*Service) InvalidateSearchCache

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

InvalidateSearchCache clears cached searches referencing the provided indexers.

func (*Service) MapCategoriesToIndexerCapabilities

func (s *Service) MapCategoriesToIndexerCapabilities(ctx context.Context, indexer *models.TorznabIndexer, requestedCategories []int) []int

MapCategoriesToIndexerCapabilities maps requested categories to categories supported by the specific indexer

func (*Service) Recent

func (s *Service) Recent(ctx context.Context, limit int, indexerIDs []int, callback func(*SearchResponse, error)) error

Recent fetches the latest releases across selected indexers without a search query.

func (*Service) ReportIndexerOutcome

func (s *Service) ReportIndexerOutcome(jobID uint64, indexerID int, outcome string, addedCount int, message string)

ReportIndexerOutcome records a cross-seed outcome for a specific indexer's search results. Called by the cross-seed service after processing search results.

func (*Service) Search

func (s *Service) Search(ctx context.Context, req *TorznabSearchRequest) error

Search searches enabled Torznab indexers with intelligent category detection

func (*Service) SearchGeneric

func (s *Service) SearchGeneric(ctx context.Context, req *TorznabSearchRequest) error

SearchGeneric performs a general Torznab search across specified or all enabled indexers

func (*Service) SearchWithScope added in v1.13.0

func (s *Service) SearchWithScope(ctx context.Context, req *TorznabSearchRequest, scope string) error

SearchWithScope performs a Torznab search with a custom cache scope. This is used by dir-scan and other features that need cache separation.

func (*Service) SyncIndexerCaps

func (s *Service) SyncIndexerCaps(ctx context.Context, indexerID int) (*models.TorznabIndexer, error)

SyncIndexerCaps fetches and persists Torznab capabilities and categories for an indexer.

func (*Service) UpdateSearchCacheSettings

func (s *Service) UpdateSearchCacheSettings(ctx context.Context, ttlMinutes int) (*models.TorznabSearchCacheSettings, error)

UpdateSearchCacheSettings updates the TTL configuration at runtime.

type ServiceOption

type ServiceOption func(*Service)

ServiceOption configures optional behaviour on the Jackett service.

func WithIndexerOutcomes

func WithIndexerOutcomes(capacity int) ServiceOption

WithIndexerOutcomes enables cross-seed outcome tracking per (jobID, indexerID). Pass 0 to use the default capacity (1000 entries).

func WithSearchCache

func WithSearchCache(cache searchCacheStore, cfg SearchCacheConfig) ServiceOption

WithSearchCache wires the search cache store and configuration.

func WithSearchHistory

func WithSearchHistory(capacity int) ServiceOption

WithSearchHistory enables in-memory search history tracking with the given capacity. Pass 0 to use the default capacity (500 entries).

func WithTorrentCache

func WithTorrentCache(cache *models.TorznabTorrentCacheStore) ServiceOption

WithTorrentCache wires a torrent payload cache into the service.

type SubmitRequest

type SubmitRequest struct {
	Indexers  []*models.TorznabIndexer
	Params    url.Values
	Meta      *searchContext
	Callbacks JobCallbacks
	ExecFn    func(context.Context, []*models.TorznabIndexer, url.Values, *searchContext) ([]Result, []int, error)
}

SubmitRequest contains all parameters for submitting a job to the scheduler.

type TorrentDownloadRequest

type TorrentDownloadRequest struct {
	IndexerID   int
	DownloadURL string
	GUID        string
	Title       string
	Size        int64
	// Pace applies per-indexer min-interval pacing before contacting the backend.
	// This is useful for background/automated workflows (e.g. dirscan) to avoid bursts of .torrent downloads.
	Pace bool
}

TorrentDownloadRequest captures the metadata required to download (and cache) a torrent payload.

type TorznabSearchRequest

type TorznabSearchRequest struct {
	// Query is the search term
	Query string `json:"query"`
	// ReleaseName is the original full release name (for debugging/logging)
	ReleaseName string `json:"release_name,omitempty"`
	// Categories to search
	Categories []int `json:"categories,omitempty"`
	// IMDbID for movies/shows (optional)
	IMDbID string `json:"imdb_id,omitempty"`
	// TVDbID for TV shows (optional)
	TVDbID string `json:"tvdb_id,omitempty"`
	// TMDbID for movies (optional, from ARR lookup)
	TMDbID int `json:"tmdb_id,omitempty"`
	// TVMazeID for TV shows (optional, from ARR lookup)
	TVMazeID int `json:"tvmaze_id,omitempty"`
	// Year for movies/shows/music (optional)
	Year int `json:"year,omitempty"`
	// Season for TV shows (optional)
	Season *int `json:"season,omitempty"`
	// Episode for TV shows (optional)
	Episode *int `json:"episode,omitempty"`
	// Artist for music searches (optional)
	Artist string `json:"artist,omitempty"`
	// Album for music searches (optional)
	Album string `json:"album,omitempty"`
	// Limit the number of results
	Limit int `json:"limit,omitempty"`
	// Offset for pagination
	Offset int `json:"offset,omitempty"`
	// IndexerIDs to search (empty = all enabled indexers)
	IndexerIDs []int `json:"indexer_ids,omitempty"`
	// CacheMode controls cache behaviour (""=default, "bypass" = skip cache)
	CacheMode string `json:"cache_mode,omitempty"`
	// OmitQueryForIDs when true, omits the q parameter if IDs are present (for cross-seed ID-driven searches)
	OmitQueryForIDs bool `json:"-"`
	// SkipHistory prevents recording this search in the history buffer
	SkipHistory bool `json:"-"`
	// OnComplete is called when a search job for an indexer completes
	OnComplete func(jobID uint64, indexerID int, err error) `json:"-"`
	// OnAllComplete is called when all search jobs complete with the final results
	OnAllComplete func(*SearchResponse, error) `json:"-"`
}

TorznabSearchRequest represents a general Torznab search request

type TrackerDomainInfo

type TrackerDomainInfo struct {
	Domain    string `json:"domain"`
	IndexerID int    `json:"indexer_id"`
	Name      string `json:"name"`
	BaseURL   string `json:"base_url"`
	JackettID string `json:"jackett_id,omitempty"`
	Backend   string `json:"backend"`
	Enabled   bool   `json:"enabled"`
}

TrackerDomainInfo represents detailed information about a tracker domain

Jump to

Keyboard shortcuts

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