From 591e04a8949e1e411ec2c3ebcb3a95ea0159b7a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0ar=C5=ABnas=20Nejus?= Date: Fri, 16 Aug 2024 08:34:24 +0100 Subject: [PATCH] Add Item.filepath property to simplify path handling Additionally, fix DefaultTemplateFunctions._func_names definition. --- beets/library.py | 23 +++++++++++++---------- beetsplug/autobpm.py | 32 +++++++------------------------- 2 files changed, 20 insertions(+), 35 deletions(-) diff --git a/beets/library.py b/beets/library.py index 6d0ee613b..84f6a7bf0 100644 --- a/beets/library.py +++ b/beets/library.py @@ -12,8 +12,8 @@ # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. -"""The core data store and collection logic for beets. -""" +"""The core data store and collection logic for beets.""" + from __future__ import annotations import os @@ -24,6 +24,7 @@ import sys import time import unicodedata from functools import cached_property +from pathlib import Path from mediafile import MediaFile, UnreadableFileError @@ -658,6 +659,11 @@ class Item(LibModel): f"ON {cls._table}.album_id = {cls._relation._table}.id" ) + @property + def filepath(self) -> Path | None: + """The path to the item's file as pathlib.Path.""" + return Path(os.fsdecode(self.path)) if self.path else self.path + @property def _cached_album(self): """The Album object that this item belongs to, if any, or @@ -1741,6 +1747,11 @@ class DefaultTemplateFunctions: _prefix = "tmpl_" + @cached_classproperty + def _func_names(cls) -> list[str]: + """Names of tmpl_* functions in this class.""" + return [s for s in dir(cls) if s.startswith(cls._prefix)] + def __init__(self, item=None, lib=None): """Parametrize the functions. @@ -2038,11 +2049,3 @@ class DefaultTemplateFunctions: return trueval if trueval else self.item.formatted().get(field) else: return falseval - - -# Get the name of tmpl_* functions in the above class. -DefaultTemplateFunctions._func_names = [ - s - for s in dir(DefaultTemplateFunctions) - if s.startswith(DefaultTemplateFunctions._prefix) -] diff --git a/beetsplug/autobpm.py b/beetsplug/autobpm.py index cfe11e39e..0262f03c2 100644 --- a/beetsplug/autobpm.py +++ b/beetsplug/autobpm.py @@ -19,7 +19,6 @@ from typing import Iterable import librosa -from beets import util from beets.importer import ImportTask from beets.library import Item, Library from beets.plugins import BeetsPlugin @@ -55,45 +54,28 @@ class AutoBPMPlugin(BeetsPlugin): def calculate_bpm(self, items: list[Item], write: bool = False) -> None: for item in items: - if item["bpm"]: - self._log.info( - "found bpm {0} for {1}", - item["bpm"], - util.displayable_path(item.path), - ) + path = item.filepath + if bpm := item.bpm: + self._log.info("BPM for {} already exists: {}", path, bpm) if not self.config["overwrite"]: continue try: - y, sr = librosa.load( - util.syspath(item.path), res_type="kaiser_fast" - ) + y, sr = librosa.load(item.filepath, res_type="kaiser_fast") except Exception as exc: - self._log.error( - "Failed to load {0}: {1}", - util.displayable_path(item.path), - exc, - ) + self._log.error("Failed to load {}: {}", path, exc) continue kwargs = self.config["beat_track_kwargs"].flatten() try: tempo, _ = librosa.beat.beat_track(y=y, sr=sr, **kwargs) except Exception as exc: - self._log.error( - "Failed to measure BPM for {0}: {1}", - util.displayable_path(item.path), - exc, - ) + self._log.error("Failed to measure BPM for {}: {}", path, exc) continue bpm = round(tempo[0] if isinstance(tempo, Iterable) else tempo) item["bpm"] = bpm - self._log.info( - "added computed bpm {0} for {1}", - bpm, - util.displayable_path(item.path), - ) + self._log.info("Computed BPM for {}: {}", path, bpm) if write: item.try_write()