From 2db346388a61a5fd71fbebb877a202d557ed7b65 Mon Sep 17 00:00:00 2001 From: Malte Ried Date: Sun, 21 Dec 2014 15:56:56 +0100 Subject: [PATCH] Added option --pretend to only print the filenames of files to import without importing them --- beets/importer.py | 33 ++++++++++++++++++++++----------- beets/ui/commands.py | 4 ++++ docs/reference/cli.rst | 6 +++++- test/test_importer.py | 41 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 12 deletions(-) diff --git a/beets/importer.py b/beets/importer.py index e8e28b3bd..4844fc128 100644 --- a/beets/importer.py +++ b/beets/importer.py @@ -34,6 +34,7 @@ from beets import dbcore from beets import plugins from beets import util from beets import config +from beets.ui import print_ from beets.util import pipeline, sorted_walk, ancestry from beets.util import syspath, normpath, displayable_path from enum import Enum @@ -960,6 +961,8 @@ class ImportTaskFactory(object): self.toppath = toppath self.session = session self.skipped = 0 + self.pretend = session.config[ + 'pretend'] if 'pretend' in session.config else False def tasks(self): """Yield all import tasks for `self.toppath`. @@ -970,15 +973,22 @@ class ImportTaskFactory(object): for dirs, paths in self.paths(): if self.session.config['singletons']: for path in paths: - task = self.singleton(path) - if task: - yield task + if self.pretend: + print_(displayable_path(path)) + else: + task = self.singleton(path) + if task: + yield task yield self.sentinel(dirs) else: - task = self.album(paths, dirs) - if task: - yield task + if self.pretend: + for path in paths: + print_(displayable_path(path)) + else: + task = self.album(paths, dirs) + if task: + yield task def paths(self): """Walk `self.toppath` and yield pairs of directory lists and @@ -1101,12 +1111,13 @@ def read_tasks(session): # Indicate the directory is finished. # FIXME hack to delete extracted archives - if archive_task is None: - yield task_factory.sentinel() - else: - yield archive_task + if not task_factory.pretend: + if archive_task is None: + yield task_factory.sentinel() + else: + yield archive_task - if not imported: + if not imported and not task_factory.pretend: log.warn(u'No files imported from {0}' .format(displayable_path(user_toppath))) diff --git a/beets/ui/commands.py b/beets/ui/commands.py index 910fe0243..69f7cb898 100644 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -943,6 +943,10 @@ import_cmd.parser.add_option( '-g', '--group-albums', dest='group_albums', action='store_true', help='group tracks in a folder into separate albums' ) +import_cmd.parser.add_option( + '-e', '--pretend', dest='pretend', action='store_true', + help='only print files to import, but don\'t import' +) import_cmd.func = import_func default_commands.append(import_cmd) diff --git a/docs/reference/cli.rst b/docs/reference/cli.rst index fc734c492..da5f0e04a 100644 --- a/docs/reference/cli.rst +++ b/docs/reference/cli.rst @@ -48,7 +48,7 @@ import `````` :: - beet import [-CWAPRqst] [-l LOGPATH] PATH... + beet import [-CeWAPRqst] [-l LOGPATH] PATH... beet import [options] -L QUERY Add music to your library, attempting to get correct tags for it from @@ -128,6 +128,10 @@ Optional command flags: ``--group-albums`` option to split the files based on their metadata before matching them as separate albums. +* If you just want to know which files would be imported, you can use the ``-e`` + (or ``--pretend``) option. If set, beets will only print a list of file + it will import when the option is removed and won't do anything else. + .. _rarfile: https://pypi.python.org/pypi/rarfile/2.2 .. only:: html diff --git a/test/test_importer.py b/test/test_importer.py index f026adf35..468315a35 100644 --- a/test/test_importer.py +++ b/test/test_importer.py @@ -1530,6 +1530,47 @@ class ReimportTest(unittest.TestCase, ImportHelper): self.assertEqual(self._item().added, 4747.0) +class ImportPretendTest(_common.TestCase, ImportHelper): + """ Test the pretend commandline option + """ + def setUp(self): + super(ImportPretendTest, self).setUp() + self.setup_beets() + self._create_import_dir(1) + self._setup_import_session() + config['import']['pretend'] = True + self.matcher = AutotagStub().install() + self.io.install() + + def tearDown(self): + self.teardown_beets() + self.matcher.restore() + + def test_import_enumerate_only(self): + resource_path = os.path.join(_common.RSRC, u'empty.mp3') + single_path = os.path.join(self.import_dir, u'track_2.mp3') + + shutil.copy(resource_path, single_path) + import_files = [ + os.path.join(self.import_dir, u'the_album'), + single_path + ] + self._setup_import_session(singletons=True) + self.importer.paths = import_files + + self.importer.run() + out = self.io.getoutput() + + self.assertEqual(len(self.lib.items()), 0) + self.assertEqual(len(self.lib.albums()), 0) + + lines = out.splitlines() + self.assertEqual(len(lines), 2) + self.assertEqual(lines[0], os.path.join(import_files[0], + u'track_1.mp3')) + self.assertEqual(lines[1], import_files[1]) + + def suite(): return unittest.TestLoader().loadTestsFromName(__name__)