Add item.try_write() to log errors

Many commands and plugins use `item.write()` to update tags. Since the success
of the call is not critical to the functionality of most consumers we want to
catch any exceptions, log an error and continue with our task. The new method
encapsulates this logic.

This fixes #675.
This commit is contained in:
Thomas Scholtes 2014-04-10 15:26:05 +02:00
parent 9d9f1b539f
commit c3ea1ded30
12 changed files with 26 additions and 28 deletions

View file

@ -895,10 +895,7 @@ def manipulate_files(session):
item.move(True)
if config['import']['write'] and task.should_write_tags():
try:
item.write()
except library.FileOperationError as exc:
log.error(exc)
item.try_write()
# Save new paths.
with session.lib.transaction():

View file

@ -454,6 +454,18 @@ class Item(LibModel):
self.mtime = self.current_mtime()
plugins.send('after_write', item=self, path=path)
def try_write(self, path=None):
"""Calls `write()` but catches and logs `FileOperationError`s.
Returns `False` an exception was caught and `True` otherwise.
"""
try:
self.write(path)
return True
except FileOperationError as exc:
log.error(exc)
return False
# Files themselves.

View file

@ -1135,10 +1135,7 @@ def modify_items(lib, mods, dels, query, write, move, album, confirm):
else:
changed_items = changed
for item in changed_items:
try:
item.write()
except library.FileOperationError as exc:
log.error(exc)
item.try_write()
modify_cmd = ui.Subcommand('modify',
help='change metadata fields', aliases=('mod',))
@ -1249,10 +1246,7 @@ def write_items(lib, query, pretend):
library.Item._media_fields,
always=True)
if changed and not pretend:
try:
item.write()
except library.FileOperationError as exc:
log.error(exc)
item.try_write()
write_cmd = ui.Subcommand('write', help='write tag information to files')
write_cmd.parser.add_option('-p', '--pretend', action='store_true',

View file

@ -270,7 +270,7 @@ def fingerprint_item(item, write=False):
log.info(u'{0}: writing fingerprint'.format(
util.displayable_path(item.path)
))
item.write()
item.try_write()
if item._db:
item.store()
return item.acoustid_fingerprint

View file

@ -414,7 +414,7 @@ class EchonestMetadataPlugin(plugins.BeetsPlugin):
# Write and save.
if write:
item.write()
item.try_write()
item.store()

View file

@ -55,7 +55,7 @@ def fetch_item_tempo(lib, loglevel, item, write):
(item.artist, item.title))
item.bpm = int(tempo)
if write:
item.write()
item.try_write()
item.store()

View file

@ -121,6 +121,6 @@ class FtInTitlePlugin(BeetsPlugin):
ft_in_title(item)
item.store()
if write:
item.write()
item.try_write()
cmd.func = func
return [cmd]

View file

@ -358,7 +358,7 @@ class LastGenrePlugin(plugins.BeetsPlugin):
))
if write:
item.write()
item.try_write()
lastgenre_cmd.func = lastgenre_func
return [lastgenre_cmd]

View file

@ -450,7 +450,7 @@ class LyricsPlugin(BeetsPlugin):
item.lyrics = lyrics
if write:
item.write()
item.try_write()
item.store()
def get_lyrics(self, artist, title):

View file

@ -38,13 +38,8 @@ def _print_and_apply_changes(lib, item, old_data, move, pretend, write):
if move and lib.directory in util.ancestry(item.path):
item.move(with_album=False)
if write:
try:
item.write()
except Exception as exc:
log.error(u'could not sync {0}: {1}'.format(
util.displayable_path(item.path), exc))
return False
if write and not item.try_write():
return False
item.store()
return True

View file

@ -547,7 +547,7 @@ class ReplayGainPlugin(BeetsPlugin):
album_gain.track_gains):
self.store_track_gain(item, track_gain)
if write:
item.write()
item.try_write()
except ReplayGainError as e:
log.warn(u"ReplayGain error: {1}".format(e))
except FatalReplayGainError as e:
@ -581,7 +581,7 @@ class ReplayGainPlugin(BeetsPlugin):
self.store_track_gain(item, track_gains[0])
if write:
item.write()
item.try_write()
except ReplayGainError as e:
log.warn(u"ReplayGain error: {1}".format(e))
except FatalReplayGainError as e:

View file

@ -77,7 +77,7 @@ class ScrubPlugin(BeetsPlugin):
# Restore tags, if enabled.
if opts.write:
log.debug(u'writing new tags after scrub')
item.write()
item.try_write()
if art:
log.info('restoring art')
mf = mediafile.MediaFile(item.path)