52 lines
2.1 KiB
Python
52 lines
2.1 KiB
Python
"""Opt-in "parent folder artist" resolution for imports.
|
|
|
|
Historically the auto-import worker derived the artist from the top Staging
|
|
folder whenever the path had >=2 levels and that folder wasn't a category word
|
|
(albums/singles/eps/...). It did so *unconditionally*, overriding even a
|
|
confidently metadata-identified artist — which mass-mislabelled files when a
|
|
user staged everything under one container folder (see the "soulsync" incident).
|
|
|
|
This module isolates that decision as a pure function so it can be:
|
|
- gated behind an opt-in setting (``import.folder_artist_override``,
|
|
default on for legacy compatibility), and
|
|
- unit-tested without standing up the whole import worker.
|
|
"""
|
|
|
|
import os
|
|
|
|
# Top-level folder names that denote a *category*, not an artist.
|
|
DEFAULT_CATEGORY_NAMES = frozenset({
|
|
'albums', 'singles', 'eps', 'compilations', 'mixtapes',
|
|
'discography', 'music', 'downloads',
|
|
})
|
|
|
|
|
|
def resolve_folder_artist(rel_path, identified_artist, enabled,
|
|
category_names=DEFAULT_CATEGORY_NAMES):
|
|
"""Return the folder-derived artist to use, or ``None`` to keep the
|
|
already-identified artist.
|
|
|
|
When ``enabled`` is False this always returns ``None`` — the import keeps
|
|
whatever artist the metadata match produced. Only when explicitly enabled
|
|
does it fall back to the staging folder name, and even then never when the
|
|
folder already equals the identified artist.
|
|
|
|
``rel_path`` is the candidate's path relative to the staging root.
|
|
"""
|
|
if not enabled:
|
|
return None
|
|
|
|
parts = [p for p in rel_path.replace('\\', '/').split('/') if p]
|
|
|
|
folder_artist = None
|
|
if len(parts) >= 2:
|
|
if len(parts) >= 3 and parts[1].lower() in category_names:
|
|
# Artist/Albums/AlbumFolder -> parts[0] is the artist
|
|
folder_artist = parts[0]
|
|
elif parts[0].lower() not in category_names:
|
|
# Artist/AlbumFolder -> parts[0] is the artist
|
|
folder_artist = parts[0]
|
|
|
|
if folder_artist and folder_artist.lower() != (identified_artist or '').lower():
|
|
return folder_artist
|
|
return None
|