Move shared metadata helpers into package
- Relocate the shared metadata helper module from core/metadata_common.py into core/metadata/common.py. - Update the new metadata package, the import pipeline, and the web entrypoint to use the package-scoped helper. - Keep the shared config, mutagen, file-lock, and tag-writing helpers centralized without touching unrelated files.
This commit is contained in:
parent
9656dbd46a
commit
9e496397da
7 changed files with 45 additions and 39 deletions
|
|
@ -52,7 +52,7 @@ from core.runtime_state import (
|
|||
tasks_lock,
|
||||
)
|
||||
from core.metadata.artwork import download_cover_art
|
||||
from core.metadata_common import wipe_source_tags
|
||||
from core.metadata.common import wipe_source_tags
|
||||
from core.metadata.enrichment import enhance_file_metadata
|
||||
from core.imports.paths import (
|
||||
build_final_path_for_track,
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@ import re
|
|||
import urllib.request
|
||||
|
||||
from core.imports.context import get_import_context_album
|
||||
from core.metadata_common import (
|
||||
from core.metadata.common import (
|
||||
get_config_manager,
|
||||
get_image_dimensions,
|
||||
get_logger,
|
||||
get_mutagen_symbols,
|
||||
)
|
||||
from utils.logging_config import get_logger as _create_logger
|
||||
|
||||
__all__ = [
|
||||
"embed_album_art_metadata",
|
||||
|
|
@ -20,9 +20,11 @@ __all__ = [
|
|||
]
|
||||
|
||||
|
||||
logger = _create_logger("metadata.artwork")
|
||||
|
||||
|
||||
def embed_album_art_metadata(audio_file, metadata: dict):
|
||||
cfg = get_config_manager()
|
||||
logger_ = get_logger()
|
||||
symbols = get_mutagen_symbols()
|
||||
if not symbols:
|
||||
return
|
||||
|
|
@ -47,14 +49,14 @@ def embed_album_art_metadata(audio_file, metadata: dict):
|
|||
if not image_data:
|
||||
art_url = metadata.get("album_art_url")
|
||||
if not art_url:
|
||||
logger_.warning("No album art URL available for embedding.")
|
||||
logger.warning("No album art URL available for embedding.")
|
||||
return
|
||||
with urllib.request.urlopen(art_url, timeout=10) as response:
|
||||
image_data = response.read()
|
||||
mime_type = response.info().get_content_type() or "image/jpeg"
|
||||
|
||||
if not image_data:
|
||||
logger_.error("Failed to download album art data.")
|
||||
logger.error("Failed to download album art data.")
|
||||
return
|
||||
|
||||
if isinstance(audio_file.tags, symbols.ID3):
|
||||
|
|
@ -73,14 +75,13 @@ def embed_album_art_metadata(audio_file, metadata: dict):
|
|||
fmt = symbols.MP4Cover.FORMAT_JPEG if "jpeg" in mime_type else symbols.MP4Cover.FORMAT_PNG
|
||||
audio_file["covr"] = [symbols.MP4Cover(image_data, imageformat=fmt)]
|
||||
|
||||
logger_.info("Album art successfully embedded.")
|
||||
logger.info("Album art successfully embedded.")
|
||||
except Exception as exc:
|
||||
logger_.error("Error embedding album art: %s", exc)
|
||||
logger.error("Error embedding album art: %s", exc)
|
||||
|
||||
|
||||
def download_cover_art(album_info: dict, target_dir: str, context: dict = None):
|
||||
cfg = get_config_manager()
|
||||
logger_ = get_logger()
|
||||
if cfg.get("metadata_enhancement.cover_art_download", True) is False:
|
||||
return
|
||||
|
||||
|
|
@ -117,7 +118,7 @@ def download_cover_art(album_info: dict, target_dir: str, context: dict = None):
|
|||
image_data = None
|
||||
|
||||
if is_upgrade and not image_data:
|
||||
logger_.error("CAA upgrade failed - keeping existing cover.jpg")
|
||||
logger.error("CAA upgrade failed - keeping existing cover.jpg")
|
||||
return
|
||||
|
||||
if not image_data:
|
||||
|
|
@ -130,7 +131,7 @@ def download_cover_art(album_info: dict, target_dir: str, context: dict = None):
|
|||
if images and isinstance(images[0], dict):
|
||||
art_url = images[0].get("url", "")
|
||||
if art_url:
|
||||
logger_.info("Using cover art URL from album context")
|
||||
logger.info("Using cover art URL from album context")
|
||||
if art_url and "i.scdn.co" in art_url:
|
||||
try:
|
||||
from core.spotify_client import _upgrade_spotify_image_url
|
||||
|
|
@ -141,7 +142,7 @@ def download_cover_art(album_info: dict, target_dir: str, context: dict = None):
|
|||
elif art_url and "mzstatic.com" in art_url:
|
||||
art_url = re.sub(r"\d+x\d+bb", "3000x3000bb", art_url)
|
||||
if not art_url:
|
||||
logger_.warning("No cover art URL available for download.")
|
||||
logger.warning("No cover art URL available for download.")
|
||||
return
|
||||
with urllib.request.urlopen(art_url, timeout=10) as response:
|
||||
image_data = response.read()
|
||||
|
|
@ -151,6 +152,6 @@ def download_cover_art(album_info: dict, target_dir: str, context: dict = None):
|
|||
|
||||
with open(cover_path, "wb") as handle:
|
||||
handle.write(image_data)
|
||||
logger_.info("Cover art downloaded to: %s", cover_path)
|
||||
logger.info("Cover art downloaded to: %s", cover_path)
|
||||
except Exception as exc:
|
||||
logger_.error("Error downloading cover.jpg: %s", exc)
|
||||
logger.error("Error downloading cover.jpg: %s", exc)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ from typing import Any, Dict
|
|||
from utils.logging_config import get_logger as _create_logger
|
||||
|
||||
|
||||
logger = _create_logger("metadata_common")
|
||||
logger = _create_logger("metadata.common")
|
||||
|
||||
__all__ = [
|
||||
"get_logger",
|
||||
|
|
@ -5,10 +5,9 @@ from __future__ import annotations
|
|||
import os
|
||||
|
||||
from core.metadata.artwork import embed_album_art_metadata
|
||||
from core.metadata_common import (
|
||||
from core.metadata.common import (
|
||||
get_config_manager,
|
||||
get_file_lock,
|
||||
get_logger,
|
||||
get_mutagen_symbols,
|
||||
is_vorbis_like,
|
||||
save_audio_file,
|
||||
|
|
@ -16,6 +15,7 @@ from core.metadata_common import (
|
|||
verify_metadata_written,
|
||||
)
|
||||
from core.metadata.source import embed_source_ids, extract_source_metadata
|
||||
from utils.logging_config import get_logger as _create_logger
|
||||
|
||||
|
||||
__all__ = [
|
||||
|
|
@ -25,11 +25,13 @@ __all__ = [
|
|||
]
|
||||
|
||||
|
||||
logger = _create_logger("metadata.enrichment")
|
||||
|
||||
|
||||
def enhance_file_metadata(file_path: str, context: dict, artist: dict, album_info: dict, runtime=None) -> bool:
|
||||
cfg = get_config_manager()
|
||||
logger_ = get_logger()
|
||||
if cfg.get("metadata_enhancement.enabled", True) is False:
|
||||
logger_.warning("Metadata enhancement disabled in config.")
|
||||
logger.warning("Metadata enhancement disabled in config.")
|
||||
return True
|
||||
|
||||
if album_info is None:
|
||||
|
|
@ -37,17 +39,17 @@ def enhance_file_metadata(file_path: str, context: dict, artist: dict, album_inf
|
|||
|
||||
symbols = get_mutagen_symbols()
|
||||
if not symbols:
|
||||
logger_.error("Mutagen is unavailable, cannot enhance metadata.")
|
||||
logger.error("Mutagen is unavailable, cannot enhance metadata.")
|
||||
return False
|
||||
|
||||
file_lock = get_file_lock(file_path)
|
||||
with file_lock:
|
||||
logger_.info("Enhancing metadata for: %s", os.path.basename(file_path))
|
||||
logger.info("Enhancing metadata for: %s", os.path.basename(file_path))
|
||||
try:
|
||||
strip_all_non_audio_tags(file_path)
|
||||
audio_file = symbols.File(file_path)
|
||||
if audio_file is None:
|
||||
logger_.error("Could not load audio file with Mutagen: %s", file_path)
|
||||
logger.error("Could not load audio file with Mutagen: %s", file_path)
|
||||
return False
|
||||
|
||||
if hasattr(audio_file, "clear_pictures"):
|
||||
|
|
@ -56,7 +58,7 @@ def enhance_file_metadata(file_path: str, context: dict, artist: dict, album_inf
|
|||
if audio_file.tags is not None:
|
||||
if len(audio_file.tags) > 0:
|
||||
tag_keys = list(audio_file.tags.keys())[:15]
|
||||
logger_.info("Clearing %s existing tags: %s", len(audio_file.tags), ", ".join(str(k) for k in tag_keys))
|
||||
logger.info("Clearing %s existing tags: %s", len(audio_file.tags), ", ".join(str(k) for k in tag_keys))
|
||||
audio_file.tags.clear()
|
||||
else:
|
||||
audio_file.add_tags()
|
||||
|
|
@ -65,7 +67,7 @@ def enhance_file_metadata(file_path: str, context: dict, artist: dict, album_inf
|
|||
|
||||
metadata = extract_source_metadata(context, artist, album_info)
|
||||
if not metadata:
|
||||
logger_.error("Could not extract source metadata, saving with cleared tags.")
|
||||
logger.error("Could not extract source metadata, saving with cleared tags.")
|
||||
save_audio_file(audio_file, symbols)
|
||||
return True
|
||||
|
||||
|
|
@ -147,17 +149,17 @@ def enhance_file_metadata(file_path: str, context: dict, artist: dict, album_inf
|
|||
|
||||
verified = verify_metadata_written(file_path)
|
||||
if verified:
|
||||
logger_.info("Metadata enhanced successfully.")
|
||||
logger.info("Metadata enhanced successfully.")
|
||||
else:
|
||||
logger_.info("Metadata saved but verification found issues (see above).")
|
||||
logger.info("Metadata saved but verification found issues (see above).")
|
||||
return True
|
||||
except Exception as exc:
|
||||
import traceback
|
||||
|
||||
logger_.error("Error enhancing metadata for %s: %s", file_path, exc)
|
||||
logger_.error("[Metadata Debug] Exception type: %s", type(exc).__name__)
|
||||
logger_.info("[Metadata Debug] File exists: %s", os.path.exists(file_path))
|
||||
logger_.warning("[Metadata Debug] Artist: %s", artist.get("name", "MISSING") if artist else "None")
|
||||
logger_.warning("[Metadata Debug] Album info: %s", album_info.get("album_name", "MISSING") if album_info else "None")
|
||||
logger_.error("[Metadata Debug] Traceback:\n%s", traceback.format_exc())
|
||||
logger.error("Error enhancing metadata for %s: %s", file_path, exc)
|
||||
logger.error("[Metadata Debug] Exception type: %s", type(exc).__name__)
|
||||
logger.info("[Metadata Debug] File exists: %s", os.path.exists(file_path))
|
||||
logger.warning("[Metadata Debug] Artist: %s", artist.get("name", "MISSING") if artist else "None")
|
||||
logger.warning("[Metadata Debug] Album info: %s", album_info.get("album_name", "MISSING") if album_info else "None")
|
||||
logger.error("[Metadata Debug] Traceback:\n%s", traceback.format_exc())
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -9,16 +9,19 @@ from core.imports.context import (
|
|||
get_import_original_search,
|
||||
normalize_import_context,
|
||||
)
|
||||
from core.metadata_common import get_config_manager, get_logger
|
||||
from core.metadata.common import get_config_manager
|
||||
from utils.logging_config import get_logger as _create_logger
|
||||
|
||||
__all__ = [
|
||||
"generate_lrc_file",
|
||||
]
|
||||
|
||||
|
||||
logger = _create_logger("metadata.lyrics")
|
||||
|
||||
|
||||
def generate_lrc_file(file_path: str, context: dict, artist: dict, album_info: dict) -> bool:
|
||||
cfg = get_config_manager()
|
||||
logger_ = get_logger()
|
||||
if cfg.get("metadata_enhancement.lrclib_enabled", True) is False:
|
||||
return False
|
||||
|
||||
|
|
@ -58,10 +61,10 @@ def generate_lrc_file(file_path: str, context: dict, artist: dict, album_info: d
|
|||
)
|
||||
|
||||
if success:
|
||||
logger_.info("LRC file generated for: %s", track_name)
|
||||
logger.info("LRC file generated for: %s", track_name)
|
||||
else:
|
||||
logger_.warning("No lyrics found for: %s", track_name)
|
||||
logger.warning("No lyrics found for: %s", track_name)
|
||||
return success
|
||||
except Exception as exc:
|
||||
logger_.error("Error generating LRC file for %s: %s", file_path, exc)
|
||||
logger.error("Error generating LRC file for %s: %s", file_path, exc)
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ from core.imports.context import (
|
|||
)
|
||||
from core.metadata_service import get_itunes_client
|
||||
from database.music_database import get_database
|
||||
from core.metadata_common import (
|
||||
from core.metadata.common import (
|
||||
get_config_manager,
|
||||
get_mutagen_symbols,
|
||||
is_vorbis_like,
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ from core.imports.staging import (
|
|||
start_import_suggestions_cache,
|
||||
)
|
||||
from core.imports.paths import build_final_path_for_track as _build_final_path_for_track
|
||||
from core.metadata_common import get_file_lock
|
||||
from core.metadata.common import get_file_lock
|
||||
from core.metadata.source import (
|
||||
mb_release_cache,
|
||||
mb_release_cache_lock,
|
||||
|
|
|
|||
Loading…
Reference in a new issue