quality

package
v0.0.0-...-d771ed5 Latest Latest
Warning

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

Go to latest
Published: May 29, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrInUse = errors.New("quality profile is in use")

ErrInUse is returned when attempting to delete a profile that is referenced by one or more series or libraries.

View Source
var ErrNotFound = errors.New("quality profile not found")

ErrNotFound is returned when a quality profile does not exist.

Functions

This section is empty.

Types

type CreateRequest

type CreateRequest struct {
	Name                 string
	Cutoff               plugin.Quality
	Qualities            []plugin.Quality
	UpgradeAllowed       bool
	UpgradeUntil         *plugin.Quality
	MinCustomFormatScore int
	UpgradeUntilCFScore  int
}

CreateRequest carries the fields needed to create a quality profile.

type Definition

type Definition struct {
	ID            string // stable slug, e.g. "1080p-bluray-x265-none"
	Name          string // human-readable label, e.g. "1080p Bluray"
	Resolution    string
	Source        string
	Codec         string
	HDR           string
	MinSize       float64 // MB per minute (0 = no minimum)
	MaxSize       float64 // MB per minute (0 = no limit)
	PreferredSize float64 // MB per minute target within [min, max] (0 = same as max)
	SortOrder     int
}

Definition describes a known quality level and the acceptable file-size range for releases of that quality, expressed in MB per minute of runtime.

type DefinitionService

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

DefinitionService manages quality definitions.

func NewDefinitionService

func NewDefinitionService(q db.Querier) *DefinitionService

NewDefinitionService returns a new DefinitionService backed by the querier.

func (*DefinitionService) BulkUpdate

func (s *DefinitionService) BulkUpdate(ctx context.Context, updates []DefinitionSizeUpdate) error

BulkUpdate applies size updates for all provided definitions. Unknown IDs are silently ignored (exec does nothing for missing rows).

func (*DefinitionService) List

func (s *DefinitionService) List(ctx context.Context) ([]Definition, error)

List returns all quality definitions ordered by sort_order.

type DefinitionSizeUpdate

type DefinitionSizeUpdate struct {
	ID            string
	MinSize       float64
	MaxSize       float64
	PreferredSize float64
}

DefinitionSizeUpdate carries the new size values for a single definition.

type Profile

type Profile struct {
	// ID is a stable identifier (e.g. a UUID).
	ID string
	// Name is the human-readable label shown in the UI.
	Name string
	// Cutoff is the minimum quality that satisfies this profile.
	// Once a file at or above the cutoff is on disk, the series is considered
	// "met" and no further grabs are triggered — unless upgrading is enabled.
	Cutoff plugin.Quality
	// Qualities lists every quality this profile will accept, ordered from
	// highest-preferred to lowest-preferred. Releases not in this list are
	// rejected regardless of other settings.
	Qualities []plugin.Quality
	// UpgradeAllowed, when true, permits grabbing a release that is better
	// than the current file even after the cutoff is met.
	UpgradeAllowed bool
	// UpgradeUntil, when non-nil, caps upgrades: once the current file meets
	// or exceeds this quality, no further upgrades are triggered.
	// Nil means "upgrade without limit" (subject to UpgradeAllowed).
	UpgradeUntil *plugin.Quality
	// MinCustomFormatScore is the minimum CF score a release must reach to be
	// considered acceptable. Releases below this threshold are rejected.
	MinCustomFormatScore int
	// UpgradeUntilCFScore caps CF-driven upgrades: once the current file's CF
	// score meets or exceeds this value (and quality cutoff is met), no further
	// upgrades are triggered.
	UpgradeUntilCFScore int
	// ManagedByPulse is true when this profile is synced from Pulse. Local edits
	// to such profiles disconnect them from Pulse (set to false).
	ManagedByPulse bool
}

Profile defines a quality policy for a monitored series. It controls which releases are acceptable and when upgrades are triggered.

func (*Profile) AllowedQualities

func (p *Profile) AllowedQualities() []plugin.Quality

