Merge pull request #925 from silb/bug-911-importadded-reimport

Fixes bug #911
This commit is contained in:
Stig Inge Lea Bjørnsen 2014-10-11 15:53:03 +02:00
commit 6f9abf4340
2 changed files with 59 additions and 21 deletions

View file

@ -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]

View file

@ -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.