store

package
v1.5.6 Latest Latest
Warning

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

Go to latest
Published: May 17, 2026 License: GPL-3.0 Imports: 8 Imported by: 0

Documentation

Index

Constants

View Source
const (
	StatusPending     = "pending"
	StatusResolving   = "resolving"
	StatusDownloading = "downloading"
	StatusConverting  = "converting"
	StatusCompleted   = "completed"
	StatusFailed      = "failed"

	FailCodeGeoBlocked  = "geo_blocked"
	FailCodeExpired     = "expired"
	FailCodeUnavailable = "stream_unavailable"
	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

type HistoryPage struct {
	Items []*Download `json:"items"`
	Total int         `json:"total"`
}

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 QualityOption struct {
	Tag       string `json:"tag"`
	Height    int    `json:"height"`
	Bitrate   int    `json:"bitrate"`
	FPS       int    `json:"fps"`
	StreamURL string `json:"stream_url"`
	Supplier  string `json:"supplier"`
	HasSubs   bool   `json:"has_subs"`
	Synthetic bool   `json:"synthetic"`
}

type SeriesMapping

type SeriesMapping struct {
	TVDBId    string    `json:"tvdb_id"`
	ShowName  string    `json:"show_name"`
	Year      int       `json:"year"`
	UpdatedAt time.Time `json:"updated_at"`
}

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 Open

func Open(path string) (*Store, error)

func (*Store) ClearHistory

func (s *Store) ClearHistory() (int, error)

ClearHistory deletes every entry in the history bucket and returns the count of entries removed.

func (*Store) Close

func (s *Store) Close() error

func (*Store) DeleteDownload

func (s *Store) DeleteDownload(id string) error

func (*Store) DeleteHistory

func (s *Store) DeleteHistory(id string) error

func (*Store) DeleteOverride

func (s *Store) DeleteOverride(showName string) error

func (*Store) DeleteProgramme

func (s *Store) DeleteProgramme(pid string) error

func (*Store) DeleteQualityCache added in v1.1.0

func (s *Store) DeleteQualityCache(pid string) error

DeleteQualityCache removes the cache entry for a single PID. Missing entries are treated as success.

func (*Store) DeleteQualityCacheByShow added in v1.1.0

func (s *Store) DeleteQualityCacheByShow(showName string) error

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 (s *Store) FindDownloadByPIDQuality(pid, quality string) (*Download, error)

func (*Store) FindHistoryByPIDQuality

func (s *Store) FindHistoryByPIDQuality(pid, quality string) (*Download, error)

func (*Store) GetConfig

func (s *Store) GetConfig(key string) (string, error)

func (*Store) GetDownload

func (s *Store) GetDownload(id string) (*Download, error)

func (*Store) GetHistory

func (s *Store) GetHistory(id string) (*Download, error)

func (*Store) GetOverride

func (s *Store) GetOverride(showName string) (*ShowOverride, error)

func (*Store) GetProgramme

func (s *Store) GetProgramme(pid string) (*Programme, 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):

  1. Exact case-insensitive match: stored "Doctor Who" == q "Doctor Who".
  2. 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 (s *Store) ListDownloads() ([]*Download, error)

func (*Store) ListHistory

func (s *Store) ListHistory() ([]*Download, error)

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

func (s *Store) ListHistoryOutputDirs() (map[string]bool, error)

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 (s *Store) MoveToHistory(id string) error

func (*Store) PurgeStaleProgrammes

func (s *Store) PurgeStaleProgrammes(maxAge time.Duration) error

func (*Store) PutDownload

func (s *Store) PutDownload(dl *Download) error

func (*Store) PutHistory

func (s *Store) PutHistory(dl *Download) error

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 (s *Store) PutProgramme(p *Programme) error

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

func (*Store) SetConfig

func (s *Store) SetConfig(key, value string) error

Jump to

Keyboard shortcuts

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