Documentation
¶
Index ¶
- Constants
- type Download
- type HistoryFilter
- type HistoryPage
- type Programme
- type QualityCache
- type QualityOption
- type SeriesMapping
- type ShowOverride
- type Store
- func (s *Store) ClearHistory() (int, error)
- func (s *Store) Close() error
- func (s *Store) DeleteDownload(id string) error
- func (s *Store) DeleteHistory(id string) error
- func (s *Store) DeleteOverride(showName string) error
- func (s *Store) DeleteProgramme(pid string) error
- func (s *Store) DeleteQualityCache(pid string) error
- func (s *Store) DeleteQualityCacheByShow(showName string) error
- func (s *Store) FindDownloadByPIDQuality(pid, quality string) (*Download, error)
- func (s *Store) FindHistoryByPIDQuality(pid, quality string) (*Download, error)
- func (s *Store) GetConfig(key string) (string, error)
- func (s *Store) GetDownload(id string) (*Download, error)
- func (s *Store) GetHistory(id string) (*Download, error)
- func (s *Store) GetOverride(showName string) (*ShowOverride, error)
- func (s *Store) GetProgramme(pid string) (*Programme, error)
- func (s *Store) GetQualityCache(pid string) (*QualityCache, error)
- func (s *Store) GetSeriesMapping(tvdbId string) (*SeriesMapping, error)
- func (s *Store) GetSeriesMappingByName(name string) (*SeriesMapping, error)
- func (s *Store) ListDownloads() ([]*Download, error)
- func (s *Store) ListHistory() ([]*Download, error)
- func (s *Store) ListHistoryFiltered(f HistoryFilter) (*HistoryPage, error)
- func (s *Store) ListHistoryOutputDirs() (map[string]bool, error)
- func (s *Store) ListOverrides() ([]*ShowOverride, error)
- func (s *Store) MoveToHistory(id string) error
- func (s *Store) PurgeStaleProgrammes(maxAge time.Duration) error
- func (s *Store) PutDownload(dl *Download) error
- func (s *Store) PutHistory(dl *Download) error
- func (s *Store) PutOverride(o *ShowOverride) error
- func (s *Store) PutProgramme(p *Programme) error
- func (s *Store) PutQualityCache(qc *QualityCache) error
- func (s *Store) PutSeriesMapping(m *SeriesMapping) error
- func (s *Store) SetConfig(key, value string) error
Constants ¶
const ( StatusPending = "pending" StatusResolving = "resolving" StatusDownloading = "downloading" StatusConverting = "converting" StatusCompleted = "completed" StatusFailed = "failed" FailCodeGeoBlocked = "geo_blocked" FailCodeExpired = "expired" FailCodeFFmpeg = "ffmpeg_error" FailCodeTruncated = "truncated" FailCodeTimeout = "timeout" FailCodeUnknown = "unknown" TierFull = "full" TierPosition = "position" TierDate = "date" TierManual = "manual" )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Download ¶
type Download struct {
ID string `json:"id"`
PID string `json:"pid"`
VPID string `json:"vpid"`
Title string `json:"title"`
ShowName string `json:"show_name"`
Season int `json:"season"`
Episode int `json:"episode"`
AirDate string `json:"air_date"`
IdentityTier string `json:"identity_tier"`
Quality string `json:"quality"`
ActualQuality string `json:"actual_quality,omitempty"`
Status string `json:"status"`
Category string `json:"category"`
StreamURL string `json:"stream_url"`
OutputDir string `json:"output_dir"`
OutputFile string `json:"output_file"`
Progress float64 `json:"progress"`
Size int64 `json:"size"`
Downloaded int64 `json:"downloaded"`
Duration int `json:"duration"`
Error string `json:"error"`
FailureCode string `json:"failure_code"`
Retryable bool `json:"retryable"`
RetryCount int `json:"retry_count"`
RetryAfter time.Time `json:"retry_after"`
CreatedAt time.Time `json:"created_at"`
StartedAt time.Time `json:"started_at"`
CompletedAt time.Time `json:"completed_at"`
FileExists *bool `json:"file_exists,omitempty"`
}
type HistoryFilter ¶
type HistoryFilter struct {
Status string // "completed", "failed", or "" (all)
Since string // ISO date string (RFC3339 or date-only) or "" (all time)
Page int // 1-based; defaults to 1
PerPage int // defaults to 20
Sort string // "completed_at" (default) or "title"
Order string // "asc" or "desc" (default)
}
HistoryFilter describes optional filters, sorting, and pagination for ListHistoryFiltered.
type HistoryPage ¶
HistoryPage is the paginated result returned by ListHistoryFiltered.
type Programme ¶
type Programme struct {
PID string `json:"pid"`
VPID string `json:"vpid"`
Name string `json:"name"`
Episode string `json:"episode"`
Series int `json:"series"`
EpisodeNum int `json:"episode_num"`
AirDate string `json:"air_date"`
Channel string `json:"channel"`
Duration int `json:"duration"`
Synopsis string `json:"synopsis"`
Thumbnail string `json:"thumbnail"`
Available time.Time `json:"available"`
Expires time.Time `json:"expires"`
Qualities []QualityOption `json:"qualities"`
Position int `json:"position"`
IdentityTier string `json:"identity_tier"`
IsDateBased bool `json:"is_date_based"`
CachedAt time.Time `json:"cached_at"`
}
type QualityCache ¶ added in v1.1.0
type QualityCache struct {
PID string `json:"pid"`
ShowName string `json:"show_name"` // normalised: lowercase + trimmed
Heights []int `json:"heights"` // sorted descending, e.g. [1080, 720, 540, 396]
ProbedAt time.Time `json:"probed_at"`
}
QualityCache records the heights BBC actually offers for a single PID. Populated by bbc.QualityProber on first encounter and reused indefinitely (BBC content masters are append-only once published, so cache entries never need TTL-based invalidation). Manual refresh is handled by the DeleteQualityCache / DeleteQualityCacheByShow methods on *store.Store.
ShowName is stored in normalised form (lower-cased and trimmed via the existing normaliseShowName helper at overrides.go:10) so that DeleteQualityCacheByShow matches cache entries regardless of how the user typed the show name in the future v1.2 refresh-button UI. The original casing is never needed because the cache is consulted by PID, not by show name.
type QualityOption ¶
type SeriesMapping ¶
type ShowOverride ¶
type ShowOverride struct {
ShowName string `json:"show_name"`
ForceDateBased bool `json:"force_date_based"`
ForceSeriesNum int `json:"force_series_num"`
ForcePosition bool `json:"force_position"`
SeriesOffset int `json:"series_offset"`
EpisodeOffset int `json:"episode_offset"`
CustomName string `json:"custom_name"`
}
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
func (*Store) ClearHistory ¶
ClearHistory deletes every entry in the history bucket and returns the count of entries removed.
func (*Store) DeleteDownload ¶
func (*Store) DeleteHistory ¶
func (*Store) DeleteOverride ¶
func (*Store) DeleteProgramme ¶
func (*Store) DeleteQualityCache ¶ added in v1.1.0
DeleteQualityCache removes the cache entry for a single PID. Missing entries are treated as success.
func (*Store) DeleteQualityCacheByShow ¶ added in v1.1.0
DeleteQualityCacheByShow removes every cache entry whose normalised ShowName matches the normalised argument. Designed for the future v1.2 refresh-by-show UI. The argument is normalised once (via normaliseShowName) before the bucket scan, so "Doctor Who", "doctor who", "DOCTOR WHO", and " Doctor Who " all match the same set of entries.
func (*Store) FindDownloadByPIDQuality ¶
func (*Store) FindHistoryByPIDQuality ¶
func (*Store) GetOverride ¶
func (s *Store) GetOverride(showName string) (*ShowOverride, error)
func (*Store) GetQualityCache ¶ added in v1.1.0
func (s *Store) GetQualityCache(pid string) (*QualityCache, error)
GetQualityCache returns the cached quality entry for a PID, or (nil, nil) if no entry exists. A missing entry is NOT an error — callers use the nil-check to distinguish "cache miss, probe fresh" from "read error, log and fall through".
func (*Store) GetSeriesMapping ¶
func (s *Store) GetSeriesMapping(tvdbId string) (*SeriesMapping, error)
func (*Store) GetSeriesMappingByName ¶ added in v1.1.6
func (s *Store) GetSeriesMappingByName(name string) (*SeriesMapping, error)
GetSeriesMappingByName returns the first SeriesMapping whose ShowName matches name (case-insensitive). Returns (nil, nil) when not found. Used by the tvsearch handler to rehydrate tvdbid on follow-up queries where Sonarr sends q=ShowName with an empty tvdbid.
Matching rules (applied in order, first match wins):
- Exact case-insensitive match: stored "Doctor Who" == q "Doctor Who".
- Year-suffix match: stored "Doctor Who (2005)" matches q "Doctor Who". Skyhook returns titles with a trailing " (YYYY)" disambiguator; Sonarr sends the bare title without it on follow-up queries.
Cost is O(n) in the number of tracked shows (one bucket scan per call). Typical deployments track tens to low hundreds of shows, so the linear scan is cheaper than maintaining a secondary name-index bucket. If this ever becomes a hot path, add a `bucketSeriesByName` secondary index that mirrors writes from PutSeriesMapping.
func (*Store) ListDownloads ¶
func (*Store) ListHistory ¶
func (*Store) ListHistoryFiltered ¶
func (s *Store) ListHistoryFiltered(f HistoryFilter) (*HistoryPage, error)
ListHistoryFiltered reads all history entries, applies status/since filters, sorts, and paginates according to f.
func (*Store) ListHistoryOutputDirs ¶
ListHistoryOutputDirs returns the set of cleaned OutputDir values from every history entry. The paths are normalised with filepath.Clean so a caller computing `filepath.Join(downloadDir, entry.Name())` (which also cleans) can do a direct map lookup without worrying about trailing slashes or other stylistic differences between how the path was written and how it is read back. See GitHub issue #21 for the Delete button symptom that motivated the normalisation.
func (*Store) ListOverrides ¶
func (s *Store) ListOverrides() ([]*ShowOverride, error)
func (*Store) MoveToHistory ¶
func (*Store) PurgeStaleProgrammes ¶
func (*Store) PutDownload ¶
func (*Store) PutHistory ¶
PutHistory writes a Download directly to the history bucket (used by MoveToHistory and for direct history inserts without a prior downloads entry).
func (*Store) PutOverride ¶
func (s *Store) PutOverride(o *ShowOverride) error
func (*Store) PutProgramme ¶
func (*Store) PutQualityCache ¶ added in v1.1.0
func (s *Store) PutQualityCache(qc *QualityCache) error
PutQualityCache upserts a quality cache entry for qc.PID. Before writing, qc.ShowName is normalised via normaliseShowName (the same helper PutOverride uses in overrides.go:14) so that every entry in the bucket has a comparable, case-insensitive show name for the future DeleteQualityCacheByShow refresh path.
func (*Store) PutSeriesMapping ¶
func (s *Store) PutSeriesMapping(m *SeriesMapping) error