AllowedQualities returns the list of quality values this profile accepts. The slice is a copy; mutations do not affect the profile.

func (*Profile) IsUpgrade

func (p *Profile) IsUpgrade(releaseQuality plugin.Quality, currentQuality plugin.Quality) bool

IsUpgrade reports whether releaseQuality is a strict improvement over currentQuality, subject to the UpgradeUntil ceiling defined in this profile.

func (*Profile) RejectReason

func (p *Profile) RejectReason(releaseQuality plugin.Quality, currentFileQuality *plugin.Quality) string

RejectReason returns a typed reason string explaining why WantRelease would return false. Returns "" if the release would be wanted (no rejection).

func (*Profile) ScoreWithBreakdown

func (p *Profile) ScoreWithBreakdown(q plugin.Quality) (int, plugin.ScoreBreakdown)

ScoreWithBreakdown scores q against this profile's cutoff and returns both the aggregate 0–100 score and a per-dimension breakdown.

Weights: Resolution 40 pts, Source 30 pts, Codec 20 pts, HDR 10 pts.

A dimension is "matched" when the release meets or exceeds the cutoff value for that dimension. If the cutoff field is empty/unknown, any value matches.

func (*Profile) WantRelease

func (p *Profile) WantRelease(releaseQuality plugin.Quality, currentFileQuality *plugin.Quality) bool

WantRelease reports whether this profile should grab a release with releaseQuality, given the quality of the file already on disk (currentFileQuality). Pass nil for currentFileQuality when no file exists.

Decision logic:

  1. The release quality must be in the profile's allowed set.
  2. If no file exists, grab it.
  3. If the current file is below the cutoff, grab anything allowed that is at least as good as what we have (or better).
  4. If the current file meets/exceeds the cutoff and upgrading is disabled, do not grab.
  5. If upgrading is enabled, grab if the release is a strict upgrade.

type Service

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

Service manages quality profiles.

func NewService

func NewService(q db.Querier, bus *events.Bus) *Service

NewService creates a new Service backed by the given querier and event bus.

func (*Service) Create

func (s *Service) Create(ctx context.Context, req CreateRequest) (Profile, error)

Create creates a new quality profile and returns the persisted domain type.

func (*Service) CreateManaged

func (s *Service) CreateManaged(ctx context.Context, id string, req CreateRequest) (Profile, error)

CreateManaged inserts a quality profile that is managed by Pulse. The caller provides the explicit ID (which is the same UUID Pulse uses). Future sync runs will update and delete this row to match Pulse's state.

func (*Service) Delete

func (s *Service) Delete(ctx context.Context, id string) error

Delete removes a quality profile. Returns ErrNotFound if it does not exist, and ErrInUse if any series or library currently references it.

func (*Service) DetachFromPulse

func (s *Service) DetachFromPulse(ctx context.Context, id string) error

DetachFromPulse flips a profile from managed to local-shadow. After this, sync loops no longer touch the profile — subsequent edits in Pulse are not propagated here.

func (*Service) Get

func (s *Service) Get(ctx context.Context, id string) (Profile, error)

Get returns a quality profile by ID. Returns ErrNotFound if no profile with that ID exists.

func (*Service) List

func (s *Service) List(ctx context.Context) ([]Profile, error)

List returns all quality profiles ordered by name.

func (*Service) ListManaged

func (s *Service) ListManaged(ctx context.Context) ([]Profile, error)

ListManaged returns only profiles flagged as managed_by_pulse. Used by the sync loop to identify which rows to reconcile with Pulse.

func (*Service) Update

func (s *Service) Update(ctx context.Context, id string, req UpdateRequest) (Profile, error)

Update replaces the mutable fields of an existing quality profile. Returns ErrNotFound if the profile does not exist.

type UpdateRequest

type UpdateRequest = CreateRequest

UpdateRequest carries the fields needed to update a quality profile. It is identical in shape to CreateRequest.

Jump to

Keyboard shortcuts

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