release / web (push) Successful in 1m42s
release / go (push) Successful in 2m7s
release / govulncheck (push) Successful in 37s
release / integration (push) Successful in 5m31s
release / Attach APK to the Release (tag releases only) (push) Canceled after 0s
release / Build + push container image (push) Canceled after 0s
release / Verify release artifacts (tag releases only) (push) Canceled after 0s
release / android (push) Canceled after 5m14s
release / Build signed APK (releases and dev) (push) Canceled after 4m42s
Lidarr's POST /api/v1/album validates `artist` as a nested resource (AlbumController: RuleFor(s => s.Artist).NotNull()), so the flat payload we sent was refused with "'Artist' must not be empty" every time. The album add has never worked against a real Lidarr; approved album and track requests sat in the reconciler retrying every 5 minutes. AddAlbum now does what Lidarr's own add-album UI does (getNewAlbum / getNewArtist): look the album up by MBID (album/lookup?term=lidarr:<mbid>), then POST that resource back with monitored + searchForNewAlbum. When Lidarr doesn't have the artist yet, the nested artist gets the request's quality/metadata profile and root folder, monitors this album only (monitor "none" + albumsToMonitor, which AlbumMonitoredService prefers) and no future releases. An artist Lidarr already has is left as it is. An MBID Lidarr's metadata doesn't know is ErrNotFound with no POST. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
82 lines
2.5 KiB
Go
82 lines
2.5 KiB
Go
package lidarr
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/url"
|
|
)
|
|
|
|
// LookupArtistByMBID returns the artist Lidarr has indexed under that
|
|
// MBID. Returns ErrNotFound if Lidarr returns an empty array.
|
|
func (c *Client) LookupArtistByMBID(ctx context.Context, mbid string) (LidarrArtist, error) {
|
|
if mbid == "" {
|
|
return LidarrArtist{}, fmt.Errorf("lidarr: empty mbid")
|
|
}
|
|
q := url.Values{"mbId": []string{mbid}}
|
|
resp, err := c.get(ctx, "/api/v1/artist", q)
|
|
if err != nil {
|
|
return LidarrArtist{}, err
|
|
}
|
|
defer func() { _ = resp.Body.Close() }()
|
|
|
|
var rows []LidarrArtist
|
|
if err := json.NewDecoder(resp.Body).Decode(&rows); err != nil {
|
|
return LidarrArtist{}, fmt.Errorf("%w: decode artist: %v", ErrInvalidPayload, err)
|
|
}
|
|
if len(rows) == 0 {
|
|
return LidarrArtist{}, ErrNotFound
|
|
}
|
|
return rows[0], nil
|
|
}
|
|
|
|
// LookupAlbumByMBID returns the album Lidarr has indexed under that
|
|
// MBID. Returns ErrNotFound on empty result.
|
|
func (c *Client) LookupAlbumByMBID(ctx context.Context, mbid string) (LidarrAlbum, error) {
|
|
if mbid == "" {
|
|
return LidarrAlbum{}, fmt.Errorf("lidarr: empty mbid")
|
|
}
|
|
q := url.Values{"foreignAlbumId": []string{mbid}}
|
|
resp, err := c.get(ctx, "/api/v1/album", q)
|
|
if err != nil {
|
|
return LidarrAlbum{}, err
|
|
}
|
|
defer func() { _ = resp.Body.Close() }()
|
|
|
|
var rows []LidarrAlbum
|
|
if err := json.NewDecoder(resp.Body).Decode(&rows); err != nil {
|
|
return LidarrAlbum{}, fmt.Errorf("%w: decode album: %v", ErrInvalidPayload, err)
|
|
}
|
|
if len(rows) == 0 {
|
|
return LidarrAlbum{}, ErrNotFound
|
|
}
|
|
return rows[0], nil
|
|
}
|
|
|
|
// lookupAlbumResource fetches the album resource Lidarr's metadata holds
|
|
// under mbid (GET /api/v1/album/lookup?term=lidarr:<mbid>), kept as raw
|
|
// JSON so AddAlbum can POST it back with every field Lidarr sent — the
|
|
// round trip Lidarr's own add-album UI makes. Returns ErrNotFound when no
|
|
// result carries that MBID.
|
|
func (c *Client) lookupAlbumResource(ctx context.Context, mbid string) (map[string]any, error) {
|
|
if mbid == "" {
|
|
return nil, fmt.Errorf("lidarr: empty album mbid")
|
|
}
|
|
resp, err := c.get(ctx, "/api/v1/album/lookup", url.Values{"term": {"lidarr:" + mbid}})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer func() { _ = resp.Body.Close() }()
|
|
|
|
var rows []map[string]any
|
|
if err := json.NewDecoder(resp.Body).Decode(&rows); err != nil {
|
|
return nil, fmt.Errorf("%w: decode album lookup: %v", ErrInvalidPayload, err)
|
|
}
|
|
for _, row := range rows {
|
|
if id, _ := row["foreignAlbumId"].(string); id == mbid {
|
|
return row, nil
|
|
}
|
|
}
|
|
return nil, fmt.Errorf("%w: album %s in Lidarr's metadata", ErrNotFound, mbid)
|
|
}
|