Documentation
¶
Overview ¶
Package plugin defines the public interfaces and value types for Pilot's plugin system. Indexer, DownloadClient, and Notifier implementations (built-in or external) depend only on this package.
Index ¶
- Variables
- type AudioChannels
- type AudioCodec
- type Capabilities
- type Codec
- type DownloadClient
- type DownloadStatus
- type EventType
- type HDRFormat
- type ImportList
- type ImportListItem
- type Indexer
- type IndexerFlag
- type MediaServer
- type NotificationEvent
- type Notifier
- type Protocol
- type Quality
- type QueueItem
- type Release
- type Resolution
- type ScoreBreakdown
- type ScoreDimension
- type SearchQuery
- type SeedLimiter
- type Source
- type TMDBInjectable
- type TraktInjectable
- type WatchEvent
- type WatchProvider
Constants ¶
This section is empty.
Variables ¶
var ErrItemNotFound = errors.New("download client: item not found")
ErrItemNotFound is returned by DownloadClient implementations when the item asked about no longer exists in the client (e.g. the user removed it directly in the client's UI, or the client forgot it after a restart).
Callers that persist grab history (queue sync, stall watchers) should distinguish this from transient errors: on ErrItemNotFound the grab is definitively gone and should be marked removed, whereas on any other error the correct behaviour is to log and retry on the next poll — a brief network blip must not nuke the queue.
Functions ¶
This section is empty.
Types ¶
type AudioChannels ¶
type AudioChannels string
AudioChannels is the channel layout of a release.
const ( AudioChannelsUnknown AudioChannels = "" AudioChannels71 AudioChannels = "7.1" AudioChannels51 AudioChannels = "5.1" AudioChannels20 AudioChannels = "2.0" AudioChannels10 AudioChannels = "1.0" )
type AudioCodec ¶
type AudioCodec string
AudioCodec is the audio codec of a release.
const ( AudioCodecUnknown AudioCodec = "" AudioCodecTrueHD AudioCodec = "truehd" AudioCodecTrueHDAtmos AudioCodec = "truehd_atmos" AudioCodecDTSX AudioCodec = "dts_x" AudioCodecDTSHDMA AudioCodec = "dts_hd_ma" AudioCodecDTSHD AudioCodec = "dts_hd" AudioCodecDTS AudioCodec = "dts" AudioCodecEAC3Atmos AudioCodec = "eac3_atmos" AudioCodecEAC3 AudioCodec = "eac3" AudioCodecAC3 AudioCodec = "ac3" AudioCodecAAC AudioCodec = "aac" AudioCodecFLAC AudioCodec = "flac" AudioCodecPCM AudioCodec = "pcm" AudioCodecMP3 AudioCodec = "mp3" AudioCodecOpus AudioCodec = "opus" )
type Capabilities ¶
type Capabilities struct {
SearchAvailable bool
TVSearchAvailable bool
MovieSearch bool
Categories []int // Newznab/Torznab category IDs
}
Capabilities describes what an indexer supports.
type DownloadClient ¶
type DownloadClient interface {
Name() string
Protocol() Protocol
// Add submits a release to the download client.
// Returns the client-assigned item ID for future status queries.
Add(ctx context.Context, r Release) (clientItemID string, err error)
// Status returns the current state of a download client item.
Status(ctx context.Context, clientItemID string) (QueueItem, error)
// GetQueue returns all items currently in the download client.
GetQueue(ctx context.Context) ([]QueueItem, error)
// Remove deletes an item from the download client.
// If deleteFiles is true, the downloaded data is also deleted.
Remove(ctx context.Context, clientItemID string, deleteFiles bool) error
// Test validates that the connection to the download client works.
Test(ctx context.Context) error
}
DownloadClient is the plugin interface for download clients.
type DownloadStatus ¶
type DownloadStatus string
DownloadStatus is the state of an item in the download client.
const ( StatusQueued DownloadStatus = "queued" StatusDownloading DownloadStatus = "downloading" StatusCompleted DownloadStatus = "completed" StatusPaused DownloadStatus = "paused" StatusFailed DownloadStatus = "failed" )
type EventType ¶
type EventType string
EventType identifies what happened.
const ( EventSeriesAdded EventType = "series_added" EventSeriesDeleted EventType = "series_deleted" EventGrabStarted EventType = "grab_started" EventDownloadDone EventType = "download_done" EventImportDone EventType = "import_done" EventImportFailed EventType = "import_failed" EventHealthIssue EventType = "health_issue" EventHealthOK EventType = "health_ok" )
type ImportList ¶
type ImportList interface {
Name() string
Fetch(ctx context.Context) ([]ImportListItem, error)
Test(ctx context.Context) error
}
ImportList is the plugin interface for import list sources. Implementations fetch series from external services (TMDb, Trakt, Plex, etc.) and return them as a flat list. The sync service handles deduplication, exclusion checks, and adding series to the library.
type ImportListItem ¶
type ImportListItem struct {
TMDbID int // required — canonical identifier
IMDbID string // optional; used for display/logging
Title string
Year int
PosterPath string // optional; TMDb poster path (e.g. "/abc123.jpg")
}
ImportListItem is a single series returned by an import list source.
type Indexer ¶
type Indexer interface {
// Name returns the human-readable plugin name, e.g. "Torznab".
Name() string
// Protocol returns the release download mechanism this indexer provides.
Protocol() Protocol
// Capabilities returns what search types this indexer supports.
Capabilities(ctx context.Context) (Capabilities, error)
// Search queries the indexer for releases matching the query.
Search(ctx context.Context, q SearchQuery) ([]Release, error)
// GetRecent returns the most recent releases from the indexer's RSS feed.
GetRecent(ctx context.Context) ([]Release, error)
// Test validates that the indexer is reachable and configured correctly.
Test(ctx context.Context) error
}
Indexer is the plugin interface for release indexers.
type IndexerFlag ¶
type IndexerFlag string
IndexerFlag represents a flag reported by an indexer for a release.
const ( FlagFreeleech IndexerFlag = "freeleech" FlagHalfleech IndexerFlag = "halfleech" FlagFreeleech75 IndexerFlag = "freeleech_75" FlagFreeleech25 IndexerFlag = "freeleech_25" FlagDoubleUpload IndexerFlag = "double_upload" FlagInternal IndexerFlag = "internal" FlagScene IndexerFlag = "scene" FlagNuked IndexerFlag = "nuked" )
type MediaServer ¶
type MediaServer interface {
// Name returns the human-readable name of the media server plugin.
Name() string
// RefreshLibrary tells the media server to re-scan the library section
// that contains seriesPath. Implementations may fall back to a full
// library refresh if path-scoped scanning is unavailable.
RefreshLibrary(ctx context.Context, seriesPath string) error
// Test verifies that the media server is reachable and the credentials
// are valid.
Test(ctx context.Context) error
}
MediaServer is implemented by media server plugins (Plex, Emby, Jellyfin). After a series file is imported, the dispatcher calls RefreshLibrary so the media server picks up the new file without waiting for a scheduled scan.
type NotificationEvent ¶
type NotificationEvent struct {
Type EventType
Timestamp time.Time
SeriesID string // UUID, if series-related; empty otherwise
Message string // human-readable summary
Data map[string]any // event-specific extra fields
}
NotificationEvent carries the context of something that happened.
type Notifier ¶
type Notifier interface {
Name() string
Notify(ctx context.Context, event NotificationEvent) error
Test(ctx context.Context) error
}
Notifier is the plugin interface for notification channels.
type Quality ¶
type Quality struct {
Resolution Resolution `json:"resolution"`
Source Source `json:"source"`
Codec Codec `json:"codec"`
HDR HDRFormat `json:"hdr"`
AudioCodec AudioCodec `json:"audio_codec,omitempty"`
AudioChannels AudioChannels `json:"audio_channels,omitempty"`
// Name is the human-readable label derived from the video fields,
// e.g. "Bluray-1080p x265" or "WEBDL-2160p HDR10".
Name string `json:"name"`
}
Quality describes the technical characteristics of a release. It is a value type — embedded in releases, files, and profiles.
func ParseQualityFromTitle ¶
ParseQualityFromTitle extracts quality metadata from a release title string.
func (Quality) BetterThan ¶
BetterThan reports whether q is strictly better than other.
type QueueItem ¶
type QueueItem struct {
ClientItemID string
Title string
Status DownloadStatus
Size int64
Downloaded int64
SeedRatio float64 // torrent only; 0 for NZB
Error string
// ContentPath is the absolute filesystem path to the downloaded content.
// For single-file downloads this is the file path; for multi-file downloads
// it is the root directory. Empty until the download client reports it.
ContentPath string
// AddedAt is the Unix timestamp when the item was added to the client.
// Zero if the client does not report this field.
AddedAt int64
}
QueueItem represents an item tracked in the download client.
type Release ¶
type Release struct {
GUID string
Title string
Indexer string
Protocol Protocol
DownloadURL string
InfoURL string
Size int64
Seeds int
Peers int
AgeDays float64
Quality Quality
Edition string // canonical edition name parsed from title; empty = untagged
ReleaseGroup string // scene group name parsed from title; empty = unknown
IndexerFlags []IndexerFlag
// Media context — populated by Pilot/Prism before sending to download client.
// Download clients that support renaming (Haul) use these fields.
MediaType string `json:"media_type,omitempty"` // "movie" or "tv"
MediaTitle string `json:"media_title,omitempty"` // series or movie title
MediaYear int `json:"media_year,omitempty"` // release year
SeasonNumber int `json:"season_number,omitempty"` // TV only
EpisodeNumber int `json:"episode_number,omitempty"` // TV only
EpisodeTitle string `json:"episode_title,omitempty"` // TV only
// Arr-side IDs forwarded to history-aware download clients (Haul)
// so they can answer "have I downloaded anything for series X?"
// later. All optional; leaving empty disables the lookup integration
// for this grab.
TMDBID int `json:"tmdb_id,omitempty"` // TMDB tv/movie id
SeriesID string `json:"series_id,omitempty"` // Pilot series UUID
EpisodeID string `json:"episode_id,omitempty"` // Pilot episode UUID
}
Release is the transient result of an indexer search. It is not stored in the database. A summary is written to GrabHistory when a release is grabbed.
type Resolution ¶
type Resolution string
Resolution is the video resolution of a release.
const ( ResolutionUnknown Resolution = "unknown" ResolutionSD Resolution = "sd" // implied SD (e.g. DVDRip without explicit resolution) Resolution480p Resolution = "480p" Resolution576p Resolution = "576p" Resolution720p Resolution = "720p" Resolution1080p Resolution = "1080p" Resolution2160p Resolution = "2160p" // 4K )
type ScoreBreakdown ¶
type ScoreBreakdown struct {
Total int `json:"total"`
Dimensions []ScoreDimension `json:"dimensions"`
// CustomFormatScore is the sum of matched custom format scores for the
// quality profile. It sits alongside (not inside) Total because CF scoring
// is an independent dimension used for separate thresholds.
CustomFormatScore int `json:"custom_format_score"`
MatchedFormats []string `json:"matched_formats,omitempty"`
// EditionBonus is the bonus points awarded when the release edition
// matches the series' preferred edition (+30 pts). It is additive
// to Total and reflected in the Dimensions list.
EditionBonus int `json:"edition_bonus"`
}
ScoreBreakdown records how a release was evaluated against a quality profile. Each dimension is independently scored; Total is the sum.
type ScoreDimension ¶
type ScoreDimension struct {
Name string `json:"name"` // "resolution", "source", "codec", "hdr"
Score int `json:"score"` // points awarded for this dimension
Max int `json:"max"` // maximum possible for this dimension
Matched bool `json:"matched"` // did it meet the profile requirement?
Got string `json:"got"` // what we found (e.g. "x264")
Want string `json:"want"` // what the profile requires (e.g. "x265")
}
ScoreDimension is one component of a ScoreBreakdown.
type SearchQuery ¶
type SearchQuery struct {
Query string // free-text query, e.g. "Breaking Bad S01E05"
TVDBID int // TVDB ID when available
TMDBID int // TMDB ID when available
IMDBID string // e.g. "tt0903747"
Year int
Season int // season number for TV episode filtering
Episode int // episode number for TV episode filtering
}
SearchQuery is the input to an indexer search.
type SeedLimiter ¶
type SeedLimiter interface {
SetSeedLimits(ctx context.Context, clientItemID string, ratioLimit float64, seedTimeSecs int) error
}
SeedLimiter is an optional interface for download clients that support configuring per-torrent seed ratio and seed time limits. Implementations should treat ratioLimit <= 0 as "use client default" and seedTimeSecs <= 0 as "no time limit".
type Source ¶
type Source string
Source is the origin/format of a release.
const ( SourceUnknown Source = "unknown" SourceWorkprint Source = "workprint" SourceCAM Source = "cam" SourceTelesync Source = "telesync" SourceTELECINE Source = "telecine" SourceDVDSCR Source = "dvdscr" SourceRegional Source = "regional" SourceDVD Source = "dvd" SourceDVDR Source = "dvdr" SourceHDTV Source = "hdtv" SourceWEBRip Source = "webrip" SourceWEBDL Source = "webdl" SourceBluRay Source = "bluray" SourceRemux Source = "remux" SourceBRDisk Source = "brdisk" SourceRawHD Source = "rawhd" )
type TMDBInjectable ¶
type TMDBInjectable interface {
SetTMDBClient(client any)
}
TMDBInjectable is an optional interface for import list plugins that need the shared TMDB client. The service calls SetTMDBClient before Fetch()/Test(). The parameter is typed as any to avoid an import cycle with internal/metadata/tmdb.
type TraktInjectable ¶
type TraktInjectable interface {
SetTraktClient(client any)
}
TraktInjectable is an optional interface for import list plugins that need the shared Trakt client. The service calls SetTraktClient before Fetch()/Test(). The parameter is typed as any to avoid an import cycle with internal/trakt.
type WatchEvent ¶
type WatchEvent struct {
TMDBID int // series identifier
Title string // for display/logging
WatchedAt time.Time // when playback completed
UserName string // media server user (for multi-user setups)
}
WatchEvent represents a single completed playback of a series episode.
type WatchProvider ¶
type WatchProvider interface {
// WatchHistory returns watch events since the given timestamp.
// Each event represents one completed playback (>= 90% watched).
WatchHistory(ctx context.Context, since time.Time) ([]WatchEvent, error)
}
WatchProvider is an optional interface for media servers that can report watch history. Plugins that don't support it simply don't implement it. Check with a type assertion at runtime:
if wp, ok := server.(WatchProvider); ok { ... }