From 4745c262e238f5da7c28ee1328bf8af41e710a37 Mon Sep 17 00:00:00 2001 From: SpirosChadoulos Date: Thu, 13 Apr 2017 12:51:11 +0300 Subject: [PATCH 01/26] New export command --- beets/ui/commands.py | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/beets/ui/commands.py b/beets/ui/commands.py index 06ab6f0a5..1afc7b540 100755 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -1450,7 +1450,7 @@ default_commands.append(modify_cmd) # move: Move/copy files to the library or a new base directory. -def move_items(lib, dest, query, copy, album, pretend, confirm=False): +def move_items(lib, dest, query, copy, album, pretend, confirm=False, export): """Moves or copies items to a new base directory, given by dest. If dest is None, then the library's base directory is used, making the command "consolidate" files. @@ -1479,17 +1479,20 @@ def move_items(lib, dest, query, copy, album, pretend, confirm=False): show_path_changes([(obj.path, obj.destination(basedir=dest)) for obj in objs]) else: - if confirm: - objs = ui.input_select_objects( - u'Really %s' % act, objs, - lambda o: show_path_changes( - [(o.path, o.destination(basedir=dest))])) + if export: + util.copy(item.path, item.destination(basedir=dest)) + else: + if confirm: + objs = ui.input_select_objects( + u'Really %s' % act, objs, + lambda o: show_path_changes( + [(o.path, o.destination(basedir=dest))])) - for obj in objs: - log.debug(u'moving: {0}', util.displayable_path(obj.path)) + for obj in objs: + log.debug(u'moving: {0}', util.displayable_path(obj.path)) - obj.move(copy, basedir=dest) - obj.store() + obj.move(copy, basedir=dest) + obj.store() def move_func(lib, opts, args): @@ -1500,7 +1503,7 @@ def move_func(lib, opts, args): raise ui.UserError(u'no such directory: %s' % dest) move_items(lib, dest, decargs(args), opts.copy, opts.album, opts.pretend, - opts.timid) + opts.timid, opts.export) move_cmd = ui.Subcommand( @@ -1522,6 +1525,10 @@ move_cmd.parser.add_option( u'-t', u'--timid', dest='timid', action='store_true', help=u'always confirm all actions' ) +move_cmd.parser.add_option( + u'-e', u'--export', default=False, action='store_true', + help=u'copy without changing the database path' +) move_cmd.parser.add_album_option() move_cmd.func = move_func default_commands.append(move_cmd) From 8f3ca12179acec8e855a31badeb3b55290086db6 Mon Sep 17 00:00:00 2001 From: SpirosChadoulos Date: Fri, 14 Apr 2017 12:19:16 +0300 Subject: [PATCH 02/26] Put export before confirm --- beets/ui/commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beets/ui/commands.py b/beets/ui/commands.py index 1afc7b540..b748c12b2 100755 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -1450,7 +1450,7 @@ default_commands.append(modify_cmd) # move: Move/copy files to the library or a new base directory. -def move_items(lib, dest, query, copy, album, pretend, confirm=False, export): +def move_items(lib, dest, query, copy, album, pretend, export, confirm=False): """Moves or copies items to a new base directory, given by dest. If dest is None, then the library's base directory is used, making the command "consolidate" files. From d4413a2bc4e028034a2886d5cda8b432f7bcf0d5 Mon Sep 17 00:00:00 2001 From: SpirosChadoulos Date: Sat, 15 Apr 2017 00:54:09 +0300 Subject: [PATCH 03/26] obj instead of item --- beets/ui/commands.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/beets/ui/commands.py b/beets/ui/commands.py index b748c12b2..eec478ea6 100755 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -1480,7 +1480,8 @@ def move_items(lib, dest, query, copy, album, pretend, export, confirm=False): for obj in objs]) else: if export: - util.copy(item.path, item.destination(basedir=dest)) + for obj in objs: + util.copy(obj.path, obj.destination(basedir=dest)) else: if confirm: objs = ui.input_select_objects( From a99b7e9e40864d1b7e5b2b6b4d7955e8e7683a28 Mon Sep 17 00:00:00 2001 From: SpirosChadoulos Date: Sun, 16 Apr 2017 15:53:11 +0300 Subject: [PATCH 04/26] Provided default value for export. --- beets/ui/commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beets/ui/commands.py b/beets/ui/commands.py index eec478ea6..befbd1a45 100755 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -1450,7 +1450,7 @@ default_commands.append(modify_cmd) # move: Move/copy files to the library or a new base directory. -def move_items(lib, dest, query, copy, album, pretend, export, confirm=False): +def move_items(lib, dest, query, copy, album, pretend, export=False, confirm=False): """Moves or copies items to a new base directory, given by dest. If dest is None, then the library's base directory is used, making the command "consolidate" files. From 53618258faec970a0005b640d6811ad0aa04684a Mon Sep 17 00:00:00 2001 From: SpirosChadoulos Date: Wed, 19 Apr 2017 11:31:08 +0300 Subject: [PATCH 05/26] added 1 line before for loop --- beets/ui/commands.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/beets/ui/commands.py b/beets/ui/commands.py index befbd1a45..26ed4836b 100755 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -1480,6 +1480,10 @@ def move_items(lib, dest, query, copy, album, pretend, export=False, confirm=Fal for obj in objs]) else: if export: + objs = ui.input_select_objects( + u'Really %s' % act, objs, + lambda o: show_path_changes( + [(o.path, o.destination(basedir=dest))])) for obj in objs: util.copy(obj.path, obj.destination(basedir=dest)) else: From 70183070b2d622278e1d29e542f903ca1a8bd026 Mon Sep 17 00:00:00 2001 From: SpirosChadoulos Date: Wed, 19 Apr 2017 12:35:07 +0300 Subject: [PATCH 06/26] deleted else --- beets/ui/commands.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/beets/ui/commands.py b/beets/ui/commands.py index 06ab6f0a5..88d9ccaf1 100755 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -1450,7 +1450,7 @@ default_commands.append(modify_cmd) # move: Move/copy files to the library or a new base directory. -def move_items(lib, dest, query, copy, album, pretend, confirm=False): +def move_items(lib, dest, query, copy, album, pretend, export=False, confirm=False): """Moves or copies items to a new base directory, given by dest. If dest is None, then the library's base directory is used, making the command "consolidate" files. @@ -1479,6 +1479,9 @@ def move_items(lib, dest, query, copy, album, pretend, confirm=False): show_path_changes([(obj.path, obj.destination(basedir=dest)) for obj in objs]) else: + if export: + for obj in objs: + util.copy(obj.path, obj.destination(basedir=dest)) if confirm: objs = ui.input_select_objects( u'Really %s' % act, objs, @@ -1500,7 +1503,7 @@ def move_func(lib, opts, args): raise ui.UserError(u'no such directory: %s' % dest) move_items(lib, dest, decargs(args), opts.copy, opts.album, opts.pretend, - opts.timid) + opts.timid, opts.export) move_cmd = ui.Subcommand( @@ -1522,6 +1525,10 @@ move_cmd.parser.add_option( u'-t', u'--timid', dest='timid', action='store_true', help=u'always confirm all actions' ) +move_cmd.parser.add_option( + u'-e', u'--export', default=False, action='store_true', + help=u'copy without changing the database path' +) move_cmd.parser.add_album_option() move_cmd.func = move_func default_commands.append(move_cmd) From de57602e3451021a43bece47f1d45b5b7d15bd96 Mon Sep 17 00:00:00 2001 From: SpirosChadoulos Date: Wed, 19 Apr 2017 12:54:03 +0300 Subject: [PATCH 07/26] fixed certain errors --- beets/ui/commands.py | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/beets/ui/commands.py b/beets/ui/commands.py index 368dd1eb4..88d9ccaf1 100755 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -1480,30 +1480,19 @@ def move_items(lib, dest, query, copy, album, pretend, export=False, confirm=Fal for obj in objs]) else: if export: -<<<<<<< HEAD for obj in objs: util.copy(obj.path, obj.destination(basedir=dest)) if confirm: -======= ->>>>>>> 53618258faec970a0005b640d6811ad0aa04684a objs = ui.input_select_objects( u'Really %s' % act, objs, lambda o: show_path_changes( [(o.path, o.destination(basedir=dest))])) - for obj in objs: - util.copy(obj.path, obj.destination(basedir=dest)) - else: - if confirm: - objs = ui.input_select_objects( - u'Really %s' % act, objs, - lambda o: show_path_changes( - [(o.path, o.destination(basedir=dest))])) - for obj in objs: - log.debug(u'moving: {0}', util.displayable_path(obj.path)) + for obj in objs: + log.debug(u'moving: {0}', util.displayable_path(obj.path)) - obj.move(copy, basedir=dest) - obj.store() + obj.move(copy, basedir=dest) + obj.store() def move_func(lib, opts, args): From 60318f1e02a248802a9ccbc2463c783111736ca3 Mon Sep 17 00:00:00 2001 From: SpirosChadoulos Date: Wed, 19 Apr 2017 13:07:04 +0300 Subject: [PATCH 08/26] fixed line length --- beets/ui/commands.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/beets/ui/commands.py b/beets/ui/commands.py index 88d9ccaf1..36876d229 100755 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -1450,7 +1450,8 @@ default_commands.append(modify_cmd) # move: Move/copy files to the library or a new base directory. -def move_items(lib, dest, query, copy, album, pretend, export=False, confirm=False): +def move_items(lib, dest, query, copy, album, pretend, export=False, + confirm=False): """Moves or copies items to a new base directory, given by dest. If dest is None, then the library's base directory is used, making the command "consolidate" files. From bab99f546f420d893581003fc5286ac35df70bdc Mon Sep 17 00:00:00 2001 From: SpirosChadoulos Date: Sun, 30 Apr 2017 15:02:50 +0300 Subject: [PATCH 09/26] Added a test for the new export feature --- test/test_ui.py | 77 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/test/test_ui.py b/test/test_ui.py index c519e66fb..f31e677c3 100644 --- a/test/test_ui.py +++ b/test/test_ui.py @@ -476,6 +476,83 @@ class MoveTest(_common.TestCase): self.i.load() self.assertIn(b'srcfile', self.i.path) +class ExportTest(_common.TestCase): + def setUp(self): + super(MoveTest, self).setUp() + + self.io.install() + + self.libdir = os.path.join(self.temp_dir, b'testlibdir') + os.mkdir(self.libdir) + + self.itempath = os.path.join(self.libdir, b'srcfile') + shutil.copy(os.path.join(_common.RSRC, b'full.mp3'), self.itempath) + + # Add a file to the library but don't copy it in yet. + self.lib = library.Library(':memory:', self.libdir) + self.i = library.Item.from_path(self.itempath) + self.lib.add(self.i) + self.album = self.lib.add_album([self.i]) + + # Alternate destination directory. + self.otherdir = os.path.join(self.temp_dir, b'testotherdir') + + def _move(self, query=(), dest=None, copy=False, album=False, + pretend=False, export=True): + commands.move_items(self.lib, dest, query, copy, album, pretend, export) + + def test_move_item(self): + self._move() + self.i.load() + self.assertTrue(b'testlibdir' in self.i.path) + self.assertExists(self.i.path) + self.assertNotExists(self.itempath) + + def test_copy_item(self): + self._move(copy=True) + self.i.load() + self.assertTrue(b'testlibdir' in self.i.path) + self.assertExists(self.i.path) + self.assertExists(self.itempath) + + def test_move_album(self): + self._move(album=True) + self.i.load() + self.assertTrue(b'testlibdir' in self.i.path) + self.assertExists(self.i.path) + self.assertNotExists(self.itempath) + + def test_copy_album(self): + self._move(copy=True, album=True) + self.i.load() + self.assertTrue(b'testlibdir' in self.i.path) + self.assertExists(self.i.path) + self.assertExists(self.itempath) + + def test_move_item_custom_dir(self): + self._move(dest=self.otherdir) + self.i.load() + self.assertTrue(b'testotherdir' in self.i.path) + self.assertExists(self.i.path) + self.assertNotExists(self.itempath) + + def test_move_album_custom_dir(self): + self._move(dest=self.otherdir, album=True) + self.i.load() + self.assertTrue(b'testotherdir' in self.i.path) + self.assertExists(self.i.path) + self.assertNotExists(self.itempath) + + def test_pretend_move_item(self): + self._move(dest=self.otherdir, pretend=True) + self.i.load() + self.assertIn(b'srcfile', self.i.path) + + def test_pretend_move_album(self): + self._move(album=True, pretend=True) + self.i.load() + self.assertIn(b'srcfile', self.i.path) + class UpdateTest(_common.TestCase): def setUp(self): From a88192240e0d9ad37424cd74242ce25eb3d3b477 Mon Sep 17 00:00:00 2001 From: SpirosChadoulos Date: Sun, 30 Apr 2017 15:14:17 +0300 Subject: [PATCH 10/26] ExportTest correction --- test/test_ui.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_ui.py b/test/test_ui.py index f31e677c3..fd65ab0a6 100644 --- a/test/test_ui.py +++ b/test/test_ui.py @@ -478,7 +478,7 @@ class MoveTest(_common.TestCase): class ExportTest(_common.TestCase): def setUp(self): - super(MoveTest, self).setUp() + super(ExportTest, self).setUp() self.io.install() From 90c30d8564b7b31427f33c83b3933921329ec497 Mon Sep 17 00:00:00 2001 From: SpirosChadoulos Date: Thu, 4 May 2017 19:08:23 +0300 Subject: [PATCH 11/26] Added an if album: statement --- beets/ui/commands.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/beets/ui/commands.py b/beets/ui/commands.py index 36876d229..840aa0a93 100755 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -1481,8 +1481,12 @@ def move_items(lib, dest, query, copy, album, pretend, export=False, for obj in objs]) else: if export: - for obj in objs: - util.copy(obj.path, obj.destination(basedir=dest)) + if album: + util.copy([(item.path, item.destination(basedir=dest)) + for obj in objs for item in obj.items()]) + else: + util.copy([(obj.path, obj.destination(basedir=dest)) + for obj in objs]) if confirm: objs = ui.input_select_objects( u'Really %s' % act, objs, From 167ae91b8d94fc252c9238c6a35f1083b09f2303 Mon Sep 17 00:00:00 2001 From: SpirosChadoulos Date: Fri, 5 May 2017 00:36:36 +0300 Subject: [PATCH 12/26] Changes at line 1486 --- beets/ui/commands.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/beets/ui/commands.py b/beets/ui/commands.py index 840aa0a93..7e2095dd1 100755 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -1482,11 +1482,12 @@ def move_items(lib, dest, query, copy, album, pretend, export=False, else: if export: if album: - util.copy([(item.path, item.destination(basedir=dest)) - for obj in objs for item in obj.items()]) + for obj in objs: + for item in obj.items(): + util.copy(item.path, item.destination(basedir=dest)) else: - util.copy([(obj.path, obj.destination(basedir=dest)) - for obj in objs]) + for item in objs: + util.copy(item.path, item.destination(basedir=dest)) if confirm: objs = ui.input_select_objects( u'Really %s' % act, objs, From f5b23fffd4494d1d799eaaef7fad4e4c0b926d50 Mon Sep 17 00:00:00 2001 From: SpirosChadoulos Date: Sat, 6 May 2017 15:03:42 +0300 Subject: [PATCH 13/26] Replaced all AssertNotExists with AssertExists --- test/test_ui.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test_ui.py b/test/test_ui.py index fd65ab0a6..0f5ad5d67 100644 --- a/test/test_ui.py +++ b/test/test_ui.py @@ -506,7 +506,7 @@ class ExportTest(_common.TestCase): self.i.load() self.assertTrue(b'testlibdir' in self.i.path) self.assertExists(self.i.path) - self.assertNotExists(self.itempath) + self.assertExists(self.itempath) def test_copy_item(self): self._move(copy=True) @@ -520,7 +520,7 @@ class ExportTest(_common.TestCase): self.i.load() self.assertTrue(b'testlibdir' in self.i.path) self.assertExists(self.i.path) - self.assertNotExists(self.itempath) + self.assertExists(self.itempath) def test_copy_album(self): self._move(copy=True, album=True) @@ -534,14 +534,14 @@ class ExportTest(_common.TestCase): self.i.load() self.assertTrue(b'testotherdir' in self.i.path) self.assertExists(self.i.path) - self.assertNotExists(self.itempath) + self.assertExists(self.itempath) def test_move_album_custom_dir(self): self._move(dest=self.otherdir, album=True) self.i.load() self.assertTrue(b'testotherdir' in self.i.path) self.assertExists(self.i.path) - self.assertNotExists(self.itempath) + self.assertExists(self.itempath) def test_pretend_move_item(self): self._move(dest=self.otherdir, pretend=True) From 0dc948d9d34cb81e63543767a088f41b50182899 Mon Sep 17 00:00:00 2001 From: SpirosChadoulos Date: Thu, 11 May 2017 12:11:21 +0300 Subject: [PATCH 14/26] Made sure that the destination directory will exist --- beets/ui/commands.py | 9 +++++++-- test/test_ui.py | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/beets/ui/commands.py b/beets/ui/commands.py index 7e2095dd1..db34ed872 100755 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -1481,13 +1481,18 @@ def move_items(lib, dest, query, copy, album, pretend, export=False, for obj in objs]) else: if export: + if album: for obj in objs: for item in obj.items(): + # Create necessary ancestry for the copy. + util.mkdirall(item.destination(basedir=dest)) util.copy(item.path, item.destination(basedir=dest)) else: - for item in objs: - util.copy(item.path, item.destination(basedir=dest)) + for obj in objs: + # Create necessary ancestry for the copy. + util.mkdirall(obj.destination(basedir=dest)) + util.copy(obj.path, obj.destination(basedir=dest)) if confirm: objs = ui.input_select_objects( u'Really %s' % act, objs, diff --git a/test/test_ui.py b/test/test_ui.py index 0f5ad5d67..33266d379 100644 --- a/test/test_ui.py +++ b/test/test_ui.py @@ -543,6 +543,8 @@ class ExportTest(_common.TestCase): self.assertExists(self.i.path) self.assertExists(self.itempath) + + def test_pretend_move_item(self): self._move(dest=self.otherdir, pretend=True) self.i.load() From 51835e762ffe10b279d7a49e459327acdc502630 Mon Sep 17 00:00:00 2001 From: SpirosChadoulos Date: Thu, 11 May 2017 12:30:21 +0300 Subject: [PATCH 15/26] Minor fixes to move tests --- test/test_ui.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test_ui.py b/test/test_ui.py index 33266d379..f017d8210 100644 --- a/test/test_ui.py +++ b/test/test_ui.py @@ -506,7 +506,7 @@ class ExportTest(_common.TestCase): self.i.load() self.assertTrue(b'testlibdir' in self.i.path) self.assertExists(self.i.path) - self.assertExists(self.itempath) + self.assertNotExists(self.itempath) def test_copy_item(self): self._move(copy=True) @@ -520,7 +520,7 @@ class ExportTest(_common.TestCase): self.i.load() self.assertTrue(b'testlibdir' in self.i.path) self.assertExists(self.i.path) - self.assertExists(self.itempath) + self.assertNotExists(self.itempath) def test_copy_album(self): self._move(copy=True, album=True) @@ -534,14 +534,14 @@ class ExportTest(_common.TestCase): self.i.load() self.assertTrue(b'testotherdir' in self.i.path) self.assertExists(self.i.path) - self.assertExists(self.itempath) + self.assertNotExists(self.itempath) def test_move_album_custom_dir(self): self._move(dest=self.otherdir, album=True) self.i.load() self.assertTrue(b'testotherdir' in self.i.path) self.assertExists(self.i.path) - self.assertExists(self.itempath) + self.assertNotExists(self.itempath) From c4ef23d9f716d889206391bdd3811c59467f1192 Mon Sep 17 00:00:00 2001 From: SpirosChadoulos Date: Thu, 11 May 2017 12:45:03 +0300 Subject: [PATCH 16/26] Minor Flake fixes --- test/test_ui.py | 72 ++++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/test/test_ui.py b/test/test_ui.py index f017d8210..92a4d4ddb 100644 --- a/test/test_ui.py +++ b/test/test_ui.py @@ -156,7 +156,6 @@ class RemoveTest(_common.TestCase): class ModifyTest(unittest.TestCase, TestHelper): - def setUp(self): self.setup_beets() self.album = self.add_album_fixture() @@ -347,7 +346,6 @@ class ModifyTest(unittest.TestCase, TestHelper): class WriteTest(unittest.TestCase, TestHelper): - def setUp(self): self.setup_beets() @@ -476,6 +474,7 @@ class MoveTest(_common.TestCase): self.i.load() self.assertIn(b'srcfile', self.i.path) + class ExportTest(_common.TestCase): def setUp(self): super(ExportTest, self).setUp() @@ -499,7 +498,8 @@ class ExportTest(_common.TestCase): def _move(self, query=(), dest=None, copy=False, album=False, pretend=False, export=True): - commands.move_items(self.lib, dest, query, copy, album, pretend, export) + commands.move_items(self.lib, dest, query, copy, album, + pretend, export) def test_move_item(self): self._move() @@ -543,8 +543,6 @@ class ExportTest(_common.TestCase): self.assertExists(self.i.path) self.assertNotExists(self.itempath) - - def test_pretend_move_item(self): self._move(dest=self.otherdir, pretend=True) self.i.load() @@ -901,37 +899,37 @@ class ConfigTest(unittest.TestCase, TestHelper, _common.Assertions): self.run_command('--config', cli_config_path, 'test', lib=None) self.assertEqual(config['anoption'].get(), 'cli overwrite') -# @unittest.skip('Difficult to implement with optparse') -# def test_multiple_cli_config_files(self): -# cli_config_path_1 = os.path.join(self.temp_dir, b'config.yaml') -# cli_config_path_2 = os.path.join(self.temp_dir, b'config_2.yaml') -# -# with open(cli_config_path_1, 'w') as file: -# file.write('first: value') -# -# with open(cli_config_path_2, 'w') as file: -# file.write('second: value') -# -# self.run_command('--config', cli_config_path_1, -# '--config', cli_config_path_2, 'test', lib=None) -# self.assertEqual(config['first'].get(), 'value') -# self.assertEqual(config['second'].get(), 'value') -# -# @unittest.skip('Difficult to implement with optparse') -# def test_multiple_cli_config_overwrite(self): -# cli_config_path = os.path.join(self.temp_dir, b'config.yaml') -# cli_overwrite_config_path = os.path.join(self.temp_dir, -# b'overwrite_config.yaml') -# -# with open(cli_config_path, 'w') as file: -# file.write('anoption: value') -# -# with open(cli_overwrite_config_path, 'w') as file: -# file.write('anoption: overwrite') -# -# self.run_command('--config', cli_config_path, -# '--config', cli_overwrite_config_path, 'test') -# self.assertEqual(config['anoption'].get(), 'cli overwrite') + # @unittest.skip('Difficult to implement with optparse') + # def test_multiple_cli_config_files(self): + # cli_config_path_1 = os.path.join(self.temp_dir, b'config.yaml') + # cli_config_path_2 = os.path.join(self.temp_dir, b'config_2.yaml') + # + # with open(cli_config_path_1, 'w') as file: + # file.write('first: value') + # + # with open(cli_config_path_2, 'w') as file: + # file.write('second: value') + # + # self.run_command('--config', cli_config_path_1, + # '--config', cli_config_path_2, 'test', lib=None) + # self.assertEqual(config['first'].get(), 'value') + # self.assertEqual(config['second'].get(), 'value') + # + # @unittest.skip('Difficult to implement with optparse') + # def test_multiple_cli_config_overwrite(self): + # cli_config_path = os.path.join(self.temp_dir, b'config.yaml') + # cli_overwrite_config_path = os.path.join(self.temp_dir, + # b'overwrite_config.yaml') + # + # with open(cli_config_path, 'w') as file: + # file.write('anoption: value') + # + # with open(cli_overwrite_config_path, 'w') as file: + # file.write('anoption: overwrite') + # + # self.run_command('--config', cli_config_path, + # '--config', cli_overwrite_config_path, 'test') + # self.assertEqual(config['anoption'].get(), 'cli overwrite') def test_cli_config_paths_resolve_relative_to_user_dir(self): cli_config_path = os.path.join(self.temp_dir, b'config.yaml') @@ -1271,6 +1269,7 @@ class CommonOptionsParserCliTest(unittest.TestCase, TestHelper): """Test CommonOptionsParser and formatting LibModel formatting on 'list' command. """ + def setUp(self): self.setup_beets() self.lib = library.Library(':memory:') @@ -1467,5 +1466,6 @@ class EncodingTest(_common.TestCase): def suite(): return unittest.TestLoader().loadTestsFromName(__name__) + if __name__ == '__main__': unittest.main(defaultTest='suite') From 8f62e8bc684a9f943baa1db4eaac1b5b43a09ec2 Mon Sep 17 00:00:00 2001 From: SpirosChadoulos Date: Fri, 12 May 2017 14:49:03 +0300 Subject: [PATCH 17/26] Requested changes done --- beets/ui/commands.py | 16 ++++---- test/test_ui.py | 93 +++++++++++++++++--------------------------- 2 files changed, 45 insertions(+), 64 deletions(-) diff --git a/beets/ui/commands.py b/beets/ui/commands.py index db34ed872..b7792d0cf 100755 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -1447,6 +1447,12 @@ modify_cmd.parser.add_option( modify_cmd.func = modify_func default_commands.append(modify_cmd) +#export(file) function copies a file without modifying the database. + +def export(file): + # Create necessary ancestry for the copy. + util.mkdirall(file.destination(basedir=dest)) + util.copy(file.path, file.destination(basedir=dest)) # move: Move/copy files to the library or a new base directory. @@ -1480,19 +1486,15 @@ def move_items(lib, dest, query, copy, album, pretend, export=False, show_path_changes([(obj.path, obj.destination(basedir=dest)) for obj in objs]) else: + #Copying files without modifying the database. if export: - if album: for obj in objs: for item in obj.items(): - # Create necessary ancestry for the copy. - util.mkdirall(item.destination(basedir=dest)) - util.copy(item.path, item.destination(basedir=dest)) + export(item) else: for obj in objs: - # Create necessary ancestry for the copy. - util.mkdirall(obj.destination(basedir=dest)) - util.copy(obj.path, obj.destination(basedir=dest)) + export(obj) if confirm: objs = ui.input_select_objects( u'Really %s' % act, objs, diff --git a/test/test_ui.py b/test/test_ui.py index 92a4d4ddb..f34cf72cb 100644 --- a/test/test_ui.py +++ b/test/test_ui.py @@ -501,54 +501,33 @@ class ExportTest(_common.TestCase): commands.move_items(self.lib, dest, query, copy, album, pretend, export) - def test_move_item(self): + def test_export_item(self): self._move() self.i.load() self.assertTrue(b'testlibdir' in self.i.path) self.assertExists(self.i.path) self.assertNotExists(self.itempath) - def test_copy_item(self): - self._move(copy=True) - self.i.load() - self.assertTrue(b'testlibdir' in self.i.path) - self.assertExists(self.i.path) - self.assertExists(self.itempath) - - def test_move_album(self): - self._move(album=True) - self.i.load() - self.assertTrue(b'testlibdir' in self.i.path) - self.assertExists(self.i.path) - self.assertNotExists(self.itempath) - - def test_copy_album(self): - self._move(copy=True, album=True) - self.i.load() - self.assertTrue(b'testlibdir' in self.i.path) - self.assertExists(self.i.path) - self.assertExists(self.itempath) - - def test_move_item_custom_dir(self): + def test_export_item_custom_dir(self): self._move(dest=self.otherdir) self.i.load() self.assertTrue(b'testotherdir' in self.i.path) self.assertExists(self.i.path) self.assertNotExists(self.itempath) - def test_move_album_custom_dir(self): + def test_export_album_custom_dir(self): self._move(dest=self.otherdir, album=True) self.i.load() self.assertTrue(b'testotherdir' in self.i.path) self.assertExists(self.i.path) self.assertNotExists(self.itempath) - def test_pretend_move_item(self): + def test_pretend_export_item(self): self._move(dest=self.otherdir, pretend=True) self.i.load() self.assertIn(b'srcfile', self.i.path) - def test_pretend_move_album(self): + def test_pretend_export_album(self): self._move(album=True, pretend=True) self.i.load() self.assertIn(b'srcfile', self.i.path) @@ -899,37 +878,37 @@ class ConfigTest(unittest.TestCase, TestHelper, _common.Assertions): self.run_command('--config', cli_config_path, 'test', lib=None) self.assertEqual(config['anoption'].get(), 'cli overwrite') - # @unittest.skip('Difficult to implement with optparse') - # def test_multiple_cli_config_files(self): - # cli_config_path_1 = os.path.join(self.temp_dir, b'config.yaml') - # cli_config_path_2 = os.path.join(self.temp_dir, b'config_2.yaml') - # - # with open(cli_config_path_1, 'w') as file: - # file.write('first: value') - # - # with open(cli_config_path_2, 'w') as file: - # file.write('second: value') - # - # self.run_command('--config', cli_config_path_1, - # '--config', cli_config_path_2, 'test', lib=None) - # self.assertEqual(config['first'].get(), 'value') - # self.assertEqual(config['second'].get(), 'value') - # - # @unittest.skip('Difficult to implement with optparse') - # def test_multiple_cli_config_overwrite(self): - # cli_config_path = os.path.join(self.temp_dir, b'config.yaml') - # cli_overwrite_config_path = os.path.join(self.temp_dir, - # b'overwrite_config.yaml') - # - # with open(cli_config_path, 'w') as file: - # file.write('anoption: value') - # - # with open(cli_overwrite_config_path, 'w') as file: - # file.write('anoption: overwrite') - # - # self.run_command('--config', cli_config_path, - # '--config', cli_overwrite_config_path, 'test') - # self.assertEqual(config['anoption'].get(), 'cli overwrite') +# @unittest.skip('Difficult to implement with optparse') +# def test_multiple_cli_config_files(self): +# cli_config_path_1 = os.path.join(self.temp_dir, b'config.yaml') +# cli_config_path_2 = os.path.join(self.temp_dir, b'config_2.yaml') +# +# with open(cli_config_path_1, 'w') as file: +# file.write('first: value') +# +# with open(cli_config_path_2, 'w') as file: +# file.write('second: value') +# +# self.run_command('--config', cli_config_path_1, +# '--config', cli_config_path_2, 'test', lib=None) +# self.assertEqual(config['first'].get(), 'value') +# self.assertEqual(config['second'].get(), 'value') +# +# @unittest.skip('Difficult to implement with optparse') +# def test_multiple_cli_config_overwrite(self): +# cli_config_path = os.path.join(self.temp_dir, b'config.yaml') +# cli_overwrite_config_path = os.path.join(self.temp_dir, +# b'overwrite_config.yaml') +# +# with open(cli_config_path, 'w') as file: +# file.write('anoption: value') +# +# with open(cli_overwrite_config_path, 'w') as file: +# file.write('anoption: overwrite') +# +# self.run_command('--config', cli_config_path, +# '--config', cli_overwrite_config_path, 'test') +# self.assertEqual(config['anoption'].get(), 'cli overwrite') def test_cli_config_paths_resolve_relative_to_user_dir(self): cli_config_path = os.path.join(self.temp_dir, b'config.yaml') From 169cf596b0f98edcddcc7a9fda791721d3c37f45 Mon Sep 17 00:00:00 2001 From: SpirosChadoulos Date: Fri, 12 May 2017 15:08:06 +0300 Subject: [PATCH 18/26] Fixed bool variable error --- beets/ui/commands.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/beets/ui/commands.py b/beets/ui/commands.py index b7792d0cf..64f3229d5 100755 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -1447,13 +1447,6 @@ modify_cmd.parser.add_option( modify_cmd.func = modify_func default_commands.append(modify_cmd) -#export(file) function copies a file without modifying the database. - -def export(file): - # Create necessary ancestry for the copy. - util.mkdirall(file.destination(basedir=dest)) - util.copy(file.path, file.destination(basedir=dest)) - # move: Move/copy files to the library or a new base directory. def move_items(lib, dest, query, copy, album, pretend, export=False, @@ -1488,6 +1481,12 @@ def move_items(lib, dest, query, copy, album, pretend, export=False, else: #Copying files without modifying the database. if export: + # export(file) function copies a file without modifying the database. + + def export(file): + # Create necessary ancestry for the copy. + util.mkdirall(file.destination(basedir=dest)) + util.copy(file.path, file.destination(basedir=dest)) if album: for obj in objs: for item in obj.items(): From 7c9198934488c6b5b9ee7e11a3e1275d901c3a8a Mon Sep 17 00:00:00 2001 From: SpirosChadoulos Date: Fri, 12 May 2017 15:25:36 +0300 Subject: [PATCH 19/26] Minor flake fixes --- beets/ui/commands.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/beets/ui/commands.py b/beets/ui/commands.py index 64f3229d5..7ffa90b11 100755 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -1447,6 +1447,7 @@ modify_cmd.parser.add_option( modify_cmd.func = modify_func default_commands.append(modify_cmd) + # move: Move/copy files to the library or a new base directory. def move_items(lib, dest, query, copy, album, pretend, export=False, @@ -1479,9 +1480,10 @@ def move_items(lib, dest, query, copy, album, pretend, export=False, show_path_changes([(obj.path, obj.destination(basedir=dest)) for obj in objs]) else: - #Copying files without modifying the database. + # Copying files without modifying the database. if export: - # export(file) function copies a file without modifying the database. + # export(file) function copies a file without modifying + # the database. def export(file): # Create necessary ancestry for the copy. @@ -1490,7 +1492,7 @@ def move_items(lib, dest, query, copy, album, pretend, export=False, if album: for obj in objs: for item in obj.items(): - export(item) + export(item) else: for obj in objs: export(obj) From 3c852d3539aafa2c9ad76a72ac88416379110139 Mon Sep 17 00:00:00 2001 From: SpirosChadoulos Date: Sat, 13 May 2017 12:26:31 +0300 Subject: [PATCH 20/26] docs --- docs/reference/cli.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/reference/cli.rst b/docs/reference/cli.rst index 403c1e174..7baa25f05 100644 --- a/docs/reference/cli.rst +++ b/docs/reference/cli.rst @@ -72,7 +72,7 @@ box. To extract `rar` files, install the `rarfile`_ package and the Optional command flags: * By default, the command copies files your the library directory and - updates the ID3 tags on your music. In order to move the files, instead of + updates the ID3 tags on your music. In order to move the files, instead of copying, use the ``-m`` (move) option. If you'd like to leave your music files untouched, try the ``-C`` (don't copy) and ``-W`` (don't write tags) options. You can also disable this behavior by default in the @@ -275,6 +275,7 @@ query are renamed into your library directory structure. By specifying a destination directory with ``-d`` manually, you can move items matching a query anywhere in your filesystem. The ``-c`` option copies files instead of moving them. As with other commands, the ``-a`` option matches albums instead of items. +The ``-e`` flag (for "export") copies files without changing the database. To perform a "dry run", just use the ``-p`` (for "pretend") flag. This will show you a list of files that would be moved but won't actually change anything From 29d6c27d02e000888a747e8bdcab03a7418f5137 Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Sat, 10 Jun 2017 20:03:01 -0400 Subject: [PATCH 21/26] Fix some spurious whitespace changes --- test/test_ui.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_ui.py b/test/test_ui.py index f34cf72cb..c67c9cb55 100644 --- a/test/test_ui.py +++ b/test/test_ui.py @@ -156,6 +156,7 @@ class RemoveTest(_common.TestCase): class ModifyTest(unittest.TestCase, TestHelper): + def setUp(self): self.setup_beets() self.album = self.add_album_fixture() @@ -346,6 +347,7 @@ class ModifyTest(unittest.TestCase, TestHelper): class WriteTest(unittest.TestCase, TestHelper): + def setUp(self): self.setup_beets() @@ -1248,7 +1250,6 @@ class CommonOptionsParserCliTest(unittest.TestCase, TestHelper): """Test CommonOptionsParser and formatting LibModel formatting on 'list' command. """ - def setUp(self): self.setup_beets() self.lib = library.Library(':memory:') @@ -1445,6 +1446,5 @@ class EncodingTest(_common.TestCase): def suite(): return unittest.TestLoader().loadTestsFromName(__name__) - if __name__ == '__main__': unittest.main(defaultTest='suite') From b25eb87f6091d5c0fad0babf4efb6a15087958a5 Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Sat, 10 Jun 2017 20:05:17 -0400 Subject: [PATCH 22/26] Remove unnecessary output capture --- test/test_ui.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/test_ui.py b/test/test_ui.py index c67c9cb55..0fbec0bde 100644 --- a/test/test_ui.py +++ b/test/test_ui.py @@ -481,8 +481,6 @@ class ExportTest(_common.TestCase): def setUp(self): super(ExportTest, self).setUp() - self.io.install() - self.libdir = os.path.join(self.temp_dir, b'testlibdir') os.mkdir(self.libdir) From 231528784d32927a72afce2116b6f07baba07ee6 Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Sat, 10 Jun 2017 20:15:02 -0400 Subject: [PATCH 23/26] Simplify implementation of export behavior --- beets/ui/commands.py | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/beets/ui/commands.py b/beets/ui/commands.py index 7ffa90b11..df23f5887 100755 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -1464,6 +1464,7 @@ def move_items(lib, dest, query, copy, album, pretend, export=False, isalbummoved = lambda album: any(isitemmoved(i) for i in album.items()) objs = [o for o in objs if (isalbummoved if album else isitemmoved)(o)] + copy = copy or export # Exporting always copies. action = u'Copying' if copy else u'Moving' act = u'copy' if copy else u'move' entity = u'album' if album else u'item' @@ -1480,22 +1481,6 @@ def move_items(lib, dest, query, copy, album, pretend, export=False, show_path_changes([(obj.path, obj.destination(basedir=dest)) for obj in objs]) else: - # Copying files without modifying the database. - if export: - # export(file) function copies a file without modifying - # the database. - - def export(file): - # Create necessary ancestry for the copy. - util.mkdirall(file.destination(basedir=dest)) - util.copy(file.path, file.destination(basedir=dest)) - if album: - for obj in objs: - for item in obj.items(): - export(item) - else: - for obj in objs: - export(obj) if confirm: objs = ui.input_select_objects( u'Really %s' % act, objs, @@ -1505,8 +1490,12 @@ def move_items(lib, dest, query, copy, album, pretend, export=False, for obj in objs: log.debug(u'moving: {0}', util.displayable_path(obj.path)) - obj.move(copy, basedir=dest) - obj.store() + if export: + # Copy without affecting the database. + obj.move(True, basedir=dest, store=False) + else: + # Ordinary move/copy: store the new path. + obj.move(copy, basedir=dest) def move_func(lib, opts, args): From 714560aace0bb53af3b594fc1ee43c4f0bed2e11 Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Sat, 10 Jun 2017 20:19:27 -0400 Subject: [PATCH 24/26] Fix parameter order and binding The calls didn't match up with the parameter order. --- beets/ui/commands.py | 4 ++-- test/test_ui.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/beets/ui/commands.py b/beets/ui/commands.py index df23f5887..d95a126d1 100755 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -1450,8 +1450,8 @@ default_commands.append(modify_cmd) # move: Move/copy files to the library or a new base directory. -def move_items(lib, dest, query, copy, album, pretend, export=False, - confirm=False): +def move_items(lib, dest, query, copy, album, pretend, confirm=False, + export=False): """Moves or copies items to a new base directory, given by dest. If dest is None, then the library's base directory is used, making the command "consolidate" files. diff --git a/test/test_ui.py b/test/test_ui.py index 0fbec0bde..a24a635f3 100644 --- a/test/test_ui.py +++ b/test/test_ui.py @@ -499,7 +499,7 @@ class ExportTest(_common.TestCase): def _move(self, query=(), dest=None, copy=False, album=False, pretend=False, export=True): commands.move_items(self.lib, dest, query, copy, album, - pretend, export) + pretend, export=export) def test_export_item(self): self._move() From 730c84e5e575488afb6a0b042582737f3fc2b2ea Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Sat, 10 Jun 2017 20:24:45 -0400 Subject: [PATCH 25/26] Correct tests for export mode The old tests were wrong but the incorrectness was hidden by the incorrect parameter passing fixed in the previous commit. Now we actually test that the item's path did not change. --- test/test_ui.py | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/test/test_ui.py b/test/test_ui.py index a24a635f3..ed31570e4 100644 --- a/test/test_ui.py +++ b/test/test_ui.py @@ -501,36 +501,23 @@ class ExportTest(_common.TestCase): commands.move_items(self.lib, dest, query, copy, album, pretend, export=export) - def test_export_item(self): - self._move() - self.i.load() - self.assertTrue(b'testlibdir' in self.i.path) - self.assertExists(self.i.path) - self.assertNotExists(self.itempath) - def test_export_item_custom_dir(self): self._move(dest=self.otherdir) self.i.load() - self.assertTrue(b'testotherdir' in self.i.path) - self.assertExists(self.i.path) - self.assertNotExists(self.itempath) + self.assertEqual(self.i.path, self.itempath) + self.assertExists(self.otherdir) def test_export_album_custom_dir(self): self._move(dest=self.otherdir, album=True) self.i.load() - self.assertTrue(b'testotherdir' in self.i.path) - self.assertExists(self.i.path) - self.assertNotExists(self.itempath) + self.assertEqual(self.i.path, self.itempath) + self.assertExists(self.otherdir) def test_pretend_export_item(self): self._move(dest=self.otherdir, pretend=True) self.i.load() self.assertIn(b'srcfile', self.i.path) - - def test_pretend_export_album(self): - self._move(album=True, pretend=True) - self.i.load() - self.assertIn(b'srcfile', self.i.path) + self.assertNotExists(self.otherdir) class UpdateTest(_common.TestCase): From ca4f96e33c0f13e1a17edfc96e94293d78ed8144 Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Sat, 10 Jun 2017 20:26:41 -0400 Subject: [PATCH 26/26] Consolidate export tests into MoveTest Just one new flag. --- test/test_ui.py | 36 ++++++------------------------------ 1 file changed, 6 insertions(+), 30 deletions(-) diff --git a/test/test_ui.py b/test/test_ui.py index ed31570e4..04c033f51 100644 --- a/test/test_ui.py +++ b/test/test_ui.py @@ -421,8 +421,9 @@ class MoveTest(_common.TestCase): self.otherdir = os.path.join(self.temp_dir, b'testotherdir') def _move(self, query=(), dest=None, copy=False, album=False, - pretend=False): - commands.move_items(self.lib, dest, query, copy, album, pretend) + pretend=False, export=False): + commands.move_items(self.lib, dest, query, copy, album, pretend, + export=export) def test_move_item(self): self._move() @@ -476,45 +477,20 @@ class MoveTest(_common.TestCase): self.i.load() self.assertIn(b'srcfile', self.i.path) - -class ExportTest(_common.TestCase): - def setUp(self): - super(ExportTest, self).setUp() - - self.libdir = os.path.join(self.temp_dir, b'testlibdir') - os.mkdir(self.libdir) - - self.itempath = os.path.join(self.libdir, b'srcfile') - shutil.copy(os.path.join(_common.RSRC, b'full.mp3'), self.itempath) - - # Add a file to the library but don't copy it in yet. - self.lib = library.Library(':memory:', self.libdir) - self.i = library.Item.from_path(self.itempath) - self.lib.add(self.i) - self.album = self.lib.add_album([self.i]) - - # Alternate destination directory. - self.otherdir = os.path.join(self.temp_dir, b'testotherdir') - - def _move(self, query=(), dest=None, copy=False, album=False, - pretend=False, export=True): - commands.move_items(self.lib, dest, query, copy, album, - pretend, export=export) - def test_export_item_custom_dir(self): - self._move(dest=self.otherdir) + self._move(dest=self.otherdir, export=True) self.i.load() self.assertEqual(self.i.path, self.itempath) self.assertExists(self.otherdir) def test_export_album_custom_dir(self): - self._move(dest=self.otherdir, album=True) + self._move(dest=self.otherdir, album=True, export=True) self.i.load() self.assertEqual(self.i.path, self.itempath) self.assertExists(self.otherdir) def test_pretend_export_item(self): - self._move(dest=self.otherdir, pretend=True) + self._move(dest=self.otherdir, pretend=True, export=True) self.i.load() self.assertIn(b'srcfile', self.i.path) self.assertNotExists(self.otherdir)