Refactor _get_genre, simplify _combine_genre

This commit is contained in:
J0J0 Todos 2025-01-13 22:37:01 +01:00
parent 4580757c8e
commit ed68bc019b

View file

@ -333,34 +333,14 @@ class LastGenrePlugin(plugins.BeetsPlugin):
) )
return unique_list([g.lower() for g in genres]) return unique_list([g.lower() for g in genres])
def _combine_and_label_genres( def _combine_genres(self, old: list[str], new: list[str]) -> str | None:
self, new_genres: list, keep_genres: list, log_label: str """Combine old and new genres."""
) -> tuple: self._log.debug(f"fetched last.fm tags: {new}")
"""Combines genres and returns them with a logging label. combined = old + new
Parameters:
new_genres (list): The new genre result to process.
keep_genres (list): Existing genres to combine with new ones
log_label (str): A label (like "track", "album") we possibly
combine with a prefix. For example resulting in something like
"keep + track" or just "track".
Returns:
tuple: A tuple containing the combined genre string and the
'logging label'.
"""
self._log.debug(f"fetched last.fm tags: {new_genres}")
combined = keep_genres + new_genres
resolved = self._resolve_genres(combined) resolved = self._resolve_genres(combined)
reduced = self._to_delimited_genre_string(resolved) return self._to_delimited_genre_string(resolved) or None
if new_genres and keep_genres: def _get_genre(self, obj) -> str | None:
return reduced, f"keep + {log_label}"
if new_genres:
return reduced, log_label
return None, log_label
def _get_genre(self, obj):
"""Get the final genre string for an Album or Item object """Get the final genre string for an Album or Item object
`self.sources` specifies allowed genre sources, prioritized as follows: `self.sources` specifies allowed genre sources, prioritized as follows:
@ -387,41 +367,37 @@ class LastGenrePlugin(plugins.BeetsPlugin):
genres = self._get_existing_genres(obj, separator) genres = self._get_existing_genres(obj, separator)
if genres and not self.config["force"]: if genres and not self.config["force"]:
# Without force we don't touch pre-populated tags and return early # Without force pre-populated tags are deduplicated and returned.
# with the original contents. We deduplicate and format back to
# string though.
keep_genres = self._dedup_genres(genres) keep_genres = self._dedup_genres(genres)
return separator.join(keep_genres), "keep" return separator.join(keep_genres), "keep"
if self.config["force"]: if self.config["force"]:
# Simply forcing doesn't keep any. # Force doesn't keep any unless keep_existing is set.
# Whitelist validation is handled in _resolve_genres.
keep_genres = [] keep_genres = []
# Remember existing genres if required. Whitelist validation is
# handled later in _resolve_genres.
if self.config["keep_existing"]: if self.config["keep_existing"]:
keep_genres = [g.lower() for g in genres] keep_genres = [g.lower() for g in genres]
# Track genre (for Items only). # Run through stages: track, album, artist,
if isinstance(obj, library.Item) and "track" in self.sources: # album artist, or most popular track genre.
if new_genres := self.fetch_track_genre(obj): if (
return self._combine_and_label_genres( isinstance(obj, library.Item)
new_genres, keep_genres, "track" and "track" in self.sources
) and (new_genres := self.fetch_track_genre(obj))
):
# Album genre. label = "track"
if "album" in self.sources: elif "album" in self.sources and (
if new_genres := self.fetch_album_genre(obj): new_genres := self.fetch_album_genre(obj)
return self._combine_and_label_genres( ):
new_genres, keep_genres, "album" label = "album"
) elif "artist" in self.sources:
# Artist (or album artist) genre.
if "artist" in self.sources:
new_genres = None new_genres = None
if isinstance(obj, library.Item): if isinstance(obj, library.Item):
new_genres = self.fetch_artist_genre(obj) new_genres = self.fetch_artist_genre(obj)
label = "artist"
elif obj.albumartist != config["va_name"].as_str(): elif obj.albumartist != config["va_name"].as_str():
new_genres = self.fetch_album_artist_genre(obj) new_genres = self.fetch_album_artist_genre(obj)
label = "album artist"
else: else:
# For "Various Artists", pick the most popular track genre. # For "Various Artists", pick the most popular track genre.
item_genres = [] item_genres = []
@ -436,26 +412,28 @@ class LastGenrePlugin(plugins.BeetsPlugin):
if item_genres: if item_genres:
most_popular, rank = plurality(item_genres) most_popular, rank = plurality(item_genres)
new_genres = [most_popular] new_genres = [most_popular]
label = "most popular track"
self._log.debug( self._log.debug(
'Most popular track genre "{}" ({}) for VA album.', 'Most popular track genre "{}" ({}) for VA album.',
most_popular, most_popular,
rank, rank,
) )
if new_genres: # Return with a combined or freshly fetched genre list.
return self._combine_and_label_genres( if new_genres:
new_genres, keep_genres, "artist" if keep_genres:
) label = f"keep + {label}"
return self._combine_genres(keep_genres, new_genres), label
# Didn't find anything, leave original # Nothing found, leave original.
if obj.genre: if obj.genre:
return obj.genre, "original fallback" return obj.genre, "original fallback"
# No original, return fallback string # No original, return fallback string.
if fallback := self.config["fallback"].get(): if fallback := self.config["fallback"].get():
return fallback, "fallback" return fallback, "fallback"
# No fallback configured # No fallback configured.
return None, None return None, None
# Beets plugin hooks and CLI. # Beets plugin hooks and CLI.