diff --git a/beetsplug/importadded.py b/beetsplug/importadded.py index 8b4b7c6b5..d362005f9 100644 --- a/beetsplug/importadded.py +++ b/beetsplug/importadded.py @@ -1,5 +1,7 @@ -"""Populate an items `added` and `mtime` field by using the file modification -time (mtime) of the item's source file before import. +"""Populate an item's `added` and `mtime` fields by using the file +modification time (mtime) of the item's source file before import. + +Reimported albums and items are skipped. """ from __future__ import unicode_literals, absolute_import, print_function @@ -26,6 +28,29 @@ class ImportAddedPlugin(BeetsPlugin): def check_config(task, session): config['importadded']['preserve_mtimes'].get(bool) +# item.id for new items that were reimported +reimported_item_ids = None + +# album.path for old albums that were replaced by a new reimported album +replaced_album_paths = None + + +def reimported_item(item): + return item.id in reimported_item_ids + + +def reimported_album(album): + return album.path in replaced_album_paths + + +@ImportAddedPlugin.listen('import_task_files') +def record_reimported(task, session): + global reimported_item_ids, replaced_album_paths + reimported_item_ids = set([item.id for item, replaced_items + in task.replaced_items.iteritems() + if replaced_items]) + replaced_album_paths = set(task.replaced_albums.keys()) + def write_file_mtime(path, mtime): """Write the given mtime to the destination path. @@ -34,17 +59,13 @@ def write_file_mtime(path, mtime): os.utime(util.syspath(path), (stat.st_atime, mtime)) -# key: item path in the library -# value: the file mtime of the file the item was imported from -item_mtime = dict() - def write_item_mtime(item, mtime): """Write the given mtime to an item's `mtime` field and to the mtime of the item's file. """ if mtime is None: - log.warn(u"No mtime to be preserved for item {0}" + log.warn(u"No mtime to be preserved for item '{0}'" .format(util.displayable_path(item.path))) return @@ -53,15 +74,16 @@ def write_item_mtime(item, mtime): item.mtime = mtime +# key: item path in the library +# value: the file mtime of the file the item was imported from +item_mtime = dict() + + @ImportAddedPlugin.listen('before_item_moved') @ImportAddedPlugin.listen('item_copied') def record_import_mtime(item, source, destination): - """Record the file mtime of an item's path before import. + """Record the file mtime of an item's path before its import. """ - if (source == destination): - # Re-import of an existing library item? - return - 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( @@ -71,26 +93,37 @@ def record_import_mtime(item, source, destination): @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))) + return + album_mtimes = [] for item in album.items(): - mtime = item_mtime[item.path] - if mtime is not None: + mtime = item_mtime.pop(item.path, None) + if mtime: album_mtimes.append(mtime) if config['importadded']['preserve_mtimes'].get(bool): write_item_mtime(item, mtime) item.store() - del item_mtime[item.path] - 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)) album.store() @ImportAddedPlugin.listen('item_imported') def update_item_times(lib, item): - mtime = item_mtime[item.path] - if mtime is not None: + if reimported_item(item): + log.debug(u"Item '{0}' is reimported, skipping import of added " + u"date.".format(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)) item.store() - del item_mtime[item.path] diff --git a/docs/plugins/importadded.rst b/docs/plugins/importadded.rst index 5da919325..90101be56 100644 --- a/docs/plugins/importadded.rst +++ b/docs/plugins/importadded.rst @@ -12,9 +12,9 @@ The ``item.added`` field is populated as follows: * For singleton items with no album, ``item.added`` is set to the item's file mtime before it was imported. -* For items that are part of an album, ``album.added`` and ``item.added`` is +* For items that are part of an album, ``album.added`` and ``item.added`` are set to the oldest mtime of the files in the album before they were imported. - The mtime of album directories are ignored. + The mtime of album directories is ignored. This plugin can optionally be configured to also preserve mtimes:: @@ -31,3 +31,8 @@ File modification times are preserved as follows: Note that there is no ``album.mtime`` field in the database and that the mtime of album directories on disk aren't preserved. + +Reimport +-------- + +This plugin will skip reimported singleton items and reimported albums and all of their items.