From cd78f8ef00ea77820a03d14dec367bcce53e32dd Mon Sep 17 00:00:00 2001 From: Nick Wallace Date: Tue, 2 Dec 2025 17:16:40 -0600 Subject: [PATCH 1/9] Adding support for includeSeasonImages in Sonarr --- sonarr/series.go | 20 +++++++++++++------- sonarr/series_test.go | 4 ++-- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/sonarr/series.go b/sonarr/series.go index c31c39a2..c8a52f5a 100644 --- a/sonarr/series.go +++ b/sonarr/series.go @@ -144,22 +144,25 @@ func (s *Sonarr) GetAllSeries() ([]*Series, error) { // GetAllSeriesContext returns all configured series. // This may not deal well with pagination atm, let us know? func (s *Sonarr) GetAllSeriesContext(ctx context.Context) ([]*Series, error) { - return s.GetSeriesContext(ctx, 0) + return s.GetSeriesContext(ctx, 0, false) } // GetSeries locates and returns a series by tvdbID. If tvdbID is 0, returns all series. -func (s *Sonarr) GetSeries(tvdbID int64) ([]*Series, error) { - return s.GetSeriesContext(context.Background(), tvdbID) +func (s *Sonarr) GetSeries(tvdbID int64, includeSeasonImages bool) ([]*Series, error) { + return s.GetSeriesContext(context.Background(), tvdbID, includeSeasonImages) } // GetSeriesContext locates and returns a series by tvdbID. If tvdbID is 0, returns all series. -func (s *Sonarr) GetSeriesContext(ctx context.Context, tvdbID int64) ([]*Series, error) { +func (s *Sonarr) GetSeriesContext(ctx context.Context, tvdbID int64, includeSeasonImages bool) ([]*Series, error) { var output []*Series req := starr.Request{URI: bpSeries, Query: make(url.Values)} if tvdbID != 0 { req.Query.Add("tvdbId", starr.Str(tvdbID)) } + if includeSeasonImages { + req.Query.Add("includeSeasonImages", "true") + } if err := s.GetInto(ctx, req, &output); err != nil { return nil, fmt.Errorf("api.Get(%s): %w", &req, err) @@ -220,14 +223,17 @@ func (s *Sonarr) AddSeriesContext(ctx context.Context, series *AddSeriesInput) ( // GetSeriesByID locates and returns a series by DB [series] ID. func (s *Sonarr) GetSeriesByID(seriesID int64) (*Series, error) { - return s.GetSeriesByIDContext(context.Background(), seriesID) + return s.GetSeriesByIDContext(context.Background(), seriesID, false) } // GetSeriesByIDContext locates and returns a series by DB [series] ID. -func (s *Sonarr) GetSeriesByIDContext(ctx context.Context, seriesID int64) (*Series, error) { +func (s *Sonarr) GetSeriesByIDContext(ctx context.Context, seriesID int64, includeSeasonImages bool) (*Series, error) { var output Series - req := starr.Request{URI: path.Join(bpSeries, starr.Str(seriesID))} + req := starr.Request{URI: path.Join(bpSeries, starr.Str(seriesID)), Query: make(url.Values)} + if includeSeasonImages { + req.Query.Add("includeSeasonImages", "true") + } if err := s.GetInto(ctx, req, &output); err != nil { return nil, fmt.Errorf("api.Get(%s): %w", &req, err) } diff --git a/sonarr/series_test.go b/sonarr/series_test.go index 04a7a1b5..3043743c 100644 --- a/sonarr/series_test.go +++ b/sonarr/series_test.go @@ -666,12 +666,12 @@ func TestGetSeries(t *testing.T) { }, } - for _, test := range tests { + for _, test := range tests { t.Run(test.Name, func(t *testing.T) { t.Parallel() mockServer := test.GetMockServer(t) client := sonarr.New(starr.New("mockAPIkey", mockServer.URL, 0)) - output, err := client.GetSeries(int64(test.WithRequest.(int))) + output, err := client.GetSeries(int64(test.WithRequest.(int)), false) require.ErrorIs(t, err, test.WithError, "error is not the same as expected") assert.EqualValues(t, output, test.WithResponse, "response is not the same as expected") }) From a304f3f524f8b43d12f5b219d71d9c6eb8d3959b Mon Sep 17 00:00:00 2001 From: Nick Wallace Date: Tue, 2 Dec 2025 17:29:20 -0600 Subject: [PATCH 2/9] Adding param for GetAllSeries --- sonarr/series.go | 8 ++++---- sonarr/series_test.go | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sonarr/series.go b/sonarr/series.go index c8a52f5a..2687c5ae 100644 --- a/sonarr/series.go +++ b/sonarr/series.go @@ -137,14 +137,14 @@ type Statistics struct { // GetAllSeries returns all configured series. // This may not deal well with pagination atm, let us know? -func (s *Sonarr) GetAllSeries() ([]*Series, error) { - return s.GetAllSeriesContext(context.Background()) +func (s *Sonarr) GetAllSeries(includeSeasonImages bool) ([]*Series, error) { + return s.GetAllSeriesContext(context.Background(), includeSeasonImages) } // GetAllSeriesContext returns all configured series. // This may not deal well with pagination atm, let us know? -func (s *Sonarr) GetAllSeriesContext(ctx context.Context) ([]*Series, error) { - return s.GetSeriesContext(ctx, 0, false) +func (s *Sonarr) GetAllSeriesContext(ctx context.Context, includeSeasonImages bool) ([]*Series, error) { + return s.GetSeriesContext(ctx, 0, includeSeasonImages) } // GetSeries locates and returns a series by tvdbID. If tvdbID is 0, returns all series. diff --git a/sonarr/series_test.go b/sonarr/series_test.go index 3043743c..e526a525 100644 --- a/sonarr/series_test.go +++ b/sonarr/series_test.go @@ -535,7 +535,7 @@ func TestGetAllSeries(t *testing.T) { t.Parallel() mockServer := test.GetMockServer(t) client := sonarr.New(starr.New("mockAPIkey", mockServer.URL, 0)) - output, err := client.GetAllSeries() + output, err := client.GetAllSeries(false) require.ErrorIs(t, err, test.WithError, "error is not the same as expected") assert.EqualValues(t, output, test.WithResponse, "response is not the same as expected") }) @@ -666,7 +666,7 @@ func TestGetSeries(t *testing.T) { }, } - for _, test := range tests { + for _, test := range tests { t.Run(test.Name, func(t *testing.T) { t.Parallel() mockServer := test.GetMockServer(t) From 53deecc46648353573687d41128d10eb71c8efcf Mon Sep 17 00:00:00 2001 From: Nick Wallace Date: Tue, 2 Dec 2025 17:31:55 -0600 Subject: [PATCH 3/9] linter fixes --- sonarr/series.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sonarr/series.go b/sonarr/series.go index 2687c5ae..9fc56fff 100644 --- a/sonarr/series.go +++ b/sonarr/series.go @@ -160,6 +160,7 @@ func (s *Sonarr) GetSeriesContext(ctx context.Context, tvdbID int64, includeSeas if tvdbID != 0 { req.Query.Add("tvdbId", starr.Str(tvdbID)) } + if includeSeasonImages { req.Query.Add("includeSeasonImages", "true") } @@ -234,6 +235,7 @@ func (s *Sonarr) GetSeriesByIDContext(ctx context.Context, seriesID int64, inclu if includeSeasonImages { req.Query.Add("includeSeasonImages", "true") } + if err := s.GetInto(ctx, req, &output); err != nil { return nil, fmt.Errorf("api.Get(%s): %w", &req, err) } From debbd7bf0389b9463d621cceb78c0f57cdc35639 Mon Sep 17 00:00:00 2001 From: Nick Wallace Date: Tue, 2 Dec 2025 18:14:50 -0600 Subject: [PATCH 4/9] Adding images to the return --- sonarr/series.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sonarr/series.go b/sonarr/series.go index 9fc56fff..67079e0b 100644 --- a/sonarr/series.go +++ b/sonarr/series.go @@ -117,9 +117,10 @@ type AlternateTitle struct { // Season is part of AddSeriesInput and Queue and used in a few places. type Season struct { - Monitored bool `json:"monitored"` - SeasonNumber int `json:"seasonNumber"` - Statistics *Statistics `json:"statistics,omitempty"` + Monitored bool `json:"monitored"` + SeasonNumber int `json:"seasonNumber"` + Statistics *Statistics `json:"statistics,omitempty"` + Images []*starr.Image `json:"images,omitempty"` } // Statistics is part of AddSeriesInput and Queue. From 088300e68aaf24c767250f89d32d487885949471 Mon Sep 17 00:00:00 2001 From: Nick Wallace Date: Sun, 25 Jan 2026 13:43:07 -0600 Subject: [PATCH 5/9] Removing the bool --- sonarr/series.go | 16 +++++++--------- sonarr/series_test.go | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/sonarr/series.go b/sonarr/series.go index 67079e0b..42f71e85 100644 --- a/sonarr/series.go +++ b/sonarr/series.go @@ -138,23 +138,23 @@ type Statistics struct { // GetAllSeries returns all configured series. // This may not deal well with pagination atm, let us know? -func (s *Sonarr) GetAllSeries(includeSeasonImages bool) ([]*Series, error) { - return s.GetAllSeriesContext(context.Background(), includeSeasonImages) +func (s *Sonarr) GetAllSeries() ([]*Series, error) { + return s.GetAllSeriesContext(context.Background()) } // GetAllSeriesContext returns all configured series. // This may not deal well with pagination atm, let us know? -func (s *Sonarr) GetAllSeriesContext(ctx context.Context, includeSeasonImages bool) ([]*Series, error) { - return s.GetSeriesContext(ctx, 0, includeSeasonImages) +func (s *Sonarr) GetAllSeriesContext(ctx context.Context) ([]*Series, error) { + return s.GetSeriesContext(ctx, 0) } // GetSeries locates and returns a series by tvdbID. If tvdbID is 0, returns all series. func (s *Sonarr) GetSeries(tvdbID int64, includeSeasonImages bool) ([]*Series, error) { - return s.GetSeriesContext(context.Background(), tvdbID, includeSeasonImages) + return s.GetSeriesContext(context.Background(), tvdbID) } // GetSeriesContext locates and returns a series by tvdbID. If tvdbID is 0, returns all series. -func (s *Sonarr) GetSeriesContext(ctx context.Context, tvdbID int64, includeSeasonImages bool) ([]*Series, error) { +func (s *Sonarr) GetSeriesContext(ctx context.Context, tvdbID int64) ([]*Series, error) { var output []*Series req := starr.Request{URI: bpSeries, Query: make(url.Values)} @@ -162,9 +162,7 @@ func (s *Sonarr) GetSeriesContext(ctx context.Context, tvdbID int64, includeSeas req.Query.Add("tvdbId", starr.Str(tvdbID)) } - if includeSeasonImages { - req.Query.Add("includeSeasonImages", "true") - } + req.Query.Add("includeSeasonImages", "true") if err := s.GetInto(ctx, req, &output); err != nil { return nil, fmt.Errorf("api.Get(%s): %w", &req, err) diff --git a/sonarr/series_test.go b/sonarr/series_test.go index e526a525..495342f8 100644 --- a/sonarr/series_test.go +++ b/sonarr/series_test.go @@ -535,7 +535,7 @@ func TestGetAllSeries(t *testing.T) { t.Parallel() mockServer := test.GetMockServer(t) client := sonarr.New(starr.New("mockAPIkey", mockServer.URL, 0)) - output, err := client.GetAllSeries(false) + output, err := client.GetAllSeries() require.ErrorIs(t, err, test.WithError, "error is not the same as expected") assert.EqualValues(t, output, test.WithResponse, "response is not the same as expected") }) From bf0b408080db5ce48708db4d723597a0ade67aba Mon Sep 17 00:00:00 2001 From: Nick Wallace Date: Sun, 25 Jan 2026 13:46:35 -0600 Subject: [PATCH 6/9] Missed a couple --- sonarr/series.go | 10 ++++------ sonarr/series_test.go | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/sonarr/series.go b/sonarr/series.go index 42f71e85..6ac5773d 100644 --- a/sonarr/series.go +++ b/sonarr/series.go @@ -149,7 +149,7 @@ func (s *Sonarr) GetAllSeriesContext(ctx context.Context) ([]*Series, error) { } // GetSeries locates and returns a series by tvdbID. If tvdbID is 0, returns all series. -func (s *Sonarr) GetSeries(tvdbID int64, includeSeasonImages bool) ([]*Series, error) { +func (s *Sonarr) GetSeries(tvdbID int64) ([]*Series, error) { return s.GetSeriesContext(context.Background(), tvdbID) } @@ -223,17 +223,15 @@ func (s *Sonarr) AddSeriesContext(ctx context.Context, series *AddSeriesInput) ( // GetSeriesByID locates and returns a series by DB [series] ID. func (s *Sonarr) GetSeriesByID(seriesID int64) (*Series, error) { - return s.GetSeriesByIDContext(context.Background(), seriesID, false) + return s.GetSeriesByIDContext(context.Background(), seriesID) } // GetSeriesByIDContext locates and returns a series by DB [series] ID. -func (s *Sonarr) GetSeriesByIDContext(ctx context.Context, seriesID int64, includeSeasonImages bool) (*Series, error) { +func (s *Sonarr) GetSeriesByIDContext(ctx context.Context, seriesID int64) (*Series, error) { var output Series req := starr.Request{URI: path.Join(bpSeries, starr.Str(seriesID)), Query: make(url.Values)} - if includeSeasonImages { - req.Query.Add("includeSeasonImages", "true") - } + req.Query.Add("includeSeasonImages", "true") if err := s.GetInto(ctx, req, &output); err != nil { return nil, fmt.Errorf("api.Get(%s): %w", &req, err) diff --git a/sonarr/series_test.go b/sonarr/series_test.go index 495342f8..04a7a1b5 100644 --- a/sonarr/series_test.go +++ b/sonarr/series_test.go @@ -671,7 +671,7 @@ func TestGetSeries(t *testing.T) { t.Parallel() mockServer := test.GetMockServer(t) client := sonarr.New(starr.New("mockAPIkey", mockServer.URL, 0)) - output, err := client.GetSeries(int64(test.WithRequest.(int)), false) + output, err := client.GetSeries(int64(test.WithRequest.(int))) require.ErrorIs(t, err, test.WithError, "error is not the same as expected") assert.EqualValues(t, output, test.WithResponse, "response is not the same as expected") }) From afcbcecbd7fb18d5fa44fe49d9a18918c95a453d Mon Sep 17 00:00:00 2001 From: Nick Wallace Date: Sun, 25 Jan 2026 14:03:37 -0600 Subject: [PATCH 7/9] Fixing tests --- sonarr/series_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sonarr/series_test.go b/sonarr/series_test.go index 04a7a1b5..c5688a6d 100644 --- a/sonarr/series_test.go +++ b/sonarr/series_test.go @@ -275,7 +275,7 @@ func TestGetAllSeries(t *testing.T) { tests := []*starrtest.MockData{ { Name: "200", - ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series"), + ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series") + "?includeSeasonImages=true", ExpectedMethod: "GET", ResponseStatus: 200, ResponseBody: listSeries, @@ -521,7 +521,7 @@ func TestGetAllSeries(t *testing.T) { }, { Name: "404", - ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series"), + ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series") + "?includeSeasonImages=true", ExpectedMethod: "GET", ResponseStatus: 404, ResponseBody: starrtest.BodyNotFound, @@ -551,7 +551,7 @@ func TestGetSeries(t *testing.T) { tests := []*starrtest.MockData{ { Name: "200", - ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series?tvdbId=360893"), + ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series?tvdbId=360893") + "&includeSeasonImages=true", ExpectedMethod: "GET", ResponseStatus: 200, ResponseBody: "[" + secondSeries + "]", @@ -656,7 +656,7 @@ func TestGetSeries(t *testing.T) { }, { Name: "404", - ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series?tvdbId=360893"), + ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series?tvdbId=360893") + "&includeSeasonImages=true", ExpectedMethod: "GET", ResponseStatus: 404, ResponseBody: starrtest.BodyNotFound, @@ -687,7 +687,7 @@ func TestGetSeriesByID(t *testing.T) { tests := []*starrtest.MockData{ { Name: "200", - ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series", "2"), + ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series", "2") + "?includeSeasonImages=true", ExpectedMethod: "GET", ResponseStatus: 200, ResponseBody: secondSeries, @@ -790,7 +790,7 @@ func TestGetSeriesByID(t *testing.T) { }, { Name: "404", - ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series", "2"), + ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series", "2") + "?includeSeasonImages=true", ExpectedMethod: "GET", ResponseStatus: 404, ResponseBody: starrtest.BodyNotFound, From 8602351488d26db12dd7821a9329c97cbbbdd59c Mon Sep 17 00:00:00 2001 From: Nick Wallace Date: Sun, 25 Jan 2026 14:08:03 -0600 Subject: [PATCH 8/9] Update sonarr/series_test.go Co-authored-by: David Newhall II --- sonarr/series_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonarr/series_test.go b/sonarr/series_test.go index c5688a6d..d2a0450e 100644 --- a/sonarr/series_test.go +++ b/sonarr/series_test.go @@ -656,7 +656,7 @@ func TestGetSeries(t *testing.T) { }, { Name: "404", - ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series?tvdbId=360893") + "&includeSeasonImages=true", + ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series?tvdbId=360893&includeSeasonImages=true"), ExpectedMethod: "GET", ResponseStatus: 404, ResponseBody: starrtest.BodyNotFound, From ea81558a52622128a140428c0c06835a7c7a9f56 Mon Sep 17 00:00:00 2001 From: Nick Wallace Date: Sun, 25 Jan 2026 14:30:38 -0600 Subject: [PATCH 9/9] ok now they pass --- sonarr/series_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sonarr/series_test.go b/sonarr/series_test.go index d2a0450e..6ee4bd88 100644 --- a/sonarr/series_test.go +++ b/sonarr/series_test.go @@ -275,7 +275,7 @@ func TestGetAllSeries(t *testing.T) { tests := []*starrtest.MockData{ { Name: "200", - ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series") + "?includeSeasonImages=true", + ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series?includeSeasonImages=true"), ExpectedMethod: "GET", ResponseStatus: 200, ResponseBody: listSeries, @@ -521,7 +521,7 @@ func TestGetAllSeries(t *testing.T) { }, { Name: "404", - ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series") + "?includeSeasonImages=true", + ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series?includeSeasonImages=true"), ExpectedMethod: "GET", ResponseStatus: 404, ResponseBody: starrtest.BodyNotFound, @@ -551,7 +551,7 @@ func TestGetSeries(t *testing.T) { tests := []*starrtest.MockData{ { Name: "200", - ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series?tvdbId=360893") + "&includeSeasonImages=true", + ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series?includeSeasonImages=true&tvdbId=360893"), ExpectedMethod: "GET", ResponseStatus: 200, ResponseBody: "[" + secondSeries + "]", @@ -656,7 +656,7 @@ func TestGetSeries(t *testing.T) { }, { Name: "404", - ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series?tvdbId=360893&includeSeasonImages=true"), + ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series?includeSeasonImages=true&tvdbId=360893"), ExpectedMethod: "GET", ResponseStatus: 404, ResponseBody: starrtest.BodyNotFound, @@ -687,7 +687,7 @@ func TestGetSeriesByID(t *testing.T) { tests := []*starrtest.MockData{ { Name: "200", - ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series", "2") + "?includeSeasonImages=true", + ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series", "2?includeSeasonImages=true"), ExpectedMethod: "GET", ResponseStatus: 200, ResponseBody: secondSeries, @@ -790,7 +790,7 @@ func TestGetSeriesByID(t *testing.T) { }, { Name: "404", - ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series", "2") + "?includeSeasonImages=true", + ExpectedPath: path.Join("/", starr.API, sonarr.APIver, "series", "2?includeSeasonImages=true"), ExpectedMethod: "GET", ResponseStatus: 404, ResponseBody: starrtest.BodyNotFound,