This commit is contained in:
ponzischeme89
2026-08-19 14:25:44 +12:00
parent 2b43b9ef12
commit 590e069366
83 changed files with 8948 additions and 1266 deletions
+26 -32
View File
@@ -12,38 +12,28 @@ import (
"github.com/ponzischeme89/memby/server/internal/store"
)
// WatchSonarrLifecycle seeds the durable status history on startup, then refreshes it
// daily. History stores changes rather than identical daily snapshots: it still records
// the complete lifecycle while making an active-to-cancelled transition unambiguous.
func (s *Server) WatchSonarrLifecycle(ctx context.Context, interval time.Duration) {
if !s.sonarrEnabled(ctx) || interval <= 0 {
return
}
scan := func() {
if s.quietTimeActive() {
return
}
if err := s.scanSonarrLifecycle(ctx); err != nil && ctx.Err() == nil {
s.log.Warn("Sonarr lifecycle scan failed", "error", err)
}
}
scan()
ticker := time.NewTicker(interval)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
scan()
}
}
// sonarrLifecycleResult is what one scan looked at and what moved.
//
// Counted rather than only logged because these are the figures the integrations console
// prints beside the run: "412 series checked, 3 changed" is an answer, where "the scan
// finished" is a line in a log an operator has to go and find.
type sonarrLifecycleResult struct {
Series int
Changes int
Added int
Cancelled int
Notifications int
}
func (s *Server) scanSonarrLifecycle(ctx context.Context) error {
// scanSonarrLifecycle seeds the durable status history and records what changed since
// the last reading. History stores changes rather than identical daily snapshots: it still
// records the complete lifecycle while making an active-to-cancelled transition
// unambiguous.
func (s *Server) scanSonarrLifecycle(ctx context.Context) (sonarrLifecycleResult, error) {
result := sonarrLifecycleResult{}
series, err := s.sonarr.Series(ctx)
if err != nil {
return fmt.Errorf("read Sonarr series: %w", err)
return result, fmt.Errorf("read Sonarr series: %w", err)
}
now := time.Now().UTC()
observations := make([]store.SonarrSeriesStatus, 0, len(series))
@@ -57,10 +47,12 @@ func (s *Server) scanSonarrLifecycle(ctx context.Context) error {
Title: item.Title, Year: item.Year, Status: item.Status, ObservedAt: now,
})
}
result.Series = len(observations)
changes, err := s.store.RecordSonarrSeriesStatuses(ctx, observations)
if err != nil {
return err
return result, err
}
result.Changes = len(changes)
cancellations := make([]store.SonarrSeriesStatusChange, 0, len(changes))
additions := make([]store.SonarrSeriesStatusChange, 0, len(changes))
for _, change := range changes {
@@ -71,14 +63,15 @@ func (s *Server) scanSonarrLifecycle(ctx context.Context) error {
cancellations = append(cancellations, change)
}
}
result.Added, result.Cancelled = len(additions), len(cancellations)
if len(cancellations) == 0 && len(additions) == 0 {
s.log.Info("Sonarr lifecycle scan complete", "series", len(observations), "changes", len(changes))
return nil
return result, nil
}
users, err := s.store.KnownUsers(ctx)
if err != nil {
return err
return result, err
}
preferences := map[string]store.NotificationPreferences{}
preferenceErrors := map[string]bool{}
@@ -153,10 +146,11 @@ func (s *Server) scanSonarrLifecycle(ctx context.Context) error {
}
}
}
result.Notifications = notifications
s.log.Info("Sonarr lifecycle scan complete",
"series", len(observations), "changes", len(changes),
"added", len(additions), "cancelled", len(cancellations), "notifications", notifications)
return nil
return result, nil
}
func sonarrLifecycleNotificationKind(previous, current string) string {