Added documentation

FileFilterPlugin uses the new return value feature
Some tweaks to get the code more readable
This commit is contained in:
Malte Ried 2015-02-01 17:01:06 +01:00
parent 754a90dc90
commit e681449785
5 changed files with 48 additions and 34 deletions

View file

@ -546,9 +546,11 @@ class ImportTask(object):
return
plugins.send('album_imported', lib=lib, album=self.album)
def emit_created(self, session):
"""Send the `import_task_created` event for this task and return a list
of tasks which might be returned by plugins.
def handle_created(self, session):
"""Send the `import_task_created` event for this task. Return a list of
tasks that should continue through the pipeline. By default, this is a
list containing only the task itself, but plugins can replace the task
with new ones.
"""
tasks = plugins.send('import_task_created', session=session, task=self)
if not tasks:
@ -557,10 +559,7 @@ class ImportTask(object):
# The plugins gave us a list of lists of task. Flatten it.
flat_tasks = []
for inner in tasks:
if isinstance(inner, list):
flat_tasks += inner
else:
flat_tasks.append(inner)
flat_tasks += inner
tasks = [t for t in flat_tasks if t]
return tasks
@ -1020,16 +1019,14 @@ class ImportTaskFactory(object):
if self.session.config['singletons']:
for path in paths:
tasks = self._create(self.singleton(path))
if tasks:
for task in tasks:
yield task
for task in tasks:
yield task
yield self.sentinel(dirs)
else:
tasks = self._create(self.album(paths, dirs))
if tasks:
for task in tasks:
yield task
for task in tasks:
yield task
# Produce the final sentinel for this toppath to indicate that
# it is finished. This is usually just a SentinelImportTask, but
@ -1048,11 +1045,10 @@ class ImportTaskFactory(object):
task. If `task` is None, do nothing.
"""
if task:
tasks = task.emit_created(self.session)
for task in tasks:
if not task.skip:
self.imported += 1
tasks = task.handle_created(self.session)
self.imported += len(tasks)
return tasks
return []
def paths(self):
"""Walk `self.toppath` and yield `(dirs, files)` pairs where
@ -1205,8 +1201,7 @@ def query_tasks(session):
# Search for items.
for item in session.lib.items(session.query):
task = SingletonImportTask(None, item)
tasks = task.emit_created(session)
for task in tasks:
for task in task.handle_created(session):
yield task
else:
@ -1223,8 +1218,7 @@ def query_tasks(session):
item.album_id = None
task = ImportTask(None, [album.item_dir()], items)
tasks = task.emit_created(session)
for task in tasks:
for task in task.handle_created(session):
yield task
@ -1272,8 +1266,7 @@ def user_query(session, task):
def emitter(task):
for item in task.items:
task = SingletonImportTask(task.toppath, item)
tasks = task.emit_created(session)
for new_task in tasks:
for new_task in task.handle_created(session):
yield new_task
yield SentinelImportTask(task.toppath, task.paths)
@ -1384,9 +1377,6 @@ def manipulate_files(session, task):
def log_files(session, task):
"""A coroutine (pipeline stage) to log each file to be imported.
"""
if task.skip:
return
if isinstance(task, SingletonImportTask):
log.info(u'Singleton: {0}', displayable_path(task.item['path']))
elif task.items:
@ -1413,7 +1403,7 @@ def group_albums(session):
tasks = []
for _, items in itertools.groupby(task.items, group):
task = ImportTask(items=list(items))
tasks += task.emit_created(session)
tasks += task.handle_created(session)
tasks.append(SentinelImportTask(task.toppath, task.paths))
task = pipeline.multiple(tasks)

View file

@ -18,7 +18,7 @@
import re
from beets import config
from beets.plugins import BeetsPlugin
from beets.importer import action, SingletonImportTask
from beets.importer import SingletonImportTask
class FileFilterPlugin(BeetsPlugin):
@ -50,10 +50,11 @@ class FileFilterPlugin(BeetsPlugin):
if len(items_to_import) > 0:
task.items = items_to_import
else:
task.choice_flag = action.SKIP
return []
elif isinstance(task, SingletonImportTask):
if not self.file_filter(task.item['path']):
task.choice_flag = action.SKIP
return []
return [task]
def file_filter(self, full_path):
"""Checks if the configured regular expressions allow the import

View file

@ -96,7 +96,8 @@ For developers:
should!) use modern ``{}``-style string formatting lazily. See
:ref:`plugin-logging` in the plugin API docs.
* A new ``import_task_created`` event lets you manipulate import tasks
immediately after they are initialized.
immediately after they are initialized. It's also possible to replace the
originally created tasks by returning new ones using this event.
1.3.10 (January 5, 2015)

View file

@ -175,9 +175,11 @@ The events currently available are:
written to disk (i.e., just after the file on disk is closed).
* *import_task_created*: called immediately after an import task is
initialized. Plugins can use this to, for example, cancel processing of a
task before anything else happens. ``task`` (an `ImportTask`) and
``session`` (an `ImportSession`).
initialized. Plugins can use this to, for example, change imported files of a
task before anything else happens. It's also possible to replace the task
with another task by returning a list of tasks. This list can contain zero
or more `ImportTask`s. Returning an empty list will stop the task.
Parameters: ``task`` (an `ImportTask`) and ``session`` (an `ImportSession`).
* *import_task_start*: called when before an import task begins processing.
Parameters: ``task`` and ``session``.

View file

@ -207,6 +207,26 @@ class EventsTest(unittest.TestCase, ImportHelper, TestHelper):
self.file_paths.append(dest_path)
def test_import_task_created(self):
import_files = [self.import_dir]
self._setup_import_session(singletons=False)
self.importer.paths = import_files
with helper.capture_log() as logs:
self.importer.run()
self.unload_plugins()
# Exactly one event should have been imported (for the album).
# Sentinels do not get emitted.
self.assertEqual(logs.count('Sending event: import_task_created'), 1)
logs = [line for line in logs if not line.startswith('Sending event:')]
self.assertEqual(logs, [
'Album: {0}'.format(os.path.join(self.import_dir, 'album')),
' {0}'.format(self.file_paths[0]),
' {0}'.format(self.file_paths[1]),
])
def test_import_task_created_with_plugin(self):
class ToSingletonPlugin(plugins.BeetsPlugin):
def __init__(self):
super(ToSingletonPlugin, self).__init__()