From b40fb507c321b227de164809b4cea094163c5fb3 Mon Sep 17 00:00:00 2001 From: Bruno Cauet Date: Sat, 3 Jan 2015 16:35:19 +0100 Subject: [PATCH 01/16] Offer new-style formatting for logging beets.logging is a drop-in replacement for logging. Any logger created from beets.logging.getLogger() will use {}-style formatting instead of %-style, on python 2 and 3. --- beets/logging.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 beets/logging.py diff --git a/beets/logging.py b/beets/logging.py new file mode 100644 index 000000000..2783c5ff5 --- /dev/null +++ b/beets/logging.py @@ -0,0 +1,37 @@ +"""Allow {}-style formatting on python 2 and 3 + +Provide everything the "logging" module does, the only difference is that when +getLogger(name) instantiates a logger that logger uses {}-style formatting. +""" + +from __future__ import absolute_import +from copy import copy +from logging import * + + +# create a str.format-based logger +class StrFormatLogger(Logger): + class _LogMessage(object): + def __init__(self, msg, args, kwargs): + self.msg = msg + self.args = args + self.kwargs = kwargs + + def __str__(self): + return self.msg.format(*self.args, **self.kwargs) + + def _log(self, level, msg, args, exc_info=None, extra=None, **kwargs): + """Log 'msg.format(*args, **kwargs)""" + msg = self._LogMessage(msg, args, kwargs) + return super(StrFormatLogger, self)._log(level, msg, (), exc_info, extra) + + +my_manager = copy(Logger.manager) +my_manager.loggerClass = StrFormatLogger + + +def getLogger(name=None): + if name: + return my_manager.getLogger(name) + else: + return root From e75f9a703d49a08098d6a840d6bebaa82c521c0e Mon Sep 17 00:00:00 2001 From: Bruno Cauet Date: Sat, 3 Jan 2015 17:46:23 +0100 Subject: [PATCH 02/16] Convert beets core to lazy logging --- beets/autotag/match.py | 30 ++++++------ beets/autotag/mb.py | 4 +- beets/importer.py | 98 ++++++++++++++++++---------------------- beets/library.py | 6 +-- beets/mediafile.py | 6 +-- beets/plugins.py | 6 +-- beets/ui/__init__.py | 22 ++++----- beets/ui/commands.py | 32 ++++++------- beets/util/artresizer.py | 22 ++++----- 9 files changed, 103 insertions(+), 123 deletions(-) diff --git a/beets/autotag/match.py b/beets/autotag/match.py index 2d1f20074..00556359f 100644 --- a/beets/autotag/match.py +++ b/beets/autotag/match.py @@ -267,7 +267,7 @@ def match_by_id(items): # If all album IDs are equal, look up the album. if bool(reduce(lambda x, y: x if x == y else (), albumids)): albumid = albumids[0] - log.debug(u'Searching for discovered album ID: {0}'.format(albumid)) + log.debug(u'Searching for discovered album ID: {0}', albumid) return hooks.album_for_mbid(albumid) else: log.debug(u'No album ID consensus.') @@ -330,7 +330,7 @@ def _add_candidate(items, results, info): checking the track count, ordering the items, checking for duplicates, and calculating the distance. """ - log.debug(u'Candidate: {0} - {1}'.format(info.artist, info.album)) + log.debug(u'Candidate: {0} - {1}', info.artist, info.album) # Discard albums with zero tracks. if not info.tracks: @@ -345,7 +345,7 @@ def _add_candidate(items, results, info): # Discard matches without required tags. for req_tag in config['match']['required'].as_str_seq(): if getattr(info, req_tag) is None: - log.debug(u'Ignored. Missing required tag: {0}'.format(req_tag)) + log.debug(u'Ignored. Missing required tag: {0}', req_tag) return # Find mapping between the items and the track info. @@ -358,10 +358,10 @@ def _add_candidate(items, results, info): penalties = [key for _, key in dist] for penalty in config['match']['ignored'].as_str_seq(): if penalty in penalties: - log.debug(u'Ignored. Penalty: {0}'.format(penalty)) + log.debug(u'Ignored. Penalty: {0}', penalty) return - log.debug(u'Success. Distance: {0}'.format(dist)) + log.debug(u'Success. Distance: {0}', dist) results[info.album_id] = hooks.AlbumMatch(dist, info, mapping, extra_items, extra_tracks) @@ -387,7 +387,7 @@ def tag_album(items, search_artist=None, search_album=None, likelies, consensus = current_metadata(items) cur_artist = likelies['artist'] cur_album = likelies['album'] - log.debug(u'Tagging {0} - {1}'.format(cur_artist, cur_album)) + log.debug(u'Tagging {0} - {1}', cur_artist, cur_album) # The output result (distance, AlbumInfo) tuples (keyed by MB album # ID). @@ -395,7 +395,7 @@ def tag_album(items, search_artist=None, search_album=None, # Search by explicit ID. if search_id is not None: - log.debug(u'Searching for album ID: {0}'.format(search_id)) + log.debug(u'Searching for album ID: {0}', search_id) search_cands = hooks.albums_for_id(search_id) # Use existing metadata or text search. @@ -405,7 +405,7 @@ def tag_album(items, search_artist=None, search_album=None, if id_info: _add_candidate(items, candidates, id_info) rec = _recommendation(candidates.values()) - log.debug(u'Album ID match recommendation is {0}'.format(str(rec))) + log.debug(u'Album ID match recommendation is {0}', str(rec)) if candidates and not config['import']['timid']: # If we have a very good MBID match, return immediately. # Otherwise, this match will compete against metadata-based @@ -418,20 +418,19 @@ def tag_album(items, search_artist=None, search_album=None, if not (search_artist and search_album): # No explicit search terms -- use current metadata. search_artist, search_album = cur_artist, cur_album - log.debug(u'Search terms: {0} - {1}'.format(search_artist, - search_album)) + log.debug(u'Search terms: {0} - {1}', search_artist, search_album) # Is this album likely to be a "various artist" release? va_likely = ((not consensus['artist']) or (search_artist.lower() in VA_ARTISTS) or any(item.comp for item in items)) - log.debug(u'Album might be VA: {0}'.format(str(va_likely))) + log.debug(u'Album might be VA: {0}', str(va_likely)) # Get the results from the data sources. search_cands = hooks.album_candidates(items, search_artist, search_album, va_likely) - log.debug(u'Evaluating {0} candidates.'.format(len(search_cands))) + log.debug(u'Evaluating {0} candidates.', len(search_cands)) for info in search_cands: _add_candidate(items, candidates, info) @@ -456,7 +455,7 @@ def tag_item(item, search_artist=None, search_title=None, # First, try matching by MusicBrainz ID. trackid = search_id or item.mb_trackid if trackid: - log.debug(u'Searching for track ID: {0}'.format(trackid)) + log.debug(u'Searching for track ID: {0}', trackid) for track_info in hooks.tracks_for_id(trackid): dist = track_distance(item, track_info, incl_artist=True) candidates[track_info.track_id] = \ @@ -477,8 +476,7 @@ def tag_item(item, search_artist=None, search_title=None, # Search terms. if not (search_artist and search_title): search_artist, search_title = item.artist, item.title - log.debug(u'Item search terms: {0} - {1}'.format(search_artist, - search_title)) + log.debug(u'Item search terms: {0} - {1}', search_artist, search_title) # Get and evaluate candidate metadata. for track_info in hooks.item_candidates(item, search_artist, search_title): @@ -486,7 +484,7 @@ def tag_item(item, search_artist=None, search_title=None, candidates[track_info.track_id] = hooks.TrackMatch(dist, track_info) # Sort by distance and return with recommendation. - log.debug(u'Found {0} candidates.'.format(len(candidates))) + log.debug(u'Found {0} candidates.', len(candidates)) candidates = sorted(candidates.itervalues()) rec = _recommendation(candidates) return candidates, rec diff --git a/beets/autotag/mb.py b/beets/autotag/mb.py index d063f6278..72662bd5c 100644 --- a/beets/autotag/mb.py +++ b/beets/autotag/mb.py @@ -374,7 +374,7 @@ def album_for_id(releaseid): """ albumid = _parse_id(releaseid) if not albumid: - log.debug(u'Invalid MBID ({0}).'.format(releaseid)) + log.debug(u'Invalid MBID ({0}).', releaseid) return try: res = musicbrainzngs.get_release_by_id(albumid, @@ -394,7 +394,7 @@ def track_for_id(releaseid): """ trackid = _parse_id(releaseid) if not trackid: - log.debug(u'Invalid MBID ({0}).'.format(releaseid)) + log.debug(u'Invalid MBID ({0}).', releaseid) return try: res = musicbrainzngs.get_recording_by_id(trackid, TRACK_INCLUDES) diff --git a/beets/importer.py b/beets/importer.py index 4a7bd997f..4aa39ff92 100644 --- a/beets/importer.py +++ b/beets/importer.py @@ -71,7 +71,7 @@ def _open_state(): # unpickling, including ImportError. We use a catch-all # exception to avoid enumerating them all (the docs don't even have a # full list!). - log.debug(u'state file could not be read: {0}'.format(exc)) + log.debug(u'state file could not be read: {0}', exc) return {} @@ -81,7 +81,7 @@ def _save_state(state): with open(config['statefile'].as_filename(), 'w') as f: pickle.dump(state, f) except IOError as exc: - log.error(u'state file could not be written: {0}'.format(exc)) + log.error(u'state file could not be written: {0}', exc) # Utilities for reading and writing the beets progress file, which @@ -347,8 +347,8 @@ class ImportSession(object): # Either accept immediately or prompt for input to decide. if self.want_resume is True or \ self.should_resume(toppath): - log.warn(u'Resuming interrupted import of {0}'.format( - util.displayable_path(toppath))) + log.warn(u'Resuming interrupted import of {0}', + util.displayable_path(toppath)) self._is_resuming[toppath] = True else: # Clear progress; we're starting from the top. @@ -481,13 +481,12 @@ class ImportTask(object): def remove_duplicates(self, lib): duplicate_items = self.duplicate_items(lib) - log.debug(u'removing {0} old duplicated items' - .format(len(duplicate_items))) + log.debug(u'removing {0} old duplicated items', len(duplicate_items)) for item in duplicate_items: item.remove() if lib.directory in util.ancestry(item.path): - log.debug(u'deleting duplicate {0}' - .format(util.displayable_path(item.path))) + log.debug(u'deleting duplicate {0}', + util.displayable_path(item.path)) util.remove(item.path) util.prune_dirs(os.path.dirname(item.path), lib.directory) @@ -686,12 +685,11 @@ class ImportTask(object): self.album.store() log.debug( u'Reimported album: added {0}, flexible ' - u'attributes {1} from album {2} for {3}'.format( - self.album.added, - replaced_album._values_flex.keys(), - replaced_album.id, - displayable_path(self.album.path), - ) + u'attributes {1} from album {2} for {3}', + self.album.added, + replaced_album._values_flex.keys(), + replaced_album.id, + displayable_path(self.album.path) ) for item in self.imported_items(): @@ -701,20 +699,18 @@ class ImportTask(object): item.added = dup_item.added log.debug( u'Reimported item added {0} ' - u'from item {1} for {2}'.format( - item.added, - dup_item.id, - displayable_path(item.path), - ) + u'from item {1} for {2}', + item.added, + dup_item.id, + displayable_path(item.path) ) item.update(dup_item._values_flex) log.debug( u'Reimported item flexible attributes {0} ' - u'from item {1} for {2}'.format( - dup_item._values_flex.keys(), - dup_item.id, - displayable_path(item.path), - ) + u'from item {1} for {2}', + dup_item._values_flex.keys(), + dup_item.id, + displayable_path(item.path) ) item.store() @@ -724,13 +720,12 @@ class ImportTask(object): """ for item in self.imported_items(): for dup_item in self.replaced_items[item]: - log.debug(u'Replacing item {0}: {1}' - .format(dup_item.id, - displayable_path(item.path))) + log.debug(u'Replacing item {0}: {1}', + dup_item.id, displayable_path(item.path)) dup_item.remove() - log.debug(u'{0} of {1} items replaced' - .format(sum(bool(l) for l in self.replaced_items.values()), - len(self.imported_items()))) + log.debug(u'{0} of {1} items replaced', + sum(bool(l) for l in self.replaced_items.values()), + len(self.imported_items())) def choose_match(self, session): """Ask the session which match should apply and apply it. @@ -1002,8 +997,8 @@ class ImportTaskFactory(object): def singleton(self, path): if self.session.already_imported(self.toppath, [path]): - log.debug(u'Skipping previously-imported path: {0}' - .format(displayable_path(path))) + log.debug(u'Skipping previously-imported path: {0}', + displayable_path(path)) self.skipped += 1 return None @@ -1026,8 +1021,8 @@ class ImportTaskFactory(object): dirs = list(set(os.path.dirname(p) for p in paths)) if self.session.already_imported(self.toppath, dirs): - log.debug(u'Skipping previously-imported path: {0}' - .format(displayable_path(dirs))) + log.debug(u'Skipping previously-imported path: {0}', + displayable_path(dirs)) self.skipped += 1 return None @@ -1055,14 +1050,10 @@ class ImportTaskFactory(object): # Silently ignore non-music files. pass elif isinstance(exc.reason, mediafile.UnreadableFileError): - log.warn(u'unreadable file: {0}'.format( - displayable_path(path)) - ) + log.warn(u'unreadable file: {0}', displayable_path(path)) else: - log.error(u'error reading {0}: {1}'.format( - displayable_path(path), - exc, - )) + log.error(u'error reading {0}: {1}', + displayable_path(path), exc) # Full-album pipeline stages. @@ -1086,13 +1077,13 @@ def read_tasks(session): "'copy' or 'move' to be enabled.") continue - log.debug(u'extracting archive {0}' - .format(displayable_path(toppath))) + log.debug(u'extracting archive {0}', + displayable_path(toppath)) archive_task = ArchiveImportTask(toppath) try: archive_task.extract() except Exception as exc: - log.error(u'extraction failed: {0}'.format(exc)) + log.error(u'extraction failed: {0}', exc) continue # Continue reading albums from the extracted directory. @@ -1112,12 +1103,12 @@ def read_tasks(session): yield archive_task if not imported: - log.warn(u'No files imported from {0}' - .format(displayable_path(user_toppath))) + log.warn(u'No files imported from {0}', + displayable_path(user_toppath)) # Show skipped directories. if skipped: - log.info(u'Skipped {0} directories.'.format(skipped)) + log.info(u'Skipped {0} directories.', skipped) def query_tasks(session): @@ -1133,8 +1124,8 @@ def query_tasks(session): else: # Search for albums. for album in session.lib.albums(session.query): - log.debug(u'yielding album {0}: {1} - {2}' - .format(album.id, album.albumartist, album.album)) + log.debug(u'yielding album {0}: {1} - {2}', + album.id, album.albumartist, album.album) items = list(album.items()) # Clear IDs from re-tagged items so they appear "fresh" when @@ -1159,7 +1150,7 @@ def lookup_candidates(session, task): return plugins.send('import_task_start', session=session, task=task) - log.debug(u'Looking up: {0}'.format(displayable_path(task.paths))) + log.debug(u'Looking up: {0}', displayable_path(task.paths)) task.lookup_candidates() @@ -1300,12 +1291,11 @@ def log_files(session, task): """A coroutine (pipeline stage) to log each file which will be imported """ if isinstance(task, SingletonImportTask): - log.info( - 'Singleton: {0}'.format(displayable_path(task.item['path']))) + log.info('Singleton: {0}', displayable_path(task.item['path'])) elif task.items: - log.info('Album {0}'.format(displayable_path(task.paths[0]))) + log.info('Album {0}', displayable_path(task.paths[0])) for item in task.items: - log.info(' {0}'.format(displayable_path(item['path']))) + log.info(' {0}', displayable_path(item['path'])) def group_albums(session): diff --git a/beets/library.py b/beets/library.py index 1de1bba56..a4213d8b3 100644 --- a/beets/library.py +++ b/beets/library.py @@ -837,9 +837,9 @@ class Album(LibModel): return new_art = util.unique_path(new_art) - log.debug(u'moving album art {0} to {1}' - .format(util.displayable_path(old_art), - util.displayable_path(new_art))) + log.debug(u'moving album art {0} to {1}', + util.displayable_path(old_art), + util.displayable_path(new_art)) if copy: util.copy(old_art, new_art) elif link: diff --git a/beets/mediafile.py b/beets/mediafile.py index 49ef10378..9106bbd71 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -1313,7 +1313,7 @@ class MediaFile(object): try: self.mgfile = mutagen.File(path) except unreadable_exc as exc: - log.debug(u'header parsing failed: {0}'.format(unicode(exc))) + log.debug(u'header parsing failed: {0}', unicode(exc)) raise UnreadableFileError(path) except IOError as exc: if type(exc) == IOError: @@ -1326,7 +1326,7 @@ class MediaFile(object): except Exception as exc: # Isolate bugs in Mutagen. log.debug(traceback.format_exc()) - log.error(u'uncaught Mutagen exception in open: {0}'.format(exc)) + log.error(u'uncaught Mutagen exception in open: {0}', exc) raise MutagenError(path, exc) if self.mgfile is None: @@ -1399,7 +1399,7 @@ class MediaFile(object): raise except Exception as exc: log.debug(traceback.format_exc()) - log.error(u'uncaught Mutagen exception in save: {0}'.format(exc)) + log.error(u'uncaught Mutagen exception in save: {0}', exc) raise MutagenError(self.path, exc) def delete(self): diff --git a/beets/plugins.py b/beets/plugins.py index 8611b92a6..c3058b617 100755 --- a/beets/plugins.py +++ b/beets/plugins.py @@ -204,7 +204,7 @@ def load_plugins(names=()): except ImportError as exc: # Again, this is hacky: if exc.args[0].endswith(' ' + name): - log.warn(u'** plugin {0} not found'.format(name)) + log.warn(u'** plugin {0} not found', name) else: raise else: @@ -214,7 +214,7 @@ def load_plugins(names=()): _classes.add(obj) except: - log.warn(u'** error loading plugin {0}'.format(name)) + log.warn(u'** error loading plugin {0}', name) log.warn(traceback.format_exc()) @@ -398,7 +398,7 @@ def send(event, **arguments): Returns a list of return values from the handlers. """ - log.debug(u'Sending event: {0}'.format(event)) + log.debug(u'Sending event: {0}', event) for handler in event_handlers()[event]: # Don't break legacy plugins if we want to pass more arguments argspec = inspect.getargspec(handler).args diff --git a/beets/ui/__init__.py b/beets/ui/__init__.py index 8978ff547..4617e84fc 100644 --- a/beets/ui/__init__.py +++ b/beets/ui/__init__.py @@ -866,14 +866,14 @@ def _configure(options): config_path = config.user_config_path() if os.path.isfile(config_path): - log.debug(u'user configuration: {0}'.format( - util.displayable_path(config_path))) + log.debug(u'user configuration: {0}', + util.displayable_path(config_path)) else: - log.debug(u'no user configuration found at {0}'.format( - util.displayable_path(config_path))) + log.debug(u'no user configuration found at {0}', + util.displayable_path(config_path)) - log.debug(u'data directory: {0}' - .format(util.displayable_path(config.config_dir()))) + log.debug(u'data directory: {0}', + util.displayable_path(config.config_dir())) return config @@ -895,9 +895,9 @@ def _open_library(config): util.displayable_path(dbpath) )) log.debug(u'library database: {0}\n' - u'library directory: {1}' - .format(util.displayable_path(lib.path), - util.displayable_path(lib.directory))) + u'library directory: {1}', + util.displayable_path(lib.path), + util.displayable_path(lib.directory)) return lib @@ -945,7 +945,7 @@ def main(args=None): _raw_main(args) except UserError as exc: message = exc.args[0] if exc.args else None - log.error(u'error: {0}'.format(message)) + log.error(u'error: {0}', message) sys.exit(1) except util.HumanReadableException as exc: exc.log(log) @@ -957,7 +957,7 @@ def main(args=None): log.error(exc) sys.exit(1) except confit.ConfigError as exc: - log.error(u'configuration error: {0}'.format(exc)) + log.error(u'configuration error: {0}', exc) sys.exit(1) except IOError as exc: if exc.errno == errno.EPIPE: diff --git a/beets/ui/commands.py b/beets/ui/commands.py index 546fe87d9..e55d41504 100644 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -764,8 +764,8 @@ class TerminalImportSession(importer.ImportSession): """Decide what to do when a new album or item seems similar to one that's already in the library. """ - log.warn(u"This {0} is already in the library!" - .format("album" if task.is_album else "item")) + log.warn(u"This {0} is already in the library!", + ("album" if task.is_album else "item")) if config['import']['quiet']: # In quiet mode, don't prompt -- just skip. @@ -1014,16 +1014,16 @@ def update_items(lib, query, album, move, pretend): # Did the item change since last checked? if item.current_mtime() <= item.mtime: - log.debug(u'skipping {0} because mtime is up to date ({1})' - .format(displayable_path(item.path), item.mtime)) + log.debug(u'skipping {0} because mtime is up to date ({1})', + displayable_path(item.path), item.mtime) continue # Read new data. try: item.read() except library.ReadError as exc: - log.error(u'error reading {0}: {1}'.format( - displayable_path(item.path), exc)) + log.error(u'error reading {0}: {1}', + displayable_path(item.path), exc) continue # Special-case album artist when it matches track artist. (Hacky @@ -1065,7 +1065,7 @@ def update_items(lib, query, album, move, pretend): continue album = lib.get_album(album_id) if not album: # Empty albums have already been removed. - log.debug(u'emptied album {0}'.format(album_id)) + log.debug(u'emptied album {0}', album_id) continue first_item = album.items().get() @@ -1076,7 +1076,7 @@ def update_items(lib, query, album, move, pretend): # Move album art (and any inconsistent items). if move and lib.directory in ancestry(first_item.path): - log.debug(u'moving album {0}'.format(album_id)) + log.debug(u'moving album {0}', album_id) album.move() @@ -1298,8 +1298,7 @@ def modify_items(lib, mods, dels, query, write, move, album, confirm): if move: cur_path = obj.path if lib.directory in ancestry(cur_path): # In library? - log.debug(u'moving object {0}' - .format(displayable_path(cur_path))) + log.debug(u'moving object {0}', displayable_path(cur_path)) obj.move() obj.try_sync(write) @@ -1377,9 +1376,9 @@ def move_items(lib, dest, query, copy, album): action = 'Copying' if copy else 'Moving' entity = 'album' if album else 'item' - log.info(u'{0} {1} {2}s.'.format(action, len(objs), entity)) + log.info(u'{0} {1} {2}s.', action, len(objs), entity) for obj in objs: - log.debug(u'moving: {0}'.format(util.displayable_path(obj.path))) + log.debug(u'moving: {0}', util.displayable_path(obj.path)) obj.move(copy, basedir=dest) obj.store() @@ -1425,18 +1424,15 @@ def write_items(lib, query, pretend, force): for item in items: # Item deleted? if not os.path.exists(syspath(item.path)): - log.info(u'missing file: {0}'.format( - util.displayable_path(item.path) - )) + log.info(u'missing file: {0}', util.displayable_path(item.path)) continue # Get an Item object reflecting the "clean" (on-disk) state. try: clean_item = library.Item.from_path(item.path) except library.ReadError as exc: - log.error(u'error reading {0}: {1}'.format( - displayable_path(item.path), exc - )) + log.error(u'error reading {0}: {1}', + displayable_path(item.path), exc) continue # Check for and display changes. diff --git a/beets/util/artresizer.py b/beets/util/artresizer.py index f17fdc5b9..0145124c1 100644 --- a/beets/util/artresizer.py +++ b/beets/util/artresizer.py @@ -58,9 +58,8 @@ def pil_resize(maxwidth, path_in, path_out=None): """ path_out = path_out or temp_file_for(path_in) from PIL import Image - log.debug(u'artresizer: PIL resizing {0} to {1}'.format( - util.displayable_path(path_in), util.displayable_path(path_out) - )) + log.debug(u'artresizer: PIL resizing {0} to {1}', + util.displayable_path(path_in), util.displayable_path(path_out)) try: im = Image.open(util.syspath(path_in)) @@ -69,9 +68,8 @@ def pil_resize(maxwidth, path_in, path_out=None): im.save(path_out) return path_out except IOError: - log.error(u"PIL cannot create thumbnail for '{0}'".format( - util.displayable_path(path_in) - )) + log.error(u"PIL cannot create thumbnail for '{0}'", + util.displayable_path(path_in)) return path_in @@ -80,9 +78,8 @@ def im_resize(maxwidth, path_in, path_out=None): Return the output path of resized image. """ path_out = path_out or temp_file_for(path_in) - log.debug(u'artresizer: ImageMagick resizing {0} to {1}'.format( - util.displayable_path(path_in), util.displayable_path(path_out) - )) + log.debug(u'artresizer: ImageMagick resizing {0} to {1}', + util.displayable_path(path_in), util.displayable_path(path_out)) # "-resize widthxheight>" shrinks images with dimension(s) larger # than the corresponding width and/or height dimension(s). The > @@ -94,9 +91,8 @@ def im_resize(maxwidth, path_in, path_out=None): '-resize', '{0}x^>'.format(maxwidth), path_out ]) except subprocess.CalledProcessError: - log.warn(u'artresizer: IM convert failed for {0}'.format( - util.displayable_path(path_in) - )) + log.warn(u'artresizer: IM convert failed for {0}', + util.displayable_path(path_in)) return path_in return path_out @@ -134,7 +130,7 @@ class ArtResizer(object): specified, with an inferred method. """ self.method = self._check_method(method) - log.debug(u"artresizer: method is {0}".format(self.method)) + log.debug(u"artresizer: method is {0}", self.method) self.can_compare = self._can_compare() def resize(self, maxwidth, path_in, path_out=None): From 8cac47af2a2d004ba90d87e38d78a6486622c273 Mon Sep 17 00:00:00 2001 From: Bruno Cauet Date: Sun, 4 Jan 2015 11:41:17 +0100 Subject: [PATCH 03/16] Convert beets plugins to lazy logging --- beetsplug/beatport.py | 8 ++-- beetsplug/bpm.py | 6 +-- beetsplug/chroma.py | 53 +++++++++++------------- beetsplug/convert.py | 61 +++++++++++---------------- beetsplug/discogs.py | 16 ++++---- beetsplug/duplicates.py | 20 ++++----- beetsplug/echonest.py | 59 ++++++++++++-------------- beetsplug/embedart.py | 50 ++++++++++------------ beetsplug/fetchart.py | 24 +++++------ beetsplug/ftintitle.py | 5 +-- beetsplug/ihate.py | 7 ++-- beetsplug/importadded.py | 22 +++++----- beetsplug/importfeeds.py | 2 +- beetsplug/info.py | 2 +- beetsplug/inline.py | 9 ++-- beetsplug/keyfinder.py | 6 +-- beetsplug/lastgenre/__init__.py | 24 +++++------ beetsplug/lastimport.py | 64 +++++++++++------------------ beetsplug/lyrics.py | 29 +++++++------ beetsplug/mbcollection.py | 2 +- beetsplug/mbsync.py | 11 +++-- beetsplug/missing.py | 6 +-- beetsplug/mpdstats.py | 37 ++++++----------- beetsplug/play.py | 8 ++-- beetsplug/replaygain.py | 73 ++++++++++----------------------- beetsplug/rewrite.py | 2 +- beetsplug/scrub.py | 10 ++--- beetsplug/spotify.py | 24 ++++------- beetsplug/the.py | 6 +-- beetsplug/zero.py | 6 +-- 30 files changed, 272 insertions(+), 380 deletions(-) diff --git a/beetsplug/beatport.py b/beetsplug/beatport.py index b83aef2f7..8afefbefb 100644 --- a/beetsplug/beatport.py +++ b/beetsplug/beatport.py @@ -194,7 +194,7 @@ class BeatportPlugin(BeetsPlugin): try: return self._get_releases(query) except BeatportAPIError as e: - log.debug(u'Beatport API Error: {0} (query: {1})'.format(e, query)) + log.debug(u'Beatport API Error: {0} (query: {1})', e, query) return [] def item_candidates(self, item, artist, title): @@ -205,14 +205,14 @@ class BeatportPlugin(BeetsPlugin): try: return self._get_tracks(query) except BeatportAPIError as e: - log.debug(u'Beatport API Error: {0} (query: {1})'.format(e, query)) + log.debug(u'Beatport API Error: {0} (query: {1})', e, query) return [] def album_for_id(self, release_id): """Fetches a release by its Beatport ID and returns an AlbumInfo object or None if the release is not found. """ - log.debug(u'Searching Beatport for release {0}'.format(release_id)) + log.debug(u'Searching Beatport for release {0}', release_id) match = re.search(r'(^|beatport\.com/release/.+/)(\d+)$', release_id) if not match: return None @@ -224,7 +224,7 @@ class BeatportPlugin(BeetsPlugin): """Fetches a track by its Beatport ID and returns a TrackInfo object or None if the track is not found. """ - log.debug(u'Searching Beatport for track {0}'.format(str(track_id))) + log.debug(u'Searching Beatport for track {0}', track_id) match = re.search(r'(^|beatport\.com/track/.+/)(\d+)$', track_id) if not match: return None diff --git a/beetsplug/bpm.py b/beetsplug/bpm.py index d895ec5be..2189e2fae 100644 --- a/beetsplug/bpm.py +++ b/beetsplug/bpm.py @@ -73,15 +73,15 @@ class BPMPlugin(BeetsPlugin): item = items[0] if item['bpm']: - log.info(u'Found bpm {0}'.format(item['bpm'])) + log.info(u'Found bpm {0}', item['bpm']) if not overwrite: return log.info(u'Press Enter {0} times to the rhythm or Ctrl-D ' - u'to exit'.format(self.config['max_strokes'].get(int))) + u'to exit', self.config['max_strokes'].get(int)) new_bpm = bpm(self.config['max_strokes'].get(int)) item['bpm'] = int(new_bpm) if write: item.try_write() item.store() - log.info(u'Added new bpm {0}'.format(item['bpm'])) + log.info(u'Added new bpm {0}', item['bpm']) diff --git a/beetsplug/chroma.py b/beetsplug/chroma.py index 106d6df76..0ff86e220 100644 --- a/beetsplug/chroma.py +++ b/beetsplug/chroma.py @@ -64,19 +64,19 @@ def acoustid_match(path): try: duration, fp = acoustid.fingerprint_file(util.syspath(path)) except acoustid.FingerprintGenerationError as exc: - log.error(u'fingerprinting of {0} failed: {1}' - .format(util.displayable_path(repr(path)), str(exc))) + log.error(u'fingerprinting of {0} failed: {1}', + util.displayable_path(repr(path)), str(exc)) return None _fingerprints[path] = fp try: res = acoustid.lookup(API_KEY, fp, duration, meta='recordings releases') except acoustid.AcoustidError as exc: - log.debug(u'fingerprint matching {0} failed: {1}' - .format(util.displayable_path(repr(path)), str(exc))) + log.debug(u'fingerprint matching {0} failed: {1}', + util.displayable_path(repr(path)), exc) return None - log.debug(u'chroma: fingerprinted {0}' - .format(util.displayable_path(repr(path)))) + log.debug(u'chroma: fingerprinted {0}', + util.displayable_path(repr(path))) # Ensure the response is usable and parse it. if res['status'] != 'ok' or not res.get('results'): @@ -99,9 +99,8 @@ def acoustid_match(path): if 'releases' in recording: release_ids += [rel['id'] for rel in recording['releases']] - log.debug(u'chroma: matched recordings {0} on releases {1}'.format( - recording_ids, release_ids, - )) + log.debug(u'chroma: matched recordings {0} on releases {1}', + recording_ids, release_ids) _matches[path] = recording_ids, release_ids @@ -155,7 +154,7 @@ class AcoustidPlugin(plugins.BeetsPlugin): if album: albums.append(album) - log.debug(u'acoustid album candidates: {0}'.format(len(albums))) + log.debug(u'acoustid album candidates: {0}', len(albums)) return albums def item_candidates(self, item, artist, title): @@ -168,7 +167,7 @@ class AcoustidPlugin(plugins.BeetsPlugin): track = hooks.track_for_mbid(recording_id) if track: tracks.append(track) - log.debug(u'acoustid item candidates: {0}'.format(len(tracks))) + log.debug(u'acoustid item candidates: {0}', len(tracks)) return tracks def commands(self): @@ -230,11 +229,11 @@ def submit_items(userkey, items, chunksize=64): def submit_chunk(): """Submit the current accumulated fingerprint data.""" - log.info(u'submitting {0} fingerprints'.format(len(data))) + log.info(u'submitting {0} fingerprints', len(data)) try: acoustid.submit(API_KEY, userkey, data) except acoustid.AcoustidError as exc: - log.warn(u'acoustid submission error: {0}'.format(exc)) + log.warn(u'acoustid submission error: {0}', exc) del data[:] for item in items: @@ -279,34 +278,28 @@ def fingerprint_item(item, write=False): """ # Get a fingerprint and length for this track. if not item.length: - log.info(u'{0}: no duration available'.format( - util.displayable_path(item.path) - )) + log.info(u'{0}: no duration available', + util.displayable_path(item.path)) elif item.acoustid_fingerprint: if write: - log.info(u'{0}: fingerprint exists, skipping'.format( - util.displayable_path(item.path) - )) + log.info(u'{0}: fingerprint exists, skipping', + util.displayable_path(item.path)) else: - log.info(u'{0}: using existing fingerprint'.format( - util.displayable_path(item.path) - )) + log.info(u'{0}: using existing fingerprint', + util.displayable_path(item.path)) return item.acoustid_fingerprint else: - log.info(u'{0}: fingerprinting'.format( - util.displayable_path(item.path) - )) + log.info(u'{0}: fingerprinting', + util.displayable_path(item.path)) try: _, fp = acoustid.fingerprint_file(item.path) item.acoustid_fingerprint = fp if write: - log.info(u'{0}: writing fingerprint'.format( - util.displayable_path(item.path) - )) + log.info(u'{0}: writing fingerprint', + util.displayable_path(item.path)) item.try_write() if item._db: item.store() return item.acoustid_fingerprint except acoustid.FingerprintGenerationError as exc: - log.info(u'fingerprint generation failed: {0}' - .format(exc)) + log.info(u'fingerprint generation failed: {0}', exc) diff --git a/beetsplug/convert.py b/beetsplug/convert.py index 0b87fb71b..679ebcd72 100644 --- a/beetsplug/convert.py +++ b/beetsplug/convert.py @@ -92,7 +92,7 @@ def encode(command, source, dest, pretend=False): quiet = config['convert']['quiet'].get() if not quiet and not pretend: - log.info(u'Encoding {0}'.format(util.displayable_path(source))) + log.info(u'Encoding {0}', util.displayable_path(source)) # Substitute $source and $dest in the argument list. args = shlex.split(command) @@ -110,12 +110,11 @@ def encode(command, source, dest, pretend=False): util.command_output(args) except subprocess.CalledProcessError as exc: # Something went wrong (probably Ctrl+C), remove temporary files - log.info(u'Encoding {0} failed. Cleaning up...' - .format(util.displayable_path(source))) - log.debug(u'Command {0} exited with status {1}'.format( - exc.cmd.decode('utf8', 'ignore'), - exc.returncode, - )) + log.info(u'Encoding {0} failed. Cleaning up...', + util.displayable_path(source)) + log.debug(u'Command {0} exited with status {1}', + exc.cmd.decode('utf8', 'ignore'), + exc.returncode) util.remove(dest) util.prune_dirs(os.path.dirname(dest)) raise @@ -127,9 +126,8 @@ def encode(command, source, dest, pretend=False): ) if not quiet and not pretend: - log.info(u'Finished encoding {0}'.format( - util.displayable_path(source)) - ) + log.info(u'Finished encoding {0}', + util.displayable_path(source)) def should_transcode(item, format): @@ -173,21 +171,17 @@ def convert_item(dest_dir, keep_new, path_formats, format, pretend=False): util.mkdirall(dest) if os.path.exists(util.syspath(dest)): - log.info(u'Skipping {0} (target file exists)'.format( - util.displayable_path(item.path) - )) + log.info(u'Skipping {0} (target file exists)', + util.displayable_path(item.path)) continue if keep_new: if pretend: - log.info(u'mv {0} {1}'.format( - util.displayable_path(item.path), - util.displayable_path(original), - )) + log.info(u'mv {0} {1}', + util.displayable_path(item.path), + util.displayable_path(original)) else: - log.info(u'Moving to {0}'.format( - util.displayable_path(original)) - ) + log.info(u'Moving to {0}', util.displayable_path(original)) util.move(item.path, original) if should_transcode(item, format): @@ -197,15 +191,12 @@ def convert_item(dest_dir, keep_new, path_formats, format, pretend=False): continue else: if pretend: - log.info(u'cp {0} {1}'.format( - util.displayable_path(original), - util.displayable_path(converted), - )) + log.info(u'cp {0} {1}', + util.displayable_path(original), + util.displayable_path(converted)) else: # No transcoding necessary. - log.info(u'Copying {0}'.format( - util.displayable_path(item.path)) - ) + log.info(u'Copying {0}', util.displayable_path(item.path)) util.copy(original, converted) if pretend: @@ -281,19 +272,17 @@ def copy_album_art(album, dest_dir, path_formats, pretend=False): util.mkdirall(dest) if os.path.exists(util.syspath(dest)): - log.info(u'Skipping {0} (target file exists)'.format( - util.displayable_path(album.artpath) - )) + log.info(u'Skipping {0} (target file exists)', + util.displayable_path(album.artpath)) return if pretend: - log.info(u'cp {0} {1}'.format( - util.displayable_path(album.artpath), - util.displayable_path(dest), - )) + log.info(u'cp {0} {1}', + util.displayable_path(album.artpath), + util.displayable_path(dest)) else: - log.info(u'Copying cover art to {0}'.format( - util.displayable_path(dest))) + log.info(u'Copying cover art to {0}', + util.displayable_path(dest)) util.copy(album.artpath, dest) diff --git a/beetsplug/discogs.py b/beetsplug/discogs.py index 234d9b6cd..41c088225 100644 --- a/beetsplug/discogs.py +++ b/beetsplug/discogs.py @@ -89,7 +89,7 @@ class DiscogsPlugin(BeetsPlugin): raise beets.ui.UserError('Discogs authorization failed') # Save the token for later use. - log.debug('Discogs token {0}, secret {1}'.format(token, secret)) + log.debug('Discogs token {0}, secret {1}', token, secret) with open(self._tokenfile(), 'w') as f: json.dump({'token': token, 'secret': secret}, f) @@ -117,10 +117,10 @@ class DiscogsPlugin(BeetsPlugin): try: return self.get_albums(query) except DiscogsAPIError as e: - log.debug(u'Discogs API Error: {0} (query: {1})'.format(e, query)) + log.debug(u'Discogs API Error: {0} (query: {1})', e, query) return [] except ConnectionError as e: - log.debug(u'HTTP Connection Error: {0}'.format(e)) + log.debug(u'HTTP Connection Error: {0}', e) return [] def album_for_id(self, album_id): @@ -130,7 +130,7 @@ class DiscogsPlugin(BeetsPlugin): if not self.discogs_client: return - log.debug(u'Searching Discogs for release {0}'.format(str(album_id))) + log.debug(u'Searching Discogs for release {0}', album_id) # Discogs-IDs are simple integers. We only look for those at the end # of an input string as to avoid confusion with other metadata plugins. # An optional bracket can follow the integer, as this is how discogs @@ -145,11 +145,11 @@ class DiscogsPlugin(BeetsPlugin): getattr(result, 'title') except DiscogsAPIError as e: if e.message != '404 Not Found': - log.debug(u'Discogs API Error: {0} (query: {1})' - .format(e, result._uri)) + log.debug(u'Discogs API Error: {0} (query: {1})', + e, result._uri) return None except ConnectionError as e: - log.debug(u'HTTP Connection Error: {0}'.format(e)) + log.debug(u'HTTP Connection Error: {0}', e) return None return self.get_album_info(result) @@ -294,7 +294,7 @@ class DiscogsPlugin(BeetsPlugin): if match: medium, index = match.groups() else: - log.debug(u'Invalid Discogs position: {0}'.format(position)) + log.debug(u'Invalid Discogs position: {0}', position) medium = index = None return medium or None, index or None diff --git a/beetsplug/duplicates.py b/beetsplug/duplicates.py index 8e0af4ab7..5229ee5ca 100644 --- a/beetsplug/duplicates.py +++ b/beetsplug/duplicates.py @@ -56,20 +56,20 @@ def _checksum(item, prog): key = args[0] checksum = getattr(item, key, False) if not checksum: - log.debug(u'{0}: key {1} on item {2} not cached: computing checksum' - .format(PLUGIN, key, displayable_path(item.path))) + log.debug(u'{0}: key {1} on item {2} not cached: computing checksum', + PLUGIN, key, displayable_path(item.path)) try: checksum = command_output(args) setattr(item, key, checksum) item.store() - log.debug(u'{)}: computed checksum for {1} using {2}' - .format(PLUGIN, item.title, key)) + log.debug(u'{)}: computed checksum for {1} using {2}', + PLUGIN, item.title, key) except subprocess.CalledProcessError as e: - log.debug(u'{0}: failed to checksum {1}: {2}' - .format(PLUGIN, displayable_path(item.path), e)) + log.debug(u'{0}: failed to checksum {1}: {2}', + PLUGIN, displayable_path(item.path), e) else: - log.debug(u'{0}: key {1} on item {2} cached: not computing checksum' - .format(PLUGIN, key, displayable_path(item.path))) + log.debug(u'{0}: key {1} on item {2} cached: not computing checksum', + PLUGIN, key, displayable_path(item.path)) return key, checksum @@ -86,8 +86,8 @@ def _group_by(objs, keys): key = '\001'.join(values) counts[key].append(obj) else: - log.debug(u'{0}: all keys {1} on item {2} are null: skipping' - .format(PLUGIN, str(keys), displayable_path(obj.path))) + log.debug(u'{0}: all keys {1} on item {2} are null: skipping', + PLUGIN, str(keys), displayable_path(obj.path)) return counts diff --git a/beetsplug/echonest.py b/beetsplug/echonest.py index db440a44a..16ba6f3bd 100644 --- a/beetsplug/echonest.py +++ b/beetsplug/echonest.py @@ -154,23 +154,23 @@ class EchonestMetadataPlugin(plugins.BeetsPlugin): if e.code == 3: # reached access limit per minute log.debug(u'echonest: rate-limited on try {0}; ' - u'waiting {1} seconds' - .format(i + 1, RETRY_INTERVAL)) + u'waiting {1} seconds', + i + 1, RETRY_INTERVAL) time.sleep(RETRY_INTERVAL) elif e.code == 5: # specified identifier does not exist # no use in trying again. - log.debug(u'echonest: {0}'.format(e)) + log.debug(u'echonest: {0}', e) return None else: - log.error(u'echonest: {0}'.format(e.args[0][0])) + log.error(u'echonest: {0}', e.args[0][0]) return None except (pyechonest.util.EchoNestIOError, socket.error) as e: - log.warn(u'echonest: IO error: {0}'.format(e)) + log.warn(u'echonest: IO error: {0}', e) time.sleep(RETRY_INTERVAL) except Exception as e: # there was an error analyzing the track, status: error - log.debug(u'echonest: {0}'.format(e)) + log.debug(u'echonest: {0}', e) return None else: break @@ -292,10 +292,9 @@ class EchonestMetadataPlugin(plugins.BeetsPlugin): fd, dest = tempfile.mkstemp(u'.ogg') os.close(fd) - log.info(u'echonest: encoding {0} to {1}'.format( - util.displayable_path(source), - util.displayable_path(dest), - )) + log.info(u'echonest: encoding {0} to {1}', + util.displayable_path(source), + util.displayable_path(dest)) opts = [] for arg in CONVERT_COMMAND.split(): @@ -306,13 +305,12 @@ class EchonestMetadataPlugin(plugins.BeetsPlugin): try: util.command_output(opts) except (OSError, subprocess.CalledProcessError) as exc: - log.debug(u'echonest: encode failed: {0}'.format(exc)) + log.debug(u'echonest: encode failed: {0}', exc) util.remove(dest) return - log.info(u'echonest: finished encoding {0}'.format( - util.displayable_path(source)) - ) + log.info(u'echonest: finished encoding {0}', + util.displayable_path(source)) return dest def truncate(self, source): @@ -320,10 +318,9 @@ class EchonestMetadataPlugin(plugins.BeetsPlugin): fd, dest = tempfile.mkstemp(u'.ogg') os.close(fd) - log.info(u'echonest: truncating {0} to {1}'.format( - util.displayable_path(source), - util.displayable_path(dest), - )) + log.info(u'echonest: truncating {0} to {1}', + util.displayable_path(source), + util.displayable_path(dest)) opts = [] for arg in TRUNCATE_COMMAND.split(): @@ -334,13 +331,12 @@ class EchonestMetadataPlugin(plugins.BeetsPlugin): try: util.command_output(opts) except (OSError, subprocess.CalledProcessError) as exc: - log.debug(u'echonest: truncate failed: {0}'.format(exc)) + log.debug(u'echonest: truncate failed: {0}', exc) util.remove(dest) return - log.info(u'echonest: truncate encoding {0}'.format( - util.displayable_path(source)) - ) + log.info(u'echonest: truncate encoding {0}', + util.displayable_path(source)) return dest def analyze(self, item): @@ -411,13 +407,11 @@ class EchonestMetadataPlugin(plugins.BeetsPlugin): for method in methods: song = method(item) if song: - log.debug( - u'echonest: got song through {0}: {1} - {2} [{3}]'.format( - method.__name__, - item.artist, - item.title, - song.get('duration'), - ) + log.debug(u'echonest: got song through {0}: {1} - {2} [{3}]', + method.__name__, + item.artist, + item.title, + song.get('duration'), ) return song @@ -429,7 +423,7 @@ class EchonestMetadataPlugin(plugins.BeetsPlugin): for k, v in values.iteritems(): if k in ATTRIBUTES: field = ATTRIBUTES[k] - log.debug(u'echonest: metadata: {0} = {1}'.format(field, v)) + log.debug(u'echonest: metadata: {0} = {1}', field, v) if field == 'bpm': item[field] = int(v) else: @@ -441,7 +435,7 @@ class EchonestMetadataPlugin(plugins.BeetsPlugin): item['initial_key'] = key if 'id' in values: enid = values['id'] - log.debug(u'echonest: metadata: {0} = {1}'.format(ID_KEY, enid)) + log.debug(u'echonest: metadata: {0} = {1}', ID_KEY, enid) item[ID_KEY] = enid # Write and save. @@ -483,8 +477,7 @@ class EchonestMetadataPlugin(plugins.BeetsPlugin): self.config.set_args(opts) write = config['import']['write'].get(bool) for item in lib.items(ui.decargs(args)): - log.info(u'echonest: {0} - {1}'.format(item.artist, - item.title)) + log.info(u'echonest: {0} - {1}', item.artist, item.title) if self.config['force'] or self.requires_update(item): song = self.fetch_song(item) if song: diff --git a/beetsplug/embedart.py b/beetsplug/embedart.py index 49ed47928..3fdfd9055 100644 --- a/beetsplug/embedart.py +++ b/beetsplug/embedart.py @@ -122,20 +122,17 @@ def embed_item(item, imagepath, maxwidth=None, itempath=None, if not art: pass else: - log.debug(u'embedart: media file contained art already {0}'.format( - displayable_path(imagepath) - )) + log.debug(u'embedart: media file contained art already {0}', + displayable_path(imagepath)) return if maxwidth and not as_album: imagepath = resize_image(imagepath, maxwidth) try: - log.debug(u'embedart: embedding {0}'.format( - displayable_path(imagepath) - )) + log.debug(u'embedart: embedding {0}', displayable_path(imagepath)) item['images'] = [_mediafile_image(imagepath, maxwidth)] except IOError as exc: - log.error(u'embedart: could not read image file: {0}'.format(exc)) + log.error(u'embedart: could not read image file: {0}', exc) else: # We don't want to store the image in the database. item.try_write(itempath) @@ -147,19 +144,18 @@ def embed_album(album, maxwidth=None, quiet=False): """ imagepath = album.artpath if not imagepath: - log.info(u'No album art present: {0} - {1}'. - format(album.albumartist, album.album)) + log.info(u'No album art present: {0} - {1}', + album.albumartist, album.album) return if not os.path.isfile(syspath(imagepath)): - log.error(u'Album art not found at {0}' - .format(displayable_path(imagepath))) + log.error(u'Album art not found at {0}', displayable_path(imagepath)) return if maxwidth: imagepath = resize_image(imagepath, maxwidth) log.log( logging.DEBUG if quiet else logging.INFO, - u'Embedding album art into {0.albumartist} - {0.album}.'.format(album), + u'Embedding album art into {0.albumartist} - {0.album}.', album ) for item in album.items(): @@ -171,8 +167,7 @@ def embed_album(album, maxwidth=None, quiet=False): def resize_image(imagepath, maxwidth): """Returns path to an image resized to maxwidth. """ - log.info(u'Resizing album art to {0} pixels wide' - .format(maxwidth)) + log.info(u'Resizing album art to {0} pixels wide', maxwidth) imagepath = ArtResizer.shared.resize(maxwidth, syspath(imagepath)) return imagepath @@ -197,15 +192,14 @@ def check_art_similarity(item, imagepath, compare_threshold): stdout, stderr = proc.communicate() if proc.returncode: if proc.returncode != 1: - log.warn(u'embedart: IM phashes compare failed for {0}, \ - {1}'.format(displayable_path(imagepath), - displayable_path(art))) + log.warn(u'embedart: IM phashes compare failed for {0}, {1}', + displayable_path(imagepath), displayable_path(art)) return phashDiff = float(stderr) else: phashDiff = float(stdout) - log.info(u'embedart: compare PHASH score is {0}'.format(phashDiff)) + log.info(u'embedart: compare PHASH score is {0}', phashDiff) if phashDiff > compare_threshold: return False @@ -226,9 +220,8 @@ def get_art(item): try: mf = mediafile.MediaFile(syspath(item.path)) except mediafile.UnreadableFileError as exc: - log.error(u'Could not extract art from {0}: {1}'.format( - displayable_path(item.path), exc - )) + log.error(u'Could not extract art from {0}: {1}', + displayable_path(item.path), exc) return return mf.art @@ -244,8 +237,8 @@ def extract(outpath, item): art = get_art(item) if not art: - log.error(u'No album art present in {0} - {1}.' - .format(item.artist, item.title)) + log.error(u'No album art present in {0} - {1}.', + item.artist, item.title) return # Add an extension to the filename. @@ -255,8 +248,8 @@ def extract(outpath, item): return outpath += '.' + ext - log.info(u'Extracting album art from: {0.artist} - {0.title} ' - u'to: {1}'.format(item, displayable_path(outpath))) + log.info(u'Extracting album art from: {0.artist} - {0.title} to: {1}', + item, displayable_path(outpath)) with open(syspath(outpath), 'wb') as f: f.write(art) return outpath @@ -267,14 +260,13 @@ def extract(outpath, item): def clear(lib, query): log.info(u'Clearing album art from items:') for item in lib.items(query): - log.info(u'{0} - {1}'.format(item.artist, item.title)) + log.info(u'{0} - {1}', item.artist, item.title) try: mf = mediafile.MediaFile(syspath(item.path), config['id3v23'].get(bool)) except mediafile.UnreadableFileError as exc: - log.error(u'Could not clear art from {0}: {1}'.format( - displayable_path(item.path), exc - )) + log.error(u'Could not clear art from {0}: {1}', + displayable_path(item.path), exc) continue del mf.art mf.save() diff --git a/beetsplug/fetchart.py b/beetsplug/fetchart.py index b2a4620b1..e8c11b2f9 100644 --- a/beetsplug/fetchart.py +++ b/beetsplug/fetchart.py @@ -50,7 +50,7 @@ def _fetch_image(url): actually be an image. If so, returns a path to the downloaded image. Otherwise, returns None. """ - log.debug(u'fetchart: downloading art: {0}'.format(url)) + log.debug(u'fetchart: downloading art: {0}', url) try: with closing(requests_session.get(url, stream=True)) as resp: if 'Content-Type' not in resp.headers \ @@ -63,9 +63,8 @@ def _fetch_image(url): as fh: for chunk in resp.iter_content(): fh.write(chunk) - log.debug(u'fetchart: downloaded art to: {0}'.format( - util.displayable_path(fh.name) - )) + log.debug(u'fetchart: downloaded art to: {0}', + util.displayable_path(fh.name)) return fh.name except (IOError, requests.RequestException): log.debug(u'fetchart: error fetching art') @@ -117,7 +116,7 @@ def aao_art(album): # Get the page from albumart.org. try: resp = requests_session.get(AAO_URL, params={'asin': album.asin}) - log.debug(u'fetchart: scraped art URL: {0}'.format(resp.url)) + log.debug(u'fetchart: scraped art URL: {0}', resp.url) except requests.RequestException: log.debug(u'fetchart: error scraping art page') return @@ -172,7 +171,7 @@ def itunes_art(album): try: itunes_album = itunes.search_album(search_string)[0] except Exception as exc: - log.debug('fetchart: iTunes search failed: {0}'.format(exc)) + log.debug('fetchart: iTunes search failed: {0}', exc) return if itunes_album.get_artwork()['100']: @@ -216,16 +215,14 @@ def art_in_path(path, cover_names, cautious): cover_pat = r"(\b|_)({0})(\b|_)".format('|'.join(cover_names)) for fn in images: if re.search(cover_pat, os.path.splitext(fn)[0], re.I): - log.debug(u'fetchart: using well-named art file {0}'.format( - util.displayable_path(fn) - )) + log.debug(u'fetchart: using well-named art file {0}', + util.displayable_path(fn)) return os.path.join(path, fn) # Fall back to any image in the folder. if images and not cautious: - log.debug(u'fetchart: using fallback art file {0}'.format( - util.displayable_path(images[0]) - )) + log.debug(u'fetchart: using fallback art file {0}', + util.displayable_path(images[0])) return os.path.join(path, images[0]) @@ -315,8 +312,7 @@ def batch_fetch_art(lib, albums, force, maxwidth=None): else: message = ui.colorize('red', 'no art found') - log.info(u'{0} - {1}: {2}'.format(album.albumartist, album.album, - message)) + log.info(u'{0} - {1}: {2}', album.albumartist, album.album, message) class FetchArtPlugin(plugins.BeetsPlugin): diff --git a/beetsplug/ftintitle.py b/beetsplug/ftintitle.py index f28a1661c..8bd0974fe 100644 --- a/beetsplug/ftintitle.py +++ b/beetsplug/ftintitle.py @@ -52,8 +52,7 @@ def update_metadata(item, feat_part, drop_feat, loglevel=logging.DEBUG): remove it from the artist field. """ # In all cases, update the artist fields. - log.log(loglevel, u'artist: {0} -> {1}'.format( - item.artist, item.albumartist)) + log.log(loglevel, u'artist: {0} -> {1}', item.artist, item.albumartist) item.artist = item.albumartist if item.artist_sort: # Just strip the featured artist from the sort name. @@ -63,7 +62,7 @@ def update_metadata(item, feat_part, drop_feat, loglevel=logging.DEBUG): # artist and if we do not drop featuring information. if not drop_feat and not contains_feat(item.title): new_title = u"{0} feat. {1}".format(item.title, feat_part) - log.log(loglevel, u'title: {0} -> {1}'.format(item.title, new_title)) + log.log(loglevel, u'title: {0} -> {1}', item.title, new_title) item.title = new_title diff --git a/beetsplug/ihate.py b/beetsplug/ihate.py index b55554d8a..c8c930833 100644 --- a/beetsplug/ihate.py +++ b/beetsplug/ihate.py @@ -72,12 +72,11 @@ class IHatePlugin(BeetsPlugin): self._log.debug(u'[ihate] processing your hate') if self.do_i_hate_this(task, skip_queries): task.choice_flag = action.SKIP - self._log.info(u'[ihate] skipped: {0}' - .format(summary(task))) + self._log.info(u'[ihate] skipped: {0}', summary(task)) return if self.do_i_hate_this(task, warn_queries): - self._log.info(u'[ihate] you maybe hate this: {0}' - .format(summary(task))) + self._log.info(u'[ihate] you maybe hate this: {0}', + summary(task)) else: self._log.debug(u'[ihate] nothing to do') else: diff --git a/beetsplug/importadded.py b/beetsplug/importadded.py index bf2de1300..728112690 100644 --- a/beetsplug/importadded.py +++ b/beetsplug/importadded.py @@ -75,8 +75,8 @@ def write_item_mtime(item, mtime): item's file. """ if mtime is None: - log.warn(u"No mtime to be preserved for item '{0}'" - .format(util.displayable_path(item.path))) + log.warn(u"No mtime to be preserved for item '{0}'", + util.displayable_path(item.path)) return # The file's mtime on disk must be in sync with the item's mtime @@ -97,17 +97,17 @@ def record_import_mtime(item, source, destination): """ mtime = os.stat(util.syspath(source)).st_mtime item_mtime[destination] = mtime - log.debug(u"Recorded mtime {0} for item '{1}' imported from '{2}'".format( - mtime, util.displayable_path(destination), - util.displayable_path(source))) + log.debug(u"Recorded mtime {0} for item '{1}' imported from '{2}'", + mtime, util.displayable_path(destination), + util.displayable_path(source)) @ImportAddedPlugin.listen('album_imported') def update_album_times(lib, album): if reimported_album(album): log.debug(u"Album '{0}' is reimported, skipping import of added dates" - u" for the album and its items." - .format(util.displayable_path(album.path))) + u" for the album and its items.", + util.displayable_path(album.path)) return album_mtimes = [] @@ -120,7 +120,7 @@ def update_album_times(lib, album): item.store() album.added = min(album_mtimes) log.debug(u"Import of album '{0}', selected album.added={1} from item" - u" file mtimes.".format(album.album, album.added)) + u" file mtimes.", album.album, album.added) album.store() @@ -128,13 +128,13 @@ def update_album_times(lib, album): def update_item_times(lib, item): if reimported_item(item): log.debug(u"Item '{0}' is reimported, skipping import of added " - u"date.".format(util.displayable_path(item.path))) + u"date.", util.displayable_path(item.path)) return mtime = item_mtime.pop(item.path, None) if mtime: item.added = mtime if config['importadded']['preserve_mtimes'].get(bool): write_item_mtime(item, mtime) - log.debug(u"Import of item '{0}', selected item.added={1}" - .format(util.displayable_path(item.path), item.added)) + log.debug(u"Import of item '{0}', selected item.added={1}", + util.displayable_path(item.path), item.added) item.store() diff --git a/beetsplug/importfeeds.py b/beetsplug/importfeeds.py index 0f1cd11c8..dd1bf87df 100644 --- a/beetsplug/importfeeds.py +++ b/beetsplug/importfeeds.py @@ -132,7 +132,7 @@ def _record_items(lib, basename, items): if 'echo' in formats: log.info("Location of imported music:") for path in paths: - log.info(" " + path) + log.info(" {0}", path) @ImportFeedsPlugin.listen('library_opened') diff --git a/beetsplug/info.py b/beetsplug/info.py index 180f35747..f593bef12 100644 --- a/beetsplug/info.py +++ b/beetsplug/info.py @@ -52,7 +52,7 @@ def run(lib, opts, args): try: data = data_emitter() except mediafile.UnreadableFileError as ex: - log.error(u'cannot read file: {0}'.format(ex.message)) + log.error(u'cannot read file: {0}', ex.message) continue if opts.summarize: diff --git a/beetsplug/inline.py b/beetsplug/inline.py index 1ce4eb788..0f2e9f1d4 100644 --- a/beetsplug/inline.py +++ b/beetsplug/inline.py @@ -64,9 +64,8 @@ def compile_inline(python_code, album): try: func = _compile_func(python_code) except SyntaxError: - log.error(u'syntax error in inline field definition:\n{0}'.format( - traceback.format_exc() - )) + log.error(u'syntax error in inline field definition:\n{0}', + traceback.format_exc()) return else: is_expr = False @@ -113,14 +112,14 @@ class InlinePlugin(BeetsPlugin): # Item fields. for key, view in itertools.chain(config['item_fields'].items(), config['pathfields'].items()): - log.debug(u'inline: adding item field {0}'.format(key)) + log.debug(u'inline: adding item field {0}', key) func = compile_inline(view.get(unicode), False) if func is not None: self.template_fields[key] = func # Album fields. for key, view in config['album_fields'].items(): - log.debug(u'inline: adding album field {0}'.format(key)) + log.debug(u'inline: adding album field {0}', key) func = compile_inline(view.get(unicode), True) if func is not None: self.album_template_fields[key] = func diff --git a/beetsplug/keyfinder.py b/beetsplug/keyfinder.py index 2abae381d..499fa5201 100644 --- a/beetsplug/keyfinder.py +++ b/beetsplug/keyfinder.py @@ -62,11 +62,11 @@ class KeyFinderPlugin(BeetsPlugin): try: key = util.command_output([bin, '-f', item.path]) except (subprocess.CalledProcessError, OSError) as exc: - log.error(u'KeyFinder execution failed: {0}'.format(exc)) + log.error(u'KeyFinder execution failed: {0}', exc) continue item['initial_key'] = key - log.debug(u'added computed initial key {0} for {1}' - .format(key, util.displayable_path(item.path))) + log.debug(u'added computed initial key {0} for {1}', + key, util.displayable_path(item.path)) item.try_write() item.store() diff --git a/beetsplug/lastgenre/__init__.py b/beetsplug/lastgenre/__init__.py index 109aaae3c..c1c1c39ab 100644 --- a/beetsplug/lastgenre/__init__.py +++ b/beetsplug/lastgenre/__init__.py @@ -71,7 +71,7 @@ def _tags_for(obj, min_weight=None): else: res = obj.get_top_tags() except PYLAST_EXCEPTIONS as exc: - log.debug(u'last.fm error: {0}'.format(exc)) + log.debug(u'last.fm error: {0}', exc) return [] # Filter by weight (optionally). @@ -371,9 +371,8 @@ class LastGenrePlugin(plugins.BeetsPlugin): for album in lib.albums(ui.decargs(args)): album.genre, src = self._get_genre(album) - log.info(u'genre for album {0} - {1} ({2}): {3}'.format( - album.albumartist, album.album, src, album.genre - )) + log.info(u'genre for album {0} - {1} ({2}): {3}', + album.albumartist, album.album, src, album.genre) album.store() for item in album.items(): @@ -382,9 +381,8 @@ class LastGenrePlugin(plugins.BeetsPlugin): if 'track' in self.sources: item.genre, src = self._get_genre(item) item.store() - log.info(u'genre for track {0} - {1} ({2}): {3}' - .format(item.artist, item.title, src, - item.genre)) + log.info(u'genre for track {0} - {1} ({2}): {3}', + item.artist, item.title, src, item.genre) if write: item.try_write() @@ -397,20 +395,20 @@ class LastGenrePlugin(plugins.BeetsPlugin): if task.is_album: album = task.album album.genre, src = self._get_genre(album) - log.debug(u'added last.fm album genre ({0}): {1}'.format( - src, album.genre)) + log.debug(u'added last.fm album genre ({0}): {1}', + src, album.genre) album.store() if 'track' in self.sources: for item in album.items(): item.genre, src = self._get_genre(item) - log.debug(u'added last.fm item genre ({0}): {1}'.format( - src, item.genre)) + log.debug(u'added last.fm item genre ({0}): {1}', + src, item.genre) item.store() else: item = task.item item.genre, src = self._get_genre(item) - log.debug(u'added last.fm item genre ({0}): {1}'.format( - src, item.genre)) + log.debug(u'added last.fm item genre ({0}): {1}', + src, item.genre) item.store() diff --git a/beetsplug/lastimport.py b/beetsplug/lastimport.py index 240aa90ca..7a723a36d 100644 --- a/beetsplug/lastimport.py +++ b/beetsplug/lastimport.py @@ -56,7 +56,7 @@ def import_lastfm(lib): if not user: raise ui.UserError('You must specify a user name for lastimport') - log.info('Fetching last.fm library for @{0}'.format(user)) + log.info('Fetching last.fm library for @{0}', user) page_total = 1 page_current = 0 @@ -65,10 +65,10 @@ def import_lastfm(lib): retry_limit = config['lastimport']['retry_limit'].get(int) # Iterate through a yet to be known page total count while page_current < page_total: - log.info('lastimport: Querying page #{0}{1}...'.format( - page_current + 1, - '/' + str(page_total) if page_total > 1 else '' - )) + log.info('lastimport: Querying page #{0}{1}...', + page_current + 1, + '/{}'.format(page_total) if page_total > 1 else '' + ) for retry in range(0, retry_limit): page = fetch_tracks(user, page_current + 1, per_page) @@ -84,27 +84,22 @@ def import_lastfm(lib): unknown_total += unknown break else: - log.error('lastimport: ERROR: unable to read page #{0}'.format( - page_current + 1 - )) + log.error('lastimport: ERROR: unable to read page #{0}', + page_current + 1) if retry < retry_limit: log.info( - 'lastimport: Retrying page #{0}... ({1}/{2} retry)' - .format(page_current + 1, retry + 1, retry_limit) + 'lastimport: Retrying page #{0}... ({1}/{2} retry)', + page_current + 1, retry + 1, retry_limit ) else: - log.error( - 'lastimport: FAIL: unable to fetch page #{0}, ' - 'tried {1} times'.format(page_current, retry + 1) - ) + log.error('lastimport: FAIL: unable to fetch page #{0}, ', + 'tried {1} times', page_current, retry + 1) page_current += 1 log.info('lastimport: ... done!') - log.info('lastimport: finished processing {0} song pages'.format( - page_total - )) - log.info('lastimport: {0} unknown play-counts'.format(unknown_total)) - log.info('lastimport: {0} play-counts imported'.format(found_total)) + log.info('lastimport: finished processing {0} song pages', page_total) + log.info('lastimport: {0} unknown play-counts', unknown_total) + log.info('lastimport: {0} play-counts imported', found_total) def fetch_tracks(user, page, limit): @@ -122,10 +117,8 @@ def process_tracks(lib, tracks): total = len(tracks) total_found = 0 total_fails = 0 - log.info( - 'lastimport: Received {0} tracks in this page, processing...' - .format(total) - ) + log.info('lastimport: Received {0} tracks in this page, processing...', + total) for num in xrange(0, total): song = '' @@ -136,8 +129,7 @@ def process_tracks(lib, tracks): if 'album' in tracks[num]: album = tracks[num]['album'].get('name', '').strip() - log.debug(u'lastimport: query: {0} - {1} ({2})' - .format(artist, title, album)) + log.debug(u'lastimport: query: {0} - {1} ({2})', artist, title, album) # First try to query by musicbrainz's trackid if trackid: @@ -148,7 +140,7 @@ def process_tracks(lib, tracks): # Otherwise try artist/title/album if not song: log.debug(u'lastimport: no match for mb_trackid {0}, trying by ' - u'artist/title/album'.format(trackid)) + u'artist/title/album', trackid) query = dbcore.AndQuery([ dbcore.query.SubstringQuery('artist', artist), dbcore.query.SubstringQuery('title', title), @@ -178,26 +170,20 @@ def process_tracks(lib, tracks): if song: count = int(song.get('play_count', 0)) new_count = int(tracks[num]['playcount']) - log.debug( - u'lastimport: match: {0} - {1} ({2}) ' - u'updating: play_count {3} => {4}'.format( - song.artist, song.title, song.album, count, new_count - ) + log.debug(u'lastimport: match: {0} - {1} ({2}) ' + u'updating: play_count {3} => {4}', + song.artist, song.title, song.album, count, new_count ) song['play_count'] = new_count song.store() total_found += 1 else: total_fails += 1 - log.info( - u'lastimport: - No match: {0} - {1} ({2})' - .format(artist, title, album) - ) + log.info(u'lastimport: - No match: {0} - {1} ({2})', + artist, title, album) if total_fails > 0: - log.info( - 'lastimport: Acquired {0}/{1} play-counts ({2} unknown)' - .format(total_found, total, total_fails) - ) + log.info('lastimport: Acquired {0}/{1} play-counts ({2} unknown)', + total_found, total, total_fails) return total_found, total_fails diff --git a/beetsplug/lyrics.py b/beetsplug/lyrics.py index a2ebe7c36..17bf4c4fc 100644 --- a/beetsplug/lyrics.py +++ b/beetsplug/lyrics.py @@ -63,12 +63,12 @@ def fetch_url(url): try: r = requests.get(url, verify=False) except requests.RequestException as exc: - log.debug(u'lyrics request failed: {0}'.format(exc)) + log.debug(u'lyrics request failed: {0}', exc) return if r.status_code == requests.codes.ok: return r.text else: - log.debug(u'failed to fetch: {0} ({1})'.format(url, r.status_code)) + log.debug(u'failed to fetch: {0} ({1})', url, r.status_code) def unescape(text): @@ -272,7 +272,7 @@ def slugify(text): text = unicodedata.normalize('NFKD', text).encode('ascii', 'ignore') text = unicode(re.sub('[-\s]+', ' ', text)) except UnicodeDecodeError: - log.exception(u"Failing to normalize '{0}'".format(text)) + log.exception(u"Failing to normalize '{0}'", text) return text @@ -323,7 +323,7 @@ def is_lyrics(text, artist=None): badTriggersOcc = [] nbLines = text.count('\n') if nbLines <= 1: - log.debug(u"Ignoring too short lyrics '{0}'".format(text)) + log.debug(u"Ignoring too short lyrics '{0}'", text) return False elif nbLines < 5: badTriggersOcc.append('too_short') @@ -341,7 +341,7 @@ def is_lyrics(text, artist=None): text, re.I)) if badTriggersOcc: - log.debug(u'Bad triggers detected: {0}'.format(badTriggersOcc)) + log.debug(u'Bad triggers detected: {0}', badTriggersOcc) return len(badTriggersOcc) < 2 @@ -409,7 +409,7 @@ def fetch_google(artist, title): data = json.load(data) if 'error' in data: reason = data['error']['errors'][0]['reason'] - log.debug(u'google lyrics backend error: {0}'.format(reason)) + log.debug(u'google lyrics backend error: {0}', reason) return if 'items' in data.keys(): @@ -424,7 +424,7 @@ def fetch_google(artist, title): continue if is_lyrics(lyrics, artist): - log.debug(u'got lyrics from {0}'.format(item['displayLink'])) + log.debug(u'got lyrics from {0}', item['displayLink']) return lyrics @@ -502,8 +502,8 @@ class LyricsPlugin(plugins.BeetsPlugin): """ # Skip if the item already has lyrics. if not force and item.lyrics: - log.log(loglevel, u'lyrics already present: {0} - {1}' - .format(item.artist, item.title)) + log.log(loglevel, u'lyrics already present: {0} - {1}', + item.artist, item.title) return lyrics = None @@ -515,11 +515,11 @@ class LyricsPlugin(plugins.BeetsPlugin): lyrics = u"\n\n---\n\n".join([l for l in lyrics if l]) if lyrics: - log.log(loglevel, u'fetched lyrics: {0} - {1}' - .format(item.artist, item.title)) + log.log(loglevel, u'fetched lyrics: {0} - {1}', + item.artist, item.title) else: - log.log(loglevel, u'lyrics not found: {0} - {1}' - .format(item.artist, item.title)) + log.log(loglevel, u'lyrics not found: {0} - {1}', + item.artist, item.title) fallback = self.config['fallback'].get() if fallback: lyrics = fallback @@ -539,6 +539,5 @@ class LyricsPlugin(plugins.BeetsPlugin): for backend in self.backends: lyrics = backend(artist, title) if lyrics: - log.debug(u'got lyrics from backend: {0}' - .format(backend.__name__)) + log.debug(u'got lyrics from backend: {0}', backend.__name__) return _scrape_strip_cruft(lyrics, True) diff --git a/beetsplug/mbcollection.py b/beetsplug/mbcollection.py index 610408232..3683c7584 100644 --- a/beetsplug/mbcollection.py +++ b/beetsplug/mbcollection.py @@ -79,7 +79,7 @@ def update_album_list(album_list): if re.match(UUID_REGEX, aid): album_ids.append(aid) else: - log.info(u'skipping invalid MBID: {0}'.format(aid)) + log.info(u'skipping invalid MBID: {0}', aid) # Submit to MusicBrainz. print('Updating MusicBrainz collection {0}...'.format(collection_id)) diff --git a/beetsplug/mbsync.py b/beetsplug/mbsync.py index 989caeb99..c96d0cf71 100644 --- a/beetsplug/mbsync.py +++ b/beetsplug/mbsync.py @@ -31,14 +31,13 @@ def mbsync_singletons(lib, query, move, pretend, write): """ for item in lib.items(query + ['singleton:true']): if not item.mb_trackid: - log.info(u'Skipping singleton {0}: has no mb_trackid' - .format(item.title)) + log.info(u'Skipping singleton {0}: has no mb_trackid', item.title) continue # Get the MusicBrainz recording info. track_info = hooks.track_for_mbid(item.mb_trackid) if not track_info: - log.info(u'Recording ID not found: {0}'.format(item.mb_trackid)) + log.info(u'Recording ID not found: {0}', item.mb_trackid) continue # Apply. @@ -54,7 +53,7 @@ def mbsync_albums(lib, query, move, pretend, write): # Process matching albums. for a in lib.albums(query): if not a.mb_albumid: - log.info(u'Skipping album {0}: has no mb_albumid'.format(a.id)) + log.info(u'Skipping album {0}: has no mb_albumid', a.id) continue items = list(a.items()) @@ -62,7 +61,7 @@ def mbsync_albums(lib, query, move, pretend, write): # Get the MusicBrainz album information. album_info = hooks.album_for_mbid(a.mb_albumid) if not album_info: - log.info(u'Release ID not found: {0}'.format(a.mb_albumid)) + log.info(u'Release ID not found: {0}', a.mb_albumid) continue # Map recording MBIDs to their information. Recordings can appear @@ -109,7 +108,7 @@ def mbsync_albums(lib, query, move, pretend, write): # Move album art (and any inconsistent items). if move and lib.directory in util.ancestry(items[0].path): - log.debug(u'moving album {0}'.format(a.id)) + log.debug(u'moving album {0}', a.id) a.move() diff --git a/beetsplug/missing.py b/beetsplug/missing.py index 74f4d4b6c..439b1d384 100644 --- a/beetsplug/missing.py +++ b/beetsplug/missing.py @@ -43,10 +43,8 @@ def _missing(album): for track_info in getattr(album_info, 'tracks', []): if track_info.track_id not in item_mbids: item = _item(track_info, album_info, album.id) - log.debug(u'{0}: track {1} in album {2}' - .format(PLUGIN, - track_info.track_id, - album_info.album_id)) + log.debug(u'{0}: track {1} in album {2}', + PLUGIN, track_info.track_id, album_info.album_id) yield item diff --git a/beetsplug/mpdstats.py b/beetsplug/mpdstats.py index c198445dc..2fddb6a8c 100644 --- a/beetsplug/mpdstats.py +++ b/beetsplug/mpdstats.py @@ -71,7 +71,7 @@ class MPDClientWrapper(object): if host[0] in ['/', '~']: host = os.path.expanduser(host) - log.info(u'mpdstats: connecting to {0}:{1}'.format(host, port)) + log.info(u'mpdstats: connecting to {0}:{1}', host, port) try: self.client.connect(host, port) except socket.error as e: @@ -99,7 +99,7 @@ class MPDClientWrapper(object): try: return getattr(self.client, command)() except (select.error, mpd.ConnectionError) as err: - log.error(u'mpdstats: {0}'.format(err)) + log.error(u'mpdstats: {0}', err) if retries <= 0: # if we exited without breaking, we couldn't reconnect in time :( @@ -171,9 +171,7 @@ class MPDStats(object): if item: return item else: - log.info(u'mpdstats: item not found: {0}'.format( - displayable_path(path) - )) + log.info(u'mpdstats: item not found: {0}', displayable_path(path)) @staticmethod def update_item(item, attribute, value=None, increment=None): @@ -192,11 +190,11 @@ class MPDStats(object): item[attribute] = value item.store() - log.debug(u'mpdstats: updated: {0} = {1} [{2}]'.format( - attribute, - item[attribute], - displayable_path(item.path), - )) + log.debug(u'mpdstats: updated: {0} = {1} [{2}]', + attribute, + item[attribute], + displayable_path(item.path), + ) def update_rating(self, item, skipped): """Update the rating for a beets item. @@ -232,17 +230,13 @@ class MPDStats(object): """Updates the play count of a song. """ self.update_item(song['beets_item'], 'play_count', increment=1) - log.info(u'mpdstats: played {0}'.format( - displayable_path(song['path']) - )) + log.info(u'mpdstats: played {0}', displayable_path(song['path'])) def handle_skipped(self, song): """Updates the skip count of a song. """ self.update_item(song['beets_item'], 'skip_count', increment=1) - log.info(u'mpdstats: skipped {0}'.format( - displayable_path(song['path']) - )) + log.info(u'mpdstats: skipped {0}', displayable_path(song['path'])) def on_stop(self, status): log.info(u'mpdstats: stop') @@ -264,9 +258,7 @@ class MPDStats(object): return if is_url(path): - log.info(u'mpdstats: playing stream {0}'.format( - displayable_path(path) - )) + log.info(u'mpdstats: playing stream {0}', displayable_path(path)) return played, duration = map(int, status['time'].split(':', 1)) @@ -275,9 +267,7 @@ class MPDStats(object): if self.now_playing and self.now_playing['path'] != path: self.handle_song_change(self.now_playing) - log.info(u'mpdstats: playing {0}'.format( - displayable_path(path) - )) + log.info(u'mpdstats: playing {0}', displayable_path(path)) self.now_playing = { 'started': time.time(), @@ -302,8 +292,7 @@ class MPDStats(object): if handler: handler(status) else: - log.debug(u'mpdstats: unhandled status "{0}"'. - format(status)) + log.debug(u'mpdstats: unhandled status "{0}"', status) events = self.mpd.events() diff --git a/beetsplug/play.py b/beetsplug/play.py index 770b84284..609627d59 100644 --- a/beetsplug/play.py +++ b/beetsplug/play.py @@ -101,10 +101,10 @@ def play_music(lib, opts, args): # Invoke the command and log the output. output = util.command_output(command) if output: - log.debug(u'Output of {0}: {1}'.format( - util.displayable_path(command[0]), - output.decode('utf8', 'ignore'), - )) + log.debug(u'Output of {0}: {1}', + util.displayable_path(command[0]), + output.decode('utf8', 'ignore'), + ) else: log.debug(u'play: no output') diff --git a/beetsplug/replaygain.py b/beetsplug/replaygain.py index 40b3a3a85..d7f8366f5 100644 --- a/beetsplug/replaygain.py +++ b/beetsplug/replaygain.py @@ -180,9 +180,9 @@ class CommandBackend(Backend): cmd = cmd + ['-d', str(self.gain_offset)] cmd = cmd + [syspath(i.path) for i in items] - log.debug(u'replaygain: analyzing {0} files'.format(len(items))) - log.debug(u"replaygain: executing {0}" - .format(" ".join(map(displayable_path, cmd)))) + log.debug(u'replaygain: analyzing {0} files', len(items)) + log.debug(u"replaygain: executing {0}", + " ".join(map(displayable_path, cmd))) output = call(cmd) log.debug(u'replaygain: analysis finished') results = self.parse_tool_output(output, @@ -199,7 +199,7 @@ class CommandBackend(Backend): for line in text.split('\n')[1:num_lines + 1]: parts = line.split('\t') if len(parts) != 6 or parts[0] == 'File': - log.debug(u'replaygain: bad tool output: {0}'.format(text)) + log.debug(u'replaygain: bad tool output: {0}', text) raise ReplayGainError('mp3gain failed') d = { 'file': parts[0], @@ -548,14 +548,8 @@ class AudioToolsBackend(Backend): # be obtained from an audiofile instance. rg_track_gain, rg_track_peak = rg.title_gain(audiofile.to_pcm()) - log.debug( - u'ReplayGain for track {0} - {1}: {2:.2f}, {3:.2f}'.format( - item.artist, - item.title, - rg_track_gain, - rg_track_peak - ) - ) + log.debug(u'ReplayGain for track {0} - {1}: {2:.2f}, {3:.2f}', + item.artist, item.title, rg_track_gain, rg_track_peak) return Gain(gain=rg_track_gain, peak=rg_track_peak) def compute_album_gain(self, album): @@ -563,12 +557,7 @@ class AudioToolsBackend(Backend): :rtype: :class:`AlbumGain` """ - log.debug( - u'Analysing album {0} - {1}'.format( - album.albumartist, - album.album - ) - ) + log.debug(u'Analysing album {0} - {1}', album.albumartist, album.album) # The first item is taken and opened to get the sample rate to # initialize the replaygain object. The object is used for all the @@ -584,26 +573,14 @@ class AudioToolsBackend(Backend): track_gains.append( Gain(gain=rg_track_gain, peak=rg_track_peak) ) - log.debug( - u'ReplayGain for track {0} - {1}: {2:.2f}, {3:.2f}'.format( - item.artist, - item.title, - rg_track_gain, - rg_track_peak - ) - ) + log.debug(u'ReplayGain for track {0} - {1}: {2:.2f}, {3:.2f}', + item.artist, item.title, rg_track_gain, rg_track_peak) # After getting the values for all tracks, it's possible to get the # album values. rg_album_gain, rg_album_peak = rg.album_gain() - log.debug( - u'ReplayGain for Album {0} - {1}: {2:.2f}, {3:.2f}'.format( - album.albumartist, - album.album, - rg_album_gain, - rg_album_peak - ) - ) + log.debug(u'ReplayGain for Album {0} - {1}: {2:.2f}, {3:.2f}', + album.albumartist, album.album, rg_album_gain, rg_album_peak) return AlbumGain( Gain(gain=rg_album_gain, peak=rg_album_peak), @@ -674,19 +651,16 @@ class ReplayGainPlugin(BeetsPlugin): item.rg_track_peak = track_gain.peak item.store() - log.debug(u'replaygain: applied track gain {0}, peak {1}'.format( - item.rg_track_gain, - item.rg_track_peak - )) + log.debug(u'replaygain: applied track gain {0}, peak {1}', + item.rg_track_gain, item.rg_track_peak) def store_album_gain(self, album, album_gain): album.rg_album_gain = album_gain.gain album.rg_album_peak = album_gain.peak album.store() - log.debug(u'replaygain: applied album gain {0}, peak {1}'.format( - album.rg_album_gain, - album.rg_album_peak)) + log.debug(u'replaygain: applied album gain {0}, peak {1}', + album.rg_album_gain, album.rg_album_peak) def handle_album(self, album, write): """Compute album and track replay gain store it in all of the @@ -697,12 +671,11 @@ class ReplayGainPlugin(BeetsPlugin): items, nothing is done. """ if not self.album_requires_gain(album): - log.info(u'Skipping album {0} - {1}'.format(album.albumartist, - album.album)) + log.info(u'Skipping album {0} - {1}', + album.albumartist, album.album) return - log.info(u'analyzing {0} - {1}'.format(album.albumartist, - album.album)) + log.info(u'analyzing {0} - {1}', album.albumartist, album.album) try: album_gain = self.backend_instance.compute_album_gain(album) @@ -721,7 +694,7 @@ class ReplayGainPlugin(BeetsPlugin): if write: item.try_write() except ReplayGainError as e: - log.info(u"ReplayGain error: {0}".format(e)) + log.info(u"ReplayGain error: {0}", e) except FatalReplayGainError as e: raise ui.UserError( u"Fatal replay gain error: {0}".format(e) @@ -735,12 +708,10 @@ class ReplayGainPlugin(BeetsPlugin): in the item, nothing is done. """ if not self.track_requires_gain(item): - log.info(u'Skipping track {0} - {1}' - .format(item.artist, item.title)) + log.info(u'Skipping track {0} - {1}', item.artist, item.title) return - log.info(u'analyzing {0} - {1}' - .format(item.artist, item.title)) + log.info(u'analyzing {0} - {1}', item.artist, item.title) try: track_gains = self.backend_instance.compute_track_gain([item]) @@ -755,7 +726,7 @@ class ReplayGainPlugin(BeetsPlugin): if write: item.try_write() except ReplayGainError as e: - log.info(u"ReplayGain error: {0}".format(e)) + log.info(u"ReplayGain error: {0}", e) except FatalReplayGainError as e: raise ui.UserError( u"Fatal replay gain error: {0}".format(e) diff --git a/beetsplug/rewrite.py b/beetsplug/rewrite.py index 55b705492..cbb9e2a74 100644 --- a/beetsplug/rewrite.py +++ b/beetsplug/rewrite.py @@ -59,7 +59,7 @@ class RewritePlugin(BeetsPlugin): if fieldname not in library.Item._fields: raise ui.UserError("invalid field name (%s) in rewriter" % fieldname) - log.debug(u'adding template field {0}'.format(key)) + log.debug(u'adding template field {0}', key) pattern = re.compile(pattern.lower()) rules[fieldname].append((pattern, value)) if fieldname == 'artist': diff --git a/beetsplug/scrub.py b/beetsplug/scrub.py index c53c27590..0b071a162 100644 --- a/beetsplug/scrub.py +++ b/beetsplug/scrub.py @@ -64,8 +64,7 @@ class ScrubPlugin(BeetsPlugin): # Walk through matching files and remove tags. for item in lib.items(ui.decargs(args)): - log.info(u'scrubbing: {0}'.format( - util.displayable_path(item.path))) + log.info(u'scrubbing: {0}', util.displayable_path(item.path)) # Get album art if we need to restore it. if opts.write: @@ -132,14 +131,13 @@ def _scrub(path): del f[tag] f.save() except IOError as exc: - log.error(u'could not scrub {0}: {1}'.format( - util.displayable_path(path), exc, - )) + log.error(u'could not scrub {0}: {1}', + util.displayable_path(path), exc) # Automatically embed art into imported albums. @ScrubPlugin.listen('write') def write_item(path): if not scrubbing and config['scrub']['auto']: - log.debug(u'auto-scrubbing {0}'.format(util.displayable_path(path))) + log.debug(u'auto-scrubbing {0}', util.displayable_path(path)) _scrub(path) diff --git a/beetsplug/spotify.py b/beetsplug/spotify.py index 7d424c828..33b29fd8d 100644 --- a/beetsplug/spotify.py +++ b/beetsplug/spotify.py @@ -63,8 +63,7 @@ class SpotifyPlugin(BeetsPlugin): self.config['show_failures'].set(True) if self.config['mode'].get() not in ['list', 'open']: - log.warn(u'{0} is not a valid mode' - .format(self.config['mode'].get())) + log.warn(u'{0} is not a valid mode', self.config['mode'].get()) return False self.opts = opts @@ -81,7 +80,7 @@ class SpotifyPlugin(BeetsPlugin): log.debug(u'Your beets query returned no items, skipping spotify') return - log.info(u'Processing {0} tracks...'.format(len(items))) + log.info(u'Processing {0} tracks...', len(items)) for item in items: @@ -113,8 +112,7 @@ class SpotifyPlugin(BeetsPlugin): try: r.raise_for_status() except HTTPError as e: - log.debug(u'URL returned a {0} error' - .format(e.response.status_code)) + log.debug(u'URL returned a {0} error', e.response.status_code) failures.append(search_url) continue @@ -130,33 +128,29 @@ class SpotifyPlugin(BeetsPlugin): # Simplest, take the first result chosen_result = None if len(r_data) == 1 or self.config['tiebreak'].get() == "first": - log.debug(u'Spotify track(s) found, count: {0}' - .format(len(r_data))) + log.debug(u'Spotify track(s) found, count: {0}', len(r_data)) chosen_result = r_data[0] elif len(r_data) > 1: # Use the popularity filter - log.debug(u'Most popular track chosen, count: {0}' - .format(len(r_data))) + log.debug(u'Most popular track chosen, count: {0}', len(r_data)) chosen_result = max(r_data, key=lambda x: x['popularity']) if chosen_result: results.append(chosen_result) else: - log.debug(u'No spotify track found: {0}'.format(search_url)) + log.debug(u'No spotify track found: {0}', search_url) failures.append(search_url) failure_count = len(failures) if failure_count > 0: if self.config['show_failures'].get(): - log.info(u'{0} track(s) did not match a Spotify ID:' - .format(failure_count)) + log.info(u'{0} track(s) did not match a Spotify ID:', failure_count) for track in failures: - log.info(u'track: {0}'.format(track)) + log.info(u'track: {0}', track) log.info(u'') else: log.warn(u'{0} track(s) did not match a Spotify ID;\n' - u'use --show-failures to display' - .format(failure_count)) + u'use --show-failures to display', failure_count) return results diff --git a/beetsplug/the.py b/beetsplug/the.py index 5bc50415a..fb441c572 100644 --- a/beetsplug/the.py +++ b/beetsplug/the.py @@ -56,11 +56,11 @@ class ThePlugin(BeetsPlugin): try: re.compile(p) except re.error: - self._log.error(u'[the] invalid pattern: {0}'.format(p)) + self._log.error(u'[the] invalid pattern: {0}', p) else: if not (p.startswith('^') or p.endswith('$')): self._log.warn(u'[the] warning: \"{0}\" will not ' - 'match string start/end'.format(p)) + 'match string start/end', p) if self.config['a']: self.patterns = [PATTERN_A] + self.patterns if self.config['the']: @@ -99,7 +99,7 @@ class ThePlugin(BeetsPlugin): r = self.unthe(text, p) if r != text: break - self._log.debug(u'[the] \"{0}\" -> \"{1}\"'.format(text, r)) + self._log.debug(u'[the] \"{0}\" -> \"{1}\"', text, r) return r else: return u'' diff --git a/beetsplug/zero.py b/beetsplug/zero.py index ed41511c8..ae164bef0 100644 --- a/beetsplug/zero.py +++ b/beetsplug/zero.py @@ -49,10 +49,10 @@ class ZeroPlugin(BeetsPlugin): for field in self.config['fields'].as_str_seq(): if field in ('id', 'path', 'album_id'): log.warn(u'[zero] field \'{0}\' ignored, zeroing ' - u'it would be dangerous'.format(field)) + u'it would be dangerous', field) continue if field not in MediaFile.fields(): - log.error(u'[zero] invalid field: {0}'.format(field)) + log.error(u'[zero] invalid field: {0}', field) continue try: @@ -97,5 +97,5 @@ class ZeroPlugin(BeetsPlugin): match = patterns is True if match: - log.debug(u'[zero] {0}: {1} -> None'.format(field, value)) + log.debug(u'[zero] {0}: {1} -> None', field, value) tags[field] = None From 6bdb02c7218c0b41ee13e17edd9c41a1557d6ad9 Mon Sep 17 00:00:00 2001 From: Bruno Cauet Date: Sun, 4 Jan 2015 12:25:24 +0100 Subject: [PATCH 04/16] Fix logging formatting string in duplicates plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit {)} → {0} --- beetsplug/duplicates.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beetsplug/duplicates.py b/beetsplug/duplicates.py index 5229ee5ca..4b15bf939 100644 --- a/beetsplug/duplicates.py +++ b/beetsplug/duplicates.py @@ -62,7 +62,7 @@ def _checksum(item, prog): checksum = command_output(args) setattr(item, key, checksum) item.store() - log.debug(u'{)}: computed checksum for {1} using {2}', + log.debug(u'{0}: computed checksum for {1} using {2}', PLUGIN, item.title, key) except subprocess.CalledProcessError as e: log.debug(u'{0}: failed to checksum {1}: {2}', From 7df8bef8b7201395886a23eaf925b46090763655 Mon Sep 17 00:00:00 2001 From: Bruno Cauet Date: Sun, 4 Jan 2015 16:19:54 +0100 Subject: [PATCH 05/16] =?UTF-8?q?Update=20logging=20imports:=20logging=20?= =?UTF-8?q?=E2=86=92=20beets.logging?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- beets/autotag/__init__.py | 2 +- beets/autotag/hooks.py | 2 +- beets/autotag/match.py | 2 +- beets/autotag/mb.py | 2 +- beets/importer.py | 2 +- beets/library.py | 2 +- beets/mediafile.py | 2 +- beets/plugins.py | 2 +- beets/ui/__init__.py | 2 +- beets/ui/commands.py | 2 +- beets/util/artresizer.py | 2 +- beetsplug/beatport.py | 2 +- beetsplug/bpd/__init__.py | 2 +- beetsplug/bpm.py | 2 +- beetsplug/bucket.py | 2 +- beetsplug/chroma.py | 2 +- beetsplug/convert.py | 2 +- beetsplug/discogs.py | 2 +- beetsplug/duplicates.py | 2 +- beetsplug/echonest.py | 2 +- beetsplug/embedart.py | 2 +- beetsplug/fetchart.py | 2 +- beetsplug/freedesktop.py | 2 +- beetsplug/ftintitle.py | 2 +- beetsplug/ihate.py | 2 +- beetsplug/importadded.py | 2 +- beetsplug/importfeeds.py | 2 +- beetsplug/info.py | 2 +- beetsplug/inline.py | 2 +- beetsplug/keyfinder.py | 2 +- beetsplug/lastgenre/__init__.py | 2 +- beetsplug/lastimport.py | 2 +- beetsplug/lyrics.py | 2 +- beetsplug/mbcollection.py | 2 +- beetsplug/mbsync.py | 2 +- beetsplug/missing.py | 2 +- beetsplug/mpdstats.py | 2 +- beetsplug/play.py | 2 +- beetsplug/replaygain.py | 2 +- beetsplug/rewrite.py | 2 +- beetsplug/scrub.py | 2 +- beetsplug/spotify.py | 2 +- beetsplug/the.py | 2 +- beetsplug/zero.py | 2 +- test/_common.py | 2 +- test/helper.py | 2 +- 46 files changed, 46 insertions(+), 46 deletions(-) diff --git a/beets/autotag/__init__.py b/beets/autotag/__init__.py index 5ac2380db..cf7048008 100644 --- a/beets/autotag/__init__.py +++ b/beets/autotag/__init__.py @@ -14,7 +14,7 @@ """Facilities for automatically determining files' correct metadata. """ -import logging +from beets import logging from beets import config diff --git a/beets/autotag/hooks.py b/beets/autotag/hooks.py index beb3bd91b..43433a2cd 100644 --- a/beets/autotag/hooks.py +++ b/beets/autotag/hooks.py @@ -13,7 +13,7 @@ # included in all copies or substantial portions of the Software. """Glue between metadata sources and the matching logic.""" -import logging +from beets import logging from collections import namedtuple import re diff --git a/beets/autotag/match.py b/beets/autotag/match.py index 00556359f..39a788c74 100644 --- a/beets/autotag/match.py +++ b/beets/autotag/match.py @@ -18,7 +18,7 @@ releases and tracks. from __future__ import division import datetime -import logging +from beets import logging import re from munkres import Munkres diff --git a/beets/autotag/mb.py b/beets/autotag/mb.py index 72662bd5c..e0f6088f6 100644 --- a/beets/autotag/mb.py +++ b/beets/autotag/mb.py @@ -14,7 +14,7 @@ """Searches for albums in the MusicBrainz database. """ -import logging +from beets import logging import musicbrainzngs import re import traceback diff --git a/beets/importer.py b/beets/importer.py index 4aa39ff92..f3b8975c5 100644 --- a/beets/importer.py +++ b/beets/importer.py @@ -19,7 +19,7 @@ from __future__ import print_function import os import re -import logging +from beets import logging import pickle import itertools from collections import defaultdict diff --git a/beets/library.py b/beets/library.py index a4213d8b3..d205e009b 100644 --- a/beets/library.py +++ b/beets/library.py @@ -16,7 +16,7 @@ """ import os import sys -import logging +from beets import logging import shlex import unicodedata import time diff --git a/beets/mediafile.py b/beets/mediafile.py index 9106bbd71..1bee05e5e 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -48,7 +48,7 @@ import math import struct import imghdr import os -import logging +from beets import logging import traceback import enum diff --git a/beets/plugins.py b/beets/plugins.py index c3058b617..917baf8a1 100755 --- a/beets/plugins.py +++ b/beets/plugins.py @@ -14,7 +14,7 @@ """Support for beets plugins.""" -import logging +from beets import logging import traceback import inspect import re diff --git a/beets/ui/__init__.py b/beets/ui/__init__.py index 4617e84fc..09dec6a78 100644 --- a/beets/ui/__init__.py +++ b/beets/ui/__init__.py @@ -23,7 +23,7 @@ import optparse import textwrap import sys from difflib import SequenceMatcher -import logging +from beets import logging import sqlite3 import errno import re diff --git a/beets/ui/commands.py b/beets/ui/commands.py index e55d41504..14b0a6afd 100644 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -17,7 +17,7 @@ interface. """ from __future__ import print_function -import logging +from beets import logging import os import time import codecs diff --git a/beets/util/artresizer.py b/beets/util/artresizer.py index 0145124c1..3bac1539f 100644 --- a/beets/util/artresizer.py +++ b/beets/util/artresizer.py @@ -20,7 +20,7 @@ import subprocess import os import re from tempfile import NamedTemporaryFile -import logging +from beets import logging from beets import util # Resizing methods diff --git a/beetsplug/beatport.py b/beetsplug/beatport.py index 8afefbefb..c431841cf 100644 --- a/beetsplug/beatport.py +++ b/beetsplug/beatport.py @@ -14,7 +14,7 @@ """Adds Beatport release and track search support to the autotagger """ -import logging +from beets import logging import re from datetime import datetime, timedelta diff --git a/beetsplug/bpd/__init__.py b/beetsplug/bpd/__init__.py index 7b550487c..e654fa6fd 100644 --- a/beetsplug/bpd/__init__.py +++ b/beetsplug/bpd/__init__.py @@ -21,7 +21,7 @@ from __future__ import print_function import re from string import Template import traceback -import logging +from beets import logging import random import time diff --git a/beetsplug/bpm.py b/beetsplug/bpm.py index 2189e2fae..d5d324bf7 100644 --- a/beetsplug/bpm.py +++ b/beetsplug/bpm.py @@ -15,7 +15,7 @@ """Determine BPM by pressing a key to the rhythm.""" import time -import logging +from beets import logging from beets import ui from beets.plugins import BeetsPlugin diff --git a/beetsplug/bucket.py b/beetsplug/bucket.py index 64dcdf6ee..86ec6be6c 100644 --- a/beetsplug/bucket.py +++ b/beetsplug/bucket.py @@ -16,7 +16,7 @@ """ from datetime import datetime -import logging +from beets import logging import re import string from itertools import tee, izip diff --git a/beetsplug/chroma.py b/beetsplug/chroma.py index 0ff86e220..a339b68a6 100644 --- a/beetsplug/chroma.py +++ b/beetsplug/chroma.py @@ -22,7 +22,7 @@ from beets import config from beets.util import confit from beets.autotag import hooks import acoustid -import logging +from beets import logging from collections import defaultdict API_KEY = '1vOwZtEn' diff --git a/beetsplug/convert.py b/beetsplug/convert.py index 679ebcd72..cd07dfb22 100644 --- a/beetsplug/convert.py +++ b/beetsplug/convert.py @@ -14,7 +14,7 @@ """Converts tracks or albums to external directory """ -import logging +from beets import logging import os import threading import subprocess diff --git a/beetsplug/discogs.py b/beetsplug/discogs.py index 41c088225..17c1b05f9 100644 --- a/beetsplug/discogs.py +++ b/beetsplug/discogs.py @@ -22,7 +22,7 @@ from discogs_client import Release, Client from discogs_client.exceptions import DiscogsAPIError from requests.exceptions import ConnectionError import beets -import logging +from beets import logging import re import time import json diff --git a/beetsplug/duplicates.py b/beetsplug/duplicates.py index 4b15bf939..adbbbcf98 100644 --- a/beetsplug/duplicates.py +++ b/beetsplug/duplicates.py @@ -15,7 +15,7 @@ """List duplicate tracks or albums. """ import shlex -import logging +from beets import logging from beets.plugins import BeetsPlugin from beets.ui import decargs, print_obj, vararg_callback, Subcommand, UserError diff --git a/beetsplug/echonest.py b/beetsplug/echonest.py index 16ba6f3bd..7ebe2c0c3 100644 --- a/beetsplug/echonest.py +++ b/beetsplug/echonest.py @@ -15,7 +15,7 @@ """Fetch a variety of acoustic metrics from The Echo Nest. """ import time -import logging +from beets import logging import socket import os import tempfile diff --git a/beetsplug/embedart.py b/beetsplug/embedart.py index 3fdfd9055..72e8b17fc 100644 --- a/beetsplug/embedart.py +++ b/beetsplug/embedart.py @@ -14,7 +14,7 @@ """Allows beets to embed album art into file metadata.""" import os.path -import logging +from beets import logging import imghdr import subprocess import platform diff --git a/beetsplug/fetchart.py b/beetsplug/fetchart.py index e8c11b2f9..dfd4c9017 100644 --- a/beetsplug/fetchart.py +++ b/beetsplug/fetchart.py @@ -15,7 +15,7 @@ """Fetches album art. """ from contextlib import closing -import logging +from beets import logging import os import re from tempfile import NamedTemporaryFile diff --git a/beetsplug/freedesktop.py b/beetsplug/freedesktop.py index 0aea97c38..303394d34 100644 --- a/beetsplug/freedesktop.py +++ b/beetsplug/freedesktop.py @@ -20,7 +20,7 @@ from beets.ui import Subcommand from beets.ui import decargs import os -import logging +from beets import logging log = logging.getLogger('beets.freedesktop') diff --git a/beetsplug/ftintitle.py b/beetsplug/ftintitle.py index 8bd0974fe..c47ae37c1 100644 --- a/beetsplug/ftintitle.py +++ b/beetsplug/ftintitle.py @@ -18,7 +18,7 @@ from beets import plugins from beets import ui from beets.util import displayable_path from beets import config -import logging +from beets import logging import re log = logging.getLogger('beets') diff --git a/beetsplug/ihate.py b/beetsplug/ihate.py index c8c930833..ed7cbd954 100644 --- a/beetsplug/ihate.py +++ b/beetsplug/ihate.py @@ -14,7 +14,7 @@ """Warns you about things you hate (or even blocks import).""" -import logging +from beets import logging from beets.plugins import BeetsPlugin from beets.importer import action from beets.library import parse_query_string diff --git a/beetsplug/importadded.py b/beetsplug/importadded.py index 728112690..3bc991750 100644 --- a/beetsplug/importadded.py +++ b/beetsplug/importadded.py @@ -6,7 +6,7 @@ Reimported albums and items are skipped. from __future__ import unicode_literals, absolute_import, print_function -import logging +from beets import logging import os from beets import config diff --git a/beetsplug/importfeeds.py b/beetsplug/importfeeds.py index dd1bf87df..2697d9eca 100644 --- a/beetsplug/importfeeds.py +++ b/beetsplug/importfeeds.py @@ -19,7 +19,7 @@ one wants to manually add music to a player by its path. import datetime import os import re -import logging +from beets import logging from beets.plugins import BeetsPlugin from beets.util import normpath, syspath, bytestring_path diff --git a/beetsplug/info.py b/beetsplug/info.py index f593bef12..24930ab52 100644 --- a/beetsplug/info.py +++ b/beetsplug/info.py @@ -16,7 +16,7 @@ """ import os -import logging +from beets import logging from beets.plugins import BeetsPlugin from beets import ui diff --git a/beetsplug/inline.py b/beetsplug/inline.py index 0f2e9f1d4..ab886be20 100644 --- a/beetsplug/inline.py +++ b/beetsplug/inline.py @@ -14,7 +14,7 @@ """Allows inline path template customization code in the config file. """ -import logging +from beets import logging import traceback import itertools diff --git a/beetsplug/keyfinder.py b/beetsplug/keyfinder.py index 499fa5201..3f1398850 100644 --- a/beetsplug/keyfinder.py +++ b/beetsplug/keyfinder.py @@ -15,7 +15,7 @@ """Uses the `KeyFinder` program to add the `initial_key` field. """ -import logging +from beets import logging import subprocess from beets import ui diff --git a/beetsplug/lastgenre/__init__.py b/beetsplug/lastgenre/__init__.py index c1c1c39ab..497b0899b 100644 --- a/beetsplug/lastgenre/__init__.py +++ b/beetsplug/lastgenre/__init__.py @@ -20,7 +20,7 @@ and has been edited to remove some questionable entries. The scraper script used is available here: https://gist.github.com/1241307 """ -import logging +from beets import logging import pylast import os import yaml diff --git a/beetsplug/lastimport.py b/beetsplug/lastimport.py index 7a723a36d..138efbe1f 100644 --- a/beetsplug/lastimport.py +++ b/beetsplug/lastimport.py @@ -12,7 +12,7 @@ # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. -import logging +from beets import logging import requests from beets import ui from beets import dbcore diff --git a/beetsplug/lyrics.py b/beetsplug/lyrics.py index 17bf4c4fc..04e6d38a8 100644 --- a/beetsplug/lyrics.py +++ b/beetsplug/lyrics.py @@ -17,7 +17,7 @@ from __future__ import print_function import re -import logging +from beets import logging import requests import json import unicodedata diff --git a/beetsplug/mbcollection.py b/beetsplug/mbcollection.py index 3683c7584..9dd90f4cd 100644 --- a/beetsplug/mbcollection.py +++ b/beetsplug/mbcollection.py @@ -21,7 +21,7 @@ from beets import config import musicbrainzngs import re -import logging +from beets import logging SUBMISSION_CHUNK_SIZE = 200 UUID_REGEX = r'^[a-f0-9]{8}(-[a-f0-9]{4}){3}-[a-f0-9]{12}$' diff --git a/beetsplug/mbsync.py b/beetsplug/mbsync.py index c96d0cf71..24823a229 100644 --- a/beetsplug/mbsync.py +++ b/beetsplug/mbsync.py @@ -14,7 +14,7 @@ """Update library's tags using MusicBrainz. """ -import logging +from beets import logging from beets.plugins import BeetsPlugin from beets import autotag, library, ui, util diff --git a/beetsplug/missing.py b/beetsplug/missing.py index 439b1d384..78142e167 100644 --- a/beetsplug/missing.py +++ b/beetsplug/missing.py @@ -14,7 +14,7 @@ """List missing tracks. """ -import logging +from beets import logging from beets.autotag import hooks from beets.library import Item diff --git a/beetsplug/mpdstats.py b/beetsplug/mpdstats.py index 2fddb6a8c..d8596c1a3 100644 --- a/beetsplug/mpdstats.py +++ b/beetsplug/mpdstats.py @@ -13,7 +13,7 @@ # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. -import logging +from beets import logging import mpd import socket import select diff --git a/beetsplug/play.py b/beetsplug/play.py index 609627d59..1de61261c 100644 --- a/beetsplug/play.py +++ b/beetsplug/play.py @@ -21,7 +21,7 @@ from beets import ui from beets import util from os.path import relpath import platform -import logging +from beets import logging import shlex from tempfile import NamedTemporaryFile diff --git a/beetsplug/replaygain.py b/beetsplug/replaygain.py index d7f8366f5..7d8cc3520 100644 --- a/beetsplug/replaygain.py +++ b/beetsplug/replaygain.py @@ -12,7 +12,7 @@ # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. -import logging +from beets import logging import subprocess import os import collections diff --git a/beetsplug/rewrite.py b/beetsplug/rewrite.py index cbb9e2a74..6a58ff490 100644 --- a/beetsplug/rewrite.py +++ b/beetsplug/rewrite.py @@ -16,7 +16,7 @@ formats. """ import re -import logging +from beets import logging from collections import defaultdict from beets.plugins import BeetsPlugin diff --git a/beetsplug/scrub.py b/beetsplug/scrub.py index 0b071a162..a6346a2f2 100644 --- a/beetsplug/scrub.py +++ b/beetsplug/scrub.py @@ -15,7 +15,7 @@ """Cleans extraneous metadata from files' tags via a command or automatically whenever tags are written. """ -import logging +from beets import logging from beets.plugins import BeetsPlugin from beets import ui diff --git a/beetsplug/spotify.py b/beetsplug/spotify.py index 33b29fd8d..273dd432b 100644 --- a/beetsplug/spotify.py +++ b/beetsplug/spotify.py @@ -2,7 +2,7 @@ from __future__ import print_function import re import webbrowser import requests -import logging +from beets import logging from beets.plugins import BeetsPlugin from beets.ui import decargs from beets import ui diff --git a/beetsplug/the.py b/beetsplug/the.py index fb441c572..d146b3e69 100644 --- a/beetsplug/the.py +++ b/beetsplug/the.py @@ -15,7 +15,7 @@ """Moves patterns in path formats (suitable for moving articles).""" import re -import logging +from beets import logging from beets.plugins import BeetsPlugin __author__ = 'baobab@heresiarch.info' diff --git a/beetsplug/zero.py b/beetsplug/zero.py index ae164bef0..a8c62d42c 100644 --- a/beetsplug/zero.py +++ b/beetsplug/zero.py @@ -15,7 +15,7 @@ """ Clears tag fields in media files.""" import re -import logging +from beets import logging from beets.plugins import BeetsPlugin from beets.mediafile import MediaFile from beets.importer import action diff --git a/test/_common.py b/test/_common.py index 64f2f7247..7341bc1a1 100644 --- a/test/_common.py +++ b/test/_common.py @@ -16,7 +16,7 @@ import time import sys import os -import logging +from beets import logging import tempfile import shutil from contextlib import contextmanager diff --git a/test/helper.py b/test/helper.py index 459e643a0..fdbe9f9bf 100644 --- a/test/helper.py +++ b/test/helper.py @@ -35,7 +35,7 @@ import os import os.path import shutil import subprocess -import logging +from beets import logging from tempfile import mkdtemp, mkstemp from contextlib import contextmanager from StringIO import StringIO From e2d3ba1c2318ac80675b4bdf489104a975f49902 Mon Sep 17 00:00:00 2001 From: Bruno Cauet Date: Sun, 4 Jan 2015 16:40:41 +0100 Subject: [PATCH 06/16] Fix 4 tests by str()-ing a logged exception --- beets/library.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beets/library.py b/beets/library.py index d205e009b..e97d335de 100644 --- a/beets/library.py +++ b/beets/library.py @@ -509,7 +509,7 @@ class Item(LibModel): self.write(path) return True except FileOperationError as exc: - log.error(exc) + log.error(str(exc)) return False def try_sync(self, write=None): From 408afa1b58dcd3a244534884604029beedfffe2e Mon Sep 17 00:00:00 2001 From: Bruno Cauet Date: Sun, 4 Jan 2015 16:56:25 +0100 Subject: [PATCH 07/16] Add tests for beets.logging --- test/test_logging.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 test/test_logging.py diff --git a/test/test_logging.py b/test/test_logging.py new file mode 100644 index 000000000..61b0591c4 --- /dev/null +++ b/test/test_logging.py @@ -0,0 +1,38 @@ +"""Stupid tests that ensure logging works as expected""" +import logging as log +from StringIO import StringIO + +import beets.logging as blog +from _common import unittest, TestCase + + +class LoggingTest(TestCase): + def test_logging_management(self): + l1 = log.getLogger("foo123") + l2 = blog.getLogger("foo123") + self.assertEqual(l1, l2) + self.assertEqual(type(l1), log.Logger) + + l3 = blog.getLogger("bar123") + l4 = log.getLogger("bar123") + self.assertEqual(l3, l4) + self.assertEqual(type(l3), blog.StrFormatLogger) + + l5 = l3.getChild("shalala") + self.assertEqual(type(l5), blog.StrFormatLogger) + + def test_str_format_logging(self): + l = blog.getLogger("baz123") + stream = StringIO() + handler = log.StreamHandler(stream) + + l.addHandler(handler) + l.propagate = False + + l.warning("foo {} {bar}", "oof", bar="baz") + handler.flush() + self.assertTrue(stream.getvalue(), "foo oof baz") + + +if __name__ == '__main__': + unittest.main() From 52243269fc080af7094debc63121357035af9c82 Mon Sep 17 00:00:00 2001 From: Bruno Cauet Date: Sun, 4 Jan 2015 17:14:34 +0100 Subject: [PATCH 08/16] Make test/test_logging work on python 2.6 --- test/test_logging.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/test_logging.py b/test/test_logging.py index 61b0591c4..f63a63b63 100644 --- a/test/test_logging.py +++ b/test/test_logging.py @@ -34,5 +34,9 @@ class LoggingTest(TestCase): self.assertTrue(stream.getvalue(), "foo oof baz") +def suite(): + return unittest.TestLoader().loadTestsFromName(__name__) + + if __name__ == '__main__': - unittest.main() + unittest.main(defaultTest='suite') From d409da8753aab884aabf8f43314fd3ef61e65efa Mon Sep 17 00:00:00 2001 From: Bruno Cauet Date: Sun, 4 Jan 2015 17:22:45 +0100 Subject: [PATCH 09/16] Fix docstring beets.logging.StrFormatLogger._log --- beets/logging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beets/logging.py b/beets/logging.py index 2783c5ff5..b2e8bb5aa 100644 --- a/beets/logging.py +++ b/beets/logging.py @@ -21,7 +21,7 @@ class StrFormatLogger(Logger): return self.msg.format(*self.args, **self.kwargs) def _log(self, level, msg, args, exc_info=None, extra=None, **kwargs): - """Log 'msg.format(*args, **kwargs)""" + """Log msg.format(*args, **kwargs)""" msg = self._LogMessage(msg, args, kwargs) return super(StrFormatLogger, self)._log(level, msg, (), exc_info, extra) From f5c56667295373eed8f4a7692aada45dcadebfaf Mon Sep 17 00:00:00 2001 From: Bruno Cauet Date: Sun, 4 Jan 2015 17:29:31 +0100 Subject: [PATCH 10/16] Attain pep8-cleanliness No more E12 or E501 --- beets/logging.py | 4 ++-- beets/ui/commands.py | 2 +- beets/util/artresizer.py | 2 +- beetsplug/echonest.py | 2 +- beetsplug/embedart.py | 5 +++-- beetsplug/lastimport.py | 6 ++---- beetsplug/mpdstats.py | 3 +-- beetsplug/play.py | 3 +-- beetsplug/spotify.py | 6 ++++-- 9 files changed, 16 insertions(+), 17 deletions(-) diff --git a/beets/logging.py b/beets/logging.py index b2e8bb5aa..2168c6a95 100644 --- a/beets/logging.py +++ b/beets/logging.py @@ -22,8 +22,8 @@ class StrFormatLogger(Logger): def _log(self, level, msg, args, exc_info=None, extra=None, **kwargs): """Log msg.format(*args, **kwargs)""" - msg = self._LogMessage(msg, args, kwargs) - return super(StrFormatLogger, self)._log(level, msg, (), exc_info, extra) + m = self._LogMessage(msg, args, kwargs) + return super(StrFormatLogger, self)._log(level, m, (), exc_info, extra) my_manager = copy(Logger.manager) diff --git a/beets/ui/commands.py b/beets/ui/commands.py index 14b0a6afd..5883f37a3 100644 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -1023,7 +1023,7 @@ def update_items(lib, query, album, move, pretend): item.read() except library.ReadError as exc: log.error(u'error reading {0}: {1}', - displayable_path(item.path), exc) + displayable_path(item.path), exc) continue # Special-case album artist when it matches track artist. (Hacky diff --git a/beets/util/artresizer.py b/beets/util/artresizer.py index 3bac1539f..101f5711e 100644 --- a/beets/util/artresizer.py +++ b/beets/util/artresizer.py @@ -69,7 +69,7 @@ def pil_resize(maxwidth, path_in, path_out=None): return path_out except IOError: log.error(u"PIL cannot create thumbnail for '{0}'", - util.displayable_path(path_in)) + util.displayable_path(path_in)) return path_in diff --git a/beetsplug/echonest.py b/beetsplug/echonest.py index 7ebe2c0c3..809a3fae2 100644 --- a/beetsplug/echonest.py +++ b/beetsplug/echonest.py @@ -412,7 +412,7 @@ class EchonestMetadataPlugin(plugins.BeetsPlugin): item.artist, item.title, song.get('duration'), - ) + ) return song def apply_metadata(self, item, values, write=False): diff --git a/beetsplug/embedart.py b/beetsplug/embedart.py index 72e8b17fc..a7df5a2a0 100644 --- a/beetsplug/embedart.py +++ b/beetsplug/embedart.py @@ -192,8 +192,9 @@ def check_art_similarity(item, imagepath, compare_threshold): stdout, stderr = proc.communicate() if proc.returncode: if proc.returncode != 1: - log.warn(u'embedart: IM phashes compare failed for {0}, {1}', - displayable_path(imagepath), displayable_path(art)) + log.warn(u'embedart: IM hashes compare failed for ' + u'{0}, {1}', displayable_path(imagepath), + displayable_path(art)) return phashDiff = float(stderr) else: diff --git a/beetsplug/lastimport.py b/beetsplug/lastimport.py index 138efbe1f..9f9011dc3 100644 --- a/beetsplug/lastimport.py +++ b/beetsplug/lastimport.py @@ -67,8 +67,7 @@ def import_lastfm(lib): while page_current < page_total: log.info('lastimport: Querying page #{0}{1}...', page_current + 1, - '/{}'.format(page_total) if page_total > 1 else '' - ) + '/{}'.format(page_total) if page_total > 1 else '') for retry in range(0, retry_limit): page = fetch_tracks(user, page_current + 1, per_page) @@ -172,8 +171,7 @@ def process_tracks(lib, tracks): new_count = int(tracks[num]['playcount']) log.debug(u'lastimport: match: {0} - {1} ({2}) ' u'updating: play_count {3} => {4}', - song.artist, song.title, song.album, count, new_count - ) + song.artist, song.title, song.album, count, new_count) song['play_count'] = new_count song.store() total_found += 1 diff --git a/beetsplug/mpdstats.py b/beetsplug/mpdstats.py index d8596c1a3..6c0be72c2 100644 --- a/beetsplug/mpdstats.py +++ b/beetsplug/mpdstats.py @@ -193,8 +193,7 @@ class MPDStats(object): log.debug(u'mpdstats: updated: {0} = {1} [{2}]', attribute, item[attribute], - displayable_path(item.path), - ) + displayable_path(item.path)) def update_rating(self, item, skipped): """Update the rating for a beets item. diff --git a/beetsplug/play.py b/beetsplug/play.py index 1de61261c..687760ff4 100644 --- a/beetsplug/play.py +++ b/beetsplug/play.py @@ -103,8 +103,7 @@ def play_music(lib, opts, args): if output: log.debug(u'Output of {0}: {1}', util.displayable_path(command[0]), - output.decode('utf8', 'ignore'), - ) + output.decode('utf8', 'ignore')) else: log.debug(u'play: no output') diff --git a/beetsplug/spotify.py b/beetsplug/spotify.py index 273dd432b..89b4a2d62 100644 --- a/beetsplug/spotify.py +++ b/beetsplug/spotify.py @@ -132,7 +132,8 @@ class SpotifyPlugin(BeetsPlugin): chosen_result = r_data[0] elif len(r_data) > 1: # Use the popularity filter - log.debug(u'Most popular track chosen, count: {0}', len(r_data)) + log.debug(u'Most popular track chosen, count: {0}', + len(r_data)) chosen_result = max(r_data, key=lambda x: x['popularity']) if chosen_result: @@ -144,7 +145,8 @@ class SpotifyPlugin(BeetsPlugin): failure_count = len(failures) if failure_count > 0: if self.config['show_failures'].get(): - log.info(u'{0} track(s) did not match a Spotify ID:', failure_count) + log.info(u'{0} track(s) did not match a Spotify ID:', + failure_count) for track in failures: log.info(u'track: {0}', track) log.info(u'') From 4ba4f53053e121208401e2c8bf8704577f604a11 Mon Sep 17 00:00:00 2001 From: Bruno Cauet Date: Sun, 4 Jan 2015 17:50:05 +0100 Subject: [PATCH 11/16] Silence flake8 on logging.* import --- beets/logging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beets/logging.py b/beets/logging.py index 2168c6a95..9d9afdab3 100644 --- a/beets/logging.py +++ b/beets/logging.py @@ -6,7 +6,7 @@ getLogger(name) instantiates a logger that logger uses {}-style formatting. from __future__ import absolute_import from copy import copy -from logging import * +from logging import * # noqa # create a str.format-based logger From 45db9304577063b336e11904be9c16d916249343 Mon Sep 17 00:00:00 2001 From: Bruno Cauet Date: Mon, 5 Jan 2015 07:59:53 +0100 Subject: [PATCH 12/16] embedart: restore an apparent typo (which wasn't) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit hashes → phashes --- beetsplug/embedart.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beetsplug/embedart.py b/beetsplug/embedart.py index a7df5a2a0..b88fcf366 100644 --- a/beetsplug/embedart.py +++ b/beetsplug/embedart.py @@ -192,7 +192,7 @@ def check_art_similarity(item, imagepath, compare_threshold): stdout, stderr = proc.communicate() if proc.returncode: if proc.returncode != 1: - log.warn(u'embedart: IM hashes compare failed for ' + log.warn(u'embedart: IM phashes compare failed for ' u'{0}, {1}', displayable_path(imagepath), displayable_path(art)) return From 06f0e1dee1d7d1076dd37e2e56d70c2e322eaf25 Mon Sep 17 00:00:00 2001 From: Bruno Cauet Date: Mon, 5 Jan 2015 09:15:18 +0100 Subject: [PATCH 13/16] Port beets.logging to python 2.6 Multiple hacks :-) --- beets/logging.py | 37 ++++++++++++++++++++++++++++++++++++- test/test_logging.py | 8 ++++---- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/beets/logging.py b/beets/logging.py index 9d9afdab3..a213f1e20 100644 --- a/beets/logging.py +++ b/beets/logging.py @@ -2,11 +2,15 @@ Provide everything the "logging" module does, the only difference is that when getLogger(name) instantiates a logger that logger uses {}-style formatting. + +It requires special hacks for python 2.6 due to logging.Logger being an old- +style class and having no loggerClass attribute. """ from __future__ import absolute_import from copy import copy from logging import * # noqa +import sys # create a str.format-based logger @@ -23,8 +27,21 @@ class StrFormatLogger(Logger): def _log(self, level, msg, args, exc_info=None, extra=None, **kwargs): """Log msg.format(*args, **kwargs)""" m = self._LogMessage(msg, args, kwargs) - return super(StrFormatLogger, self)._log(level, m, (), exc_info, extra) + return Logger._log(self, level, m, (), exc_info, extra) + # we cannot call super(StrFormatLogger, self) because it is not + # allowed on old-style classes (py2) which Logger is in python 2.6 + # moreover we cannot make StrFormatLogger a new-style class (by + # declaring 'class StrFormatLogger(Logger, object)' because the class- + # patching stmt 'logger.__class__ = StrFormatLogger' would not work: + # both prev & new __class__ values must be either old- or new- style, + # no mixing allowed. + if sys.version_info[:2] == (2, 6): + def getChild(self, suffix): + """Shameless copy from cpython's Lib/logging/__init__.py""" + if self.root is not self: + suffix = '.'.join((self.name, suffix)) + return self.manager.getLogger(suffix) my_manager = copy(Logger.manager) my_manager.loggerClass = StrFormatLogger @@ -35,3 +52,21 @@ def getLogger(name=None): return my_manager.getLogger(name) else: return root + + +if sys.version_info[:2] == (2, 6): + # no Manager.loggerClass so we dynamically change the logger class + # we must be careful to do that on new loggers only to avoid side-effects. + # Wrap Manager.getLogger + old_getLogger = my_manager.getLogger + + def new_getLogger(name): + change_its_type = not isinstance(my_manager.loggerDict.get(name), + Logger) + # it either does not exist or is a placeholder + logger = old_getLogger(name) + if change_its_type: + logger.__class__ = StrFormatLogger + return logger + + my_manager.getLogger = new_getLogger diff --git a/test/test_logging.py b/test/test_logging.py index f63a63b63..0d2eb7291 100644 --- a/test/test_logging.py +++ b/test/test_logging.py @@ -11,15 +11,15 @@ class LoggingTest(TestCase): l1 = log.getLogger("foo123") l2 = blog.getLogger("foo123") self.assertEqual(l1, l2) - self.assertEqual(type(l1), log.Logger) + self.assertEqual(l1.__class__, log.Logger) l3 = blog.getLogger("bar123") l4 = log.getLogger("bar123") self.assertEqual(l3, l4) - self.assertEqual(type(l3), blog.StrFormatLogger) + self.assertEqual(l3.__class__, blog.StrFormatLogger) l5 = l3.getChild("shalala") - self.assertEqual(type(l5), blog.StrFormatLogger) + self.assertEqual(l5.__class__, blog.StrFormatLogger) def test_str_format_logging(self): l = blog.getLogger("baz123") @@ -29,7 +29,7 @@ class LoggingTest(TestCase): l.addHandler(handler) l.propagate = False - l.warning("foo {} {bar}", "oof", bar="baz") + l.warning("foo {0} {bar}", "oof", bar="baz") handler.flush() self.assertTrue(stream.getvalue(), "foo oof baz") From fa696beef2145031e0fa83519e315259a1fbc1eb Mon Sep 17 00:00:00 2001 From: Bruno Cauet Date: Mon, 5 Jan 2015 09:53:56 +0100 Subject: [PATCH 14/16] beets.logging: fix root logger access logging does not export 'root', so we must use Logger.root --- beets/logging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beets/logging.py b/beets/logging.py index a213f1e20..ec594698e 100644 --- a/beets/logging.py +++ b/beets/logging.py @@ -51,7 +51,7 @@ def getLogger(name=None): if name: return my_manager.getLogger(name) else: - return root + return Logger.root if sys.version_info[:2] == (2, 6): From a8b0454bfb79721d00cd83bda00fa5e7e83a5fe5 Mon Sep 17 00:00:00 2001 From: Bruno Cauet Date: Mon, 5 Jan 2015 09:55:05 +0100 Subject: [PATCH 15/16] Minor fix in beets.logging docstring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit formatting → logging --- beets/logging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beets/logging.py b/beets/logging.py index ec594698e..48c9d4625 100644 --- a/beets/logging.py +++ b/beets/logging.py @@ -1,4 +1,4 @@ -"""Allow {}-style formatting on python 2 and 3 +"""Allow {}-style logging on python 2 and 3 Provide everything the "logging" module does, the only difference is that when getLogger(name) instantiates a logger that logger uses {}-style formatting. From 30f158a95e1bd264592c786e8a6d5083e929061d Mon Sep 17 00:00:00 2001 From: Bruno Cauet Date: Mon, 5 Jan 2015 10:05:21 +0100 Subject: [PATCH 16/16] Move "from beets import logging" statements Move the import next to other beets-related imports --- beets/autotag/__init__.py | 2 +- beets/autotag/hooks.py | 2 +- beets/autotag/match.py | 2 +- beets/autotag/mb.py | 2 +- beets/importer.py | 2 +- beets/library.py | 3 ++- beets/mediafile.py | 2 +- beets/plugins.py | 2 +- beets/ui/__init__.py | 2 +- beets/ui/commands.py | 2 +- beets/util/artresizer.py | 1 + beetsplug/beatport.py | 2 +- beetsplug/bpd/__init__.py | 2 +- beetsplug/bpm.py | 3 +-- beetsplug/bucket.py | 3 ++- beetsplug/chroma.py | 2 +- beetsplug/convert.py | 3 +-- beetsplug/discogs.py | 2 +- beetsplug/duplicates.py | 2 +- beetsplug/echonest.py | 3 +-- beetsplug/embedart.py | 2 +- beetsplug/fetchart.py | 2 +- beetsplug/freedesktop.py | 2 +- beetsplug/ftintitle.py | 3 ++- beetsplug/importadded.py | 2 +- beetsplug/importfeeds.py | 3 +-- beetsplug/info.py | 2 +- beetsplug/inline.py | 3 +-- beetsplug/keyfinder.py | 2 +- beetsplug/lastgenre/__init__.py | 2 +- beetsplug/lastimport.py | 2 +- beetsplug/lyrics.py | 2 +- beetsplug/mbcollection.py | 2 +- beetsplug/mbsync.py | 4 +--- beetsplug/missing.py | 1 - beetsplug/mpdstats.py | 2 +- beetsplug/play.py | 2 +- beetsplug/replaygain.py | 2 +- beetsplug/rewrite.py | 2 +- beetsplug/scrub.py | 2 +- beetsplug/spotify.py | 3 +-- test/_common.py | 3 +-- test/helper.py | 2 +- 43 files changed, 45 insertions(+), 51 deletions(-) diff --git a/beets/autotag/__init__.py b/beets/autotag/__init__.py index cf7048008..3fa98758c 100644 --- a/beets/autotag/__init__.py +++ b/beets/autotag/__init__.py @@ -14,8 +14,8 @@ """Facilities for automatically determining files' correct metadata. """ -from beets import logging +from beets import logging from beets import config # Parts of external interface. diff --git a/beets/autotag/hooks.py b/beets/autotag/hooks.py index 43433a2cd..5118212b4 100644 --- a/beets/autotag/hooks.py +++ b/beets/autotag/hooks.py @@ -13,10 +13,10 @@ # included in all copies or substantial portions of the Software. """Glue between metadata sources and the matching logic.""" -from beets import logging from collections import namedtuple import re +from beets import logging from beets import plugins from beets import config from beets.autotag import mb diff --git a/beets/autotag/match.py b/beets/autotag/match.py index 39a788c74..d51cd4fb1 100644 --- a/beets/autotag/match.py +++ b/beets/autotag/match.py @@ -18,10 +18,10 @@ releases and tracks. from __future__ import division import datetime -from beets import logging import re from munkres import Munkres +from beets import logging from beets import plugins from beets import config from beets.util import plurality diff --git a/beets/autotag/mb.py b/beets/autotag/mb.py index e0f6088f6..7c598a17f 100644 --- a/beets/autotag/mb.py +++ b/beets/autotag/mb.py @@ -14,12 +14,12 @@ """Searches for albums in the MusicBrainz database. """ -from beets import logging import musicbrainzngs import re import traceback from urlparse import urljoin +from beets import logging import beets.autotag.hooks import beets from beets import util diff --git a/beets/importer.py b/beets/importer.py index f3b8975c5..a0f100749 100644 --- a/beets/importer.py +++ b/beets/importer.py @@ -19,7 +19,6 @@ from __future__ import print_function import os import re -from beets import logging import pickle import itertools from collections import defaultdict @@ -28,6 +27,7 @@ from bisect import insort, bisect_left from contextlib import contextmanager import shutil +from beets import logging from beets import autotag from beets import library from beets import dbcore diff --git a/beets/library.py b/beets/library.py index e97d335de..180f029cb 100644 --- a/beets/library.py +++ b/beets/library.py @@ -16,12 +16,13 @@ """ import os import sys -from beets import logging import shlex import unicodedata import time import re from unidecode import unidecode + +from beets import logging from beets.mediafile import MediaFile, MutagenError, UnreadableFileError from beets import plugins from beets import util diff --git a/beets/mediafile.py b/beets/mediafile.py index 1bee05e5e..3e3d2aa23 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -48,10 +48,10 @@ import math import struct import imghdr import os -from beets import logging import traceback import enum +from beets import logging from beets.util import displayable_path diff --git a/beets/plugins.py b/beets/plugins.py index 917baf8a1..a975145db 100755 --- a/beets/plugins.py +++ b/beets/plugins.py @@ -14,7 +14,6 @@ """Support for beets plugins.""" -from beets import logging import traceback import inspect import re @@ -22,6 +21,7 @@ from collections import defaultdict import beets +from beets import logging from beets import mediafile PLUGIN_NAMESPACE = 'beetsplug' diff --git a/beets/ui/__init__.py b/beets/ui/__init__.py index 09dec6a78..a69b98ac2 100644 --- a/beets/ui/__init__.py +++ b/beets/ui/__init__.py @@ -23,7 +23,6 @@ import optparse import textwrap import sys from difflib import SequenceMatcher -from beets import logging import sqlite3 import errno import re @@ -31,6 +30,7 @@ import struct import traceback import os.path +from beets import logging from beets import library from beets import plugins from beets import util diff --git a/beets/ui/commands.py b/beets/ui/commands.py index 5883f37a3..8de9ab1bc 100644 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -17,7 +17,6 @@ interface. """ from __future__ import print_function -from beets import logging import os import time import codecs @@ -37,6 +36,7 @@ from beets.util import syspath, normpath, ancestry, displayable_path from beets.util.functemplate import Template from beets import library from beets import config +from beets import logging from beets.util.confit import _package_path VARIOUS_ARTISTS = u'Various Artists' diff --git a/beets/util/artresizer.py b/beets/util/artresizer.py index 101f5711e..5b51392bd 100644 --- a/beets/util/artresizer.py +++ b/beets/util/artresizer.py @@ -20,6 +20,7 @@ import subprocess import os import re from tempfile import NamedTemporaryFile + from beets import logging from beets import util diff --git a/beetsplug/beatport.py b/beetsplug/beatport.py index c431841cf..39054aab1 100644 --- a/beetsplug/beatport.py +++ b/beetsplug/beatport.py @@ -14,12 +14,12 @@ """Adds Beatport release and track search support to the autotagger """ -from beets import logging import re from datetime import datetime, timedelta import requests +from beets import logging from beets.autotag.hooks import AlbumInfo, TrackInfo, Distance from beets.plugins import BeetsPlugin diff --git a/beetsplug/bpd/__init__.py b/beetsplug/bpd/__init__.py index e654fa6fd..b0b8ce6c2 100644 --- a/beetsplug/bpd/__init__.py +++ b/beetsplug/bpd/__init__.py @@ -21,13 +21,13 @@ from __future__ import print_function import re from string import Template import traceback -from beets import logging import random import time import beets from beets.plugins import BeetsPlugin import beets.ui +from beets import logging from beets import vfs from beets.util import bluelet from beets.library import Item diff --git a/beetsplug/bpm.py b/beetsplug/bpm.py index d5d324bf7..028af7eae 100644 --- a/beetsplug/bpm.py +++ b/beetsplug/bpm.py @@ -15,9 +15,8 @@ """Determine BPM by pressing a key to the rhythm.""" import time -from beets import logging -from beets import ui +from beets import ui, logging from beets.plugins import BeetsPlugin log = logging.getLogger('beets') diff --git a/beetsplug/bucket.py b/beetsplug/bucket.py index 86ec6be6c..68d520395 100644 --- a/beetsplug/bucket.py +++ b/beetsplug/bucket.py @@ -16,10 +16,11 @@ """ from datetime import datetime -from beets import logging import re import string from itertools import tee, izip + +from beets import logging from beets import plugins, ui log = logging.getLogger('beets') diff --git a/beetsplug/chroma.py b/beetsplug/chroma.py index a339b68a6..485bfba61 100644 --- a/beetsplug/chroma.py +++ b/beetsplug/chroma.py @@ -19,10 +19,10 @@ from beets import plugins from beets import ui from beets import util from beets import config +from beets import logging from beets.util import confit from beets.autotag import hooks import acoustid -from beets import logging from collections import defaultdict API_KEY = '1vOwZtEn' diff --git a/beetsplug/convert.py b/beetsplug/convert.py index cd07dfb22..c9b83c03f 100644 --- a/beetsplug/convert.py +++ b/beetsplug/convert.py @@ -14,7 +14,6 @@ """Converts tracks or albums to external directory """ -from beets import logging import os import threading import subprocess @@ -22,7 +21,7 @@ import tempfile import shlex from string import Template -from beets import ui, util, plugins, config +from beets import logging, ui, util, plugins, config from beets.plugins import BeetsPlugin from beetsplug.embedart import embed_item from beets.util.confit import ConfigTypeError diff --git a/beetsplug/discogs.py b/beetsplug/discogs.py index 17c1b05f9..e3a55fbdd 100644 --- a/beetsplug/discogs.py +++ b/beetsplug/discogs.py @@ -15,6 +15,7 @@ """Adds Discogs album search support to the autotagger. Requires the discogs-client library. """ +from beets import logging from beets.autotag.hooks import AlbumInfo, TrackInfo, Distance from beets.plugins import BeetsPlugin from beets.util import confit @@ -22,7 +23,6 @@ from discogs_client import Release, Client from discogs_client.exceptions import DiscogsAPIError from requests.exceptions import ConnectionError import beets -from beets import logging import re import time import json diff --git a/beetsplug/duplicates.py b/beetsplug/duplicates.py index adbbbcf98..1d7b6f9f1 100644 --- a/beetsplug/duplicates.py +++ b/beetsplug/duplicates.py @@ -15,8 +15,8 @@ """List duplicate tracks or albums. """ import shlex -from beets import logging +from beets import logging from beets.plugins import BeetsPlugin from beets.ui import decargs, print_obj, vararg_callback, Subcommand, UserError from beets.util import command_output, displayable_path, subprocess diff --git a/beetsplug/echonest.py b/beetsplug/echonest.py index 809a3fae2..e38814437 100644 --- a/beetsplug/echonest.py +++ b/beetsplug/echonest.py @@ -15,14 +15,13 @@ """Fetch a variety of acoustic metrics from The Echo Nest. """ import time -from beets import logging import socket import os import tempfile from string import Template import subprocess -from beets import util, config, plugins, ui +from beets import util, config, plugins, ui, logging from beets.dbcore import types import pyechonest import pyechonest.song diff --git a/beetsplug/embedart.py b/beetsplug/embedart.py index b88fcf366..7f04cd1fb 100644 --- a/beetsplug/embedart.py +++ b/beetsplug/embedart.py @@ -14,12 +14,12 @@ """Allows beets to embed album art into file metadata.""" import os.path -from beets import logging import imghdr import subprocess import platform from tempfile import NamedTemporaryFile +from beets import logging from beets.plugins import BeetsPlugin from beets import mediafile from beets import ui diff --git a/beetsplug/fetchart.py b/beetsplug/fetchart.py index dfd4c9017..3b0059817 100644 --- a/beetsplug/fetchart.py +++ b/beetsplug/fetchart.py @@ -15,13 +15,13 @@ """Fetches album art. """ from contextlib import closing -from beets import logging import os import re from tempfile import NamedTemporaryFile import requests +from beets import logging from beets import plugins from beets import importer from beets import ui diff --git a/beetsplug/freedesktop.py b/beetsplug/freedesktop.py index 303394d34..3f3307c82 100644 --- a/beetsplug/freedesktop.py +++ b/beetsplug/freedesktop.py @@ -15,12 +15,12 @@ """Creates freedesktop.org-compliant .directory files on an album level. """ +from beets import logging from beets.plugins import BeetsPlugin from beets.ui import Subcommand from beets.ui import decargs import os -from beets import logging log = logging.getLogger('beets.freedesktop') diff --git a/beetsplug/ftintitle.py b/beetsplug/ftintitle.py index c47ae37c1..f36cfb348 100644 --- a/beetsplug/ftintitle.py +++ b/beetsplug/ftintitle.py @@ -14,12 +14,13 @@ """Moves "featured" artists to the title from the artist field. """ +import re + from beets import plugins from beets import ui from beets.util import displayable_path from beets import config from beets import logging -import re log = logging.getLogger('beets') diff --git a/beetsplug/importadded.py b/beetsplug/importadded.py index 3bc991750..8cb590111 100644 --- a/beetsplug/importadded.py +++ b/beetsplug/importadded.py @@ -6,9 +6,9 @@ Reimported albums and items are skipped. from __future__ import unicode_literals, absolute_import, print_function -from beets import logging import os +from beets import logging from beets import config from beets import util from beets.plugins import BeetsPlugin diff --git a/beetsplug/importfeeds.py b/beetsplug/importfeeds.py index 2697d9eca..4ac1dda2b 100644 --- a/beetsplug/importfeeds.py +++ b/beetsplug/importfeeds.py @@ -19,11 +19,10 @@ one wants to manually add music to a player by its path. import datetime import os import re -from beets import logging from beets.plugins import BeetsPlugin from beets.util import normpath, syspath, bytestring_path -from beets import config +from beets import config, logging M3U_DEFAULT_NAME = 'imported.m3u' log = logging.getLogger('beets') diff --git a/beetsplug/info.py b/beetsplug/info.py index 24930ab52..30cccb1b2 100644 --- a/beetsplug/info.py +++ b/beetsplug/info.py @@ -16,8 +16,8 @@ """ import os -from beets import logging +from beets import logging from beets.plugins import BeetsPlugin from beets import ui from beets import mediafile diff --git a/beetsplug/inline.py b/beetsplug/inline.py index ab886be20..e7e7e0f41 100644 --- a/beetsplug/inline.py +++ b/beetsplug/inline.py @@ -14,12 +14,11 @@ """Allows inline path template customization code in the config file. """ -from beets import logging import traceback import itertools from beets.plugins import BeetsPlugin -from beets import config +from beets import config, logging log = logging.getLogger('beets') diff --git a/beetsplug/keyfinder.py b/beetsplug/keyfinder.py index 3f1398850..49830edef 100644 --- a/beetsplug/keyfinder.py +++ b/beetsplug/keyfinder.py @@ -15,9 +15,9 @@ """Uses the `KeyFinder` program to add the `initial_key` field. """ -from beets import logging import subprocess +from beets import logging from beets import ui from beets import util from beets.plugins import BeetsPlugin diff --git a/beetsplug/lastgenre/__init__.py b/beetsplug/lastgenre/__init__.py index 497b0899b..2b4acb590 100644 --- a/beetsplug/lastgenre/__init__.py +++ b/beetsplug/lastgenre/__init__.py @@ -20,11 +20,11 @@ and has been edited to remove some questionable entries. The scraper script used is available here: https://gist.github.com/1241307 """ -from beets import logging import pylast import os import yaml +from beets import logging from beets import plugins from beets import ui from beets.util import normpath, plurality diff --git a/beetsplug/lastimport.py b/beetsplug/lastimport.py index 9f9011dc3..087213031 100644 --- a/beetsplug/lastimport.py +++ b/beetsplug/lastimport.py @@ -12,12 +12,12 @@ # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. -from beets import logging import requests from beets import ui from beets import dbcore from beets import config from beets import plugins +from beets import logging from beets.dbcore import types log = logging.getLogger('beets') diff --git a/beetsplug/lyrics.py b/beetsplug/lyrics.py index 04e6d38a8..a87715fe3 100644 --- a/beetsplug/lyrics.py +++ b/beetsplug/lyrics.py @@ -17,7 +17,6 @@ from __future__ import print_function import re -from beets import logging import requests import json import unicodedata @@ -26,6 +25,7 @@ import difflib import itertools from HTMLParser import HTMLParseError +from beets import logging from beets import plugins from beets import config, ui diff --git a/beetsplug/mbcollection.py b/beetsplug/mbcollection.py index 9dd90f4cd..764c4529f 100644 --- a/beetsplug/mbcollection.py +++ b/beetsplug/mbcollection.py @@ -16,12 +16,12 @@ from __future__ import print_function from beets.plugins import BeetsPlugin from beets.ui import Subcommand +from beets import logging from beets import ui from beets import config import musicbrainzngs import re -from beets import logging SUBMISSION_CHUNK_SIZE = 200 UUID_REGEX = r'^[a-f0-9]{8}(-[a-f0-9]{4}){3}-[a-f0-9]{12}$' diff --git a/beetsplug/mbsync.py b/beetsplug/mbsync.py index 24823a229..105122639 100644 --- a/beetsplug/mbsync.py +++ b/beetsplug/mbsync.py @@ -14,10 +14,8 @@ """Update library's tags using MusicBrainz. """ -from beets import logging - from beets.plugins import BeetsPlugin -from beets import autotag, library, ui, util +from beets import autotag, library, ui, util, logging from beets.autotag import hooks from beets import config from collections import defaultdict diff --git a/beetsplug/missing.py b/beetsplug/missing.py index 78142e167..2ebe3edf8 100644 --- a/beetsplug/missing.py +++ b/beetsplug/missing.py @@ -15,7 +15,6 @@ """List missing tracks. """ from beets import logging - from beets.autotag import hooks from beets.library import Item from beets.plugins import BeetsPlugin diff --git a/beetsplug/mpdstats.py b/beetsplug/mpdstats.py index 6c0be72c2..5a5d27b4e 100644 --- a/beetsplug/mpdstats.py +++ b/beetsplug/mpdstats.py @@ -13,13 +13,13 @@ # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. -from beets import logging import mpd import socket import select import time import os +from beets import logging from beets import ui from beets import config from beets import plugins diff --git a/beetsplug/play.py b/beetsplug/play.py index 687760ff4..7f9ff3ce9 100644 --- a/beetsplug/play.py +++ b/beetsplug/play.py @@ -16,12 +16,12 @@ """ from beets.plugins import BeetsPlugin from beets.ui import Subcommand +from beets import logging from beets import config from beets import ui from beets import util from os.path import relpath import platform -from beets import logging import shlex from tempfile import NamedTemporaryFile diff --git a/beetsplug/replaygain.py b/beetsplug/replaygain.py index 7d8cc3520..5d50f61c5 100644 --- a/beetsplug/replaygain.py +++ b/beetsplug/replaygain.py @@ -12,7 +12,6 @@ # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. -from beets import logging import subprocess import os import collections @@ -20,6 +19,7 @@ import itertools import sys import warnings +from beets import logging from beets import ui from beets.plugins import BeetsPlugin from beets.util import syspath, command_output, displayable_path diff --git a/beetsplug/rewrite.py b/beetsplug/rewrite.py index 6a58ff490..8a59bdbfd 100644 --- a/beetsplug/rewrite.py +++ b/beetsplug/rewrite.py @@ -16,10 +16,10 @@ formats. """ import re -from beets import logging from collections import defaultdict from beets.plugins import BeetsPlugin +from beets import logging from beets import ui from beets import library diff --git a/beetsplug/scrub.py b/beetsplug/scrub.py index a6346a2f2..7c5b097cb 100644 --- a/beetsplug/scrub.py +++ b/beetsplug/scrub.py @@ -15,8 +15,8 @@ """Cleans extraneous metadata from files' tags via a command or automatically whenever tags are written. """ -from beets import logging +from beets import logging from beets.plugins import BeetsPlugin from beets import ui from beets import util diff --git a/beetsplug/spotify.py b/beetsplug/spotify.py index 89b4a2d62..704660894 100644 --- a/beetsplug/spotify.py +++ b/beetsplug/spotify.py @@ -2,10 +2,9 @@ from __future__ import print_function import re import webbrowser import requests -from beets import logging from beets.plugins import BeetsPlugin from beets.ui import decargs -from beets import ui +from beets import ui, logging from requests.exceptions import HTTPError log = logging.getLogger('beets') diff --git a/test/_common.py b/test/_common.py index 7341bc1a1..b222566b7 100644 --- a/test/_common.py +++ b/test/_common.py @@ -16,7 +16,6 @@ import time import sys import os -from beets import logging import tempfile import shutil from contextlib import contextmanager @@ -30,7 +29,7 @@ except ImportError: # Mangle the search path to include the beets sources. sys.path.insert(0, '..') import beets.library -from beets import importer +from beets import importer, logging from beets.ui import commands import beets diff --git a/test/helper.py b/test/helper.py index fdbe9f9bf..4dafb4c39 100644 --- a/test/helper.py +++ b/test/helper.py @@ -35,13 +35,13 @@ import os import os.path import shutil import subprocess -from beets import logging from tempfile import mkdtemp, mkstemp from contextlib import contextmanager from StringIO import StringIO from enum import Enum import beets +from beets import logging from beets import config import beets.plugins from beets.library import Library, Item, Album