Fix Sonarr TV request policy and bump gateway to 0.1.40

This commit is contained in:
ponzischeme89
2026-08-14 10:30:25 +12:00
parent 5e2ed3d12e
commit 19f08e6293
11 changed files with 366 additions and 29 deletions
+54
View File
@@ -18,6 +18,10 @@ const MaintenanceKey = "maintenance"
// RequestPolicyKey controls which Emby users may send titles to Sonarr/Radarr.
const RequestPolicyKey = "request_policy"
// SonarrRequestPolicyKey is deliberately separate from request access. Access answers who
// may ask; this policy answers the safe, household-wide way a TV request is created.
const SonarrRequestPolicyKey = "sonarr_request_policy"
// PlaybackPolicyKey controls presentation behaviour that should be adjustable without
// shipping a new TV build.
const PlaybackPolicyKey = "playback_policy"
@@ -379,6 +383,56 @@ type RequestPolicy struct {
UpdatedAt time.Time `json:"updatedAt"`
}
// SonarrRequestPolicy stores Sonarr's stable quality-profile id, never its mutable name.
// A zero id means the operator has not selected one yet; the gateway may use only a profile
// named 720p as its safe first-run recommendation, never Sonarr's arbitrary default.
type SonarrRequestPolicy struct {
QualityProfileID int `json:"qualityProfileId"`
SearchImmediately bool `json:"searchImmediately"`
UpdatedAt time.Time `json:"updatedAt"`
}
func DefaultSonarrRequestPolicy() SonarrRequestPolicy { return SonarrRequestPolicy{} }
func (s *Store) SonarrRequestPolicy(ctx context.Context) (SonarrRequestPolicy, error) {
var raw []byte
err := s.pool.QueryRow(ctx, `SELECT value FROM app_settings WHERE key = $1`, SonarrRequestPolicyKey).Scan(&raw)
if errors.Is(err, pgx.ErrNoRows) {
return DefaultSonarrRequestPolicy(), nil
}
if err != nil {
return DefaultSonarrRequestPolicy(), fmt.Errorf("store: read Sonarr request policy: %w", err)
}
var policy SonarrRequestPolicy
if err := json.Unmarshal(raw, &policy); err != nil {
return DefaultSonarrRequestPolicy(), fmt.Errorf("store: decode Sonarr request policy: %w", err)
}
if policy.QualityProfileID < 0 {
policy.QualityProfileID = 0
}
return policy, nil
}
func (s *Store) SetSonarrRequestPolicy(ctx context.Context, policy SonarrRequestPolicy) error {
if policy.QualityProfileID <= 0 {
return fmt.Errorf("store: Sonarr request quality profile is required")
}
policy.UpdatedAt = time.Now().UTC()
raw, err := json.Marshal(policy)
if err != nil {
return err
}
_, err = s.pool.Exec(ctx, `
INSERT INTO app_settings (key, value, updated_at)
VALUES ($1, $2::jsonb, now())
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = now()`,
SonarrRequestPolicyKey, string(raw))
if err != nil {
return fmt.Errorf("store: write Sonarr request policy: %w", err)
}
return nil
}
func (p RequestPolicy) Allows(userID string) bool {
for _, allowed := range p.AllowedUserIDs {
if allowed == userID {