diff --git a/executor.py b/executor.py index 077c3e6..f13c808 100644 --- a/executor.py +++ b/executor.py @@ -73,7 +73,10 @@ def write_tags(path: Path, proposal: TrackProposal, album_proposal: AlbumProposa if proposal.disc_number: tags_to_write["discnumber"] = str(proposal.disc_number) if album_proposal.date: - tags_to_write["date"] = album_proposal.date + # Strip everything except valid ID3 timestamp characters to prevent ID3TimeStamp errors + date_clean = re.sub(r"[^\d\-T:+Z]", "", str(album_proposal.date)).strip() + if date_clean: + tags_to_write["date"] = date_clean if album_proposal.genre: tags_to_write["genre"] = album_proposal.genre if album_proposal.label: @@ -84,11 +87,22 @@ def write_tags(path: Path, proposal: TrackProposal, album_proposal: AlbumProposa try: audio = EasyID3(str(path)) except Exception: - audio = EasyID3() - audio.save(str(path)) + # File has no ID3 header — add one without wiping audio data + from mutagen.id3 import ID3NoHeaderError + try: + from mutagen.mp3 import MP3 + full = MP3(str(path)) + full.tags = None + full.add_tags() + full.save(str(path), v2_version=4) + except Exception: + pass audio = EasyID3(str(path)) for k, v in tags_to_write.items(): - audio[k] = [v] + try: + audio[k] = [v] + except Exception as tag_err: + print(f" ⚠️ Tag-Feld '{k}' übersprungen ({path.name}): {tag_err}", file=sys.stderr) audio.save(v2_version=4) return True diff --git a/metadata_resolver.py b/metadata_resolver.py index 2fd8eb5..56a8ccc 100644 --- a/metadata_resolver.py +++ b/metadata_resolver.py @@ -337,8 +337,12 @@ def resolve( album = album or Counter(tag_albums).most_common(1)[0][0] # Tag year/genre/label + import re as _re for t in hints.tracks: - year = year or t.existing_tags.get("date") or t.existing_tags.get("year") + raw_year = t.existing_tags.get("date") or t.existing_tags.get("year") + if raw_year and not year: + # Strip invisible chars so ID3TimeStamp validation doesn't fail later + year = _re.sub(r"[^\d\-T:+Z]", "", str(raw_year)).strip()[:10] or None genre = genre or t.existing_tags.get("genre") label = label or t.existing_tags.get("label") or t.existing_tags.get("organization")