diff --git a/beets/importer.py b/beets/importer.py index b02ee0ede..d3cd623d4 100644 --- a/beets/importer.py +++ b/beets/importer.py @@ -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(): diff --git a/beets/library.py b/beets/library.py index f9285cabb..499d67403 100644 --- a/beets/library.py +++ b/beets/library.py @@ -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. diff --git a/beets/ui/commands.py b/beets/ui/commands.py index 1b1aab5b0..32050accd 100644 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -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', diff --git a/beetsplug/chroma.py b/beetsplug/chroma.py index d1624c6be..9221e107e 100644 --- a/beetsplug/chroma.py +++ b/beetsplug/chroma.py @@ -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 diff --git a/beetsplug/echonest.py b/beetsplug/echonest.py index 4ac000885..8b6509a55 100644 --- a/beetsplug/echonest.py +++ b/beetsplug/echonest.py @@ -414,7 +414,7 @@ class EchonestMetadataPlugin(plugins.BeetsPlugin): # Write and save. if write: - item.write() + item.try_write() item.store() diff --git a/beetsplug/echonest_tempo.py b/beetsplug/echonest_tempo.py index 11db03de2..0e144fb4d 100644 --- a/beetsplug/echonest_tempo.py +++ b/beetsplug/echonest_tempo.py @@ -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() diff --git a/beetsplug/ftintitle.py b/beetsplug/ftintitle.py index e9aae1ed1..731d8116c 100644 --- a/beetsplug/ftintitle.py +++ b/beetsplug/ftintitle.py @@ -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] diff --git a/beetsplug/lastgenre/__init__.py b/beetsplug/lastgenre/__init__.py index c398bf7e3..b166af034 100644 --- a/beetsplug/lastgenre/__init__.py +++ b/beetsplug/lastgenre/__init__.py @@ -358,7 +358,7 @@ class LastGenrePlugin(plugins.BeetsPlugin): )) if write: - item.write() + item.try_write() lastgenre_cmd.func = lastgenre_func return [lastgenre_cmd] diff --git a/beetsplug/lyrics.py b/beetsplug/lyrics.py index 28949b307..50d1529e1 100644 --- a/beetsplug/lyrics.py +++ b/beetsplug/lyrics.py @@ -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): diff --git a/beetsplug/mbsync.py b/beetsplug/mbsync.py index 8df913472..f5551f5a1 100644 --- a/beetsplug/mbsync.py +++ b/beetsplug/mbsync.py @@ -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 diff --git a/beetsplug/replaygain.py b/beetsplug/replaygain.py index 9fa894177..6a0cf593d 100644 --- a/beetsplug/replaygain.py +++ b/beetsplug/replaygain.py @@ -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: diff --git a/beetsplug/scrub.py b/beetsplug/scrub.py index ddd7fd0cc..ca37538f6 100644 --- a/beetsplug/scrub.py +++ b/beetsplug/scrub.py @@ -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)