Files
minstrel/web/src/routes/admin/metadata/+page.svelte
T
bvandeusenandClaude Opus 5.5 7e1cfb8d08
release / govulncheck (push) Successful in 14s
release / web (push) Failing after 16s
release / go (push) Successful in 1m13s
release / integration (push) Successful in 4m54s
release / android (push) Successful in 5m5s
release / Build signed APK (releases and dev) (push) Successful in 5m18s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Skipped
release / Verify release artifacts (tag releases only) (push) Skipped
feat: Integrations splits into Library, Acquisition, Metadata sources and Email & network, each a page on the admin rail; the Overview keeps only what needs you (M503 #5607)
- Library: the folders, Run scan and a row per scan job, cover art, fingerprints and loudness (off the Overview and Duplicates)
- Acquisition: indexers and clients, searching, re-acquisition (off Missing files), Lidarr
- Metadata sources: AcoustID, and one provider block for cover art and tags in place of the pasted pair
- Email & network: outgoing email, the notification schedule, public address, proxies
- Lidarr, outgoing email and the provider block are rebuilt as SettingsGroup rows; failures read as sentences, not codes
- Duplicates and Missing files say what their setting is and link to where it is set

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 11:21:48 -04:00

93 lines
3.0 KiB
Svelte
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script lang="ts">
import { pageTitle } from '#lib/branding.js';
import { useQueryClient } from '@tanstack/svelte-query';
import {
createCoverProvidersQuery,
updateCoverProvider,
testCoverProvider,
createTagProvidersQuery,
updateTagProvider,
testTagProvider
} from '#lib/api/admin.js';
import { qk } from '#lib/api/queries.js';
import AcoustIDCard from '#lib/components/AcoustIDCard.svelte';
import ProviderGroup from '#lib/components/admin/ProviderGroup.svelte';
import SettingsColumns from '#lib/components/settings/SettingsColumns.svelte';
// Admin › Metadata sources (#5607): the outside sources Minstrel asks
// about your music. AcoustID names a recording from its sound; the cover
// art and tag sources share one block.
const client = useQueryClient();
const coverStore = createCoverProvidersQuery();
const tagStore = createTagProvidersQuery();
async function saveCover(id: string, patch: { enabled?: boolean; api_key?: string }) {
const result = await updateCoverProvider(id, patch);
await client.invalidateQueries({ queryKey: qk.coverProviders() });
// A change to the sources opens covers no source had to another try.
if (result.version_bumped) await client.invalidateQueries({ queryKey: qk.coverage() });
return result;
}
async function saveTag(id: string, patch: { enabled?: boolean; api_key?: string }) {
const result = await updateTagProvider(id, patch);
await client.invalidateQueries({ queryKey: qk.tagProviders() });
return result;
}
const link = 'underline hover:no-underline';
</script>
<svelte:head><title>{pageTitle('Admin · Metadata sources')}</title></svelte:head>
<h2 class="sr-only">Metadata sources</h2>
{#snippet coverNote(p: { id: string })}
{#if p.id === 'theaudiodb'}
Works with the public key;
<a class={link} href="https://www.theaudiodb.com/api_apply.php" target="_blank" rel="noopener noreferrer"
>a free key of your own</a
> gets its own quota.
{/if}
{/snippet}
{#snippet tagNote(p: { id: string })}
{#if p.id === 'musicbrainz'}
Needs no key; matches by MusicBrainz id.
{:else if p.id === 'lastfm'}
Matches by artist and title.
<a class={link} href="https://www.last.fm/api/account/create" target="_blank" rel="noopener noreferrer"
>Get a free key</a
>.
{/if}
{/snippet}
<SettingsColumns>
{#snippet main()}
<AcoustIDCard />
{/snippet}
{#snippet side()}
<ProviderGroup
title="Cover art"
hint="Asked in this order for covers and artist images; the first to have one wins."
noun="cover art sources"
query={$coverStore}
save={saveCover}
test={testCoverProvider}
keyPlaceholder="Empty uses the public key"
note={coverNote}
/>
<ProviderGroup
title="Tags"
hint="Styles and moods for each track, merged from every source switched on."
noun="tag sources"
query={$tagStore}
save={saveTag}
test={testTagProvider}
keyPlaceholder="Paste a key to use this source"
note={tagNote}
/>
{/snippet}
</SettingsColumns>