Add genre normalization: German/variant genres → canonical Jellyfin names
_GENRE_MAP translates common German genre names (Volksmusik, Schlager, Marschmusik, Klassik …) and English variants (rhythm and blues, swing music …) to consistent Jellyfin-friendly labels. All-upper or all-lower genres without a mapping entry are title-cased. Applied in resolve() before building AlbumProposal. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
b54d83ecb5
commit
8212a918dd
1 changed files with 58 additions and 1 deletions
|
|
@ -33,6 +33,63 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
HAS_ANTHROPIC = False
|
HAS_ANTHROPIC = False
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Genre normalization
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
_GENRE_MAP: Dict[str, str] = {
|
||||||
|
# Deutsch → Englisch (Jellyfin-Standardbegriffe)
|
||||||
|
"volksmusik": "Folk",
|
||||||
|
"volkslieder": "Folk",
|
||||||
|
"volkslied": "Folk",
|
||||||
|
"heimatlieder": "Folk",
|
||||||
|
"schlager": "Schlager",
|
||||||
|
"deutsche schlager": "Schlager",
|
||||||
|
"marsch": "March",
|
||||||
|
"marschmusik": "March",
|
||||||
|
"militaermusik": "March",
|
||||||
|
"militärmusik": "March",
|
||||||
|
"kirchenmusik": "Sacred",
|
||||||
|
"chormusik": "Choral",
|
||||||
|
"kinderlieder": "Children",
|
||||||
|
"weihnachtslieder": "Christmas",
|
||||||
|
"weihnachtsmusik": "Christmas",
|
||||||
|
"blasmusik": "Brass Band",
|
||||||
|
"operette": "Operetta",
|
||||||
|
"oper": "Opera",
|
||||||
|
"kammermusik": "Chamber Music",
|
||||||
|
"klassik": "Classical",
|
||||||
|
"classic": "Classical",
|
||||||
|
"klassische musik": "Classical",
|
||||||
|
"barock": "Baroque",
|
||||||
|
"romantik": "Romantic",
|
||||||
|
# Englische Varianten vereinheitlichen
|
||||||
|
"rhythm and blues": "R&B",
|
||||||
|
"rhythmic soul": "R&B",
|
||||||
|
"rock and roll": "Rock 'n' Roll",
|
||||||
|
"rock & roll": "Rock 'n' Roll",
|
||||||
|
"easy listening": "Easy Listening",
|
||||||
|
"vocal pop": "Pop",
|
||||||
|
"adult contemporary": "Pop",
|
||||||
|
"big band": "Big Band",
|
||||||
|
"swing music": "Swing",
|
||||||
|
"latin jazz": "Latin Jazz",
|
||||||
|
"bossa nova": "Bossa Nova",
|
||||||
|
"nueva cancion": "Nueva Canción",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def normalize_genre(genre: Optional[str]) -> Optional[str]:
|
||||||
|
if not genre:
|
||||||
|
return genre
|
||||||
|
key = genre.strip().lower()
|
||||||
|
normalized = _GENRE_MAP.get(key)
|
||||||
|
if normalized:
|
||||||
|
return normalized
|
||||||
|
# Titlcase wenn nicht in der Map (verhindert ALL CAPS oder all lowercase)
|
||||||
|
return genre.strip().title() if genre == genre.upper() or genre == genre.lower() else genre.strip()
|
||||||
|
|
||||||
|
|
||||||
_MB_RATE_LIMIT = 1.1 # seconds between MusicBrainz requests
|
_MB_RATE_LIMIT = 1.1 # seconds between MusicBrainz requests
|
||||||
_last_mb_call = 0.0
|
_last_mb_call = 0.0
|
||||||
ACOUSTID_API_KEY = os.getenv("ACOUSTID_API_KEY", "")
|
ACOUSTID_API_KEY = os.getenv("ACOUSTID_API_KEY", "")
|
||||||
|
|
@ -505,7 +562,7 @@ def resolve(
|
||||||
album=album,
|
album=album,
|
||||||
albumartist=albumartist,
|
albumartist=albumartist,
|
||||||
date=year,
|
date=year,
|
||||||
genre=genre,
|
genre=normalize_genre(genre),
|
||||||
label=label,
|
label=label,
|
||||||
mbid=release_mbid,
|
mbid=release_mbid,
|
||||||
cover_path=None,
|
cover_path=None,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue