From a73ad99dd80378e48dc9219e8ba18cc82918b218 Mon Sep 17 00:00:00 2001 From: Dixon Xavier Date: Sun, 19 Jun 2016 12:53:37 +0530 Subject: [PATCH 01/11] Add new importer configuration to deal with duplicate items --- beets/config_default.yaml | 1 + beets/importer.py | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/beets/config_default.yaml b/beets/config_default.yaml index 4c12c3df0..fa77a82dc 100644 --- a/beets/config_default.yaml +++ b/beets/config_default.yaml @@ -23,6 +23,7 @@ import: group_albums: no pretend: false search_ids: [] + duplicate_action: ask clutter: ["Thumbs.DB", ".DS_Store"] ignore: [".*", "*~", "System Volume Information", "lost+found"] diff --git a/beets/importer.py b/beets/importer.py index 4209a4831..25daefe4e 100644 --- a/beets/importer.py +++ b/beets/importer.py @@ -1327,7 +1327,24 @@ def resolve_duplicates(session, task): log.debug(u'found duplicates: {}'.format( [o.id for o in found_duplicates] )) - session.resolve_duplicate(task, found_duplicates) + + # Get the default action to follow from config. + duplicate_action = config['import']['duplicate_action'].get() + log.debug(u'default action for duplicates: {0}', duplicate_action) + + if duplicate_action == 'skip': + # Skip new. + task.set_choice(action.SKIP) + elif duplicate_action == 'keep': + # Keep both. Do nothing; leave the choice intact. + pass + elif duplicate_action == 'remove': + # Remove old. + task.should_remove_duplicates = True + else: + # No default action set; ask the session. + session.resolve_duplicate(task, found_duplicates) + session.log_choice(task, True) From fbcc8dbf1ec4e6354e5b75214126da924f8edc0c Mon Sep 17 00:00:00 2001 From: Dixon Xavier Date: Sun, 19 Jun 2016 12:54:27 +0530 Subject: [PATCH 02/11] Update changelog and documentation --- docs/changelog.rst | 2 ++ docs/reference/config.rst | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index 64b582450..b350381af 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -8,6 +8,8 @@ New features: * A new ``--force`` option for :ref:`remove-cmd` allows removal of items without prompting beforehand. :bug:`2042` +* A new importer configuration :ref:`duplicate_action` controls how + duplicate albums or tracks treated in import task. :bug:`185` Some fixes for Windows: diff --git a/docs/reference/config.rst b/docs/reference/config.rst index 4ca54652a..11310ac0c 100644 --- a/docs/reference/config.rst +++ b/docs/reference/config.rst @@ -550,6 +550,17 @@ with the ``-a`` flag to the :ref:`import-cmd` command.) Default: ``yes``. +.. _duplicate_action + +duplicate_action +~~~~~~~~~~~~~~~~ + +Either ``skip``, ``keep``, ``remove``, or ``ask``. Controls how duplicates +are treated in import task. "skip" means that new item(album or track) will be +skiped; "keep" means keep both old and new items; "remove" means remove old +item; "ask" means the user should be prompted for the action each time. +The default is ``ask``. + .. _musicbrainz-config: From 80ca527f76d75aa549b3e2f6654fec65de1fdd3f Mon Sep 17 00:00:00 2001 From: Dixon Xavier Date: Sun, 19 Jun 2016 13:20:54 +0530 Subject: [PATCH 03/11] Fix typo in documentation --- docs/reference/config.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/config.rst b/docs/reference/config.rst index 11310ac0c..0892aaa30 100644 --- a/docs/reference/config.rst +++ b/docs/reference/config.rst @@ -550,7 +550,7 @@ with the ``-a`` flag to the :ref:`import-cmd` command.) Default: ``yes``. -.. _duplicate_action +.. _duplicate_action: duplicate_action ~~~~~~~~~~~~~~~~ From 366a6d7fb29708e7380a500ceff4af1b79af997d Mon Sep 17 00:00:00 2001 From: Dixon Xavier Date: Mon, 20 Jun 2016 00:35:47 +0530 Subject: [PATCH 04/11] add validation for configuration --- beets/importer.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/beets/importer.py b/beets/importer.py index 25daefe4e..120a3ddb8 100644 --- a/beets/importer.py +++ b/beets/importer.py @@ -1329,16 +1329,21 @@ def resolve_duplicates(session, task): )) # Get the default action to follow from config. - duplicate_action = config['import']['duplicate_action'].get() + duplicate_action = config['import']['duplicate_action'].as_choice({ + u'skip': u's', + u'keep': u'k', + u'remove': u'r', + u'ask' : u'a', + }) log.debug(u'default action for duplicates: {0}', duplicate_action) - if duplicate_action == 'skip': + if duplicate_action == u's': # Skip new. task.set_choice(action.SKIP) - elif duplicate_action == 'keep': + elif duplicate_action == u'k': # Keep both. Do nothing; leave the choice intact. pass - elif duplicate_action == 'remove': + elif duplicate_action == u'r': # Remove old. task.should_remove_duplicates = True else: From 4d75d4c06326f8e3a83bf75f5fb8c51f34b40b34 Mon Sep 17 00:00:00 2001 From: Dixon Xavier Date: Mon, 20 Jun 2016 00:52:09 +0530 Subject: [PATCH 05/11] Fix lint error --- beets/importer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beets/importer.py b/beets/importer.py index 120a3ddb8..60aeb2f2b 100644 --- a/beets/importer.py +++ b/beets/importer.py @@ -1333,7 +1333,7 @@ def resolve_duplicates(session, task): u'skip': u's', u'keep': u'k', u'remove': u'r', - u'ask' : u'a', + u'ask': u'a', }) log.debug(u'default action for duplicates: {0}', duplicate_action) From 09322530ca35b2571783ab69f4128447a61f54e8 Mon Sep 17 00:00:00 2001 From: Johnny Robeson Date: Sun, 19 Jun 2016 22:30:58 -0400 Subject: [PATCH 06/11] replace 2 map() calls with a list comprehension --- beets/importer.py | 2 +- beetsplug/info.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/beets/importer.py b/beets/importer.py index 60aeb2f2b..072c2ad5b 100644 --- a/beets/importer.py +++ b/beets/importer.py @@ -331,7 +331,7 @@ class ImportSession(object): been imported in a previous session. """ if self.is_resuming(toppath) \ - and all(map(lambda p: progress_element(toppath, p), paths)): + and all([progress_element(toppath, p) for p in paths]): return True if self.config['incremental'] \ and tuple(paths) in self.history_dirs: diff --git a/beetsplug/info.py b/beetsplug/info.py index 29bff7a29..d29d9b45f 100644 --- a/beetsplug/info.py +++ b/beetsplug/info.py @@ -230,7 +230,7 @@ def make_key_filter(include): def filter_(data): filtered = dict() for key, value in data.items(): - if any(map(lambda m: m.match(key), matchers)): + if any([m.match(key) for m in matchers]): filtered[key] = value return filtered From e1ede6827bfd204e2d53ec289881c8d9116a56b1 Mon Sep 17 00:00:00 2001 From: Johnny Robeson Date: Sun, 19 Jun 2016 22:33:40 -0400 Subject: [PATCH 07/11] replace a filter() on search_ids with a list comp --- beets/autotag/match.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beets/autotag/match.py b/beets/autotag/match.py index 9870f157f..ba657cedb 100644 --- a/beets/autotag/match.py +++ b/beets/autotag/match.py @@ -462,7 +462,7 @@ def tag_item(item, search_artist=None, search_title=None, candidates = {} # First, try matching by MusicBrainz ID. - trackids = search_ids or filter(None, [item.mb_trackid]) + trackids = search_ids or [t for t in [item.mb_trackid] if t] if trackids: for trackid in trackids: log.debug(u'Searching for track ID: {0}', trackid) From 705557a5d269bfdea5fd084b72efeb8df64d3aa3 Mon Sep 17 00:00:00 2001 From: Johnny Robeson Date: Sun, 19 Jun 2016 22:55:31 -0400 Subject: [PATCH 08/11] add six as a new dependency for beets --- setup.py | 1 + tox.ini | 1 + 2 files changed, 2 insertions(+) diff --git a/setup.py b/setup.py index c0cf15354..0ec655730 100755 --- a/setup.py +++ b/setup.py @@ -86,6 +86,7 @@ setup( }, install_requires=[ + 'six', 'enum34>=1.0.4', 'mutagen>=1.27', 'munkres', diff --git a/tox.ini b/tox.ini index 22d4aba2a..fe05a52fa 100644 --- a/tox.ini +++ b/tox.ini @@ -24,6 +24,7 @@ deps = jellyfish python-mpd2 coverage + six [_flake8] deps = From 196176f1802e4b4d62b530ea8a5aafb7864248f8 Mon Sep 17 00:00:00 2001 From: Johnny Robeson Date: Sun, 19 Jun 2016 22:56:14 -0400 Subject: [PATCH 09/11] use six.integer_types in library --- beets/library.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/beets/library.py b/beets/library.py index b9d9d4ffc..93441ef9c 100644 --- a/beets/library.py +++ b/beets/library.py @@ -23,6 +23,7 @@ import unicodedata import time import re from unidecode import unidecode +import six from beets import logging from beets.mediafile import MediaFile, MutagenError, UnreadableFileError @@ -565,7 +566,7 @@ class Item(LibModel): for key in self._media_fields: value = getattr(mediafile, key) - if isinstance(value, (int, long)): + if isinstance(value, six.integer_types): if value.bit_length() > 63: value = 0 self[key] = value From ae4fd64d3a5fba39731abd2ba05d085f4d4a456c Mon Sep 17 00:00:00 2001 From: Johnny Robeson Date: Mon, 20 Jun 2016 00:15:28 -0400 Subject: [PATCH 10/11] Revert "use six.integer_types in library" for now It will return post bugfix release This reverts commit 196176f1802e4b4d62b530ea8a5aafb7864248f8. --- beets/library.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/beets/library.py b/beets/library.py index 93441ef9c..b9d9d4ffc 100644 --- a/beets/library.py +++ b/beets/library.py @@ -23,7 +23,6 @@ import unicodedata import time import re from unidecode import unidecode -import six from beets import logging from beets.mediafile import MediaFile, MutagenError, UnreadableFileError @@ -566,7 +565,7 @@ class Item(LibModel): for key in self._media_fields: value = getattr(mediafile, key) - if isinstance(value, six.integer_types): + if isinstance(value, (int, long)): if value.bit_length() > 63: value = 0 self[key] = value From 5208cfcaed09059ac64cf653fd5022585f2e4887 Mon Sep 17 00:00:00 2001 From: Johnny Robeson Date: Mon, 20 Jun 2016 00:16:18 -0400 Subject: [PATCH 11/11] Revert "add six as a new dependency for beets" for now It will return after the next bugfix release This reverts commit 705557a5d269bfdea5fd084b72efeb8df64d3aa3. --- setup.py | 1 - tox.ini | 1 - 2 files changed, 2 deletions(-) diff --git a/setup.py b/setup.py index 0ec655730..c0cf15354 100755 --- a/setup.py +++ b/setup.py @@ -86,7 +86,6 @@ setup( }, install_requires=[ - 'six', 'enum34>=1.0.4', 'mutagen>=1.27', 'munkres', diff --git a/tox.ini b/tox.ini index fe05a52fa..22d4aba2a 100644 --- a/tox.ini +++ b/tox.ini @@ -24,7 +24,6 @@ deps = jellyfish python-mpd2 coverage - six [_flake8] deps =