mirror of
https://github.com/beetbox/beets.git
synced 2025-12-06 08:39:17 +01:00
Reimports are now detected by inspecting the fields for reimported items and replaced albums in ImportTask. Reimported albums and items are skipped.
125 lines
4 KiB
Python
125 lines
4 KiB
Python
"""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
|
|
|
|
import logging
|
|
import os
|
|
|
|
from beets import config
|
|
from beets import util
|
|
from beets.plugins import BeetsPlugin
|
|
|
|
log = logging.getLogger('beets')
|
|
|
|
|
|
class ImportAddedPlugin(BeetsPlugin):
|
|
def __init__(self):
|
|
super(ImportAddedPlugin, self).__init__()
|
|
self.config.add({
|
|
'preserve_mtimes': False,
|
|
})
|
|
|
|
|
|
@ImportAddedPlugin.listen('import_task_start')
|
|
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.
|
|
"""
|
|
stat = os.stat(util.syspath(path))
|
|
os.utime(util.syspath(path),
|
|
(stat.st_atime, mtime))
|
|
|
|
|
|
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}"
|
|
.format(util.displayable_path(item.path)))
|
|
return
|
|
|
|
# The file's mtime on disk must be in sync with the item's mtime
|
|
write_file_mtime(util.syspath(item.path), 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 its import.
|
|
"""
|
|
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(
|
|
mtime, util.displayable_path(destination),
|
|
util.displayable_path(source)))
|
|
|
|
|
|
@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 "
|
|
u"dates for the album and its items.".format(album.path))
|
|
return
|
|
|
|
album_mtimes = []
|
|
for item in album.items():
|
|
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()
|
|
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):
|
|
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()
|