Add Item.filepath property to simplify path handling

Additionally, fix DefaultTemplateFunctions._func_names definition.
This commit is contained in:
Šarūnas Nejus 2024-08-16 08:34:24 +01:00
parent 8f02020db4
commit 591e04a894
No known key found for this signature in database
GPG key ID: DD28F6704DBE3435
2 changed files with 20 additions and 35 deletions

View file

@ -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)
]

View file

@ -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()