Skip to content

Commit 1c99cf1

Browse files
committed
feat(lastgenre): canonicalize_existing
Introduce a new lastgenre `canonicalize_existing` flag. It handles the case where canonicalization is desired on existing tags. The new logic triggers if: - `force`: False - `whitelist`: True - `canonical`: True - `canonicalize_existing: True
1 parent ef59cfa commit 1c99cf1

File tree

4 files changed

+49
-0
lines changed

4 files changed

+49
-0
lines changed

beetsplug/lastgenre/__init__.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ def __init__(self) -> None:
106106
"count": 1,
107107
"fallback": None,
108108
"canonical": False,
109+
"canonicalize_existing": False,
109110
"source": "album",
110111
"force": False,
111112
"keep_existing": False,
@@ -399,6 +400,24 @@ def _try_resolve_stage(
399400
genres = self._get_existing_genres(obj)
400401

401402
if genres and not self.config["force"]:
403+
# Without force and whitelisting + canonicalize_existing, we attempt
404+
# to canonicalize pre-populated tags before returning them.
405+
# If none are found, we use the fallback.
406+
if (
407+
self.config["whitelist"]
408+
and self.config["canonical"]
409+
and self.config["canonicalize_existing"]
410+
):
411+
keep_genres = [g.lower() for g in genres]
412+
if result := _try_resolve_stage("original", keep_genres, []):
413+
return result
414+
elif fallback := self.config["fallback"].get():
415+
# Return fallback string.
416+
return fallback, "fallback"
417+
else:
418+
# No fallback configured.
419+
return None, "fallback unconfigured"
420+
402421
# Without force pre-populated tags are returned as-is.
403422
label = "keep any, no-force"
404423
if isinstance(obj, library.Item):

docs/changelog.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ been dropped.
1212

1313
New features:
1414

15+
- :doc:`plugins/lastgenre`: Added ``canonicalize_existing`` configuration flag
16+
to allow whitelist canonicalization of existing genres.
1517
- :doc:`plugins/fetchart`: Added config setting for a fallback cover art image.
1618
- :doc:`plugins/ftintitle`: Added argument for custom feat. words in ftintitle.
1719
- :doc:`plugins/ftintitle`: Added album template value ``album_artist_no_feat``.

docs/plugins/lastgenre.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,11 @@ file. The available options are:
171171
- **canonical**: Use a canonicalization tree. Setting this to ``yes`` will use a
172172
built-in tree. You can also set it to a path, like the ``whitelist`` config
173173
value, to use your own tree. Default: ``no`` (disabled).
174+
- **canonicalize_existing**: This option only takes effect with ``force: no``,
175+
``canonical: yes`` and ``whitelist: yes``.
176+
Setting this to ``yes`` will result in attempted canonicalization of existing
177+
genres. If this fails, the ``fallback`` is used isntead.
178+
Default: ``no`` (disabled).
174179
- **count**: Number of genres to fetch. Default: 1
175180
- **fallback**: A string to use as a fallback genre when no genre is found
176181
``or`` the original genre is not desired to be kept (``keep_existing: no``).

test/plugins/test_lastgenre.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,29 @@ def test_sort_by_depth(self):
302302
},
303303
("Jazzin", "album, any"),
304304
),
305+
# 5.1 - Canonicalize original genre when force is **off** and
306+
# whitelist, canonical and canonicalize_existing are on.
307+
# "Cosmic Disco" is not in the default whitelist, thus gets resolved "up" in the
308+
# tree to "Disco" and "Electronic".
309+
(
310+
{
311+
"force": False,
312+
"keep_existing": False,
313+
"source": "artist",
314+
"whitelist": True,
315+
"canonical": True,
316+
"canonicalize_existing": True,
317+
"prefer_specific": False,
318+
},
319+
"Cosmic Disco",
320+
{
321+
"artist": [],
322+
},
323+
(
324+
"Disco, Electronic",
325+
"keep + original, whitelist",
326+
),
327+
),
305328
# 6 - fallback to next stages until found
306329
(
307330
{

0 commit comments

Comments
 (0)