Add library view and series drill-down (M8)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-20 19:31:12 +02:00
co-authored by Claude Sonnet 5.5
parent a469eca871
commit 61373bbe45
11 changed files with 1080 additions and 18 deletions
+48 -8
View File
@@ -3,6 +3,7 @@ package sonarr
import (
"context"
"encoding/json"
"net/http"
"net/url"
"strconv"
@@ -41,16 +42,18 @@ type Rating struct {
// Season is a season entry of a series.
type Season struct {
SeasonNumber int `json:"seasonNumber"`
Monitored bool `json:"monitored"`
SeasonNumber int `json:"seasonNumber"`
Monitored bool `json:"monitored"`
Statistics Statistics `json:"statistics"`
}
// Statistics are the episode counts Sonarr reports for library series.
type Statistics struct {
SeasonCount int `json:"seasonCount"`
EpisodeFileCount int `json:"episodeFileCount"`
EpisodeCount int `json:"episodeCount"`
TotalEpisodeCount int `json:"totalEpisodeCount"`
SeasonCount int `json:"seasonCount"`
EpisodeFileCount int `json:"episodeFileCount"`
EpisodeCount int `json:"episodeCount"`
TotalEpisodeCount int `json:"totalEpisodeCount"`
SizeOnDisk int64 `json:"sizeOnDisk"`
}
// Series is a lookup result or library series. ID is 0 when the series is
@@ -159,8 +162,45 @@ func (c *Client) AddSeries(ctx context.Context, s Series, opts AddOptions) (Seri
// SearchSeries triggers an automatic search for all missing episodes of a library series.
func (c *Client) SearchSeries(ctx context.Context, seriesID int) error {
body := map[string]any{"name": "SeriesSearch", "seriesId": seriesID}
return c.Do(ctx, http.MethodPost, "command", nil, body, nil)
return c.Command(ctx, map[string]any{"name": "SeriesSearch", "seriesId": seriesID})
}
// SearchSeason triggers an automatic search for the missing episodes of one season.
func (c *Client) SearchSeason(ctx context.Context, seriesID, season int) error {
return c.Command(ctx, map[string]any{"name": "SeasonSearch", "seriesId": seriesID, "seasonNumber": season})
}
// SearchEpisode triggers an automatic search for one episode.
func (c *Client) SearchEpisode(ctx context.Context, episodeID int) error {
return c.Command(ctx, map[string]any{"name": "EpisodeSearch", "episodeIds": []int{episodeID}})
}
// GetSeries fetches one library series.
func (c *Client) GetSeries(ctx context.Context, id int) (Series, error) {
var s Series
err := c.Do(ctx, http.MethodGet, "series/"+strconv.Itoa(id), nil, nil, &s)
return s, err
}
// SetMonitored changes the monitored flag of a library series.
func (c *Client) SetMonitored(ctx context.Context, seriesID int, monitored bool) error {
return c.Update(ctx, "series", seriesID, func(o map[string]json.RawMessage) error {
arr.SetBool(o, "monitored", monitored)
return nil
})
}
// SetSeasonMonitored changes the monitored flag of one season of a library series.
func (c *Client) SetSeasonMonitored(ctx context.Context, seriesID, season int, monitored bool) error {
return c.Update(ctx, "series", seriesID, func(o map[string]json.RawMessage) error {
return arr.SetSeasonMonitored(o, season, monitored)
})
}
// SetEpisodesMonitored changes the monitored flag of episodes.
func (c *Client) SetEpisodesMonitored(ctx context.Context, episodeIDs []int, monitored bool) error {
body := map[string]any{"episodeIds": episodeIDs, "monitored": monitored}
return c.Do(ctx, http.MethodPut, "episode/monitor", nil, body, nil)
}
// Queue lists Sonarr's download queue, including series and episode info.