Add importmtimes plugin for preserving file mtimes during copy imports.

File modification times are stored as item.mtime, item.added and
album.added.
This commit is contained in:
Stig Inge Lea Bjørnsen 2014-05-12 15:41:23 +02:00
parent a19e3f30b6
commit 0bf4222947
3 changed files with 104 additions and 0 deletions

77
beetsplug/importmtimes.py Normal file
View file

@ -0,0 +1,77 @@
"""Preserve file modification times during copy imports.
File modification times are also stored in the `added` field.
"""
from __future__ import unicode_literals, absolute_import, print_function
import logging, os
from beets import config
from beets import util
from beets.plugins import BeetsPlugin
log = logging.getLogger('beets')
class ImportMtimesPlugin(BeetsPlugin):
pass
@ImportMtimesPlugin.listen('import_task_start')
def check_config(task, session):
if not config['import']['copy']:
raise ValueError('The importmtimes plugin can only be used for copy'
' imports')
def copy_mtime(source_path, dest_path):
"""Copy the file mtime from the source path to the destination path.
"""
source_stat = os.stat(util.syspath(source_path))
dest_stat = os.stat(util.syspath(dest_path))
os.utime(util.syspath(dest_path),
(dest_stat.st_atime, source_stat.st_mtime))
# key: item path in the library
# value: file outside the library from which the item was imported
item_source_paths = dict()
def preserve_mtime(item):
"""Preserve the file modification time of an imported item by copying the
mtime from the file that the item is copied from.
"""
source_path = item_source_paths.get(item.path)
if source_path is None:
log.warn("No import source path found for item "
+ util.displayable_path(item.path))
return
copy_mtime(source_path, item.path)
item.mtime = os.path.getmtime(util.syspath(item.path))
del item_source_paths[item.path]
@ImportMtimesPlugin.listen('item_copied')
def record_import_source_path(item, source, destination):
"""Record which file an imported item is copied from.
"""
if (source == destination):
return
item_source_paths[destination] = source
log.debug('Recorded item source path "%s" <- "%s"',
util.displayable_path(destination),
util.displayable_path(source))
@ImportMtimesPlugin.listen('album_imported')
def update_album_times(lib, album):
for item in album.items():
preserve_mtime(item)
item.store()
item_mtimes = (item.mtime for item in album.items() if item.mtime > 0)
album.added = min(item_mtimes)
album.store()
@ImportMtimesPlugin.listen('item_imported')
def update_item_times(lib, item):
preserve_mtime(item)
item.added = item.mtime
item.store()

View file

@ -0,0 +1,24 @@
ImportMtimes Plugin
===================
The ``importmtimes`` plugin is useful when an existing collection is imported
and the time when albums and items were added should be preserved.
The :abbr:`mtime (modification time)` of files that are imported into the
library are assumed to represent the time when the items were originally
added.
File modification times are imported as follows:
* For all items, ``item.mtime`` is set to the mtime of the file
from which the item is imported from.
* For singleton items with no album, ``item.added`` is set to ``item.mtime``
during import.
* For items that are part of an album, ``album.added`` and ``item.added`` is
set to the oldest mtime of the album items.
* The mtime of an album's directory is ignored.
There are no configuration options for this plugin.
This plugin can only be used if Beets is :doc:`configured </reference/config>` to copy
files on import.

View file

@ -59,6 +59,7 @@ by typing ``beet version``.
ftintitle ftintitle
keyfinder keyfinder
bucket bucket
importmtimes
Autotagger Extensions Autotagger Extensions
--------------------- ---------------------
@ -91,6 +92,8 @@ Metadata
statistics (last_played, play_count, skip_count, rating). statistics (last_played, play_count, skip_count, rating).
* :doc:`keyfinder`: Use the `KeyFinder`_ program to detect the musical * :doc:`keyfinder`: Use the `KeyFinder`_ program to detect the musical
key from the audio. key from the audio.
* :doc:`importmtimes`: Preserve file modification times and use them as values
for the `added` and `mtime` fields in the database.
.. _Acoustic Attributes: http://developer.echonest.com/acoustic-attributes.html .. _Acoustic Attributes: http://developer.echonest.com/acoustic-attributes.html
.. _the Echo Nest: http://www.echonest.com .. _the Echo Nest: http://www.echonest.com