diff --git a/beetsplug/lastgenre/__init__.py b/beetsplug/lastgenre/__init__.py index dacd72f93..8c09eefea 100644 --- a/beetsplug/lastgenre/__init__.py +++ b/beetsplug/lastgenre/__init__.py @@ -22,9 +22,9 @@ The scraper script used is available here: https://gist.github.com/1241307 """ -import codecs import os import traceback +from pathlib import Path from typing import Union import pylast @@ -32,7 +32,7 @@ import yaml from beets import config, library, plugins, ui from beets.library import Album, Item -from beets.util import normpath, plurality, unique_list +from beets.util import plurality, unique_list LASTFM = pylast.LastFMNetwork(api_key=plugins.LASTFM_KEY) @@ -111,39 +111,49 @@ class LastGenrePlugin(plugins.BeetsPlugin): self.import_stages = [self.imported] self._genre_cache = {} + self.whitelist = self._load_whitelist() + self.c14n_branches, self.canonicalize = self._load_c14n_tree() - # Read the whitelist file if enabled. - self.whitelist = set() + def _load_whitelist(self) -> set[str]: + """Load the whitelist from a text file. + + Default whitelist is used if config is True, empty string or set to "nothing". + """ + whitelist = set() wl_filename = self.config["whitelist"].get() - if wl_filename in (True, ""): # Indicates the default whitelist. + if wl_filename in (True, "", None): # Indicates the default whitelist. wl_filename = WHITELIST if wl_filename: - wl_filename = normpath(wl_filename) - with open(wl_filename, "rb") as f: - for line in f: - line = line.decode("utf-8").strip().lower() - if line and not line.startswith("#"): - self.whitelist.add(line) + self._log.debug("Loading whitelist {}", wl_filename) + text = Path(wl_filename).expanduser().read_text(encoding="utf-8") + for line in text.splitlines(): + if (line := line.strip().lower()) and not line.startswith("#"): + whitelist.add(line) - # Read the genres tree for canonicalization if enabled. - self.c14n_branches = [] + return whitelist + + def _load_c14n_tree(self) -> tuple[list[list[str]], bool]: + """Load the canonicalization tree from a YAML file. + + Default tree is used if config is True, empty string, set to "nothing" + or if prefer_specific is enabled. + """ + c14n_branches: list[list[str]] = [] c14n_filename = self.config["canonical"].get() - self.canonicalize = c14n_filename is not False - + canonicalize = c14n_filename is not False # Default tree - if c14n_filename in (True, ""): - c14n_filename = C14N_TREE - elif not self.canonicalize and self.config["prefer_specific"].get(): + if c14n_filename in (True, "", None) or ( # prefer_specific requires a tree, load default tree + not canonicalize and self.config["prefer_specific"].get() + ): c14n_filename = C14N_TREE - # Read the tree if c14n_filename: self._log.debug("Loading canonicalization tree {}", c14n_filename) - c14n_filename = normpath(c14n_filename) - with codecs.open(c14n_filename, "r", encoding="utf-8") as f: + with Path(c14n_filename).expanduser().open(encoding="utf-8") as f: genres_tree = yaml.safe_load(f) - flatten_tree(genres_tree, [], self.c14n_branches) + flatten_tree(genres_tree, [], c14n_branches) + return c14n_branches, canonicalize @property def sources(self) -> tuple[str, ...]: diff --git a/docs/changelog.rst b/docs/changelog.rst index 4b4134cae..6532c5beb 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -131,6 +131,8 @@ Other changes: beets/library directory. - Added a test to check that all plugins can be imported without errors. - :doc:`/guides/main`: Add instructions to install beets on Void Linux. +- :doc:`plugins/lastgenre`: Refactor loading whitelist and canonicalization + file. :bug:`5979` 2.3.1 (May 14, 2025) --------------------