Do not use explicit indices for logging args when not needed

This commit is contained in:
Šarūnas Nejus 2025-08-02 12:33:13 +01:00
parent 2fccf64efe
commit d93ddf8dd4
No known key found for this signature in database
GPG key ID: DD28F6704DBE3435
56 changed files with 297 additions and 305 deletions

View file

@ -261,7 +261,7 @@ There are a few coding conventions we use in beets:
- The loggers use `str.format
<http://docs.python.org/library/stdtypes.html#str.format>`__-style logging
instead of ``%``-style, so you can type ``log.debug("{0}", obj)`` to do your
instead of ``%``-style, so you can type ``log.debug("{}", obj)`` to do your
formatting.
- Exception handlers must use ``except A as B:`` instead of ``except A, B:``.

View file

@ -39,7 +39,7 @@ def get_art(log, item):
mf = mediafile.MediaFile(syspath(item.path))
except mediafile.UnreadableFileError as exc:
log.warning(
"Could not extract art from {0}: {1}",
"Could not extract art from {}: {}",
displayable_path(item.path),
exc,
)
@ -83,10 +83,10 @@ def embed_item(
# Get the `Image` object from the file.
try:
log.debug("embedding {0}", displayable_path(imagepath))
log.debug("embedding {}", displayable_path(imagepath))
image = mediafile_image(imagepath, maxwidth)
except OSError as exc:
log.warning("could not read image file: {0}", exc)
log.warning("could not read image file: {}", exc)
return
# Make sure the image kind is safe (some formats only support PNG
@ -110,11 +110,11 @@ def embed_album(
"""Embed album art into all of the album's items."""
imagepath = album.artpath
if not imagepath:
log.info("No album art present for {0}", album)
log.info("No album art present for {}", album)
return
if not os.path.isfile(syspath(imagepath)):
log.info(
"Album art not found at {0} for {1}",
"Album art not found at {} for {}",
displayable_path(imagepath),
album,
)
@ -122,7 +122,7 @@ def embed_album(
if maxwidth:
imagepath = resize_image(log, imagepath, maxwidth, quality)
log.info("Embedding album art into {0}", album)
log.info("Embedding album art into {}", album)
for item in album.items():
embed_item(
@ -143,7 +143,7 @@ def resize_image(log, imagepath, maxwidth, quality):
specified quality level.
"""
log.debug(
"Resizing album art to {0} pixels wide and encoding at quality level {1}",
"Resizing album art to {} pixels wide and encoding at quality level {}",
maxwidth,
quality,
)
@ -183,18 +183,18 @@ def extract(log, outpath, item):
art = get_art(log, item)
outpath = bytestring_path(outpath)
if not art:
log.info("No album art present in {0}, skipping.", item)
log.info("No album art present in {}, skipping.", item)
return
# Add an extension to the filename.
ext = mediafile.image_extension(art)
if not ext:
log.warning("Unknown image type in {0}.", displayable_path(item.path))
log.warning("Unknown image type in {}.", displayable_path(item.path))
return
outpath += bytestring_path(f".{ext}")
log.info(
"Extracting album art from: {0} to: {1}",
"Extracting album art from: {} to: {}",
item,
displayable_path(outpath),
)
@ -212,7 +212,7 @@ def extract_first(log, outpath, items):
def clear(log, lib, query):
items = lib.items(query)
log.info("Clearing album art from {0} items", len(items))
log.info("Clearing album art from {} items", len(items))
for item in items:
log.debug("Clearing art for {0}", item)
log.debug("Clearing art for {}", item)
item.try_write(tags={"images": None})

View file

@ -118,7 +118,7 @@ def match_by_id(items: Iterable[Item]) -> AlbumInfo | None:
log.debug("No album ID consensus.")
return None
# If all album IDs are equal, look up the album.
log.debug("Searching for discovered album ID: {0}", first)
log.debug("Searching for discovered album ID: {}", first)
return metadata_plugins.album_for_id(first)
@ -197,9 +197,7 @@ def _add_candidate(
checking the track count, ordering the items, checking for
duplicates, and calculating the distance.
"""
log.debug(
"Candidate: {0} - {1} ({2})", info.artist, info.album, info.album_id
)
log.debug("Candidate: {} - {} ({})", info.artist, info.album, info.album_id)
# Discard albums with zero tracks.
if not info.tracks:
@ -215,7 +213,7 @@ def _add_candidate(
required_tags: Sequence[str] = config["match"]["required"].as_str_seq()
for req_tag in required_tags:
if getattr(info, req_tag) is None:
log.debug("Ignored. Missing required tag: {0}", req_tag)
log.debug("Ignored. Missing required tag: {}", req_tag)
return
# Find mapping between the items and the track info.
@ -229,10 +227,10 @@ def _add_candidate(
ignored_tags: Sequence[str] = config["match"]["ignored"].as_str_seq()
for penalty in ignored_tags:
if penalty in penalties:
log.debug("Ignored. Penalty: {0}", penalty)
log.debug("Ignored. Penalty: {}", penalty)
return
log.debug("Success. Distance: {0}", dist)
log.debug("Success. Distance: {}", dist)
results[info.album_id] = hooks.AlbumMatch(
dist, info, mapping, extra_items, extra_tracks
)
@ -265,7 +263,7 @@ def tag_album(
likelies, consensus = get_most_common_tags(items)
cur_artist: str = likelies["artist"]
cur_album: str = likelies["album"]
log.debug("Tagging {0} - {1}", cur_artist, cur_album)
log.debug("Tagging {} - {}", cur_artist, cur_album)
# The output result, keys are the MB album ID.
candidates: dict[Any, AlbumMatch] = {}
@ -273,7 +271,7 @@ def tag_album(
# Search by explicit ID.
if search_ids:
for search_id in search_ids:
log.debug("Searching for album ID: {0}", search_id)
log.debug("Searching for album ID: {}", search_id)
if info := metadata_plugins.album_for_id(search_id):
_add_candidate(items, candidates, info)
@ -283,7 +281,7 @@ def tag_album(
if info := match_by_id(items):
_add_candidate(items, candidates, info)
rec = _recommendation(list(candidates.values()))
log.debug("Album ID match recommendation is {0}", rec)
log.debug("Album ID match recommendation is {}", rec)
if candidates and not config["import"]["timid"]:
# If we have a very good MBID match, return immediately.
# Otherwise, this match will compete against metadata-based
@ -300,7 +298,7 @@ def tag_album(
if not (search_artist and search_album):
# No explicit search terms -- use current metadata.
search_artist, search_album = cur_artist, cur_album
log.debug("Search terms: {0} - {1}", search_artist, search_album)
log.debug("Search terms: {} - {}", search_artist, search_album)
# Is this album likely to be a "various artist" release?
va_likely = (
@ -308,7 +306,7 @@ def tag_album(
or (search_artist.lower() in VA_ARTISTS)
or any(item.comp for item in items)
)
log.debug("Album might be VA: {0}", va_likely)
log.debug("Album might be VA: {}", va_likely)
# Get the results from the data sources.
for matched_candidate in metadata_plugins.candidates(
@ -316,7 +314,7 @@ def tag_album(
):
_add_candidate(items, candidates, matched_candidate)
log.debug("Evaluating {0} candidates.", len(candidates))
log.debug("Evaluating {} candidates.", len(candidates))
# Sort and get the recommendation.
candidates_sorted = _sort_candidates(candidates.values())
rec = _recommendation(candidates_sorted)
@ -345,7 +343,7 @@ def tag_item(
trackids = search_ids or [t for t in [item.mb_trackid] if t]
if trackids:
for trackid in trackids:
log.debug("Searching for track ID: {0}", trackid)
log.debug("Searching for track ID: {}", trackid)
if info := metadata_plugins.track_for_id(trackid):
dist = track_distance(item, info, incl_artist=True)
candidates[info.track_id] = hooks.TrackMatch(dist, info)
@ -369,7 +367,7 @@ def tag_item(
# Search terms.
search_artist = search_artist or item.artist
search_title = search_title or item.title
log.debug("Item search terms: {0} - {1}", search_artist, search_title)
log.debug("Item search terms: {} - {}", search_artist, search_title)
# Get and evaluate candidate metadata.
for track_info in metadata_plugins.item_candidates(
@ -379,7 +377,7 @@ def tag_item(
candidates[track_info.track_id] = hooks.TrackMatch(dist, track_info)
# Sort by distance and return with recommendation.
log.debug("Found {0} candidates.", len(candidates))
log.debug("Found {} candidates.", len(candidates))
candidates_sorted = _sort_candidates(candidates.values())
rec = _recommendation(candidates_sorted)
return Proposal(candidates_sorted, rec)

View file

@ -150,7 +150,7 @@ class ImportSession:
"""Log a message about a given album to the importer log. The status
should reflect the reason the album couldn't be tagged.
"""
self.logger.info("{0} {1}", status, displayable_path(paths))
self.logger.info("{} {}", status, displayable_path(paths))
def log_choice(self, task: ImportTask, duplicate=False):
"""Logs the task's current choice if it should be logged. If
@ -187,7 +187,7 @@ class ImportSession:
def run(self):
"""Run the import task."""
self.logger.info("import started {0}", time.asctime())
self.logger.info("import started {}", time.asctime())
self.set_config(config["import"])
# Set up the pipeline.
@ -297,7 +297,7 @@ class ImportSession:
# Either accept immediately or prompt for input to decide.
if self.want_resume is True or self.should_resume(toppath):
log.warning(
"Resuming interrupted import of {0}",
"Resuming interrupted import of {}",
util.displayable_path(toppath),
)
self._is_resuming[toppath] = True

View file

@ -58,11 +58,11 @@ def read_tasks(session: ImportSession):
skipped += task_factory.skipped
if not task_factory.imported:
log.warning("No files imported from {0}", displayable_path(toppath))
log.warning("No files imported from {}", displayable_path(toppath))
# Show skipped directories (due to incremental/resume).
if skipped:
log.info("Skipped {0} paths.", skipped)
log.info("Skipped {} paths.", skipped)
def query_tasks(session: ImportSession):
@ -82,7 +82,7 @@ def query_tasks(session: ImportSession):
# Search for albums.
for album in session.lib.albums(session.query):
log.debug(
"yielding album {0}: {1} - {2}",
"yielding album {}: {} - {}",
album.id,
album.albumartist,
album.album,
@ -140,7 +140,7 @@ def lookup_candidates(session: ImportSession, task: ImportTask):
return
plugins.send("import_task_start", session=session, task=task)
log.debug("Looking up: {0}", displayable_path(task.paths))
log.debug("Looking up: {}", displayable_path(task.paths))
# Restrict the initial lookup to IDs specified by the user via the -m
# option. Currently all the IDs are passed onto the tasks directly.
@ -259,11 +259,11 @@ def plugin_stage(
def log_files(session: ImportSession, task: ImportTask):
"""A coroutine (pipeline stage) to log each file to be imported."""
if isinstance(task, SingletonImportTask):
log.info("Singleton: {0}", displayable_path(task.item["path"]))
log.info("Singleton: {}", displayable_path(task.item["path"]))
elif task.items:
log.info("Album: {0}", displayable_path(task.paths[0]))
log.info("Album: {}", displayable_path(task.paths[0]))
for item in task.items:
log.info(" {0}", displayable_path(item["path"]))
log.info(" {}", displayable_path(item["path"]))
# --------------------------------- Consumer --------------------------------- #
@ -353,7 +353,7 @@ def _resolve_duplicates(session: ImportSession, task: ImportTask):
"ask": "a",
}
)
log.debug("default action for duplicates: {0}", duplicate_action)
log.debug("default action for duplicates: {}", duplicate_action)
if duplicate_action == "s":
# Skip new.

View file

@ -87,7 +87,7 @@ class ImportState:
# unpickling, including ImportError. We use a catch-all
# exception to avoid enumerating them all (the docs don't even have a
# full list!).
log.debug("state file could not be read: {0}", exc)
log.debug("state file could not be read: {}", exc)
def _save(self):
try:
@ -100,7 +100,7 @@ class ImportState:
f,
)
except OSError as exc:
log.error("state file could not be written: {0}", exc)
log.error("state file could not be written: {}", exc)
# -------------------------------- Tagprogress ------------------------------- #

View file

@ -267,12 +267,12 @@ class ImportTask(BaseImportTask):
def remove_duplicates(self, lib: library.Library):
duplicate_items = self.duplicate_items(lib)
log.debug("removing {0} old duplicated items", len(duplicate_items))
log.debug("removing {} old duplicated items", len(duplicate_items))
for item in duplicate_items:
item.remove()
if lib.directory in util.ancestry(item.path):
log.debug(
"deleting duplicate {0}", util.displayable_path(item.path)
"deleting duplicate {}", util.displayable_path(item.path)
)
util.remove(item.path)
util.prune_dirs(os.path.dirname(item.path), lib.directory)
@ -285,10 +285,10 @@ class ImportTask(BaseImportTask):
for field, view in config["import"]["set_fields"].items():
value = str(view.get())
log.debug(
"Set field {1}={2} for {0}",
util.displayable_path(self.paths),
"Set field {}={} for {}",
field,
value,
util.displayable_path(self.paths),
)
self.album.set_parse(field, format(self.album, value))
for item in items:
@ -622,13 +622,13 @@ class ImportTask(BaseImportTask):
for item in self.imported_items():
for dup_item in self.replaced_items[item]:
log.debug(
"Replacing item {0}: {1}",
"Replacing item {}: {}",
dup_item.id,
util.displayable_path(item.path),
)
dup_item.remove()
log.debug(
"{0} of {1} items replaced",
"{} of {} items replaced",
sum(bool(v) for v in self.replaced_items.values()),
len(self.imported_items()),
)
@ -747,10 +747,10 @@ class SingletonImportTask(ImportTask):
for field, view in config["import"]["set_fields"].items():
value = str(view.get())
log.debug(
"Set field {1}={2} for {0}",
util.displayable_path(self.paths),
"Set field {}={} for {}",
field,
value,
util.displayable_path(self.paths),
)
self.item.set_parse(field, format(self.item, value))
self.item.store()
@ -870,7 +870,7 @@ class ArchiveImportTask(SentinelImportTask):
"""Removes the temporary directory the archive was extracted to."""
if self.extracted and self.toppath:
log.debug(
"Removing extracted directory: {0}",
"Removing extracted directory: {}",
util.displayable_path(self.toppath),
)
shutil.rmtree(util.syspath(self.toppath))
@ -1002,7 +1002,7 @@ class ImportTaskFactory:
"""Return a `SingletonImportTask` for the music file."""
if self.session.already_imported(self.toppath, [path]):
log.debug(
"Skipping previously-imported path: {0}",
"Skipping previously-imported path: {}",
util.displayable_path(path),
)
self.skipped += 1
@ -1026,7 +1026,7 @@ class ImportTaskFactory:
if self.session.already_imported(self.toppath, dirs):
log.debug(
"Skipping previously-imported path: {0}",
"Skipping previously-imported path: {}",
util.displayable_path(dirs),
)
self.skipped += 1
@ -1063,19 +1063,17 @@ class ImportTaskFactory:
)
return
log.debug(
"Extracting archive: {0}", util.displayable_path(self.toppath)
)
log.debug("Extracting archive: {}", util.displayable_path(self.toppath))
archive_task = ArchiveImportTask(self.toppath)
try:
archive_task.extract()
except Exception as exc:
log.error("extraction failed: {0}", exc)
log.error("extraction failed: {}", exc)
return
# Now read albums from the extracted directory.
self.toppath = archive_task.toppath
log.debug("Archive extracted to: {0}", self.toppath)
log.debug("Archive extracted to: {}", self.toppath)
return archive_task
def read_item(self, path: util.PathBytes):
@ -1091,10 +1089,10 @@ class ImportTaskFactory:
# Silently ignore non-music files.
pass
elif isinstance(exc.reason, mediafile.UnreadableFileError):
log.warning("unreadable file: {0}", util.displayable_path(path))
log.warning("unreadable file: {}", util.displayable_path(path))
else:
log.error(
"error reading {0}: {1}", util.displayable_path(path), exc
"error reading {}: {}", util.displayable_path(path), exc
)

View file

@ -425,7 +425,7 @@ class Album(LibModel):
new_art = util.unique_path(new_art)
log.debug(
"moving album art {0} to {1}",
"moving album art {} to {}",
util.displayable_path(old_art),
util.displayable_path(new_art),
)
@ -992,7 +992,7 @@ class Item(LibModel):
self.write(*args, **kwargs)
return True
except FileOperationError as exc:
log.error("{0}", exc)
log.error("{}", exc)
return False
def try_sync(self, write, move, with_album=True):
@ -1013,7 +1013,7 @@ class Item(LibModel):
# Check whether this file is inside the library directory.
if self._db and self._db.directory in util.ancestry(self.path):
log.debug(
"moving {0} to synchronize path",
"moving {} to synchronize path",
util.displayable_path(self.path),
)
self.move(with_album=with_album)
@ -1087,7 +1087,7 @@ class Item(LibModel):
try:
return os.path.getsize(syspath(self.path))
except (OSError, Exception) as exc:
log.warning("could not get filesize: {0}", exc)
log.warning("could not get filesize: {}", exc)
return 0
# Model methods.

View file

@ -543,7 +543,7 @@ def send(event: EventType, **arguments: Any) -> list[Any]:
Return a list of non-None values returned from the handlers.
"""
log.debug("Sending event: {0}", event)
log.debug("Sending event: {}", event)
return [
r
for handler in BeetsPlugin.listeners[event]

View file

@ -267,7 +267,7 @@ class TestHelper(ConfigMixin):
The item is attached to the database from `self.lib`.
"""
values_ = {
"title": "t\u00eftle {0}",
"title": "t\u00eftle {}",
"artist": "the \u00e4rtist",
"album": "the \u00e4lbum",
"track": 1,

View file

@ -572,7 +572,7 @@ def colorize(color_name, text):
# instead of the abstract color name ('text_error')
color = COLORS.get(color_name)
if not color:
log.debug("Invalid color_name: {0}", color_name)
log.debug("Invalid color_name: {}", color_name)
color = color_name
return _colorize(color, text)
else:
@ -1587,19 +1587,19 @@ def _configure(options):
if overlay_path:
log.debug(
"overlaying configuration: {0}", util.displayable_path(overlay_path)
"overlaying configuration: {}", util.displayable_path(overlay_path)
)
config_path = config.user_config_path()
if os.path.isfile(config_path):
log.debug("user configuration: {0}", util.displayable_path(config_path))
log.debug("user configuration: {}", util.displayable_path(config_path))
else:
log.debug(
"no user configuration found at {0}",
"no user configuration found at {}",
util.displayable_path(config_path),
)
log.debug("data directory: {0}", util.displayable_path(config.config_dir()))
log.debug("data directory: {}", util.displayable_path(config.config_dir()))
return config
@ -1634,7 +1634,7 @@ def _open_library(config: confuse.LazyConfig) -> library.Library:
f" opened: {db_error}"
)
log.debug(
"library database: {0}\nlibrary directory: {1}",
"library database: {}\nlibrary directory: {}",
util.displayable_path(lib.path),
util.displayable_path(lib.directory),
)
@ -1751,7 +1751,7 @@ def main(args=None):
_raw_main(args)
except UserError as exc:
message = exc.args[0] if exc.args else None
log.error("error: {0}", message)
log.error("error: {}", message)
sys.exit(1)
except util.HumanReadableError as exc:
exc.log(log)
@ -1763,10 +1763,10 @@ def main(args=None):
log.error("{}", exc)
sys.exit(1)
except confuse.ConfigError as exc:
log.error("configuration error: {0}", exc)
log.error("configuration error: {}", exc)
sys.exit(1)
except db_query.InvalidQueryError as exc:
log.error("invalid query: {0}", exc)
log.error("invalid query: {}", exc)
sys.exit(1)
except OSError as exc:
if exc.errno == errno.EPIPE:
@ -1779,7 +1779,7 @@ def main(args=None):
log.debug("{}", traceback.format_exc())
except db.DBAccessError as exc:
log.error(
"database access error: {0}\n"
"database access error: {}\n"
"the library file might have a permissions problem",
exc,
)

View file

@ -1148,7 +1148,7 @@ class TerminalImportSession(importer.ImportSession):
that's already in the library.
"""
log.warning(
"This {0} is already in the library!",
"This {} is already in the library!",
("album" if task.is_album else "item"),
)
@ -1280,8 +1280,8 @@ class TerminalImportSession(importer.ImportSession):
dup_choices = [c for c in all_choices if c.short == short]
for c in dup_choices[1:]:
log.warning(
"Prompt choice '{0}' removed due to conflict "
"with '{1}' (short letter: '{2}')",
"Prompt choice '{}' removed due to conflict "
"with '{}' (short letter: '{}')",
c.long,
dup_choices[0].long,
c.short,
@ -1639,7 +1639,7 @@ def update_items(lib, query, album, move, pretend, fields, exclude_fields=None):
# Did the item change since last checked?
if item.current_mtime() <= item.mtime:
log.debug(
"skipping {0} because mtime is up to date ({1})",
"skipping {} because mtime is up to date ({})",
displayable_path(item.path),
item.mtime,
)
@ -1650,7 +1650,7 @@ def update_items(lib, query, album, move, pretend, fields, exclude_fields=None):
item.read()
except library.ReadError as exc:
log.error(
"error reading {0}: {1}", displayable_path(item.path), exc
"error reading {}: {}", displayable_path(item.path), exc
)
continue
@ -1692,7 +1692,7 @@ def update_items(lib, query, album, move, pretend, fields, exclude_fields=None):
continue
album = lib.get_album(album_id)
if not album: # Empty albums have already been removed.
log.debug("emptied album {0}", album_id)
log.debug("emptied album {}", album_id)
continue
first_item = album.items().get()
@ -1703,7 +1703,7 @@ def update_items(lib, query, album, move, pretend, fields, exclude_fields=None):
# Move album art (and any inconsistent items).
if move and lib.directory in ancestry(first_item.path):
log.debug("moving album {0}", album_id)
log.debug("moving album {}", album_id)
# Manually moving and storing the album.
items = list(album.items())
@ -2141,7 +2141,7 @@ def move_items(
act = "copy" if copy else "move"
entity = "album" if album else "item"
log.info(
"{0} {1} {2}{3}{4}.",
"{} {} {}{}{}.",
action,
len(objs),
entity,
@ -2175,7 +2175,7 @@ def move_items(
)
for obj in objs:
log.debug("moving: {0}", util.displayable_path(obj.path))
log.debug("moving: {}", util.displayable_path(obj.path))
if export:
# Copy without affecting the database.
@ -2258,16 +2258,14 @@ def write_items(lib, query, pretend, force):
for item in items:
# Item deleted?
if not os.path.exists(syspath(item.path)):
log.info("missing file: {0}", util.displayable_path(item.path))
log.info("missing file: {}", util.displayable_path(item.path))
continue
# Get an Item object reflecting the "clean" (on-disk) state.
try:
clean_item = library.Item.from_path(item.path)
except library.ReadError as exc:
log.error(
"error reading {0}: {1}", displayable_path(item.path), exc
)
log.error("error reading {}: {}", displayable_path(item.path), exc)
continue
# Check for and display changes.

View file

@ -126,7 +126,7 @@ class HumanReadableError(Exception):
"""
if self.tb:
logger.debug(self.tb)
logger.error("{0}: {1}", self.error_kind, self.args[0])
logger.error("{}: {}", self.error_kind, self.args[0])
class FilesystemError(HumanReadableError):

View file

@ -255,7 +255,7 @@ class IMBackend(LocalBackend):
path_out = get_temp_filename(__name__, "resize_IM_", path_in)
log.debug(
"artresizer: ImageMagick resizing {0} to {1}",
"artresizer: ImageMagick resizing {} to {}",
displayable_path(path_in),
displayable_path(path_out),
)
@ -287,7 +287,7 @@ class IMBackend(LocalBackend):
util.command_output(cmd)
except subprocess.CalledProcessError:
log.warning(
"artresizer: IM convert failed for {0}",
"artresizer: IM convert failed for {}",
displayable_path(path_in),
)
return path_in
@ -452,7 +452,7 @@ class IMBackend(LocalBackend):
if compare_proc.returncode:
if compare_proc.returncode != 1:
log.debug(
"ImageMagick compare failed: {0}, {1}",
"ImageMagick compare failed: {}, {}",
displayable_path(im2),
displayable_path(im1),
)
@ -472,7 +472,7 @@ class IMBackend(LocalBackend):
log.debug("IM output is not a number: {0!r}", out_str)
return None
log.debug("ImageMagick compare score: {0}", phash_diff)
log.debug("ImageMagick compare score: {}", phash_diff)
return phash_diff <= compare_threshold
@property
@ -523,7 +523,7 @@ class PILBackend(LocalBackend):
from PIL import Image
log.debug(
"artresizer: PIL resizing {0} to {1}",
"artresizer: PIL resizing {} to {}",
displayable_path(path_in),
displayable_path(path_out),
)
@ -552,7 +552,7 @@ class PILBackend(LocalBackend):
for i in range(5):
# 5 attempts is an arbitrary choice
filesize = os.stat(syspath(path_out)).st_size
log.debug("PIL Pass {0} : Output size: {1}B", i, filesize)
log.debug("PIL Pass {} : Output size: {}B", i, filesize)
if filesize <= max_filesize:
return path_out
# The relationship between filesize & quality will be
@ -569,7 +569,7 @@ class PILBackend(LocalBackend):
progressive=False,
)
log.warning(
"PIL Failed to resize file to below {0}B", max_filesize
"PIL Failed to resize file to below {}B", max_filesize
)
return path_out
@ -577,7 +577,7 @@ class PILBackend(LocalBackend):
return path_out
except OSError:
log.error(
"PIL cannot create thumbnail for '{0}'",
"PIL cannot create thumbnail for '{}'",
displayable_path(path_in),
)
return path_in

View file

@ -366,7 +366,7 @@ class BeatportPlugin(MetadataSourcePlugin):
try:
url = auth_client.get_authorize_url()
except AUTH_ERRORS as e:
self._log.debug("authentication error: {0}", e)
self._log.debug("authentication error: {}", e)
raise beets.ui.UserError("communication with Beatport failed")
beets.ui.print_("To authenticate with Beatport, visit:")
@ -377,11 +377,11 @@ class BeatportPlugin(MetadataSourcePlugin):
try:
token, secret = auth_client.get_access_token(data)
except AUTH_ERRORS as e:
self._log.debug("authentication error: {0}", e)
self._log.debug("authentication error: {}", e)
raise beets.ui.UserError("Beatport token request failed")
# Save the token for later use.
self._log.debug("Beatport token {0}, secret {1}", token, secret)
self._log.debug("Beatport token {}, secret {}", token, secret)
with open(self._tokenfile(), "w") as f:
json.dump({"token": token, "secret": secret}, f)
@ -405,7 +405,7 @@ class BeatportPlugin(MetadataSourcePlugin):
try:
yield from self._get_releases(query)
except BeatportAPIError as e:
self._log.debug("API Error: {0} (query: {1})", e, query)
self._log.debug("API Error: {} (query: {})", e, query)
return
def item_candidates(
@ -415,14 +415,14 @@ class BeatportPlugin(MetadataSourcePlugin):
try:
return self._get_tracks(query)
except BeatportAPIError as e:
self._log.debug("API Error: {0} (query: {1})", e, query)
self._log.debug("API Error: {} (query: {})", e, query)
return []
def album_for_id(self, album_id: str):
"""Fetches a release by its Beatport ID and returns an AlbumInfo object
or None if the query is not a valid ID or release is not found.
"""
self._log.debug("Searching for release {0}", album_id)
self._log.debug("Searching for release {}", album_id)
if not (release_id := self._extract_id(album_id)):
self._log.debug("Not a valid Beatport release ID.")
@ -437,7 +437,7 @@ class BeatportPlugin(MetadataSourcePlugin):
"""Fetches a track by its Beatport ID and returns a TrackInfo object
or None if the track is not a valid Beatport ID or track is not found.
"""
self._log.debug("Searching for track {0}", track_id)
self._log.debug("Searching for track {}", track_id)
# TODO: move to extractor
match = re.search(r"(^|beatport\.com/track/.+/)(\d+)$", track_id)
if not match:

View file

@ -73,12 +73,12 @@ class BPMPlugin(BeetsPlugin):
item = items[0]
if item["bpm"]:
self._log.info("Found bpm {0}", item["bpm"])
self._log.info("Found bpm {}", item["bpm"])
if not overwrite:
return
self._log.info(
"Press Enter {0} times to the rhythm or Ctrl-D to exit",
"Press Enter {} times to the rhythm or Ctrl-D to exit",
self.config["max_strokes"].get(int),
)
new_bpm = bpm(self.config["max_strokes"].get(int))
@ -86,4 +86,4 @@ class BPMPlugin(BeetsPlugin):
if write:
item.try_write()
item.store()
self._log.info("Added new bpm {0}", item["bpm"])
self._log.info("Added new bpm {}", item["bpm"])

View file

@ -90,7 +90,7 @@ def acoustid_match(log, path):
duration, fp = acoustid.fingerprint_file(util.syspath(path))
except acoustid.FingerprintGenerationError as exc:
log.error(
"fingerprinting of {0} failed: {1}",
"fingerprinting of {} failed: {}",
util.displayable_path(repr(path)),
exc,
)
@ -103,12 +103,12 @@ def acoustid_match(log, path):
)
except acoustid.AcoustidError as exc:
log.debug(
"fingerprint matching {0} failed: {1}",
"fingerprint matching {} failed: {}",
util.displayable_path(repr(path)),
exc,
)
return None
log.debug("chroma: fingerprinted {0}", util.displayable_path(repr(path)))
log.debug("chroma: fingerprinted {}", util.displayable_path(repr(path)))
# Ensure the response is usable and parse it.
if res["status"] != "ok" or not res.get("results"):
@ -146,7 +146,7 @@ def acoustid_match(log, path):
release_ids = [rel["id"] for rel in releases]
log.debug(
"matched recordings {0} on releases {1}", recording_ids, release_ids
"matched recordings {} on releases {}", recording_ids, release_ids
)
_matches[path] = recording_ids, release_ids
@ -211,7 +211,7 @@ class AcoustidPlugin(MetadataSourcePlugin):
if album:
albums.append(album)
self._log.debug("acoustid album candidates: {0}", len(albums))
self._log.debug("acoustid album candidates: {}", len(albums))
return albums
def item_candidates(self, item, artist, title) -> Iterable[TrackInfo]:
@ -224,7 +224,7 @@ class AcoustidPlugin(MetadataSourcePlugin):
track = self.mb.track_for_id(recording_id)
if track:
tracks.append(track)
self._log.debug("acoustid item candidates: {0}", len(tracks))
self._log.debug("acoustid item candidates: {}", len(tracks))
return tracks
def album_for_id(self, *args, **kwargs):
@ -292,11 +292,11 @@ def submit_items(log, userkey, items, chunksize=64):
def submit_chunk():
"""Submit the current accumulated fingerprint data."""
log.info("submitting {0} fingerprints", len(data))
log.info("submitting {} fingerprints", len(data))
try:
acoustid.submit(API_KEY, userkey, data, timeout=10)
except acoustid.AcoustidError as exc:
log.warning("acoustid submission error: {0}", exc)
log.warning("acoustid submission error: {}", exc)
del data[:]
for item in items:
@ -343,31 +343,31 @@ def fingerprint_item(log, item, write=False):
"""
# Get a fingerprint and length for this track.
if not item.length:
log.info("{0}: no duration available", util.displayable_path(item.path))
log.info("{}: no duration available", util.displayable_path(item.path))
elif item.acoustid_fingerprint:
if write:
log.info(
"{0}: fingerprint exists, skipping",
"{}: fingerprint exists, skipping",
util.displayable_path(item.path),
)
else:
log.info(
"{0}: using existing fingerprint",
"{}: using existing fingerprint",
util.displayable_path(item.path),
)
return item.acoustid_fingerprint
else:
log.info("{0}: fingerprinting", util.displayable_path(item.path))
log.info("{}: fingerprinting", util.displayable_path(item.path))
try:
_, fp = acoustid.fingerprint_file(util.syspath(item.path))
item.acoustid_fingerprint = fp.decode()
if write:
log.info(
"{0}: writing fingerprint", util.displayable_path(item.path)
"{}: writing fingerprint", util.displayable_path(item.path)
)
item.try_write()
if item._db:
item.store()
return item.acoustid_fingerprint
except acoustid.FingerprintGenerationError as exc:
log.info("fingerprint generation failed: {0}", exc)
log.info("fingerprint generation failed: {}", exc)

View file

@ -288,7 +288,7 @@ class ConvertPlugin(BeetsPlugin):
quiet = self.config["quiet"].get(bool)
if not quiet and not pretend:
self._log.info("Encoding {0}", util.displayable_path(source))
self._log.info("Encoding {}", util.displayable_path(source))
command = os.fsdecode(command)
source = os.fsdecode(source)
@ -307,7 +307,7 @@ class ConvertPlugin(BeetsPlugin):
encode_cmd.append(os.fsdecode(args[i]))
if pretend:
self._log.info("{0}", " ".join(args))
self._log.info("{}", " ".join(args))
return
try:
@ -315,11 +315,11 @@ class ConvertPlugin(BeetsPlugin):
except subprocess.CalledProcessError as exc:
# Something went wrong (probably Ctrl+C), remove temporary files
self._log.info(
"Encoding {0} failed. Cleaning up...",
"Encoding {} failed. Cleaning up...",
util.displayable_path(source),
)
self._log.debug(
"Command {0} exited with status {1}: {2}",
"Command {} exited with status {}: {}",
args,
exc.returncode,
exc.output,
@ -334,7 +334,7 @@ class ConvertPlugin(BeetsPlugin):
if not quiet and not pretend:
self._log.info(
"Finished encoding {0}", util.displayable_path(source)
"Finished encoding {}", util.displayable_path(source)
)
def convert_item(
@ -362,7 +362,7 @@ class ConvertPlugin(BeetsPlugin):
try:
mediafile.MediaFile(util.syspath(item.path))
except mediafile.UnreadableFileError as exc:
self._log.error("Could not open file to convert: {0}", exc)
self._log.error("Could not open file to convert: {}", exc)
continue
# When keeping the new file in the library, we first move the
@ -388,7 +388,7 @@ class ConvertPlugin(BeetsPlugin):
if os.path.exists(util.syspath(dest)):
self._log.info(
"Skipping {0} (target file exists)",
"Skipping {} (target file exists)",
util.displayable_path(item.path),
)
continue
@ -396,13 +396,13 @@ class ConvertPlugin(BeetsPlugin):
if keep_new:
if pretend:
self._log.info(
"mv {0} {1}",
"mv {} {}",
util.displayable_path(item.path),
util.displayable_path(original),
)
else:
self._log.info(
"Moving to {0}", util.displayable_path(original)
"Moving to {}", util.displayable_path(original)
)
util.move(item.path, original)
@ -418,10 +418,10 @@ class ConvertPlugin(BeetsPlugin):
msg = "ln" if hardlink else ("ln -s" if link else "cp")
self._log.info(
"{2} {0} {1}",
"{} {} {}",
msg,
util.displayable_path(original),
util.displayable_path(converted),
msg,
)
else:
# No transcoding necessary.
@ -432,7 +432,7 @@ class ConvertPlugin(BeetsPlugin):
)
self._log.info(
"{1} {0}", util.displayable_path(item.path), msg
"{} {}", msg, util.displayable_path(item.path)
)
if hardlink:
@ -523,7 +523,7 @@ class ConvertPlugin(BeetsPlugin):
if os.path.exists(util.syspath(dest)):
self._log.info(
"Skipping {0} (target file exists)",
"Skipping {} (target file exists)",
util.displayable_path(album.artpath),
)
return
@ -534,7 +534,7 @@ class ConvertPlugin(BeetsPlugin):
# Either copy or resize (while copying) the image.
if maxwidth is not None:
self._log.info(
"Resizing cover art from {0} to {1}",
"Resizing cover art from {} to {}",
util.displayable_path(album.artpath),
util.displayable_path(dest),
)
@ -545,10 +545,10 @@ class ConvertPlugin(BeetsPlugin):
msg = "ln" if hardlink else ("ln -s" if link else "cp")
self._log.info(
"{2} {0} {1}",
"{} {} {}",
msg,
util.displayable_path(album.artpath),
util.displayable_path(dest),
msg,
)
else:
msg = (
@ -558,10 +558,10 @@ class ConvertPlugin(BeetsPlugin):
)
self._log.info(
"{2} cover art from {0} to {1}",
"{} cover art from {} to {}",
msg,
util.displayable_path(album.artpath),
util.displayable_path(dest),
msg,
)
if hardlink:
util.hardlink(album.artpath, dest)
@ -622,7 +622,7 @@ class ConvertPlugin(BeetsPlugin):
# Playlist paths are understood as relative to the dest directory.
pl_normpath = util.normpath(playlist)
pl_dir = os.path.dirname(pl_normpath)
self._log.info("Creating playlist file {0}", pl_normpath)
self._log.info("Creating playlist file {}", pl_normpath)
# Generates a list of paths to media files, ensures the paths are
# relative to the playlist's location and translates the unicode
# strings we get from item.destination to bytes.
@ -672,7 +672,7 @@ class ConvertPlugin(BeetsPlugin):
if self.config["delete_originals"]:
self._log.log(
logging.DEBUG if self.config["quiet"] else logging.INFO,
"Removing original file {0}",
"Removing original file {}",
source_path,
)
util.remove(source_path, False)

View file

@ -145,7 +145,7 @@ class DiscogsPlugin(MetadataSourcePlugin):
try:
_, _, url = auth_client.get_authorize_url()
except CONNECTION_ERRORS as e:
self._log.debug("connection error: {0}", e)
self._log.debug("connection error: {}", e)
raise beets.ui.UserError("communication with Discogs failed")
beets.ui.print_("To authenticate with Discogs, visit:")
@ -158,11 +158,11 @@ class DiscogsPlugin(MetadataSourcePlugin):
except DiscogsAPIError:
raise beets.ui.UserError("Discogs authorization failed")
except CONNECTION_ERRORS as e:
self._log.debug("connection error: {0}", e)
self._log.debug("connection error: {}", e)
raise beets.ui.UserError("Discogs token request failed")
# Save the token for later use.
self._log.debug("Discogs token {0}, secret {1}", token, secret)
self._log.debug("Discogs token {}, secret {}", token, secret)
with open(self._tokenfile(), "w") as f:
json.dump({"token": token, "secret": secret}, f)
@ -202,7 +202,7 @@ class DiscogsPlugin(MetadataSourcePlugin):
"""Fetches an album by its Discogs ID and returns an AlbumInfo object
or None if the album is not found.
"""
self._log.debug("Searching for release {0}", album_id)
self._log.debug("Searching for release {}", album_id)
discogs_id = self._extract_id(album_id)
@ -216,7 +216,7 @@ class DiscogsPlugin(MetadataSourcePlugin):
except DiscogsAPIError as e:
if e.status_code != 404:
self._log.debug(
"API Error: {0} (query: {1})",
"API Error: {} (query: {})",
e,
result.data["resource_url"],
)
@ -266,7 +266,7 @@ class DiscogsPlugin(MetadataSourcePlugin):
"""Fetches a master release given its Discogs ID and returns its year
or None if the master release is not found.
"""
self._log.debug("Getting master release {0}", master_id)
self._log.debug("Getting master release {}", master_id)
result = Master(self.discogs_client, {"id": master_id})
try:
@ -274,7 +274,7 @@ class DiscogsPlugin(MetadataSourcePlugin):
except DiscogsAPIError as e:
if e.status_code != 404:
self._log.debug(
"API Error: {0} (query: {1})",
"API Error: {} (query: {})",
e,
result.data["resource_url"],
)

View file

@ -254,7 +254,7 @@ class DuplicatesPlugin(BeetsPlugin):
checksum = getattr(item, key, False)
if not checksum:
self._log.debug(
"key {0} on item {1} not cached:computing checksum",
"key {} on item {} not cached:computing checksum",
key,
displayable_path(item.path),
)
@ -263,17 +263,17 @@ class DuplicatesPlugin(BeetsPlugin):
setattr(item, key, checksum)
item.store()
self._log.debug(
"computed checksum for {0} using {1}", item.title, key
"computed checksum for {} using {}", item.title, key
)
except subprocess.CalledProcessError as e:
self._log.debug(
"failed to checksum {0}: {1}",
"failed to checksum {}: {}",
displayable_path(item.path),
e,
)
else:
self._log.debug(
"key {0} on item {1} cached:not computing checksum",
"key {} on item {} cached:not computing checksum",
key,
displayable_path(item.path),
)
@ -293,13 +293,13 @@ class DuplicatesPlugin(BeetsPlugin):
values = [v for v in values if v not in (None, "")]
if strict and len(values) < len(keys):
self._log.debug(
"some keys {0} on item {1} are null or empty: skipping",
"some keys {} on item {} are null or empty: skipping",
keys,
displayable_path(obj.path),
)
elif not strict and not len(values):
self._log.debug(
"all keys {0} on item {1} are null or empty: skipping",
"all keys {} on item {} are null or empty: skipping",
keys,
displayable_path(obj.path),
)
@ -359,8 +359,8 @@ class DuplicatesPlugin(BeetsPlugin):
value = getattr(o, f, None)
if value:
self._log.debug(
"key {0} on item {1} is null "
"or empty: setting from item {2}",
"key {} on item {} is null "
"or empty: setting from item {}",
f,
displayable_path(objs[0].path),
displayable_path(o.path),
@ -383,8 +383,8 @@ class DuplicatesPlugin(BeetsPlugin):
missing.album_id = objs[0].id
missing.add(i._db)
self._log.debug(
"item {0} missing from album {1}:"
" merging from {2} into {3}",
"item {} missing from album {}:"
" merging from {} into {}",
missing,
objs[0],
displayable_path(o.path),

View file

@ -273,7 +273,7 @@ class EmbedCoverArtPlugin(BeetsPlugin):
"""
if self.config["remove_art_file"] and album.artpath:
if os.path.isfile(syspath(album.artpath)):
self._log.debug("Removing album art file for {0}", album)
self._log.debug("Removing album art file for {}", album)
os.remove(syspath(album.artpath))
album.artpath = None
album.store()

View file

@ -196,7 +196,7 @@ class EmbyUpdate(BeetsPlugin):
# Get authentication token.
token = get_token(host, port, headers, auth_data)
if not token:
self._log.warning("Could not get token for user {0}", username)
self._log.warning("Could not get token for user {}", username)
return
# Recreate headers with a token.

View file

@ -150,7 +150,7 @@ class ExportPlugin(BeetsPlugin):
try:
data, item = data_emitter(included_keys or "*")
except (mediafile.UnreadableFileError, OSError) as ex:
self._log.error("cannot read file: {0}", ex)
self._log.error("cannot read file: {}", ex)
continue
for key, value in data.items():

View file

@ -1541,7 +1541,7 @@ class FetchArtPlugin(plugins.BeetsPlugin, RequestMixin):
out = candidate
assert out.path is not None # help mypy
self._log.debug(
"using {0.LOC} image {1}",
"using {.LOC} image {}",
source,
util.displayable_path(out.path),
)
@ -1576,7 +1576,7 @@ class FetchArtPlugin(plugins.BeetsPlugin, RequestMixin):
message = ui.colorize(
"text_highlight_minor", "has album art"
)
self._log.info("{0}: {1}", album, message)
self._log.info("{}: {}", album, message)
else:
# In ordinary invocations, look for images on the
# filesystem. When forcing, however, always go to the Web
@ -1589,4 +1589,4 @@ class FetchArtPlugin(plugins.BeetsPlugin, RequestMixin):
message = ui.colorize("text_success", "found album art")
else:
message = ui.colorize("text_error", "no art found")
self._log.info("{0}: {1}", album, message)
self._log.info("{}: {}", album, message)

View file

@ -90,7 +90,7 @@ class FtInTitlePlugin(plugins.BeetsPlugin):
{
"auto": True,
"drop": False,
"format": "feat. {0}",
"format": "feat. {}",
"keep_in_artist": False,
}
)
@ -151,10 +151,10 @@ class FtInTitlePlugin(plugins.BeetsPlugin):
# In case the artist is kept, do not update the artist fields.
if keep_in_artist_field:
self._log.info(
"artist: {0} (Not changing due to keep_in_artist)", item.artist
"artist: {} (Not changing due to keep_in_artist)", item.artist
)
else:
self._log.info("artist: {0} -> {1}", item.artist, item.albumartist)
self._log.info("artist: {} -> {}", item.artist, item.albumartist)
item.artist = item.albumartist
if item.artist_sort:
@ -167,7 +167,7 @@ class FtInTitlePlugin(plugins.BeetsPlugin):
feat_format = self.config["format"].as_str()
new_format = feat_format.format(feat_part)
new_title = f"{item.title} {new_format}"
self._log.info("title: {0} -> {1}", item.title, new_title)
self._log.info("title: {} -> {}", item.title, new_title)
item.title = new_title
def ft_in_title(

View file

@ -62,7 +62,7 @@ class HookPlugin(BeetsPlugin):
def create_and_register_hook(self, event, command):
def hook_function(**kwargs):
if command is None or len(command) == 0:
self._log.error('invalid command "{0}"', command)
self._log.error('invalid command "{}"', command)
return
# For backwards compatibility, use a string formatter that decodes
@ -74,7 +74,7 @@ class HookPlugin(BeetsPlugin):
]
self._log.debug(
'running command "{0}" for event {1}',
'running command "{}" for event {}',
" ".join(command_pieces),
event,
)
@ -83,9 +83,9 @@ class HookPlugin(BeetsPlugin):
subprocess.check_call(command_pieces)
except subprocess.CalledProcessError as exc:
self._log.error(
"hook for {0} exited with status {1}", event, exc.returncode
"hook for {} exited with status {}", event, exc.returncode
)
except OSError as exc:
self._log.error("hook for {0} failed: {1}", event, exc)
self._log.error("hook for {} failed: {}", event, exc)
self.register_listener(event, hook_function)

View file

@ -70,10 +70,10 @@ class IHatePlugin(BeetsPlugin):
self._log.debug("processing your hate")
if self.do_i_hate_this(task, skip_queries):
task.choice_flag = Action.SKIP
self._log.info("skipped: {0}", summary(task))
self._log.info("skipped: {}", summary(task))
return
if self.do_i_hate_this(task, warn_queries):
self._log.info("you may hate this: {0}", summary(task))
self._log.info("you may hate this: {}", summary(task))
else:
self._log.debug("nothing to do")
else:

View file

@ -94,7 +94,7 @@ class ImportAddedPlugin(BeetsPlugin):
mtime = os.stat(util.syspath(source)).st_mtime
self.item_mtime[destination] = mtime
self._log.debug(
"Recorded mtime {0} for item '{1}' imported from '{2}'",
"Recorded mtime {} for item '{}' imported from '{}'",
mtime,
util.displayable_path(destination),
util.displayable_path(source),
@ -103,7 +103,7 @@ class ImportAddedPlugin(BeetsPlugin):
def update_album_times(self, lib, album):
if self.reimported_album(album):
self._log.debug(
"Album '{0}' is reimported, skipping import of "
"Album '{}' is reimported, skipping import of "
"added dates for the album and its items.",
util.displayable_path(album.path),
)
@ -119,7 +119,7 @@ class ImportAddedPlugin(BeetsPlugin):
item.store()
album.added = min(album_mtimes)
self._log.debug(
"Import of album '{0}', selected album.added={1} "
"Import of album '{}', selected album.added={} "
"from item file mtimes.",
album.album,
album.added,
@ -129,7 +129,7 @@ class ImportAddedPlugin(BeetsPlugin):
def update_item_times(self, lib, item):
if self.reimported_item(item):
self._log.debug(
"Item '{0}' is reimported, skipping import of added date.",
"Item '{}' is reimported, skipping import of added date.",
util.displayable_path(item.path),
)
return
@ -139,7 +139,7 @@ class ImportAddedPlugin(BeetsPlugin):
if self.config["preserve_mtimes"].get(bool):
self.write_item_mtime(item, mtime)
self._log.debug(
"Import of item '{0}', selected item.added={1}",
"Import of item '{}', selected item.added={}",
util.displayable_path(item.path),
item.added,
)
@ -153,7 +153,7 @@ class ImportAddedPlugin(BeetsPlugin):
if self.config["preserve_write_mtimes"].get(bool):
self.write_item_mtime(item, item.added)
self._log.debug(
"Write of item '{0}', selected item.added={1}",
"Write of item '{}', selected item.added={}",
util.displayable_path(item.path),
item.added,
)

View file

@ -136,7 +136,7 @@ class ImportFeedsPlugin(BeetsPlugin):
if "echo" in formats:
self._log.info("Location of imported music:")
for path in paths:
self._log.info(" {0}", path)
self._log.info(" {}", path)
def album_imported(self, lib, album):
self._record_items(lib, album.album, album.items())

View file

@ -219,7 +219,7 @@ class InfoPlugin(BeetsPlugin):
try:
data, item = data_emitter(included_keys or "*")
except (mediafile.UnreadableFileError, OSError) as ex:
self._log.error("cannot read file: {0}", ex)
self._log.error("cannot read file: {}", ex)
continue
if opts.summarize:

View file

@ -60,14 +60,14 @@ class InlinePlugin(BeetsPlugin):
for key, view in itertools.chain(
config["item_fields"].items(), config["pathfields"].items()
):
self._log.debug("adding item field {0}", key)
self._log.debug("adding item field {}", key)
func = self.compile_inline(view.as_str(), False)
if func is not None:
self.template_fields[key] = func
# Album fields.
for key, view in config["album_fields"].items():
self._log.debug("adding album field {0}", key)
self._log.debug("adding album field {}", key)
func = self.compile_inline(view.as_str(), True)
if func is not None:
self.album_template_fields[key] = func
@ -87,7 +87,7 @@ class InlinePlugin(BeetsPlugin):
func = _compile_func(python_code)
except SyntaxError:
self._log.error(
"syntax error in inline field definition:\n{0}",
"syntax error in inline field definition:\n{}",
traceback.format_exc(),
)
return

View file

@ -77,7 +77,7 @@ class IPFSPlugin(BeetsPlugin):
for album in lib.albums(args):
if len(album.items()) == 0:
self._log.info(
"{0} does not contain items, aborting", album
"{} does not contain items, aborting", album
)
self.ipfs_add(album)
@ -122,13 +122,13 @@ class IPFSPlugin(BeetsPlugin):
return False
try:
if album.ipfs:
self._log.debug("{0} already added", album_dir)
self._log.debug("{} already added", album_dir)
# Already added to ipfs
return False
except AttributeError:
pass
self._log.info("Adding {0} to ipfs", album_dir)
self._log.info("Adding {} to ipfs", album_dir)
if self.config["nocopy"]:
cmd = "ipfs add --nocopy -q -r".split()
@ -138,7 +138,7 @@ class IPFSPlugin(BeetsPlugin):
try:
output = util.command_output(cmd).stdout.split()
except (OSError, subprocess.CalledProcessError) as exc:
self._log.error("Failed to add {0}, error: {1}", album_dir, exc)
self._log.error("Failed to add {}, error: {}", album_dir, exc)
return False
length = len(output)
@ -146,12 +146,12 @@ class IPFSPlugin(BeetsPlugin):
line = line.strip()
if linenr == length - 1:
# last printed line is the album hash
self._log.info("album: {0}", line)
self._log.info("album: {}", line)
album.ipfs = line
else:
try:
item = album.items()[linenr]
self._log.info("item: {0}", line)
self._log.info("item: {}", line)
item.ipfs = line
item.store()
except IndexError:
@ -180,11 +180,11 @@ class IPFSPlugin(BeetsPlugin):
util.command_output(cmd)
except (OSError, subprocess.CalledProcessError) as err:
self._log.error(
"Failed to get {0} from ipfs.\n{1}", _hash, err.output
"Failed to get {} from ipfs.\n{}", _hash, err.output
)
return False
self._log.info("Getting {0} from ipfs", _hash)
self._log.info("Getting {} from ipfs", _hash)
imp = ui.commands.TerminalImportSession(
lib, loghandler=None, query=None, paths=[_hash]
)
@ -208,7 +208,7 @@ class IPFSPlugin(BeetsPlugin):
msg = f"Failed to publish library. Error: {err}"
self._log.error(msg)
return False
self._log.info("hash of library: {0}", output)
self._log.info("hash of library: {}", output)
def ipfs_import(self, lib, args):
_hash = args[0]
@ -306,7 +306,7 @@ class IPFSPlugin(BeetsPlugin):
items.append(item)
if len(items) < 1:
return False
self._log.info("Adding '{0}' to temporary library", album)
self._log.info("Adding '{}' to temporary library", album)
new_album = tmplib.add_album(items)
new_album.ipfs = album.ipfs
new_album.store(inherit=False)

View file

@ -65,7 +65,7 @@ class KeyFinderPlugin(BeetsPlugin):
command + [util.syspath(item.path)]
).stdout
except (subprocess.CalledProcessError, OSError) as exc:
self._log.error("execution failed: {0}", exc)
self._log.error("execution failed: {}", exc)
continue
try:
@ -73,7 +73,7 @@ class KeyFinderPlugin(BeetsPlugin):
except IndexError:
# Sometimes keyfinder-cli returns 0 but with no key, usually
# when the file is silent or corrupt, so we log and skip.
self._log.error("no key returned for path: {0}", item.path)
self._log.error("no key returned for path: {}", item.path)
continue
try:
@ -84,7 +84,7 @@ class KeyFinderPlugin(BeetsPlugin):
item["initial_key"] = key
self._log.info(
"added computed initial key {0} for {1}",
"added computed initial key {} for {}",
key,
util.displayable_path(item.path),
)

View file

@ -96,10 +96,10 @@ class KodiUpdate(BeetsPlugin):
continue
self._log.info(
"Kodi update triggered for {0}:{1}",
"Kodi update triggered for {}:{}",
instance["host"],
instance["port"],
)
except requests.exceptions.RequestException as e:
self._log.warning("Kodi update failed: {0}", str(e))
self._log.warning("Kodi update failed: {}", str(e))
continue

View file

@ -139,7 +139,7 @@ class LastGenrePlugin(plugins.BeetsPlugin):
# Read the tree
if c14n_filename:
self._log.debug("Loading canonicalization tree {0}", 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:
genres_tree = yaml.safe_load(f)
@ -607,12 +607,12 @@ class LastGenrePlugin(plugins.BeetsPlugin):
try:
res = obj.get_top_tags()
except PYLAST_EXCEPTIONS as exc:
self._log.debug("last.fm error: {0}", exc)
self._log.debug("last.fm error: {}", exc)
return []
except Exception as exc:
# Isolate bugs in pylast.
self._log.debug("{}", traceback.format_exc())
self._log.error("error in pylast library: {0}", exc)
self._log.error("error in pylast library: {}", exc)
return []
# Filter by weight (optionally).

View file

@ -120,7 +120,7 @@ def import_lastfm(lib, log):
if not user:
raise ui.UserError("You must specify a user name for lastimport")
log.info("Fetching last.fm library for @{0}", user)
log.info("Fetching last.fm library for @{}", user)
page_total = 1
page_current = 0
@ -130,7 +130,7 @@ def import_lastfm(lib, log):
# Iterate through a yet to be known page total count
while page_current < page_total:
log.info(
"Querying page #{0}{1}...",
"Querying page #{}{}...",
page_current + 1,
f"/{page_total}" if page_total > 1 else "",
)
@ -147,27 +147,27 @@ def import_lastfm(lib, log):
unknown_total += unknown
break
else:
log.error("ERROR: unable to read page #{0}", page_current + 1)
log.error("ERROR: unable to read page #{}", page_current + 1)
if retry < retry_limit:
log.info(
"Retrying page #{0}... ({1}/{2} retry)",
"Retrying page #{}... ({}/{} retry)",
page_current + 1,
retry + 1,
retry_limit,
)
else:
log.error(
"FAIL: unable to fetch page #{0}, ",
"tried {1} times",
"FAIL: unable to fetch page #{}, ",
"tried {} times",
page_current,
retry + 1,
)
page_current += 1
log.info("... done!")
log.info("finished processing {0} song pages", page_total)
log.info("{0} unknown play-counts", unknown_total)
log.info("{0} play-counts imported", found_total)
log.info("finished processing {} song pages", page_total)
log.info("{} unknown play-counts", unknown_total)
log.info("{} play-counts imported", found_total)
def fetch_tracks(user, page, limit):
@ -201,7 +201,7 @@ def process_tracks(lib, tracks, log):
total = len(tracks)
total_found = 0
total_fails = 0
log.info("Received {0} tracks in this page, processing...", total)
log.info("Received {} tracks in this page, processing...", total)
for num in range(0, total):
song = None
@ -220,7 +220,7 @@ def process_tracks(lib, tracks, log):
else None
)
log.debug("query: {0} - {1} ({2})", artist, title, album)
log.debug("query: {} - {} ({})", artist, title, album)
# First try to query by musicbrainz's trackid
if trackid:
@ -231,7 +231,7 @@ def process_tracks(lib, tracks, log):
# If not, try just album/title
if song is None:
log.debug(
"no album match, trying by album/title: {0} - {1}", album, title
"no album match, trying by album/title: {} - {}", album, title
)
query = dbcore.AndQuery(
[
@ -268,7 +268,7 @@ def process_tracks(lib, tracks, log):
count = int(song.get("play_count", 0))
new_count = int(tracks[num].get("playcount", 1))
log.debug(
"match: {0} - {1} ({2}) updating: play_count {3} => {4}",
"match: {} - {} ({}) updating: play_count {} => {}",
song.artist,
song.title,
song.album,
@ -280,11 +280,11 @@ def process_tracks(lib, tracks, log):
total_found += 1
else:
total_fails += 1
log.info(" - No match: {0} - {1} ({2})", artist, title, album)
log.info(" - No match: {} - {} ({})", artist, title, album)
if total_fails > 0:
log.info(
"Acquired {0}/{1} play-counts ({2} unknown)",
"Acquired {}/{} play-counts ({} unknown)",
total_found,
total,
total_fails,

View file

@ -48,8 +48,8 @@ class ListenBrainzPlugin(BeetsPlugin):
found_total += found
unknown_total += unknown
log.info("... done!")
log.info("{0} unknown play-counts", unknown_total)
log.info("{0} play-counts imported", found_total)
log.info("{} unknown play-counts", unknown_total)
log.info("{} play-counts imported", found_total)
def _make_request(self, url, params=None):
"""Makes a request to the ListenBrainz API."""

View file

@ -1090,7 +1090,7 @@ class LyricsPlugin(RequestHandler, plugins.BeetsPlugin):
return
if lyrics := self.find_lyrics(item):
self.info("🟢 Found lyrics: {0}", item)
self.info("🟢 Found lyrics: {}", item)
if translator := self.translator:
lyrics = translator.translate(lyrics, item.lyrics)
else:

View file

@ -154,10 +154,10 @@ class MusicBrainzCollectionPlugin(BeetsPlugin):
if re.match(UUID_REGEX, aid):
album_ids.append(aid)
else:
self._log.info("skipping invalid MBID: {0}", aid)
self._log.info("skipping invalid MBID: {}", aid)
# Submit to MusicBrainz.
self._log.info("Updating MusicBrainz collection {0}...", collection_id)
self._log.info("Updating MusicBrainz collection {}...", collection_id)
submit_albums(collection_id, album_ids)
if remove_missing:
self.remove_missing(collection_id, lib.albums())

View file

@ -226,7 +226,7 @@ class MissingPlugin(BeetsPlugin):
for track_info in album_info.tracks:
if track_info.track_id not in item_mbids:
self._log.debug(
"track {0} in album {1}",
"track {} in album {}",
track_info.track_id,
album_info.album_id,
)

View file

@ -51,8 +51,8 @@ class MPDClientWrapper:
if not self.strip_path.endswith("/"):
self.strip_path += "/"
self._log.debug("music_directory: {0}", self.music_directory)
self._log.debug("strip_path: {0}", self.strip_path)
self._log.debug("music_directory: {}", self.music_directory)
self._log.debug("strip_path: {}", self.strip_path)
self.client = mpd.MPDClient()
@ -64,7 +64,7 @@ class MPDClientWrapper:
if host[0] in ["/", "~"]:
host = os.path.expanduser(host)
self._log.info("connecting to {0}:{1}", host, port)
self._log.info("connecting to {}:{}", host, port)
try:
self.client.connect(host, port)
except OSError as e:
@ -89,7 +89,7 @@ class MPDClientWrapper:
try:
return getattr(self.client, command)()
except (OSError, mpd.ConnectionError) as err:
self._log.error("{0}", err)
self._log.error("{}", err)
if retries <= 0:
# if we exited without breaking, we couldn't reconnect in time :(
@ -123,7 +123,7 @@ class MPDClientWrapper:
result = os.path.join(self.music_directory, file)
else:
result = entry["file"]
self._log.debug("returning: {0}", result)
self._log.debug("returning: {}", result)
return result, entry.get("id")
def status(self):
@ -169,7 +169,7 @@ class MPDStats:
if item:
return item
else:
self._log.info("item not found: {0}", displayable_path(path))
self._log.info("item not found: {}", displayable_path(path))
def update_item(self, item, attribute, value=None, increment=None):
"""Update the beets item. Set attribute to value or increment the value
@ -188,7 +188,7 @@ class MPDStats:
item.store()
self._log.debug(
"updated: {0} = {1} [{2}]",
"updated: {} = {} [{}]",
attribute,
item[attribute],
displayable_path(item.path),
@ -234,12 +234,12 @@ class MPDStats:
def handle_played(self, song):
"""Updates the play count of a song."""
self.update_item(song["beets_item"], "play_count", increment=1)
self._log.info("played {0}", displayable_path(song["path"]))
self._log.info("played {}", displayable_path(song["path"]))
def handle_skipped(self, song):
"""Updates the skip count of a song."""
self.update_item(song["beets_item"], "skip_count", increment=1)
self._log.info("skipped {0}", displayable_path(song["path"]))
self._log.info("skipped {}", displayable_path(song["path"]))
def on_stop(self, status):
self._log.info("stop")
@ -278,11 +278,11 @@ class MPDStats:
self.handle_song_change(self.now_playing)
if is_url(path):
self._log.info("playing stream {0}", displayable_path(path))
self._log.info("playing stream {}", displayable_path(path))
self.now_playing = None
return
self._log.info("playing {0}", displayable_path(path))
self._log.info("playing {}", displayable_path(path))
self.now_playing = {
"started": time.time(),
@ -312,7 +312,7 @@ class MPDStats:
if handler:
handler(status)
else:
self._log.debug('unhandled status "{0}"', status)
self._log.debug('unhandled status "{}"', status)
events = self.mpd.events()

View file

@ -102,7 +102,7 @@ class MPDUpdatePlugin(BeetsPlugin):
try:
s = BufferedSocket(host, port)
except OSError as e:
self._log.warning("MPD connection failed: {0}", str(e.strerror))
self._log.warning("MPD connection failed: {}", str(e.strerror))
return
resp = s.readline()

View file

@ -836,7 +836,7 @@ class MusicBrainzPlugin(MetadataSourcePlugin):
"""
self._log.debug("Requesting MusicBrainz release {}", album_id)
if not (albumid := self._extract_id(album_id)):
self._log.debug("Invalid MBID ({0}).", album_id)
self._log.debug("Invalid MBID ({}).", album_id)
return None
try:
@ -873,7 +873,7 @@ class MusicBrainzPlugin(MetadataSourcePlugin):
or None if no track is found. May raise a MusicBrainzAPIError.
"""
if not (trackid := self._extract_id(track_id)):
self._log.debug("Invalid MBID ({0}).", track_id)
self._log.debug("Invalid MBID ({}).", track_id)
return None
try:

View file

@ -141,7 +141,7 @@ class RgTask:
item.rg_track_peak = track_gain.peak
item.store()
self._log.debug(
"applied track gain {0} LU, peak {1} of FS",
"applied track gain {} LU, peak {} of FS",
item.rg_track_gain,
item.rg_track_peak,
)
@ -155,7 +155,7 @@ class RgTask:
item.rg_album_peak = album_gain.peak
item.store()
self._log.debug(
"applied album gain {0} LU, peak {1} of FS",
"applied album gain {} LU, peak {} of FS",
item.rg_album_gain,
item.rg_album_peak,
)
@ -175,7 +175,7 @@ class RgTask:
self._store_track_gain(item, self.track_gains[0])
if write:
item.try_write()
self._log.debug("done analyzing {0}", item)
self._log.debug("done analyzing {}", item)
def _store_album(self, write: bool):
"""Store track/album gains for all tracks of the task in the database."""
@ -196,7 +196,7 @@ class RgTask:
self._store_album_gain(item, self.album_gain)
if write:
item.try_write()
self._log.debug("done analyzing {0}", item)
self._log.debug("done analyzing {}", item)
def store(self, write: bool):
"""Store computed gains for the items of this task in the database."""
@ -230,7 +230,7 @@ class R128Task(RgTask):
def _store_track_gain(self, item: Item, track_gain: Gain):
item.r128_track_gain = track_gain.gain
item.store()
self._log.debug("applied r128 track gain {0} LU", item.r128_track_gain)
self._log.debug("applied r128 track gain {} LU", item.r128_track_gain)
def _store_album_gain(self, item: Item, album_gain: Gain):
"""
@ -239,7 +239,7 @@ class R128Task(RgTask):
"""
item.r128_album_gain = album_gain.gain
item.store()
self._log.debug("applied r128 album gain {0} LU", item.r128_album_gain)
self._log.debug("applied r128 album gain {} LU", item.r128_album_gain)
AnyRgTask = TypeVar("AnyRgTask", bound=RgTask)
@ -428,7 +428,7 @@ class FfmpegBackend(Backend):
# call ffmpeg
self._log.debug(f"analyzing {item}")
cmd = self._construct_cmd(item, peak_method)
self._log.debug("executing {0}", " ".join(map(displayable_path, cmd)))
self._log.debug("executing {}", " ".join(map(displayable_path, cmd)))
output = call(cmd, self._log).stderr.splitlines()
# parse output
@ -654,8 +654,8 @@ class CommandBackend(Backend):
cmd = cmd + ["-d", str(int(target_level - 89))]
cmd = cmd + [syspath(i.path) for i in items]
self._log.debug("analyzing {0} files", len(items))
self._log.debug("executing {0}", " ".join(map(displayable_path, cmd)))
self._log.debug("analyzing {} files", len(items))
self._log.debug("executing {}", " ".join(map(displayable_path, cmd)))
output = call(cmd, self._log).stdout
self._log.debug("analysis finished")
return self.parse_tool_output(
@ -671,7 +671,7 @@ class CommandBackend(Backend):
for line in text.split(b"\n")[1 : num_lines + 1]:
parts = line.split(b"\t")
if len(parts) != 6 or parts[0] == b"File":
self._log.debug("bad tool output: {0}", text)
self._log.debug("bad tool output: {}", text)
raise ReplayGainError("mp3gain failed")
# _file = parts[0]
@ -1096,7 +1096,7 @@ class AudioToolsBackend(Backend):
)
self._log.debug(
"ReplayGain for track {0} - {1}: {2:.2f}, {3:.2f}",
"ReplayGain for track {} - {}: {2:.2f}, {3:.2f}",
item.artist,
item.title,
rg_track_gain,
@ -1123,7 +1123,7 @@ class AudioToolsBackend(Backend):
)
track_gains.append(Gain(gain=rg_track_gain, peak=rg_track_peak))
self._log.debug(
"ReplayGain for track {0}: {1:.2f}, {2:.2f}",
"ReplayGain for track {}: {.2f}, {.2f}",
item,
rg_track_gain,
rg_track_peak,
@ -1136,7 +1136,7 @@ class AudioToolsBackend(Backend):
rg_album_gain, task.target_level
)
self._log.debug(
"ReplayGain for album {0}: {1:.2f}, {2:.2f}",
"ReplayGain for album {}: {.2f}, {.2f}",
task.items[0].album,
rg_album_gain,
rg_album_peak,
@ -1336,19 +1336,19 @@ class ReplayGainPlugin(BeetsPlugin):
items, nothing is done.
"""
if not force and not self.album_requires_gain(album):
self._log.info("Skipping album {0}", album)
self._log.info("Skipping album {}", album)
return
items_iter = iter(album.items())
use_r128 = self.should_use_r128(next(items_iter))
if any(use_r128 != self.should_use_r128(i) for i in items_iter):
self._log.error(
"Cannot calculate gain for album {0} (incompatible formats)",
"Cannot calculate gain for album {} (incompatible formats)",
album,
)
return
self._log.info("analyzing {0}", album)
self._log.info("analyzing {}", album)
discs: dict[int, list[Item]] = {}
if self.config["per_disc"].get(bool):
@ -1372,7 +1372,7 @@ class ReplayGainPlugin(BeetsPlugin):
callback=store_cb,
)
except ReplayGainError as e:
self._log.info("ReplayGain error: {0}", e)
self._log.info("ReplayGain error: {}", e)
except FatalReplayGainError as e:
raise ui.UserError(f"Fatal replay gain error: {e}")
@ -1384,7 +1384,7 @@ class ReplayGainPlugin(BeetsPlugin):
in the item, nothing is done.
"""
if not force and not self.track_requires_gain(item):
self._log.info("Skipping track {0}", item)
self._log.info("Skipping track {}", item)
return
use_r128 = self.should_use_r128(item)
@ -1401,7 +1401,7 @@ class ReplayGainPlugin(BeetsPlugin):
callback=store_cb,
)
except ReplayGainError as e:
self._log.info("ReplayGain error: {0}", e)
self._log.info("ReplayGain error: {}", e)
except FatalReplayGainError as e:
raise ui.UserError(f"Fatal replay gain error: {e}")

View file

@ -59,7 +59,7 @@ class RewritePlugin(BeetsPlugin):
raise ui.UserError(
f"invalid field name ({fieldname}) in rewriter"
)
self._log.debug("adding template field {0}", key)
self._log.debug("adding template field {}", key)
pattern = re.compile(pattern.lower())
rules[fieldname].append((pattern, value))
if fieldname == "artist":

View file

@ -60,7 +60,7 @@ class ScrubPlugin(BeetsPlugin):
# Walk through matching files and remove tags.
for item in lib.items(args):
self._log.info(
"scrubbing: {0}", util.displayable_path(item.path)
"scrubbing: {}", util.displayable_path(item.path)
)
self._scrub_item(item, opts.write)
@ -110,7 +110,7 @@ class ScrubPlugin(BeetsPlugin):
f.save()
except (OSError, mutagen.MutagenError) as exc:
self._log.error(
"could not scrub {0}: {1}", util.displayable_path(path), exc
"could not scrub {}: {}", util.displayable_path(path), exc
)
def _scrub_item(self, item, restore):
@ -124,7 +124,7 @@ class ScrubPlugin(BeetsPlugin):
util.syspath(item.path), config["id3v23"].get(bool)
)
except mediafile.UnreadableFileError as exc:
self._log.error("could not open file to scrub: {0}", exc)
self._log.error("could not open file to scrub: {}", exc)
return
images = mf.images
@ -144,12 +144,12 @@ class ScrubPlugin(BeetsPlugin):
mf.images = images
mf.save()
except mediafile.UnreadableFileError as exc:
self._log.error("could not write tags: {0}", exc)
self._log.error("could not write tags: {}", exc)
def import_task_files(self, session, task):
"""Automatically scrub imported files."""
for item in task.imported_items():
self._log.debug(
"auto-scrubbing {0}", util.displayable_path(item.path)
"auto-scrubbing {}", util.displayable_path(item.path)
)
self._scrub_item(item, ui.should_write())

View file

@ -234,7 +234,7 @@ class SmartPlaylistPlugin(BeetsPlugin):
for playlist in self._unmatched_playlists:
n, (q, _), (a_q, _) = playlist
if self.matches(model, q, a_q):
self._log.debug("{0} will be updated because of {1}", n, model)
self._log.debug("{} will be updated because of {}", n, model)
self._matched_playlists.add(playlist)
self.register_listener("cli_exit", self.update_playlists)
@ -243,12 +243,12 @@ class SmartPlaylistPlugin(BeetsPlugin):
def update_playlists(self, lib, pretend=False):
if pretend:
self._log.info(
"Showing query results for {0} smart playlists...",
"Showing query results for {} smart playlists...",
len(self._matched_playlists),
)
else:
self._log.info(
"Updating {0} smart playlists...", len(self._matched_playlists)
"Updating {} smart playlists...", len(self._matched_playlists)
)
playlist_dir = self.config["playlist_dir"].as_filename()
@ -267,7 +267,7 @@ class SmartPlaylistPlugin(BeetsPlugin):
if pretend:
self._log.info("Results for playlist {}:", name)
else:
self._log.info("Creating playlist {0}", name)
self._log.info("Creating playlist {}", name)
items = []
if query:
@ -340,13 +340,11 @@ class SmartPlaylistPlugin(BeetsPlugin):
if pretend:
self._log.info(
"Displayed results for {0} playlists",
"Displayed results for {} playlists",
len(self._matched_playlists),
)
else:
self._log.info(
"{0} playlists updated", len(self._matched_playlists)
)
self._log.info("{} playlists updated", len(self._matched_playlists))
class PlaylistItem:

View file

@ -516,7 +516,7 @@ class SpotifyPlugin(
if self.config["mode"].get() not in ["list", "open"]:
self._log.warning(
"{0} is not a valid mode", self.config["mode"].get()
"{} is not a valid mode", self.config["mode"].get()
)
return False

View file

@ -107,8 +107,8 @@ class SubsonicUpdate(BeetsPlugin):
user = self.config["user"].as_str()
auth = self.config["auth"].as_str()
url = self.__format_url("startScan")
self._log.debug("URL is {0}", url)
self._log.debug("auth type is {0}", self.config["auth"])
self._log.debug("URL is {}", url)
self._log.debug("auth type is {}", self.config["auth"])
if auth == "token":
salt, token = self.__create_token()
@ -153,6 +153,6 @@ class SubsonicUpdate(BeetsPlugin):
error_message = json["subsonic-response"]["error"]["message"]
self._log.error(f"Error: {error_message}")
else:
self._log.error("Error: {0}", json)
self._log.error("Error: {}", json)
except Exception as error:
self._log.error(f"Error: {error}")

View file

@ -23,7 +23,7 @@ __version__ = "1.1"
PATTERN_THE = "^the\\s"
PATTERN_A = "^[a][n]?\\s"
FORMAT = "{0}, {1}"
FORMAT = "{}, {}"
class ThePlugin(BeetsPlugin):
@ -38,7 +38,7 @@ class ThePlugin(BeetsPlugin):
{
"the": True,
"a": True,
"format": "{0}, {1}",
"format": "{}, {}",
"strip": False,
"patterns": [],
}
@ -50,11 +50,11 @@ class ThePlugin(BeetsPlugin):
try:
re.compile(p)
except re.error:
self._log.error("invalid pattern: {0}", p)
self._log.error("invalid pattern: {}", p)
else:
if not (p.startswith("^") or p.endswith("$")):
self._log.warning(
'warning: "{0}" will not match string start/end',
'warning: "{}" will not match string start/end',
p,
)
if self.config["a"]:
@ -94,7 +94,7 @@ class ThePlugin(BeetsPlugin):
for p in self.patterns:
r = self.unthe(text, p)
if r != text:
self._log.debug('"{0}" -> "{1}"', text, r)
self._log.debug('"{}" -> "{}"', text, r)
break
return r
else:

View file

@ -109,16 +109,16 @@ class ThumbnailsPlugin(BeetsPlugin):
uri_getter = GioURI()
if not uri_getter.available:
uri_getter = PathlibURI()
self._log.debug("using {0.name} to compute URIs", uri_getter)
self._log.debug("using {.name} to compute URIs", uri_getter)
self.get_uri = uri_getter.uri
return True
def process_album(self, album):
"""Produce thumbnails for the album folder."""
self._log.debug("generating thumbnail for {0}", album)
self._log.debug("generating thumbnail for {}", album)
if not album.artpath:
self._log.info("album {0} has no art", album)
self._log.info("album {} has no art", album)
return
if self.config["dolphin"]:
@ -127,7 +127,7 @@ class ThumbnailsPlugin(BeetsPlugin):
size = ArtResizer.shared.get_size(album.artpath)
if not size:
self._log.warning(
"problem getting the picture size for {0}", album.artpath
"problem getting the picture size for {}", album.artpath
)
return
@ -137,9 +137,9 @@ class ThumbnailsPlugin(BeetsPlugin):
wrote &= self.make_cover_thumbnail(album, 128, NORMAL_DIR)
if wrote:
self._log.info("wrote thumbnail for {0}", album)
self._log.info("wrote thumbnail for {}", album)
else:
self._log.info("nothing to do for {0}", album)
self._log.info("nothing to do for {}", album)
def make_cover_thumbnail(self, album, size, target_dir):
"""Make a thumbnail of given size for `album` and put it in
@ -154,16 +154,16 @@ class ThumbnailsPlugin(BeetsPlugin):
):
if self.config["force"]:
self._log.debug(
"found a suitable {1}x{1} thumbnail for {0}, "
"found a suitable {0}x{0} thumbnail for {1}, "
"forcing regeneration",
album,
size,
album,
)
else:
self._log.debug(
"{1}x{1} thumbnail for {0} exists and is recent enough",
album,
"{0}x{0} thumbnail for {1} exists and is recent enough",
size,
album,
)
return False
resized = ArtResizer.shared.resize(size, album.artpath, target)
@ -192,7 +192,7 @@ class ThumbnailsPlugin(BeetsPlugin):
ArtResizer.shared.write_metadata(image_path, metadata)
except Exception:
self._log.exception(
"could not write metadata to {0}", displayable_path(image_path)
"could not write metadata to {}", displayable_path(image_path)
)
def make_dolphin_cover_thumbnail(self, album):
@ -204,7 +204,7 @@ class ThumbnailsPlugin(BeetsPlugin):
f.write("[Desktop Entry]\n")
f.write(f"Icon=./{artfile.decode('utf-8')}")
f.close()
self._log.debug("Wrote file {0}", displayable_path(outfilename))
self._log.debug("Wrote file {}", displayable_path(outfilename))
class URIGetter:

View file

@ -474,7 +474,7 @@ class WebPlugin(BeetsPlugin):
# Enable CORS if required.
if self.config["cors"]:
self._log.info(
"Enabling CORS with origin: {0}", self.config["cors"]
"Enabling CORS with origin: {}", self.config["cors"]
)
from flask_cors import CORS

View file

@ -90,10 +90,10 @@ class ZeroPlugin(BeetsPlugin):
Do some sanity checks then compile the regexes.
"""
if field not in MediaFile.fields():
self._log.error("invalid field: {0}", field)
self._log.error("invalid field: {}", field)
elif field in ("id", "path", "album_id"):
self._log.warning(
"field '{0}' ignored, zeroing it would be dangerous", field
"field '{}' ignored, zeroing it would be dangerous", field
)
else:
try:
@ -137,7 +137,7 @@ class ZeroPlugin(BeetsPlugin):
if match:
fields_set = True
self._log.debug("{0}: {1} -> None", field, value)
self._log.debug("{}: {} -> None", field, value)
tags[field] = None
if self.config["update_database"]:
item[field] = None

View file

@ -56,21 +56,21 @@ class FtInTitlePluginFunctional(PluginTestCase):
assert item["title"] == "Song 1"
def test_functional_custom_format(self):
self._ft_set_config("feat. {0}")
self._ft_set_config("feat. {}")
item = self._ft_add_item("/", "Alice ft Bob", "Song 1", "Alice")
self.run_command("ftintitle")
item.load()
assert item["artist"] == "Alice"
assert item["title"] == "Song 1 feat. Bob"
self._ft_set_config("featuring {0}")
self._ft_set_config("featuring {}")
item = self._ft_add_item("/", "Alice feat. Bob", "Song 1", "Alice")
self.run_command("ftintitle")
item.load()
assert item["artist"] == "Alice"
assert item["title"] == "Song 1 featuring Bob"
self._ft_set_config("with {0}")
self._ft_set_config("with {}")
item = self._ft_add_item("/", "Alice feat Bob", "Song 1", "Alice")
self.run_command("ftintitle")
item.load()
@ -78,7 +78,7 @@ class FtInTitlePluginFunctional(PluginTestCase):
assert item["title"] == "Song 1 with Bob"
def test_functional_keep_in_artist(self):
self._ft_set_config("feat. {0}", keep_in_artist=True)
self._ft_set_config("feat. {}", keep_in_artist=True)
item = self._ft_add_item("/", "Alice ft Bob", "Song 1", "Alice")
self.run_command("ftintitle")
item.load()

View file

@ -77,7 +77,7 @@ class MPDStatsTest(PluginTestCase):
except KeyboardInterrupt:
pass
log.debug.assert_has_calls([call('unhandled status "{0}"', ANY)])
log.debug.assert_has_calls([call('unhandled status "{}"', ANY)])
log.info.assert_has_calls(
[call("pause"), call("playing {0}", ANY), call("stop")]
[call("pause"), call("playing {}", ANY), call("stop")]
)

View file

@ -42,7 +42,7 @@ class LoggingTest(unittest.TestCase):
logger.addHandler(handler)
logger.propagate = False
logger.warning("foo {0} {bar}", "oof", bar="baz")
logger.warning("foo {} {bar}", "oof", bar="baz")
handler.flush()
assert stream.getvalue(), "foo oof baz"