diff --git a/web_server.py b/web_server.py
index 2097043a..484f3cd5 100644
--- a/web_server.py
+++ b/web_server.py
@@ -4198,7 +4198,7 @@ def handle_settings():
if 'active_media_server' in new_settings:
config_manager.set_active_media_server(new_settings['active_media_server'])
- for service in ['spotify', 'plex', 'jellyfin', 'navidrome', 'soulseek', 'download_source', 'settings', 'database', 'metadata_enhancement', 'file_organization', 'playlist_sync', 'tidal', 'tidal_download', 'qobuz', 'listenbrainz', 'acoustid', 'lastfm', 'genius', 'import', 'lossy_copy', 'ui_appearance', 'youtube', 'content_filter', 'itunes', 'm3u_export']:
+ for service in ['spotify', 'plex', 'jellyfin', 'navidrome', 'soulseek', 'download_source', 'settings', 'database', 'metadata_enhancement', 'file_organization', 'playlist_sync', 'tidal', 'tidal_download', 'qobuz', 'listenbrainz', 'acoustid', 'lastfm', 'genius', 'import', 'lossy_copy', 'ui_appearance', 'youtube', 'content_filter', 'itunes', 'm3u_export', 'musicbrainz', 'deezer', 'audiodb']:
if service in new_settings:
for key, value in new_settings[service].items():
config_manager.set(f'{service}.{key}', value)
@@ -14314,6 +14314,8 @@ def _generate_lrc_file(file_path: str, context: dict, artist: dict, album_info:
Generate LRC lyrics file using LRClib API.
Elegant addition to post-processing - extracts metadata from existing context.
"""
+ if not config_manager.get('metadata_enhancement.lrclib_enabled', True):
+ return False
try:
# Extract track information from existing context (same as metadata enhancement)
original_search = context.get("original_search_result", {})
@@ -14698,7 +14700,9 @@ def _embed_source_ids(audio_file, metadata: dict):
# ── 2d. Tidal lookup for ISRC fallback, copyright, and source IDs ──
tidal_isrc = None
tidal_copyright = None
- if track_title and artist_name:
+ if not config_manager.get('tidal.embed_tags', True):
+ pass
+ elif track_title and artist_name:
try:
if tidal_client and tidal_client.is_authenticated():
td_result = tidal_client.search_track(artist_name, track_title)
@@ -14729,7 +14733,9 @@ def _embed_source_ids(audio_file, metadata: dict):
qobuz_isrc = None
qobuz_copyright = None
qobuz_label = None
- if track_title and artist_name:
+ if not config_manager.get('qobuz.embed_tags', True):
+ pass
+ elif track_title and artist_name:
try:
qz_client = qobuz_enrichment_worker.client if qobuz_enrichment_worker else None
if qz_client and qz_client.is_authenticated():
@@ -14768,7 +14774,9 @@ def _embed_source_ids(audio_file, metadata: dict):
# ── 2f. Last.fm lookup for tags (genre merge) and URL ──
lastfm_tags = []
lastfm_url = None
- if track_title and artist_name:
+ if not config_manager.get('lastfm.embed_tags', True):
+ pass
+ elif track_title and artist_name:
try:
lf_client = lastfm_worker.client if lastfm_worker else None
if lf_client:
@@ -14794,7 +14802,9 @@ def _embed_source_ids(audio_file, metadata: dict):
# state directly and skip immediately if Genius is rate-limited, rather
# than entering search_song which would sleep for up to 120s.
genius_url = None
- if track_title and artist_name:
+ if not config_manager.get('genius.embed_tags', True):
+ pass
+ elif track_title and artist_name:
try:
import core.genius_client as _genius_module
if time.time() < _genius_module._rate_limit_until:
@@ -14980,6 +14990,8 @@ def _embed_source_ids(audio_file, metadata: dict):
def _download_cover_art(album_info: dict, target_dir: str):
"""Downloads cover.jpg into the specified directory."""
+ if not config_manager.get('metadata_enhancement.cover_art_download', True):
+ return
try:
cover_path = os.path.join(target_dir, "cover.jpg")
if os.path.exists(cover_path):
diff --git a/webui/index.html b/webui/index.html
index dacbd5f9..bdb836bc 100644
--- a/webui/index.html
+++ b/webui/index.html
@@ -4210,25 +4210,82 @@
-
🎵 Metadata Enhancement
+
🎵 Post-Processing
+ Master toggle — disabling this skips all metadata, artwork, and lyrics processing
-
-
-
+
+
+
+
Core Features
+
+
+
+
+
+
+
+
+
+
-
diff --git a/webui/static/script.js b/webui/static/script.js
index 40039ad8..d8db91c8 100644
--- a/webui/static/script.js
+++ b/webui/static/script.js
@@ -4827,9 +4827,19 @@ async function loadSettingsData() {
// Populate Database settings
document.getElementById('max-workers').value = settings.database?.max_workers || '5';
- // Populate Metadata Enhancement settings
+ // Populate Post-Processing settings
document.getElementById('metadata-enabled').checked = settings.metadata_enhancement?.enabled !== false;
document.getElementById('embed-album-art').checked = settings.metadata_enhancement?.embed_album_art !== false;
+ document.getElementById('cover-art-download').checked = settings.metadata_enhancement?.cover_art_download !== false;
+ document.getElementById('lrclib-enabled').checked = settings.metadata_enhancement?.lrclib_enabled !== false;
+ document.getElementById('embed-musicbrainz').checked = settings.musicbrainz?.embed_tags !== false;
+ document.getElementById('embed-deezer').checked = settings.deezer?.embed_tags !== false;
+ document.getElementById('embed-audiodb').checked = settings.audiodb?.embed_tags !== false;
+ document.getElementById('embed-tidal').checked = settings.tidal?.embed_tags !== false;
+ document.getElementById('embed-qobuz').checked = settings.qobuz?.embed_tags !== false;
+ document.getElementById('embed-lastfm').checked = settings.lastfm?.embed_tags !== false;
+ document.getElementById('embed-genius').checked = settings.genius?.embed_tags !== false;
+ document.getElementById('post-processing-options').style.display = settings.metadata_enhancement?.enabled !== false ? 'block' : 'none';
// Populate File Organization settings
document.getElementById('file-organization-enabled').checked = settings.file_organization?.enabled !== false;
@@ -5571,7 +5581,8 @@ async function saveSettings(quiet = false) {
tidal: {
client_id: document.getElementById('tidal-client-id').value,
client_secret: document.getElementById('tidal-client-secret').value,
- redirect_uri: document.getElementById('tidal-redirect-uri').value
+ redirect_uri: document.getElementById('tidal-redirect-uri').value,
+ embed_tags: document.getElementById('embed-tidal').checked
},
plex: {
base_url: document.getElementById('plex-url').value,
@@ -5604,10 +5615,12 @@ async function saveSettings(quiet = false) {
enabled: document.getElementById('acoustid-enabled').checked
},
lastfm: {
- api_key: document.getElementById('lastfm-api-key').value
+ api_key: document.getElementById('lastfm-api-key').value,
+ embed_tags: document.getElementById('embed-lastfm').checked
},
genius: {
- access_token: document.getElementById('genius-access-token').value
+ access_token: document.getElementById('genius-access-token').value,
+ embed_tags: document.getElementById('embed-genius').checked
},
itunes: {
country: document.getElementById('itunes-country').value || 'US'
@@ -5621,14 +5634,26 @@ async function saveSettings(quiet = false) {
quality: document.getElementById('tidal-download-quality').value || 'lossless'
},
qobuz: {
- quality: document.getElementById('qobuz-quality').value || 'lossless'
+ quality: document.getElementById('qobuz-quality').value || 'lossless',
+ embed_tags: document.getElementById('embed-qobuz').checked
},
database: {
max_workers: parseInt(document.getElementById('max-workers').value)
},
metadata_enhancement: {
enabled: document.getElementById('metadata-enabled').checked,
- embed_album_art: document.getElementById('embed-album-art').checked
+ embed_album_art: document.getElementById('embed-album-art').checked,
+ cover_art_download: document.getElementById('cover-art-download').checked,
+ lrclib_enabled: document.getElementById('lrclib-enabled').checked
+ },
+ musicbrainz: {
+ embed_tags: document.getElementById('embed-musicbrainz').checked
+ },
+ deezer: {
+ embed_tags: document.getElementById('embed-deezer').checked
+ },
+ audiodb: {
+ embed_tags: document.getElementById('embed-audiodb').checked
},
file_organization: {
enabled: document.getElementById('file-organization-enabled').checked,
diff --git a/webui/static/style.css b/webui/static/style.css
index edb789e1..0a021cfe 100644
--- a/webui/static/style.css
+++ b/webui/static/style.css
@@ -2067,6 +2067,30 @@ body {
padding: 6px 10px;
}
+/* Post-Processing Settings */
+.post-processing-section {
+ background: rgba(255, 255, 255, 0.02);
+ border: 1px solid rgba(255, 255, 255, 0.06);
+ border-radius: 10px;
+ padding: 14px 16px;
+ margin-bottom: 12px;
+}
+
+.post-processing-section-title {
+ font-size: 11px;
+ font-weight: 600;
+ text-transform: uppercase;
+ letter-spacing: 1.2px;
+ color: rgba(var(--accent-rgb), 0.8);
+ margin-bottom: 10px;
+}
+
+.post-processing-grid {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 4px 16px;
+}
+
/* Read-only Fields */
.readonly-field {
padding: 8px 12px;