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
+
+ +
+
+ +
+
+ +
+
-
- -
MP3, FLAC, MP4/M4A, OGG
+ +
+
Metadata Services
+ Choose which services embed IDs, genres, and metadata into your files during download + +
+ + + + + + + +
+
+ +
+ +
MP3, FLAC, MP4/M4A, OGG
+
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;