0.2.52
This commit is contained in:
@@ -3,6 +3,7 @@ package store
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -31,6 +32,24 @@ type UserNotification struct {
|
||||
ReadAt *time.Time `json:"readAt,omitempty"`
|
||||
}
|
||||
|
||||
// SonarrSeriesStatus is one daily observation. SeriesKey prefers Sonarr's stable TVDB id;
|
||||
// the local Sonarr id is retained for diagnosis and as a fallback when TVDB has no answer.
|
||||
type SonarrSeriesStatus struct {
|
||||
SeriesKey string
|
||||
SonarrSeriesID int
|
||||
TVDBID int
|
||||
Title string
|
||||
Year int
|
||||
Status string
|
||||
ObservedAt time.Time
|
||||
}
|
||||
|
||||
type SonarrSeriesStatusChange struct {
|
||||
HistoryID int64
|
||||
PreviousStatus string
|
||||
Current SonarrSeriesStatus
|
||||
}
|
||||
|
||||
func (s *Store) SaveUserShow(ctx context.Context, userID string, show UserShow) error {
|
||||
_, err := s.pool.Exec(ctx, `
|
||||
INSERT INTO user_shows (emby_user_id, item_id, title, year, image_tag)
|
||||
@@ -89,6 +108,83 @@ func (s *Store) UserShows(ctx context.Context, userID string) ([]UserShow, error
|
||||
return shows, rows.Err()
|
||||
}
|
||||
|
||||
// RecordSonarrSeriesStatuses appends only first sightings and changes. A first sighting is
|
||||
// the baseline and is deliberately absent from the returned changes, so enabling the
|
||||
// scanner cannot announce every series that was already cancelled before it existed.
|
||||
func (s *Store) RecordSonarrSeriesStatuses(
|
||||
ctx context.Context, observations []SonarrSeriesStatus,
|
||||
) ([]SonarrSeriesStatusChange, error) {
|
||||
tx, err := s.pool.Begin(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("store: begin Sonarr status history: %w", err)
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
|
||||
rows, err := tx.Query(ctx, `
|
||||
SELECT DISTINCT ON (series_key) series_key, status
|
||||
FROM sonarr_series_status_history
|
||||
ORDER BY series_key, observed_at DESC, id DESC`)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("store: read Sonarr status history: %w", err)
|
||||
}
|
||||
previous := map[string]string{}
|
||||
for rows.Next() {
|
||||
var key, status string
|
||||
if err := rows.Scan(&key, &status); err != nil {
|
||||
rows.Close()
|
||||
return nil, fmt.Errorf("store: scan Sonarr status history: %w", err)
|
||||
}
|
||||
previous[key] = status
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
rows.Close()
|
||||
return nil, fmt.Errorf("store: iterate Sonarr status history: %w", err)
|
||||
}
|
||||
rows.Close()
|
||||
|
||||
changes := []SonarrSeriesStatusChange{}
|
||||
seen := map[string]bool{}
|
||||
for _, observation := range observations {
|
||||
observation.SeriesKey = strings.TrimSpace(observation.SeriesKey)
|
||||
observation.Title = strings.TrimSpace(observation.Title)
|
||||
observation.Status = strings.ToLower(strings.TrimSpace(observation.Status))
|
||||
if observation.SeriesKey == "" || observation.Title == "" || observation.Status == "" ||
|
||||
seen[observation.SeriesKey] {
|
||||
continue
|
||||
}
|
||||
seen[observation.SeriesKey] = true
|
||||
prior, known := previous[observation.SeriesKey]
|
||||
if known && strings.EqualFold(prior, observation.Status) {
|
||||
continue
|
||||
}
|
||||
if observation.ObservedAt.IsZero() {
|
||||
observation.ObservedAt = time.Now()
|
||||
}
|
||||
var historyID int64
|
||||
err := tx.QueryRow(ctx, `
|
||||
INSERT INTO sonarr_series_status_history
|
||||
(series_key, sonarr_series_id, tvdb_id, title, year, status, observed_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
||||
RETURNING id`,
|
||||
observation.SeriesKey, observation.SonarrSeriesID, observation.TVDBID,
|
||||
observation.Title, observation.Year, observation.Status, observation.ObservedAt,
|
||||
).Scan(&historyID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("store: append Sonarr status history: %w", err)
|
||||
}
|
||||
if known {
|
||||
changes = append(changes, SonarrSeriesStatusChange{
|
||||
HistoryID: historyID, PreviousStatus: prior, Current: observation,
|
||||
})
|
||||
}
|
||||
previous[observation.SeriesKey] = observation.Status
|
||||
}
|
||||
if err := tx.Commit(ctx); err != nil {
|
||||
return nil, fmt.Errorf("store: commit Sonarr status history: %w", err)
|
||||
}
|
||||
return changes, nil
|
||||
}
|
||||
|
||||
func (s *Store) NotificationPreferences(ctx context.Context, userID string) (NotificationPreferences, error) {
|
||||
prefs := NotificationPreferences{Enabled: true, ShowReturnAlerts: true, LeadDays: 7}
|
||||
err := s.pool.QueryRow(ctx, `
|
||||
|
||||
Reference in New Issue
Block a user