From a608a5fc36d27e9cbc5fda5dad4e247532a6af37 Mon Sep 17 00:00:00 2001 From: Malte Ried Date: Sat, 31 Jan 2015 12:41:01 +0100 Subject: [PATCH] Plugins are able to return a list of import tasks to create instead of the original import task using the import_task_created event. Needed for #1167 --- beets/importer.py | 58 +++++++++++++++++++++++++++++--------------- test/test_plugins.py | 5 ++-- 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/beets/importer.py b/beets/importer.py index f7d6aedba..973097f9e 100644 --- a/beets/importer.py +++ b/beets/importer.py @@ -547,9 +547,22 @@ class ImportTask(object): plugins.send('album_imported', lib=lib, album=self.album) def emit_created(self, session): - """Send the `import_task_created` event for this task. + """Send the `import_task_created` event for this task and return a list + of tasks which might be returned by plugins. """ - plugins.send('import_task_created', session=session, task=self) + tasks = plugins.send('import_task_created', session=session, task=self) + if not tasks: + tasks = [self] + else: + # 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) + tasks = [t for t in flat_tasks if t] + return tasks def lookup_candidates(self): """Retrieve and store candidates for this album. @@ -1006,15 +1019,17 @@ class ImportTaskFactory(object): for dirs, paths in self.paths(): if self.session.config['singletons']: for path in paths: - task = self._create(self.singleton(path)) - if task: - yield task + tasks = self._create(self.singleton(path)) + if tasks: + for task in tasks: + yield task yield self.sentinel(dirs) else: - task = self._create(self.album(paths, dirs)) - if task: - yield task + tasks = self._create(self.album(paths, dirs)) + if tasks: + 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 @@ -1033,10 +1048,11 @@ class ImportTaskFactory(object): task. If `task` is None, do nothing. """ if task: - task.emit_created(self.session) - if not task.skip: - self.imported += 1 - return task + tasks = task.emit_created(self.session) + for task in tasks: + if not task.skip: + self.imported += 1 + return tasks def paths(self): """Walk `self.toppath` and yield `(dirs, files)` pairs where @@ -1189,8 +1205,9 @@ def query_tasks(session): # Search for items. for item in session.lib.items(session.query): task = SingletonImportTask(None, item) - task.emit_created(session) - yield task + tasks = task.emit_created(session) + for task in tasks: + yield task else: # Search for albums. @@ -1206,8 +1223,9 @@ def query_tasks(session): item.album_id = None task = ImportTask(None, [album.item_dir()], items) - task.emit_created(session) - yield task + tasks = task.emit_created(session) + for task in tasks: + yield task @pipeline.mutator_stage @@ -1254,8 +1272,9 @@ def user_query(session, task): def emitter(task): for item in task.items: task = SingletonImportTask(task.toppath, item) - task.emit_created(session) - yield task + tasks = task.emit_created(session) + for new_task in tasks: + yield new_task yield SentinelImportTask(task.toppath, task.paths) ipl = pipeline.Pipeline([ @@ -1394,8 +1413,7 @@ def group_albums(session): tasks = [] for _, items in itertools.groupby(task.items, group): task = ImportTask(items=list(items)) - task.emit_created(session) - tasks.append(task) + tasks += task.emit_created(session) tasks.append(SentinelImportTask(task.toppath, task.paths)) task = pipeline.multiple(tasks) diff --git a/test/test_plugins.py b/test/test_plugins.py index 3b8d79cab..056be14e4 100644 --- a/test/test_plugins.py +++ b/test/test_plugins.py @@ -243,9 +243,8 @@ class EventsTest(unittest.TestCase, ImportHelper, TestHelper): logs = [line for line in logs if not line.startswith('Sending event:')] self.assertEqual(logs, [ - 'Album: {0}/album'.format(self.import_dir), - ' {0}'.format(self.file_paths[0]), - ' {0}'.format(self.file_paths[1]), + 'Singleton: {0}'.format(self.file_paths[0]), + 'Singleton: {0}'.format(self.file_paths[1]), ])