fix: ENOENT file mismatch
This commit is contained in:
@@ -183,6 +183,12 @@ def apply_tags_to_track(track: Track, metadata_dict: Dict[str, Any]) -> None:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
track.tags = metadata_dict
|
track.tags = metadata_dict
|
||||||
|
try:
|
||||||
|
import os
|
||||||
|
path = getattr(track, 'song_path', None)
|
||||||
|
logger.debug(f"Pre-tagging: path={repr(path)}, exists={os.path.exists(path) if path else None}")
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
write_tags(track)
|
write_tags(track)
|
||||||
logger.debug(f"Successfully applied tags to track: {metadata_dict.get('music', 'Unknown')}")
|
logger.debug(f"Successfully applied tags to track: {metadata_dict.get('music', 'Unknown')}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -16,9 +16,40 @@ import requests
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import traceback
|
import traceback
|
||||||
|
import time
|
||||||
|
import unicodedata
|
||||||
|
|
||||||
logger = logging.getLogger("deezspot.taggers")
|
logger = logging.getLogger("deezspot.taggers")
|
||||||
|
|
||||||
|
# Helper: wait for a file to appear on disk (and preferably become non-empty)
|
||||||
|
def _wait_for_file(path: str, timeout: float = 3.0, interval: float = 0.1) -> bool:
|
||||||
|
end_time = time.time() + timeout
|
||||||
|
while time.time() < end_time:
|
||||||
|
try:
|
||||||
|
if os.path.exists(path):
|
||||||
|
try:
|
||||||
|
# Consider file ready if size can be read and > 0
|
||||||
|
if os.path.getsize(path) > 0:
|
||||||
|
return True
|
||||||
|
except OSError:
|
||||||
|
# If stat fails intermittently, but path exists, allow another cycle
|
||||||
|
pass
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
time.sleep(interval)
|
||||||
|
# One last check
|
||||||
|
return os.path.exists(path)
|
||||||
|
|
||||||
|
# Helper: safe directory snapshot for diagnostics
|
||||||
|
def _safe_dir_snapshot(path: str, limit: int = 25):
|
||||||
|
try:
|
||||||
|
dirname = os.path.dirname(path) or "."
|
||||||
|
entries = os.listdir(dirname)
|
||||||
|
return entries[:limit]
|
||||||
|
except Exception as e:
|
||||||
|
return [f"<listdir failed: {e}>"]
|
||||||
|
|
||||||
|
|
||||||
def request(url):
|
def request(url):
|
||||||
response = requests.get(url)
|
response = requests.get(url)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
@@ -182,16 +213,15 @@ def __write_m4a(filepath, data):
|
|||||||
|
|
||||||
# --- Vorbis Comments (FLAC, OGG, OPUS) ---
|
# --- Vorbis Comments (FLAC, OGG, OPUS) ---
|
||||||
def __write_vorbis(filepath, data, audio_format_class):
|
def __write_vorbis(filepath, data, audio_format_class):
|
||||||
|
# Mitigate races with late renames or slow mounts
|
||||||
|
if not _wait_for_file(filepath, timeout=3.0, interval=0.1):
|
||||||
|
logger.error(f"Vorbis tagging aborted: file not found after wait: {filepath}")
|
||||||
|
return
|
||||||
try:
|
try:
|
||||||
tags = audio_format_class(filepath)
|
tags = audio_format_class(filepath)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"Could not open {filepath} for Vorbis tagging ({audio_format_class.__name__}), creating new tags: {e}")
|
logger.warning(f"Could not open {filepath} for Vorbis tagging ({audio_format_class.__name__}): {e}")
|
||||||
try:
|
# Do not attempt to create a new OGG/Opus/FLAC container via mutagen; abort cleanly.
|
||||||
instance = audio_format_class()
|
|
||||||
instance.save(filepath)
|
|
||||||
tags = audio_format_class(filepath)
|
|
||||||
except Exception as e_create:
|
|
||||||
logger.error(f"Failed to create/load {filepath} for Vorbis tagging: {e_create}")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
tags.delete() # Clear existing tags before adding new ones
|
tags.delete() # Clear existing tags before adding new ones
|
||||||
@@ -270,6 +300,23 @@ def write_tags(media):
|
|||||||
logger.warning(f"No metadata (tags) found for {filepath}. Skipping tagging.")
|
logger.warning(f"No metadata (tags) found for {filepath}. Skipping tagging.")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Diagnostics: probe existence and normalization
|
||||||
|
try:
|
||||||
|
dirname = os.path.dirname(filepath)
|
||||||
|
basename = os.path.basename(filepath)
|
||||||
|
nfc = unicodedata.normalize('NFC', basename)
|
||||||
|
nfkc = unicodedata.normalize('NFKC', basename)
|
||||||
|
logger.debug(f"Tagging probe: path={repr(filepath)}, exists={os.path.exists(filepath)}, dir={repr(dirname)}")
|
||||||
|
logger.debug(f"Tagging probe: basename={repr(basename)}, NFC==basename? {nfc==basename}, NFKC==basename? {nfkc==basename}")
|
||||||
|
logger.debug(f"Directory sample: {_safe_dir_snapshot(filepath, limit=25)}")
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# If the file isn't visible yet, wait briefly to avoid races
|
||||||
|
if not _wait_for_file(filepath, timeout=3.0, interval=0.1):
|
||||||
|
logger.error(f"write_tags: File not found after wait, skipping tagging: {filepath}")
|
||||||
|
return
|
||||||
|
|
||||||
file_ext = getattr(media, 'file_format', None)
|
file_ext = getattr(media, 'file_format', None)
|
||||||
if not file_ext:
|
if not file_ext:
|
||||||
logger.warning(f"File format not specified in media object for {filepath}. Attempting to guess from filepath.")
|
logger.warning(f"File format not specified in media object for {filepath}. Attempting to guess from filepath.")
|
||||||
|
|||||||
Reference in New Issue
Block a user