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 - The loggers use `str.format
<http://docs.python.org/library/stdtypes.html#str.format>`__-style logging <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. formatting.
- Exception handlers must use ``except A as B:`` instead of ``except A, B:``. - 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)) mf = mediafile.MediaFile(syspath(item.path))
except mediafile.UnreadableFileError as exc: except mediafile.UnreadableFileError as exc:
log.warning( log.warning(
"Could not extract art from {0}: {1}", "Could not extract art from {}: {}",
displayable_path(item.path), displayable_path(item.path),
exc, exc,
) )
@ -83,10 +83,10 @@ def embed_item(
# Get the `Image` object from the file. # Get the `Image` object from the file.
try: try:
log.debug("embedding {0}", displayable_path(imagepath)) log.debug("embedding {}", displayable_path(imagepath))
image = mediafile_image(imagepath, maxwidth) image = mediafile_image(imagepath, maxwidth)
except OSError as exc: except OSError as exc:
log.warning("could not read image file: {0}", exc) log.warning("could not read image file: {}", exc)
return return
# Make sure the image kind is safe (some formats only support PNG # 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.""" """Embed album art into all of the album's items."""
imagepath = album.artpath imagepath = album.artpath
if not imagepath: if not imagepath:
log.info("No album art present for {0}", album) log.info("No album art present for {}", album)
return return
if not os.path.isfile(syspath(imagepath)): if not os.path.isfile(syspath(imagepath)):
log.info( log.info(
"Album art not found at {0} for {1}", "Album art not found at {} for {}",
displayable_path(imagepath), displayable_path(imagepath),
album, album,
) )
@ -122,7 +122,7 @@ def embed_album(
if maxwidth: if maxwidth:
imagepath = resize_image(log, imagepath, maxwidth, quality) 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(): for item in album.items():
embed_item( embed_item(
@ -143,7 +143,7 @@ def resize_image(log, imagepath, maxwidth, quality):
specified quality level. specified quality level.
""" """
log.debug( 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, maxwidth,
quality, quality,
) )
@ -183,18 +183,18 @@ def extract(log, outpath, item):
art = get_art(log, item) art = get_art(log, item)
outpath = bytestring_path(outpath) outpath = bytestring_path(outpath)
if not art: if not art:
log.info("No album art present in {0}, skipping.", item) log.info("No album art present in {}, skipping.", item)
return return
# Add an extension to the filename. # Add an extension to the filename.
ext = mediafile.image_extension(art) ext = mediafile.image_extension(art)
if not ext: 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 return
outpath += bytestring_path(f".{ext}") outpath += bytestring_path(f".{ext}")
log.info( log.info(
"Extracting album art from: {0} to: {1}", "Extracting album art from: {} to: {}",
item, item,
displayable_path(outpath), displayable_path(outpath),
) )
@ -212,7 +212,7 @@ def extract_first(log, outpath, items):
def clear(log, lib, query): def clear(log, lib, query):
items = lib.items(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: for item in items:
log.debug("Clearing art for {0}", item) log.debug("Clearing art for {}", item)
item.try_write(tags={"images": None}) 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.") log.debug("No album ID consensus.")
return None return None
# If all album IDs are equal, look up the album. # 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) return metadata_plugins.album_for_id(first)
@ -197,9 +197,7 @@ def _add_candidate(
checking the track count, ordering the items, checking for checking the track count, ordering the items, checking for
duplicates, and calculating the distance. duplicates, and calculating the distance.
""" """
log.debug( log.debug("Candidate: {} - {} ({})", info.artist, info.album, info.album_id)
"Candidate: {0} - {1} ({2})", info.artist, info.album, info.album_id
)
# Discard albums with zero tracks. # Discard albums with zero tracks.
if not info.tracks: if not info.tracks:
@ -215,7 +213,7 @@ def _add_candidate(
required_tags: Sequence[str] = config["match"]["required"].as_str_seq() required_tags: Sequence[str] = config["match"]["required"].as_str_seq()
for req_tag in required_tags: for req_tag in required_tags:
if getattr(info, req_tag) is None: 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 return
# Find mapping between the items and the track info. # 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() ignored_tags: Sequence[str] = config["match"]["ignored"].as_str_seq()
for penalty in ignored_tags: for penalty in ignored_tags:
if penalty in penalties: if penalty in penalties:
log.debug("Ignored. Penalty: {0}", penalty) log.debug("Ignored. Penalty: {}", penalty)
return return
log.debug("Success. Distance: {0}", dist) log.debug("Success. Distance: {}", dist)
results[info.album_id] = hooks.AlbumMatch( results[info.album_id] = hooks.AlbumMatch(
dist, info, mapping, extra_items, extra_tracks dist, info, mapping, extra_items, extra_tracks
) )
@ -265,7 +263,7 @@ def tag_album(
likelies, consensus = get_most_common_tags(items) likelies, consensus = get_most_common_tags(items)
cur_artist: str = likelies["artist"] cur_artist: str = likelies["artist"]
cur_album: str = likelies["album"] 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. # The output result, keys are the MB album ID.
candidates: dict[Any, AlbumMatch] = {} candidates: dict[Any, AlbumMatch] = {}
@ -273,7 +271,7 @@ def tag_album(
# Search by explicit ID. # Search by explicit ID.
if search_ids: if search_ids:
for search_id in 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): if info := metadata_plugins.album_for_id(search_id):
_add_candidate(items, candidates, info) _add_candidate(items, candidates, info)
@ -283,7 +281,7 @@ def tag_album(
if info := match_by_id(items): if info := match_by_id(items):
_add_candidate(items, candidates, info) _add_candidate(items, candidates, info)
rec = _recommendation(list(candidates.values())) 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 candidates and not config["import"]["timid"]:
# If we have a very good MBID match, return immediately. # If we have a very good MBID match, return immediately.
# Otherwise, this match will compete against metadata-based # Otherwise, this match will compete against metadata-based
@ -300,7 +298,7 @@ def tag_album(
if not (search_artist and search_album): if not (search_artist and search_album):
# No explicit search terms -- use current metadata. # No explicit search terms -- use current metadata.
search_artist, search_album = cur_artist, cur_album 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? # Is this album likely to be a "various artist" release?
va_likely = ( va_likely = (
@ -308,7 +306,7 @@ def tag_album(
or (search_artist.lower() in VA_ARTISTS) or (search_artist.lower() in VA_ARTISTS)
or any(item.comp for item in items) 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. # Get the results from the data sources.
for matched_candidate in metadata_plugins.candidates( for matched_candidate in metadata_plugins.candidates(
@ -316,7 +314,7 @@ def tag_album(
): ):
_add_candidate(items, candidates, matched_candidate) _add_candidate(items, candidates, matched_candidate)
log.debug("Evaluating {0} candidates.", len(candidates)) log.debug("Evaluating {} candidates.", len(candidates))
# Sort and get the recommendation. # Sort and get the recommendation.
candidates_sorted = _sort_candidates(candidates.values()) candidates_sorted = _sort_candidates(candidates.values())
rec = _recommendation(candidates_sorted) rec = _recommendation(candidates_sorted)
@ -345,7 +343,7 @@ def tag_item(
trackids = search_ids or [t for t in [item.mb_trackid] if t] trackids = search_ids or [t for t in [item.mb_trackid] if t]
if trackids: if trackids:
for trackid in 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): if info := metadata_plugins.track_for_id(trackid):
dist = track_distance(item, info, incl_artist=True) dist = track_distance(item, info, incl_artist=True)
candidates[info.track_id] = hooks.TrackMatch(dist, info) candidates[info.track_id] = hooks.TrackMatch(dist, info)
@ -369,7 +367,7 @@ def tag_item(
# Search terms. # Search terms.
search_artist = search_artist or item.artist search_artist = search_artist or item.artist
search_title = search_title or item.title 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. # Get and evaluate candidate metadata.
for track_info in metadata_plugins.item_candidates( 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) candidates[track_info.track_id] = hooks.TrackMatch(dist, track_info)
# Sort by distance and return with recommendation. # 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()) candidates_sorted = _sort_candidates(candidates.values())
rec = _recommendation(candidates_sorted) rec = _recommendation(candidates_sorted)
return Proposal(candidates_sorted, rec) 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 """Log a message about a given album to the importer log. The status
should reflect the reason the album couldn't be tagged. 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): def log_choice(self, task: ImportTask, duplicate=False):
"""Logs the task's current choice if it should be logged. If """Logs the task's current choice if it should be logged. If
@ -187,7 +187,7 @@ class ImportSession:
def run(self): def run(self):
"""Run the import task.""" """Run the import task."""
self.logger.info("import started {0}", time.asctime()) self.logger.info("import started {}", time.asctime())
self.set_config(config["import"]) self.set_config(config["import"])
# Set up the pipeline. # Set up the pipeline.
@ -297,7 +297,7 @@ class ImportSession:
# Either accept immediately or prompt for input to decide. # Either accept immediately or prompt for input to decide.
if self.want_resume is True or self.should_resume(toppath): if self.want_resume is True or self.should_resume(toppath):
log.warning( log.warning(
"Resuming interrupted import of {0}", "Resuming interrupted import of {}",
util.displayable_path(toppath), util.displayable_path(toppath),
) )
self._is_resuming[toppath] = True self._is_resuming[toppath] = True

View file

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

View file

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

View file

@ -267,12 +267,12 @@ class ImportTask(BaseImportTask):
def remove_duplicates(self, lib: library.Library): def remove_duplicates(self, lib: library.Library):
duplicate_items = self.duplicate_items(lib) 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: for item in duplicate_items:
item.remove() item.remove()
if lib.directory in util.ancestry(item.path): if lib.directory in util.ancestry(item.path):
log.debug( log.debug(
"deleting duplicate {0}", util.displayable_path(item.path) "deleting duplicate {}", util.displayable_path(item.path)
) )
util.remove(item.path) util.remove(item.path)
util.prune_dirs(os.path.dirname(item.path), lib.directory) 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(): for field, view in config["import"]["set_fields"].items():
value = str(view.get()) value = str(view.get())
log.debug( log.debug(
"Set field {1}={2} for {0}", "Set field {}={} for {}",
util.displayable_path(self.paths),
field, field,
value, value,
util.displayable_path(self.paths),
) )
self.album.set_parse(field, format(self.album, value)) self.album.set_parse(field, format(self.album, value))
for item in items: for item in items:
@ -622,13 +622,13 @@ class ImportTask(BaseImportTask):
for item in self.imported_items(): for item in self.imported_items():
for dup_item in self.replaced_items[item]: for dup_item in self.replaced_items[item]:
log.debug( log.debug(
"Replacing item {0}: {1}", "Replacing item {}: {}",
dup_item.id, dup_item.id,
util.displayable_path(item.path), util.displayable_path(item.path),
) )
dup_item.remove() dup_item.remove()
log.debug( log.debug(
"{0} of {1} items replaced", "{} of {} items replaced",
sum(bool(v) for v in self.replaced_items.values()), sum(bool(v) for v in self.replaced_items.values()),
len(self.imported_items()), len(self.imported_items()),
) )
@ -747,10 +747,10 @@ class SingletonImportTask(ImportTask):
for field, view in config["import"]["set_fields"].items(): for field, view in config["import"]["set_fields"].items():
value = str(view.get()) value = str(view.get())
log.debug( log.debug(
"Set field {1}={2} for {0}", "Set field {}={} for {}",
util.displayable_path(self.paths),
field, field,
value, value,
util.displayable_path(self.paths),
) )
self.item.set_parse(field, format(self.item, value)) self.item.set_parse(field, format(self.item, value))
self.item.store() self.item.store()
@ -870,7 +870,7 @@ class ArchiveImportTask(SentinelImportTask):
"""Removes the temporary directory the archive was extracted to.""" """Removes the temporary directory the archive was extracted to."""
if self.extracted and self.toppath: if self.extracted and self.toppath:
log.debug( log.debug(
"Removing extracted directory: {0}", "Removing extracted directory: {}",
util.displayable_path(self.toppath), util.displayable_path(self.toppath),
) )
shutil.rmtree(util.syspath(self.toppath)) shutil.rmtree(util.syspath(self.toppath))
@ -1002,7 +1002,7 @@ class ImportTaskFactory:
"""Return a `SingletonImportTask` for the music file.""" """Return a `SingletonImportTask` for the music file."""
if self.session.already_imported(self.toppath, [path]): if self.session.already_imported(self.toppath, [path]):
log.debug( log.debug(
"Skipping previously-imported path: {0}", "Skipping previously-imported path: {}",
util.displayable_path(path), util.displayable_path(path),
) )
self.skipped += 1 self.skipped += 1
@ -1026,7 +1026,7 @@ class ImportTaskFactory:
if self.session.already_imported(self.toppath, dirs): if self.session.already_imported(self.toppath, dirs):
log.debug( log.debug(
"Skipping previously-imported path: {0}", "Skipping previously-imported path: {}",
util.displayable_path(dirs), util.displayable_path(dirs),
) )
self.skipped += 1 self.skipped += 1
@ -1063,19 +1063,17 @@ class ImportTaskFactory:
) )
return return
log.debug( log.debug("Extracting archive: {}", util.displayable_path(self.toppath))
"Extracting archive: {0}", util.displayable_path(self.toppath)
)
archive_task = ArchiveImportTask(self.toppath) archive_task = ArchiveImportTask(self.toppath)
try: try:
archive_task.extract() archive_task.extract()
except Exception as exc: except Exception as exc:
log.error("extraction failed: {0}", exc) log.error("extraction failed: {}", exc)
return return
# Now read albums from the extracted directory. # Now read albums from the extracted directory.
self.toppath = archive_task.toppath self.toppath = archive_task.toppath
log.debug("Archive extracted to: {0}", self.toppath) log.debug("Archive extracted to: {}", self.toppath)
return archive_task return archive_task
def read_item(self, path: util.PathBytes): def read_item(self, path: util.PathBytes):
@ -1091,10 +1089,10 @@ class ImportTaskFactory:
# Silently ignore non-music files. # Silently ignore non-music files.
pass pass
elif isinstance(exc.reason, mediafile.UnreadableFileError): elif isinstance(exc.reason, mediafile.UnreadableFileError):
log.warning("unreadable file: {0}", util.displayable_path(path)) log.warning("unreadable file: {}", util.displayable_path(path))
else: else:
log.error( 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) new_art = util.unique_path(new_art)
log.debug( log.debug(
"moving album art {0} to {1}", "moving album art {} to {}",
util.displayable_path(old_art), util.displayable_path(old_art),
util.displayable_path(new_art), util.displayable_path(new_art),
) )
@ -992,7 +992,7 @@ class Item(LibModel):
self.write(*args, **kwargs) self.write(*args, **kwargs)
return True return True
except FileOperationError as exc: except FileOperationError as exc:
log.error("{0}", exc) log.error("{}", exc)
return False return False
def try_sync(self, write, move, with_album=True): 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. # Check whether this file is inside the library directory.
if self._db and self._db.directory in util.ancestry(self.path): if self._db and self._db.directory in util.ancestry(self.path):
log.debug( log.debug(
"moving {0} to synchronize path", "moving {} to synchronize path",
util.displayable_path(self.path), util.displayable_path(self.path),
) )
self.move(with_album=with_album) self.move(with_album=with_album)
@ -1087,7 +1087,7 @@ class Item(LibModel):
try: try:
return os.path.getsize(syspath(self.path)) return os.path.getsize(syspath(self.path))
except (OSError, Exception) as exc: except (OSError, Exception) as exc:
log.warning("could not get filesize: {0}", exc) log.warning("could not get filesize: {}", exc)
return 0 return 0
# Model methods. # 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. Return a list of non-None values returned from the handlers.
""" """
log.debug("Sending event: {0}", event) log.debug("Sending event: {}", event)
return [ return [
r r
for handler in BeetsPlugin.listeners[event] 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`. The item is attached to the database from `self.lib`.
""" """
values_ = { values_ = {
"title": "t\u00eftle {0}", "title": "t\u00eftle {}",
"artist": "the \u00e4rtist", "artist": "the \u00e4rtist",
"album": "the \u00e4lbum", "album": "the \u00e4lbum",
"track": 1, "track": 1,

View file

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

View file

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

View file

@ -126,7 +126,7 @@ class HumanReadableError(Exception):
""" """
if self.tb: if self.tb:
logger.debug(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): class FilesystemError(HumanReadableError):

View file

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

View file

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

View file

@ -73,12 +73,12 @@ class BPMPlugin(BeetsPlugin):
item = items[0] item = items[0]
if item["bpm"]: if item["bpm"]:
self._log.info("Found bpm {0}", item["bpm"]) self._log.info("Found bpm {}", item["bpm"])
if not overwrite: if not overwrite:
return return
self._log.info( 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), self.config["max_strokes"].get(int),
) )
new_bpm = bpm(self.config["max_strokes"].get(int)) new_bpm = bpm(self.config["max_strokes"].get(int))
@ -86,4 +86,4 @@ class BPMPlugin(BeetsPlugin):
if write: if write:
item.try_write() item.try_write()
item.store() 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)) duration, fp = acoustid.fingerprint_file(util.syspath(path))
except acoustid.FingerprintGenerationError as exc: except acoustid.FingerprintGenerationError as exc:
log.error( log.error(
"fingerprinting of {0} failed: {1}", "fingerprinting of {} failed: {}",
util.displayable_path(repr(path)), util.displayable_path(repr(path)),
exc, exc,
) )
@ -103,12 +103,12 @@ def acoustid_match(log, path):
) )
except acoustid.AcoustidError as exc: except acoustid.AcoustidError as exc:
log.debug( log.debug(
"fingerprint matching {0} failed: {1}", "fingerprint matching {} failed: {}",
util.displayable_path(repr(path)), util.displayable_path(repr(path)),
exc, exc,
) )
return None 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. # Ensure the response is usable and parse it.
if res["status"] != "ok" or not res.get("results"): 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] release_ids = [rel["id"] for rel in releases]
log.debug( 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 _matches[path] = recording_ids, release_ids
@ -211,7 +211,7 @@ class AcoustidPlugin(MetadataSourcePlugin):
if album: if album:
albums.append(album) albums.append(album)
self._log.debug("acoustid album candidates: {0}", len(albums)) self._log.debug("acoustid album candidates: {}", len(albums))
return albums return albums
def item_candidates(self, item, artist, title) -> Iterable[TrackInfo]: def item_candidates(self, item, artist, title) -> Iterable[TrackInfo]:
@ -224,7 +224,7 @@ class AcoustidPlugin(MetadataSourcePlugin):
track = self.mb.track_for_id(recording_id) track = self.mb.track_for_id(recording_id)
if track: if track:
tracks.append(track) tracks.append(track)
self._log.debug("acoustid item candidates: {0}", len(tracks)) self._log.debug("acoustid item candidates: {}", len(tracks))
return tracks return tracks
def album_for_id(self, *args, **kwargs): def album_for_id(self, *args, **kwargs):
@ -292,11 +292,11 @@ def submit_items(log, userkey, items, chunksize=64):
def submit_chunk(): def submit_chunk():
"""Submit the current accumulated fingerprint data.""" """Submit the current accumulated fingerprint data."""
log.info("submitting {0} fingerprints", len(data)) log.info("submitting {} fingerprints", len(data))
try: try:
acoustid.submit(API_KEY, userkey, data, timeout=10) acoustid.submit(API_KEY, userkey, data, timeout=10)
except acoustid.AcoustidError as exc: except acoustid.AcoustidError as exc:
log.warning("acoustid submission error: {0}", exc) log.warning("acoustid submission error: {}", exc)
del data[:] del data[:]
for item in items: for item in items:
@ -343,31 +343,31 @@ def fingerprint_item(log, item, write=False):
""" """
# Get a fingerprint and length for this track. # Get a fingerprint and length for this track.
if not item.length: 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: elif item.acoustid_fingerprint:
if write: if write:
log.info( log.info(
"{0}: fingerprint exists, skipping", "{}: fingerprint exists, skipping",
util.displayable_path(item.path), util.displayable_path(item.path),
) )
else: else:
log.info( log.info(
"{0}: using existing fingerprint", "{}: using existing fingerprint",
util.displayable_path(item.path), util.displayable_path(item.path),
) )
return item.acoustid_fingerprint return item.acoustid_fingerprint
else: else:
log.info("{0}: fingerprinting", util.displayable_path(item.path)) log.info("{}: fingerprinting", util.displayable_path(item.path))
try: try:
_, fp = acoustid.fingerprint_file(util.syspath(item.path)) _, fp = acoustid.fingerprint_file(util.syspath(item.path))
item.acoustid_fingerprint = fp.decode() item.acoustid_fingerprint = fp.decode()
if write: if write:
log.info( log.info(
"{0}: writing fingerprint", util.displayable_path(item.path) "{}: writing fingerprint", util.displayable_path(item.path)
) )
item.try_write() item.try_write()
if item._db: if item._db:
item.store() item.store()
return item.acoustid_fingerprint return item.acoustid_fingerprint
except acoustid.FingerprintGenerationError as exc: 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) quiet = self.config["quiet"].get(bool)
if not quiet and not pretend: 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) command = os.fsdecode(command)
source = os.fsdecode(source) source = os.fsdecode(source)
@ -307,7 +307,7 @@ class ConvertPlugin(BeetsPlugin):
encode_cmd.append(os.fsdecode(args[i])) encode_cmd.append(os.fsdecode(args[i]))
if pretend: if pretend:
self._log.info("{0}", " ".join(args)) self._log.info("{}", " ".join(args))
return return
try: try:
@ -315,11 +315,11 @@ class ConvertPlugin(BeetsPlugin):
except subprocess.CalledProcessError as exc: except subprocess.CalledProcessError as exc:
# Something went wrong (probably Ctrl+C), remove temporary files # Something went wrong (probably Ctrl+C), remove temporary files
self._log.info( self._log.info(
"Encoding {0} failed. Cleaning up...", "Encoding {} failed. Cleaning up...",
util.displayable_path(source), util.displayable_path(source),
) )
self._log.debug( self._log.debug(
"Command {0} exited with status {1}: {2}", "Command {} exited with status {}: {}",
args, args,
exc.returncode, exc.returncode,
exc.output, exc.output,
@ -334,7 +334,7 @@ class ConvertPlugin(BeetsPlugin):
if not quiet and not pretend: if not quiet and not pretend:
self._log.info( self._log.info(
"Finished encoding {0}", util.displayable_path(source) "Finished encoding {}", util.displayable_path(source)
) )
def convert_item( def convert_item(
@ -362,7 +362,7 @@ class ConvertPlugin(BeetsPlugin):
try: try:
mediafile.MediaFile(util.syspath(item.path)) mediafile.MediaFile(util.syspath(item.path))
except mediafile.UnreadableFileError as exc: 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 continue
# When keeping the new file in the library, we first move the # 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)): if os.path.exists(util.syspath(dest)):
self._log.info( self._log.info(
"Skipping {0} (target file exists)", "Skipping {} (target file exists)",
util.displayable_path(item.path), util.displayable_path(item.path),
) )
continue continue
@ -396,13 +396,13 @@ class ConvertPlugin(BeetsPlugin):
if keep_new: if keep_new:
if pretend: if pretend:
self._log.info( self._log.info(
"mv {0} {1}", "mv {} {}",
util.displayable_path(item.path), util.displayable_path(item.path),
util.displayable_path(original), util.displayable_path(original),
) )
else: else:
self._log.info( self._log.info(
"Moving to {0}", util.displayable_path(original) "Moving to {}", util.displayable_path(original)
) )
util.move(item.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") msg = "ln" if hardlink else ("ln -s" if link else "cp")
self._log.info( self._log.info(
"{2} {0} {1}", "{} {} {}",
msg,
util.displayable_path(original), util.displayable_path(original),
util.displayable_path(converted), util.displayable_path(converted),
msg,
) )
else: else:
# No transcoding necessary. # No transcoding necessary.
@ -432,7 +432,7 @@ class ConvertPlugin(BeetsPlugin):
) )
self._log.info( self._log.info(
"{1} {0}", util.displayable_path(item.path), msg "{} {}", msg, util.displayable_path(item.path)
) )
if hardlink: if hardlink:
@ -523,7 +523,7 @@ class ConvertPlugin(BeetsPlugin):
if os.path.exists(util.syspath(dest)): if os.path.exists(util.syspath(dest)):
self._log.info( self._log.info(
"Skipping {0} (target file exists)", "Skipping {} (target file exists)",
util.displayable_path(album.artpath), util.displayable_path(album.artpath),
) )
return return
@ -534,7 +534,7 @@ class ConvertPlugin(BeetsPlugin):
# Either copy or resize (while copying) the image. # Either copy or resize (while copying) the image.
if maxwidth is not None: if maxwidth is not None:
self._log.info( self._log.info(
"Resizing cover art from {0} to {1}", "Resizing cover art from {} to {}",
util.displayable_path(album.artpath), util.displayable_path(album.artpath),
util.displayable_path(dest), util.displayable_path(dest),
) )
@ -545,10 +545,10 @@ class ConvertPlugin(BeetsPlugin):
msg = "ln" if hardlink else ("ln -s" if link else "cp") msg = "ln" if hardlink else ("ln -s" if link else "cp")
self._log.info( self._log.info(
"{2} {0} {1}", "{} {} {}",
msg,
util.displayable_path(album.artpath), util.displayable_path(album.artpath),
util.displayable_path(dest), util.displayable_path(dest),
msg,
) )
else: else:
msg = ( msg = (
@ -558,10 +558,10 @@ class ConvertPlugin(BeetsPlugin):
) )
self._log.info( self._log.info(
"{2} cover art from {0} to {1}", "{} cover art from {} to {}",
msg,
util.displayable_path(album.artpath), util.displayable_path(album.artpath),
util.displayable_path(dest), util.displayable_path(dest),
msg,
) )
if hardlink: if hardlink:
util.hardlink(album.artpath, dest) util.hardlink(album.artpath, dest)
@ -622,7 +622,7 @@ class ConvertPlugin(BeetsPlugin):
# Playlist paths are understood as relative to the dest directory. # Playlist paths are understood as relative to the dest directory.
pl_normpath = util.normpath(playlist) pl_normpath = util.normpath(playlist)
pl_dir = os.path.dirname(pl_normpath) 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 # Generates a list of paths to media files, ensures the paths are
# relative to the playlist's location and translates the unicode # relative to the playlist's location and translates the unicode
# strings we get from item.destination to bytes. # strings we get from item.destination to bytes.
@ -672,7 +672,7 @@ class ConvertPlugin(BeetsPlugin):
if self.config["delete_originals"]: if self.config["delete_originals"]:
self._log.log( self._log.log(
logging.DEBUG if self.config["quiet"] else logging.INFO, logging.DEBUG if self.config["quiet"] else logging.INFO,
"Removing original file {0}", "Removing original file {}",
source_path, source_path,
) )
util.remove(source_path, False) util.remove(source_path, False)

View file

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

View file

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

View file

@ -273,7 +273,7 @@ class EmbedCoverArtPlugin(BeetsPlugin):
""" """
if self.config["remove_art_file"] and album.artpath: if self.config["remove_art_file"] and album.artpath:
if os.path.isfile(syspath(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)) os.remove(syspath(album.artpath))
album.artpath = None album.artpath = None
album.store() album.store()

View file

@ -196,7 +196,7 @@ class EmbyUpdate(BeetsPlugin):
# Get authentication token. # Get authentication token.
token = get_token(host, port, headers, auth_data) token = get_token(host, port, headers, auth_data)
if not token: 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 return
# Recreate headers with a token. # Recreate headers with a token.

View file

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

View file

@ -1541,7 +1541,7 @@ class FetchArtPlugin(plugins.BeetsPlugin, RequestMixin):
out = candidate out = candidate
assert out.path is not None # help mypy assert out.path is not None # help mypy
self._log.debug( self._log.debug(
"using {0.LOC} image {1}", "using {.LOC} image {}",
source, source,
util.displayable_path(out.path), util.displayable_path(out.path),
) )
@ -1576,7 +1576,7 @@ class FetchArtPlugin(plugins.BeetsPlugin, RequestMixin):
message = ui.colorize( message = ui.colorize(
"text_highlight_minor", "has album art" "text_highlight_minor", "has album art"
) )
self._log.info("{0}: {1}", album, message) self._log.info("{}: {}", album, message)
else: else:
# In ordinary invocations, look for images on the # In ordinary invocations, look for images on the
# filesystem. When forcing, however, always go to the Web # 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") message = ui.colorize("text_success", "found album art")
else: else:
message = ui.colorize("text_error", "no art found") 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, "auto": True,
"drop": False, "drop": False,
"format": "feat. {0}", "format": "feat. {}",
"keep_in_artist": False, "keep_in_artist": False,
} }
) )
@ -151,10 +151,10 @@ class FtInTitlePlugin(plugins.BeetsPlugin):
# In case the artist is kept, do not update the artist fields. # In case the artist is kept, do not update the artist fields.
if keep_in_artist_field: if keep_in_artist_field:
self._log.info( 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: else:
self._log.info("artist: {0} -> {1}", item.artist, item.albumartist) self._log.info("artist: {} -> {}", item.artist, item.albumartist)
item.artist = item.albumartist item.artist = item.albumartist
if item.artist_sort: if item.artist_sort:
@ -167,7 +167,7 @@ class FtInTitlePlugin(plugins.BeetsPlugin):
feat_format = self.config["format"].as_str() feat_format = self.config["format"].as_str()
new_format = feat_format.format(feat_part) new_format = feat_format.format(feat_part)
new_title = f"{item.title} {new_format}" 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 item.title = new_title
def ft_in_title( def ft_in_title(

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -59,7 +59,7 @@ class RewritePlugin(BeetsPlugin):
raise ui.UserError( raise ui.UserError(
f"invalid field name ({fieldname}) in rewriter" 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()) pattern = re.compile(pattern.lower())
rules[fieldname].append((pattern, value)) rules[fieldname].append((pattern, value))
if fieldname == "artist": if fieldname == "artist":

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -56,21 +56,21 @@ class FtInTitlePluginFunctional(PluginTestCase):
assert item["title"] == "Song 1" assert item["title"] == "Song 1"
def test_functional_custom_format(self): 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") item = self._ft_add_item("/", "Alice ft Bob", "Song 1", "Alice")
self.run_command("ftintitle") self.run_command("ftintitle")
item.load() item.load()
assert item["artist"] == "Alice" assert item["artist"] == "Alice"
assert item["title"] == "Song 1 feat. Bob" 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") item = self._ft_add_item("/", "Alice feat. Bob", "Song 1", "Alice")
self.run_command("ftintitle") self.run_command("ftintitle")
item.load() item.load()
assert item["artist"] == "Alice" assert item["artist"] == "Alice"
assert item["title"] == "Song 1 featuring Bob" 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") item = self._ft_add_item("/", "Alice feat Bob", "Song 1", "Alice")
self.run_command("ftintitle") self.run_command("ftintitle")
item.load() item.load()
@ -78,7 +78,7 @@ class FtInTitlePluginFunctional(PluginTestCase):
assert item["title"] == "Song 1 with Bob" assert item["title"] == "Song 1 with Bob"
def test_functional_keep_in_artist(self): 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") item = self._ft_add_item("/", "Alice ft Bob", "Song 1", "Alice")
self.run_command("ftintitle") self.run_command("ftintitle")
item.load() item.load()

View file

@ -77,7 +77,7 @@ class MPDStatsTest(PluginTestCase):
except KeyboardInterrupt: except KeyboardInterrupt:
pass 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( 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.addHandler(handler)
logger.propagate = False logger.propagate = False
logger.warning("foo {0} {bar}", "oof", bar="baz") logger.warning("foo {} {bar}", "oof", bar="baz")
handler.flush() handler.flush()
assert stream.getvalue(), "foo oof baz" assert stream.getvalue(), "foo oof baz"