support move action when importing

This commit is contained in:
Domen Kožar 2012-04-05 01:14:17 +02:00
parent 009596d0af
commit 1af4f86c17
6 changed files with 48 additions and 10 deletions

View file

@ -259,7 +259,7 @@ class ImportConfig(object):
then never touched again.
"""
_fields = ['lib', 'paths', 'resume', 'logfile', 'color', 'quiet',
'quiet_fallback', 'copy', 'write', 'art', 'delete',
'quiet_fallback', 'copy', 'move', 'write', 'art', 'delete',
'choose_match_func', 'should_resume_func', 'threaded',
'autot', 'singletons', 'timid', 'choose_item_func',
'query', 'incremental', 'ignore',
@ -697,16 +697,20 @@ def apply_choices(config):
# Move/copy files.
task.old_paths = [item.path for item in items]
for item in items:
if config.copy:
if config.copy or config.move:
# If we're replacing an item, then move rather than
# copying.
old_path = item.path
do_copy = not bool(replaced_items[item])
lib.move(item, do_copy, task.is_album)
if config.move:
lib.move(item, False, task.is_album)
else:
lib.move(item, do_copy, task.is_album)
if not do_copy:
# If we moved the item, remove the now-nonexistent
# file from old_paths.
task.old_paths.remove(old_path)
if config.write and task.should_write_tags():
item.write()

View file

@ -87,6 +87,7 @@ def _showdiff(field, oldval, newval, color):
# import: Autotagger and importer.
DEFAULT_IMPORT_COPY = True
DEFAULT_IMPORT_MOVE = False
DEFAULT_IMPORT_WRITE = True
DEFAULT_IMPORT_DELETE = False
DEFAULT_IMPORT_AUTOT = True
@ -598,7 +599,7 @@ def resolve_duplicate(task, config):
# The import command.
def import_files(lib, paths, copy, write, autot, logpath, art, threaded,
def import_files(lib, paths, copy, move, write, autot, logpath, art, threaded,
color, delete, quiet, resume, quiet_fallback, singletons,
timid, query, incremental, ignore):
"""Import the files in the given list of paths, tagging each leaf
@ -655,6 +656,7 @@ def import_files(lib, paths, copy, write, autot, logpath, art, threaded,
quiet = quiet,
quiet_fallback = quiet_fallback,
copy = copy,
move = move,
write = write,
art = art,
delete = delete,
@ -686,6 +688,8 @@ import_cmd.parser.add_option('-c', '--copy', action='store_true',
default=None, help="copy tracks into library directory (default)")
import_cmd.parser.add_option('-C', '--nocopy', action='store_false',
dest='copy', help="don't copy tracks (opposite of -c)")
import_cmd.parser.add_option('-m', '--move', action='store_true',
default=None, help="move tracks into library directory")
import_cmd.parser.add_option('-w', '--write', action='store_true',
default=None, help="write new metadata to files' tags (default)")
import_cmd.parser.add_option('-W', '--nowrite', action='store_false',
@ -719,6 +723,9 @@ def import_func(lib, config, opts, args):
copy = opts.copy if opts.copy is not None else \
ui.config_val(config, 'beets', 'import_copy',
DEFAULT_IMPORT_COPY, bool)
move = opts.move if opts.move is not None else \
ui.config_val(config, 'beets', 'import_move',
DEFAULT_IMPORT_MOVE, bool)
write = opts.write if opts.write is not None else \
ui.config_val(config, 'beets', 'import_write',
DEFAULT_IMPORT_WRITE, bool)
@ -768,7 +775,7 @@ def import_func(lib, config, opts, args):
query = None
paths = args
import_files(lib, paths, copy, write, autot, logpath, art, threaded,
import_files(lib, paths, copy, move, write, autot, logpath, art, threaded,
color, delete, quiet, resume, quiet_fallback, singletons,
timid, query, incremental, ignore)
import_cmd.func = import_func

View file

@ -24,6 +24,10 @@ section header:
directory when using ``beet import``. Defaults to ``yes``. Can be
overridden with the ``-c`` and ``-C`` command-line options.
``import_move``
Either ``yes`` or ``no``, indicating whether to move files into the library
directory when using ``beet import``. Defaults to ``no``.
``import_write``
Either ``yes`` or ``no``, controlling whether metadata (e.g., ID3) tags are
written to files when using ``beet import``. Defaults to ``yes``. The ``-w``

View file

@ -82,6 +82,7 @@ def iconfig(lib, **kwargs):
quiet = True,
quiet_fallback = importer.action.SKIP,
copy = True,
move = False,
write = False,
art = False,
delete = False,

View file

@ -69,7 +69,7 @@ class NonAutotaggedImportTest(unittest.TestCase):
return realpath
def _run_import(self, titles=TEST_TITLES, delete=False, threaded=False,
singletons=False):
singletons=False, move=False):
# Make a bunch of tracks to import.
paths = []
for i, title in enumerate(titles):
@ -86,7 +86,8 @@ class NonAutotaggedImportTest(unittest.TestCase):
importer.run_import(
lib=self.lib,
paths=[os.path.dirname(paths[0])],
copy=True,
copy=not move,
move=move,
write=True,
autot=False,
logfile=None,
@ -125,12 +126,33 @@ class NonAutotaggedImportTest(unittest.TestCase):
filenames = set(os.listdir(album_folder))
destinations = set('%s.mp3' % title for title in TEST_TITLES)
self.assertEqual(filenames, destinations)
def test_import_copy_arrives(self):
self._run_import()
paths = self._run_import()
self._copy_arrives()
for path in paths:
self.assertTrue(os.path.exists(path))
def test_threaded_import_copy_arrives(self):
self._run_import(threaded=True)
paths = self._run_import(threaded=True)
self._copy_arrives()
for path in paths:
self.assertTrue(os.path.exists(path))
def test_import_move(self):
paths = self._run_import(move=True)
self._copy_arrives()
for path in paths:
self.assertFalse(os.path.exists(path))
def test_threaded_import_move(self):
paths = self._run_import(threaded=True, move=True)
self._copy_arrives()
for path in paths:
self.assertFalse(os.path.exists(path))
def test_import_no_delete(self):
paths = self._run_import(['sometrack'], delete=False)

View file

@ -470,7 +470,7 @@ class AutotagTest(unittest.TestCase):
class ImportTest(unittest.TestCase):
def test_quiet_timid_disallowed(self):
self.assertRaises(ui.UserError, commands.import_files,
None, [], False, False, False, None, False, False,
None, [], False, False, False, False, None, False, False,
False, False, True, False, None, False, True, None,
False, [])