diff --git a/beets/importer.py b/beets/importer.py index aa8555240..8a48cb326 100644 --- a/beets/importer.py +++ b/beets/importer.py @@ -702,29 +702,9 @@ def apply_choices(config): util.prune_dirs(os.path.dirname(duplicate_path), lib.directory) - # Move/copy files. - task.old_paths = [item.path for item in items] # For deletion. - for item in items: - if config.copy or config.move: - if config.move: - # Just move the file. - lib.move(item, False, task.is_album) - else: - # If it's a reimport, move the file. Otherwise, copy - # and keep track of the old path. - old_path = item.path - do_copy = not bool(replaced_items[item]) - lib.move(item, do_copy, task.is_album) - if not do_copy: - # If we moved the item, remove the now-nonexistent - # file from old_paths. - task.old_paths.remove(old_path) - - if config.write and task.should_write_tags(): - item.write() - - # Add items to library. We consolidate this at the end to avoid - # locking while we do the copying and tag updates. + # Add items -- before path changes -- to the library. We add the + # items now (rather than at the end) so that album structures + # are in place before calls to destination(). try: # Remove old items. for replaced in replaced_items.itervalues(): @@ -745,6 +725,34 @@ def apply_choices(config): finally: lib.save() + # Move/copy files. + task.old_paths = [item.path for item in items] # For deletion. + for item in items: + if config.copy or config.move: + if config.move: + # Just move the file. + lib.move(item, False) + else: + # If it's a reimport, move the file. Otherwise, copy + # and keep track of the old path. + old_path = item.path + do_copy = not bool(replaced_items[item]) + lib.move(item, do_copy) + if not do_copy: + # If we moved the item, remove the now-nonexistent + # file from old_paths. + task.old_paths.remove(old_path) + + if config.write and task.should_write_tags(): + item.write() + + # Save new paths. + try: + for item in items: + lib.store(item) + finally: + lib.save() + def fetch_art(config): """A coroutine that fetches and applies album art for albums where appropriate. diff --git a/beets/library.py b/beets/library.py index efa8f0c68..322c158c7 100644 --- a/beets/library.py +++ b/beets/library.py @@ -829,11 +829,10 @@ class Library(BaseLibrary): self.conn.executescript(setup_sql) self.conn.commit() - def destination(self, item, pathmod=None, in_album=False, - fragment=False, basedir=None, platform=None): + def destination(self, item, pathmod=None, fragment=False, + basedir=None, platform=None): """Returns the path in the library directory designated for item - item (i.e., where the file ought to be). in_album forces the - item to be treated as part of an album. fragment makes this + item (i.e., where the file ought to be). fragment makes this method return just the path fragment underneath the root library directory; the path is also returned as Unicode instead of encoded as a bytestring. basedir can override the library's base @@ -848,14 +847,6 @@ class Library(BaseLibrary): if query == PF_KEY_DEFAULT: continue query = AndQuery.from_string(query) - if in_album: - # If we're treating this item as a member of the item, - # hack the query so that singleton queries always - # observe the item to be non-singleton. - for i, subquery in enumerate(query): - if isinstance(subquery, SingletonQuery): - query[i] = FalseQuery() if subquery.sense \ - else TrueQuery() if query.match(item): # The query matches the item! Use the corresponding path # format. @@ -1024,7 +1015,7 @@ class Library(BaseLibrary): util.soft_remove(item.path) util.prune_dirs(os.path.dirname(item.path), self.directory) - def move(self, item, copy=False, in_album=False, basedir=None, + def move(self, item, copy=False, basedir=None, with_album=True): """Move the item to its designated location within the library directory (provided by destination()). Subdirectories are @@ -1033,11 +1024,6 @@ class Library(BaseLibrary): If copy is True, moving the file is copied rather than moved. - If in_album is True, then the track is treated as part of an - album even if it does not yet have an album_id associated with - it. (This allows items to be moved before they are added to the - database, a performance optimization.) - basedir overrides the library base directory for the destination. @@ -1050,7 +1036,7 @@ class Library(BaseLibrary): side effect. You probably want to call save() to commit the DB transaction. """ - dest = self.destination(item, in_album=in_album, basedir=basedir) + dest = self.destination(item, basedir=basedir) # Create necessary ancestry for the move. util.mkdirall(dest) diff --git a/docs/changelog.rst b/docs/changelog.rst index f1a327714..63a041327 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -46,6 +46,7 @@ Changelog even on Unix platforms (this causes less surprise when using Samba shares to store music). To customize your character substitutions, see :ref:`the replace config option `. +* Filename collisions are now avoided when moving album art. * :doc:`/plugins/bpd`: Use Gstreamer's ``playbin2`` element instead of the deprecated ``playbin``. * :doc:`/plugins/bpd`: Listings are now sorted (thanks once again to Matteo