Trakt lists: keep the Radarr/Sonarr lookups of their titles on disk

Library membership is asked every time via movie?tmdbId= / series?tvdbId=;
only the lookups of titles not in the library are stored (3 days).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-24 20:48:20 +02:00
co-authored by Claude Opus 5.5
parent a70daaa0a3
commit f0bc284e82
10 changed files with 281 additions and 15 deletions
+48 -10
View File
@@ -72,7 +72,10 @@ func (m movieResult) withID(id int) result {
return m
}
type radarrBackend struct{ c *radarr.Client }
type radarrBackend struct {
c *radarr.Client
lookups *lookupStore
}
func (b radarrBackend) name() string { return "Radarr" }
func (b radarrBackend) noun() string { return "Movies" }
@@ -91,14 +94,30 @@ func (b radarrBackend) search(ctx context.Context, term string) ([]result, error
func (radarrBackend) lists() []trakt.List { return trakt.MovieLists }
func (b radarrBackend) resolve(ctx context.Context, e trakt.Entry) (result, error) {
if e.IDs.TMDB == 0 {
id := e.IDs.TMDB
if id == 0 {
return nil, errNotListed
}
found, err := b.search(ctx, radarr.TMDBTerm(e.IDs.TMDB))
if err != nil || len(found) == 0 {
if m, ok, err := b.c.MovieByTMDB(ctx, id); err != nil {
return nil, err
} else if ok {
return movieResult{Movie: m, poster: coverFor(b.c.Client, m.Images, true)}, nil
}
// Not in the library: the lookup from an earlier run, if fresh.
key := radarr.TMDBTerm(id)
var m radarr.Movie
if b.lookups.get(key, &m) {
return movieResult{Movie: m, poster: coverFor(b.c.Client, m.Images, false)}, nil
}
movies, err := b.c.Lookup(ctx, key)
if err != nil || len(movies) == 0 {
return nil, err
}
return found[0], nil
m = movies[0]
if !m.InLibrary() {
b.lookups.put(key, m)
}
return movieResult{Movie: m, poster: coverFor(b.c.Client, m.Images, m.InLibrary())}, nil
}
func (b radarrBackend) add(ctx context.Context, r result, c addChoice) (int, error) {
@@ -136,7 +155,10 @@ func (s seriesResult) withID(id int) result {
return s
}
type sonarrBackend struct{ c *sonarr.Client }
type sonarrBackend struct {
c *sonarr.Client
lookups *lookupStore
}
func (b sonarrBackend) name() string { return "Sonarr" }
func (b sonarrBackend) noun() string { return "Series" }
@@ -165,14 +187,30 @@ func (b sonarrBackend) search(ctx context.Context, term string) ([]result, error
func (sonarrBackend) lists() []trakt.List { return trakt.ShowLists }
func (b sonarrBackend) resolve(ctx context.Context, e trakt.Entry) (result, error) {
if e.IDs.TVDB == 0 {
id := e.IDs.TVDB
if id == 0 {
return nil, errNotListed
}
found, err := b.search(ctx, "tvdb:"+itoa(e.IDs.TVDB))
if err != nil || len(found) == 0 {
if s, ok, err := b.c.SeriesByTVDB(ctx, id); err != nil {
return nil, err
} else if ok {
return seriesResult{Series: s, poster: coverFor(b.c.Client, s.Images, true)}, nil
}
// Not in the library: the lookup from an earlier run, if fresh.
key := "tvdb:" + itoa(id)
var s sonarr.Series
if b.lookups.get(key, &s) {
return seriesResult{Series: s, poster: coverFor(b.c.Client, s.Images, false)}, nil
}
series, err := b.c.Lookup(ctx, key)
if err != nil || len(series) == 0 {
return nil, err
}
return found[0], nil
s = series[0]
if !s.InLibrary() {
b.lookups.put(key, s)
}
return seriesResult{Series: s, poster: coverFor(b.c.Client, s.Images, s.InLibrary())}, nil
}
func (b sonarrBackend) add(ctx context.Context, r result, c addChoice) (int, error) {