Skip to content

feat(music): add TheAudioDB metadata provider#3124

Open
Crow-Control wants to merge 2 commits into
seerr-team:musicfrom
Crow-Control:music-tadb-standalone
Open

feat(music): add TheAudioDB metadata provider#3124
Crow-Control wants to merge 2 commits into
seerr-team:musicfrom
Crow-Control:music-tadb-standalone

Conversation

@Crow-Control

@Crow-Control Crow-Control commented Jun 5, 2026

Copy link
Copy Markdown

Description

This adds the TheAudioDB metadata provider for use in fetching music cover art

In the future these can be expanded to include persistent caching using the database to track caching (like done in #2132), however this is technically not needed to have these providers fully-functional and allows for improved review ability.

Adds standalone TheAudioDB client along with admin settings, route, UI and OpenAPI documentation so their API surface, rate limiting and credentials can be validated before any music features consume them.

Changes:

  • New TheAudioDB api client
  • Unittests
  • GUI configuration
  • GUI testing feature
  • new settings documented

AI usage:

  • Copilot-auto for automatic review
  • Claude Opus 4.7 for splitting this of the old PR
  • Claude Opus 4.7 for unittest and documentation (pre-)generation

Structural coding and GUI review/design done manually
Architectural design mostly done in original music PR.

How Has This Been Tested?

  • New unit tests
  • pnpm dev
  • pnpm build
  • prettier
  • Manual GUI testing

Screenshots / Logs (if applicable)

Screenshot 2026-06-03 at 22 19 55 Screenshot 2026-06-04 at 13 02 16 Screenshot 2026-06-04 at 13 02 25

Checklist:

  • I have read and followed the contribution guidelines.
  • Disclosed any use of AI (see our policy)
  • I have updated the documentation accordingly.
  • All new and existing tests passed.
  • Successful build pnpm build
  • Translation keys pnpm i18n:extract
  • Database migration (if required) -> not required

Summary by CodeRabbit

Release Notes

  • New Features

    • Added Artwork Providers configuration section enabling administrators to configure TheAudioDB API credentials and rate limits.
    • Added connectivity testing for artwork provider sources.
  • Documentation

    • Added guide for Artwork Providers configuration setup.

Copilot AI review requested due to automatic review settings June 5, 2026 15:13
@Crow-Control Crow-Control requested a review from a team as a code owner June 5, 2026 15:13
@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 36f1945a-ef04-494c-8bc8-c1e89f792a14

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR integrates TheAudioDB as a configurable artwork provider into Seerr. It adds a complete data model, API client, backend routes, admin UI, and documentation for managing TheAudioDB credentials and rate limits with connectivity testing.

Changes

TheAudioDB Artwork Provider Integration

Layer / File(s) Summary
Settings model and cache infrastructure
server/lib/settings/index.ts, server/lib/cache.ts, seerr-api.yml
AllSettings extended with ArtworkProvidersSettings containing TheAudioDbSettings (apiKey, maxRPS, maxRequests); cache registry adds tadb entry with 6-hour TTL; OpenAPI schemas define settings and test response structures.
TheAudioDB API client
server/api/theaudiodb/interfaces.ts, server/api/theaudiodb/index.ts, server/api/theaudiodb/theaudiodb.test.ts
TheAudioDb class wraps ExternalAPI with configured caching and rate limiting; implements getArtistImages() (returns artist thumbnail/fanart) and testConnection() (validates API key via Coldplay artist lookup); test suite verifies correct endpoint construction, error handling, and short-circuit behavior when API key is missing.
Backend settings routes and API
server/routes/settings/artworkProviders.ts, server/routes/settings/artworkProviders.test.ts, server/routes/settings/index.ts, seerr-api.yml
Routes handle GET (fetch current settings with defaults), PUT (merge and coerce numeric fields, persist changes), and POST /test (invoke TheAudioDb.testConnection() and map result to ok|failed|not tested); tests verify settings persistence, numeric coercion, and test state handling; OpenAPI endpoints document request/response contracts; routes mounted under /settings/artwork-providers.
Frontend settings UI and internationalization
src/components/Settings/SettingsMetadata.tsx, src/i18n/locale/en.json
SettingsMetadata refactored to add "Artwork Providers Configuration" form section with Formik inputs for TheAudioDB apiKey, maxRPS, maxRequests; testConnection() runs metadata and artwork tests concurrently and maps results to unified provider status model; dedicated artwork Test and Save buttons manage isTesting state and persist via PUT to /api/v1/settings/artwork-providers; provider status panel displays TheAudioDB badge; i18n strings added for configuration labels, throttling fields, and connectivity messages.
Documentation
docs/using-seerr/settings/artwork-providers.md
Admin guide explaining Artwork Providers configuration page, Test button behavior and status badges, TheAudioDB-specific setup (API key defaults, rate-limit and concurrent-request fields, caching duration, and persistence via Save).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • gauthier-th
  • fallenbagel
  • M0NsTeRRR

🐰 A new provider hops in, credentials in hand,
Artwork flows swift through TheAudioDB's land,
Settings are saved, defaults stand tall,
Test buttons flourish on the admin hall,
Music finds its visual thrall! 🎨🎵

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat(music): add TheAudioDB metadata provider' clearly and concisely describes the primary change: adding TheAudioDB as a metadata/artwork provider for music, which aligns with all substantial changes across API, backend, UI, and documentation files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds configurable “Artwork Providers” settings (TheAudioDB) with server-side persistence, connectivity testing, caching, UI controls, OpenAPI updates, and user documentation.

Changes:

  • Introduces settings storage + API routes for artwork providers, including a /test endpoint.
  • Adds TheAudioDB API client with cache + rate limiting controls.
  • Extends Settings → Metadata Providers UI to configure/test TheAudioDB and show status.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/i18n/locale/en.json Adds UI strings for artwork provider configuration and TheAudioDB status messaging.
src/components/Settings/SettingsMetadata.tsx Adds Artwork Providers Configuration UI, fetch/save/test flows, and status badge for TheAudioDB.
server/routes/settings/index.ts Registers new /settings/artwork-providers router.
server/routes/settings/artworkProviders.ts Implements GET/PUT settings persistence and POST connectivity test for TheAudioDB.
server/routes/settings/artworkProviders.test.ts Adds route-level tests for settings merge/defaults and connectivity test behavior.
server/lib/settings/index.ts Adds persisted settings schema/defaults + accessors for artwork providers.
server/lib/cache.ts Adds dedicated cache bucket for TheAudioDB.
server/api/theaudiodb/interfaces.ts Adds response typing for TheAudioDB artist lookup.
server/api/theaudiodb/index.ts Adds TheAudioDB client with caching, rate limit config, and connectivity test.
server/api/theaudiodb/theaudiodb.test.ts Adds unit tests for TheAudioDB client behavior and request construction.
seerr-api.yml Documents new settings endpoints and schemas for artwork providers.
docs/using-seerr/settings/artwork-providers.md Documents new Artwork Providers settings page and TheAudioDB configuration.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +289 to +311
const failures: string[] = [];
if (resp.tvdb === 'failed') {
failures.push(intl.formatMessage(messages.tvdbProviderDoesnotWork));
}
if (resp.tmdb === 'failed') {
failures.push(intl.formatMessage(messages.tmdbProviderDoesnotWork));
}
if (resp.theAudioDb === 'failed') {
failures.push(
intl.formatMessage(messages.theAudioDbProviderDoesnotWork)
);
}

if (failures.length > 0) {
for (const msg of failures) {
addToast(msg, { appearance: 'error', autoDismiss: true });
}
} else {
addToast(
intl.formatMessage(messages.allChosenProvidersAreOperational),
{ appearance: 'success', autoDismiss: true }
);
}
Comment on lines +322 to +342
const runArtworkProviderTests = async (): Promise<void> => {
setIsTesting(true);
try {
const resp = await axios
.post<{
success: boolean;
tests: {
theAudioDb: ProviderStatus;
};
}>('/api/v1/settings/artwork-providers/test')
.then((r) => r.data.tests)
.catch((e) => {
if (axios.isAxiosError(e) && e.response?.data?.tests) {
return e.response.data.tests as {
theAudioDb: ProviderStatus;
};
}
return {
theAudioDb: 'failed' as const,
};
});
Comment on lines +38 to +42
| Field | Default | Description |
| --------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **API key** | `195003` | Your TheAudioDB API key. Defaults to the public test key shared by the community; supply your own from [theaudiodb.com](https://www.theaudiodb.com) for production use and higher limits. |
| **Max requests per second** | `25` | Outbound rate limit. |
| **Max concurrent requests** | `20` | Cap on in-flight requests. |
Comment thread seerr-api.yml
Comment on lines +2709 to +2714
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ArtworkProvidersSettings'
@Crow-Control Crow-Control changed the base branch from develop to music June 5, 2026 15:16
@Crow-Control Crow-Control force-pushed the music-tadb-standalone branch from e2ad9b7 to 284d395 Compare June 5, 2026 15:17

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/Settings/SettingsMetadata.tsx`:
- Around line 580-592: The form currently uses hardcoded fallback defaults in
initialValues (artworkData ?? { theAudioDb: {...} }), which lets a user save
those defaults before SWR finishes and overwrite real settings; change
initialValues to use artworkData only (initialValues={artworkData}) and prevent
rendering/submission while artworkData is undefined — e.g., conditionally render
the form or show a loading state when artworkData is null and disable the submit
button until data loads; ensure the onSubmit handler (the axios.put call and
subsequent mutateArtwork) only runs when artworkData is present so you never
send the fallback defaults to /api/v1/settings/artwork-providers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3c78919d-a542-4173-a02f-4b6d35aa8199

📥 Commits

Reviewing files that changed from the base of the PR and between 0a305f6 and e2ad9b7.

📒 Files selected for processing (12)
  • docs/using-seerr/settings/artwork-providers.md
  • seerr-api.yml
  • server/api/theaudiodb/index.ts
  • server/api/theaudiodb/interfaces.ts
  • server/api/theaudiodb/theaudiodb.test.ts
  • server/lib/cache.ts
  • server/lib/settings/index.ts
  • server/routes/settings/artworkProviders.test.ts
  • server/routes/settings/artworkProviders.ts
  • server/routes/settings/index.ts
  • src/components/Settings/SettingsMetadata.tsx
  • src/i18n/locale/en.json

Comment on lines +580 to +592
initialValues={
artworkData ?? {
theAudioDb: { apiKey: '195003', maxRPS: 25, maxRequests: 20 },
}
}
enableReinitialize
onSubmit={async (values) => {
try {
const resp = await axios.put<{
success: boolean;
theAudioDb: TheAudioDbSettings;
}>('/api/v1/settings/artwork-providers', values);
mutateArtwork({

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Prevent overwriting saved artwork settings before SWR data loads.

Line 581 initializes the form with hardcoded defaults when artworkData is still undefined. If Save is clicked before the fetch resolves, the PUT request can overwrite a previously configured API key/rate limits with fallback values.

Suggested fix
-  const { data: artworkData, mutate: mutateArtwork } =
-    useSWR<ArtworkProvidersSettings>('/api/v1/settings/artwork-providers');
+  const {
+    data: artworkData,
+    error: artworkError,
+    mutate: mutateArtwork,
+  } = useSWR<ArtworkProvidersSettings>('/api/v1/settings/artwork-providers');
+
+  const artworkLoading = !artworkData && !artworkError;

-  if (!data && !error) {
+  if ((!data && !error) || artworkLoading) {
     return <LoadingSpinner />;
   }
...
-          initialValues={
-            artworkData ?? {
-              theAudioDb: { apiKey: '195003', maxRPS: 25, maxRequests: 20 },
-            }
-          }
+          initialValues={artworkData}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/Settings/SettingsMetadata.tsx` around lines 580 - 592, The
form currently uses hardcoded fallback defaults in initialValues (artworkData ??
{ theAudioDb: {...} }), which lets a user save those defaults before SWR
finishes and overwrite real settings; change initialValues to use artworkData
only (initialValues={artworkData}) and prevent rendering/submission while
artworkData is undefined — e.g., conditionally render the form or show a loading
state when artworkData is null and disable the submit button until data loads;
ensure the onSubmit handler (the axios.put call and subsequent mutateArtwork)
only runs when artworkData is present so you never send the fallback defaults to
/api/v1/settings/artwork-providers.

@M0NsTeRRR M0NsTeRRR linked an issue Jun 8, 2026 that may be closed by this pull request
@github-actions github-actions Bot added the merge conflict Cannot merge due to merge conflicts label Jun 9, 2026
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown

This pull request has merge conflicts. Please resolve the conflicts so the PR can be successfully reviewed and merged.

@github-actions github-actions Bot removed the merge conflict Cannot merge due to merge conflicts label Jun 9, 2026
@Crow-Control Crow-Control force-pushed the music-tadb-standalone branch from 2676b77 to 2d7267a Compare June 9, 2026 11:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request] Music / Audio support

2 participants