From 325ae6f0eea3c69a8f7a0cd394375eeb8a7d4928 Mon Sep 17 00:00:00 2001 From: Owen Parry Date: Mon, 27 Nov 2017 07:55:38 -0800 Subject: [PATCH 01/27] Add tags configuration to acousticbrainz plugin --- beetsplug/acousticbrainz.py | 18 +++++++++++++----- docs/plugins/acousticbrainz.rst | 4 +++- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/beetsplug/acousticbrainz.py b/beetsplug/acousticbrainz.py index 4291d9117..cee765bbb 100644 --- a/beetsplug/acousticbrainz.py +++ b/beetsplug/acousticbrainz.py @@ -110,6 +110,7 @@ class AcousticPlugin(plugins.BeetsPlugin): self.config.add({ 'auto': True, 'force': False, + 'tags': [] }) if self.config['auto']: @@ -164,6 +165,7 @@ class AcousticPlugin(plugins.BeetsPlugin): def _fetch_info(self, items, write, force): """Fetch additional information from AcousticBrainz for the `item`s. """ + tags = self.config['tags'].get() for item in items: # If we're not forcing re-downloading for all tracks, check # whether the data is already present. We use one @@ -183,11 +185,17 @@ class AcousticPlugin(plugins.BeetsPlugin): data = self._get_data(item.mb_trackid) if data: for attr, val in self._map_data_to_scheme(data, ABSCHEME): - self._log.debug(u'attribute {} of {} set to {}', - attr, - item, - val) - setattr(item, attr, val) + if not tags or attr in tags: + self._log.debug(u'attribute {} of {} set to {}', + attr, + item, + val) + setattr(item, attr, val) + else: + self._log.debug(u'skipping attribute {} of {} (value {}) due to config', + attr, + item, + val) item.store() if write: item.try_write() diff --git a/docs/plugins/acousticbrainz.rst b/docs/plugins/acousticbrainz.rst index bf2102790..5bd514c64 100644 --- a/docs/plugins/acousticbrainz.rst +++ b/docs/plugins/acousticbrainz.rst @@ -54,10 +54,12 @@ Configuration ------------- To configure the plugin, make a ``acousticbrainz:`` section in your -configuration file. There is one option: +configuration file. There are three options: - **auto**: Enable AcousticBrainz during ``beet import``. Default: ``yes``. - **force**: Download AcousticBrainz data even for tracks that already have it. Default: ``no``. +- **tags**: Which tags from the list above to set on your files. + Default: [] (all) From eaa84178f71427901c6d5b22e16fa70b953446c3 Mon Sep 17 00:00:00 2001 From: Owen Parry Date: Mon, 27 Nov 2017 09:11:53 -0800 Subject: [PATCH 02/27] split long line --- beetsplug/acousticbrainz.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/beetsplug/acousticbrainz.py b/beetsplug/acousticbrainz.py index cee765bbb..982f7829c 100644 --- a/beetsplug/acousticbrainz.py +++ b/beetsplug/acousticbrainz.py @@ -192,7 +192,8 @@ class AcousticPlugin(plugins.BeetsPlugin): val) setattr(item, attr, val) else: - self._log.debug(u'skipping attribute {} of {} (value {}) due to config', + self._log.debug(u'skipping attribute {} of {} (value {})' + u' due to config', attr, item, val) From a2393e48f250719e435901966b170bc819880fa9 Mon Sep 17 00:00:00 2001 From: Owen Parry Date: Mon, 27 Nov 2017 09:15:03 -0800 Subject: [PATCH 03/27] add changelog entry for acousticbrainz 'tag' option --- docs/changelog.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index fe19403f0..e3518cba6 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -28,9 +28,9 @@ New features: before touching your files. Thanks to :user:`konman2`. :bug:`2708` :bug:`2427` -* :doc:`/plugins/lyrics`: The Genius backend should work again. - Thanks to :user:`lmagno`. - :bug:`2709` +* :doc:`/plugins/acousticbrainz`: The plugin can now be configured to write only + a specific list of tags. + Thanks to :user:`woparry`. Fixes: From 1f45ea00f49ba6a9697333204dbfd67045d5a2c6 Mon Sep 17 00:00:00 2001 From: Owen Parry Date: Sat, 2 Dec 2017 11:31:31 -0800 Subject: [PATCH 04/27] use as_str_seq and fix line length --- beetsplug/acousticbrainz.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/beetsplug/acousticbrainz.py b/beetsplug/acousticbrainz.py index 982f7829c..f4960c301 100644 --- a/beetsplug/acousticbrainz.py +++ b/beetsplug/acousticbrainz.py @@ -165,7 +165,7 @@ class AcousticPlugin(plugins.BeetsPlugin): def _fetch_info(self, items, write, force): """Fetch additional information from AcousticBrainz for the `item`s. """ - tags = self.config['tags'].get() + tags = self.config['tags'].as_str_seq() for item in items: # If we're not forcing re-downloading for all tracks, check # whether the data is already present. We use one @@ -192,8 +192,8 @@ class AcousticPlugin(plugins.BeetsPlugin): val) setattr(item, attr, val) else: - self._log.debug(u'skipping attribute {} of {} (value {})' - u' due to config', + self._log.debug(u'skipping attribute {} of {}' + u' (value {}) due to config', attr, item, val) From e848adab0490621cbc5c3b3d7f7dcad0b5932ac3 Mon Sep 17 00:00:00 2001 From: tummychow Date: Thu, 7 Dec 2017 14:46:40 -0500 Subject: [PATCH 05/27] Implement from_scratch option Fixes #934, and also helps with #1173. --- beets/config_default.yaml | 1 + beets/importer.py | 4 ++++ beets/library.py | 5 +++++ beets/ui/commands.py | 4 ++++ docs/reference/cli.rst | 6 ++++++ docs/reference/config.rst | 9 +++++++++ test/test_importer.py | 11 +++++++++++ 7 files changed, 40 insertions(+) diff --git a/beets/config_default.yaml b/beets/config_default.yaml index 439a93f55..942459738 100644 --- a/beets/config_default.yaml +++ b/beets/config_default.yaml @@ -10,6 +10,7 @@ import: delete: no resume: ask incremental: no + from_scratch: no quiet_fallback: skip none_rec_action: ask timid: no diff --git a/beets/importer.py b/beets/importer.py index e91b35656..186d824b6 100644 --- a/beets/importer.py +++ b/beets/importer.py @@ -534,6 +534,10 @@ class ImportTask(BaseImportTask): def apply_metadata(self): """Copy metadata from match info to the items. """ + if config['import']['from_scratch']: + for item in self.match.mapping: + item.clear() + autotag.apply_metadata(self.match.info, self.match.mapping) def duplicate_items(self, lib): diff --git a/beets/library.py b/beets/library.py index 597cfe625..64035e642 100644 --- a/beets/library.py +++ b/beets/library.py @@ -561,6 +561,11 @@ class Item(LibModel): if self.mtime == 0 and 'mtime' in values: self.mtime = values['mtime'] + def clear(self): + """Set all key/value pairs to None.""" + for key in self._media_fields: + setattr(self, key, None) + def get_album(self): """Get the Album object that this item belongs to, if any, or None if the item is a singleton or is not associated with a diff --git a/beets/ui/commands.py b/beets/ui/commands.py index c8beb11e2..3a1811cf3 100644 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -1004,6 +1004,10 @@ import_cmd.parser.add_option( u'-I', u'--noincremental', dest='incremental', action='store_false', help=u'do not skip already-imported directories' ) +import_cmd.parser.add_option( + u'--from-scratch', dest='from_scratch', action='store_true', + help=u'erase existing metadata before applying new metadata' +) import_cmd.parser.add_option( u'--flat', dest='flat', action='store_true', help=u'import an entire tree as a single album' diff --git a/docs/reference/cli.rst b/docs/reference/cli.rst index 3e668f013..39a4b3f10 100644 --- a/docs/reference/cli.rst +++ b/docs/reference/cli.rst @@ -111,6 +111,12 @@ Optional command flags: time, when no subdirectories will be skipped. So consider enabling the ``incremental`` configuration option. +* When beets applies metadata to your music, it will retain the value of any + existing tags that weren't overwritten, and import them into the database. You + may prefer to only use existing metadata for finding matches, and to erase it + completely when new metadata is applied. You can enforce this behavior with + the ``--from-scratch`` option, or the ``from_scratch`` configuration option. + * By default, beets will proceed without asking if it finds a very close metadata match. To disable this and have the importer ask you every time, use the ``-t`` (for *timid*) option. diff --git a/docs/reference/config.rst b/docs/reference/config.rst index ce45a94ee..a4ed96699 100644 --- a/docs/reference/config.rst +++ b/docs/reference/config.rst @@ -475,6 +475,15 @@ Either ``yes`` or ``no``, controlling whether imported directories are recorded and whether these recorded directories are skipped. This corresponds to the ``-i`` flag to ``beet import``. +.. _from_scratch: + +from_scratch +~~~~~~~~~~~~ + +Either ``yes`` or ``no`` (default), controlling whether existing metadata is +discarded when a match is applied. This corresponds to the ``-from_scratch`` +flag to ``beet import``. + quiet_fallback ~~~~~~~~~~~~~~ diff --git a/test/test_importer.py b/test/test_importer.py index c6b021f33..e30f5609c 100644 --- a/test/test_importer.py +++ b/test/test_importer.py @@ -633,6 +633,17 @@ class ImportTest(_common.TestCase, ImportHelper): self.assert_file_in_lib( b'Applied Artist', b'Applied Album', b'Applied Title 1.mp3') + def test_apply_from_scratch_removes_other_metadata(self): + config['import']['from_scratch'] = True + + for mediafile in self.import_media: + mediafile.genre = u'Tag Genre' + mediafile.save() + + self.importer.add_choice(importer.action.APPLY) + self.importer.run() + self.assertEqual(self.lib.items().get().genre, u'') + def test_apply_with_move_deletes_import(self): config['import']['move'] = True From c9b4e9b414673ec41de93e4bd70a6bfb0569b73c Mon Sep 17 00:00:00 2001 From: Constantine Evans Date: Sun, 10 Dec 2017 12:28:47 -0800 Subject: [PATCH 06/27] only use tiebreak if tiebreak includes an entry for the kind being considered, otherwise use default (eg, if only items is specified, and -a is being used, use default order of priority --- beetsplug/duplicates.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/beetsplug/duplicates.py b/beetsplug/duplicates.py index 2584e6628..6913aaef6 100644 --- a/beetsplug/duplicates.py +++ b/beetsplug/duplicates.py @@ -253,13 +253,12 @@ class DuplicatesPlugin(BeetsPlugin): "completeness" (objects with more non-null fields come first) and Albums are ordered by their track count. """ - if tiebreak: - kind = 'items' if all(isinstance(o, Item) - for o in objs) else 'albums' + kind = 'items' if all(isinstance(o, Item) for o in objs) else 'albums' + + if tiebreak and kind in tiebreak.keys(): key = lambda x: tuple(getattr(x, k) for k in tiebreak[kind]) else: - kind = Item if all(isinstance(o, Item) for o in objs) else Album - if kind is Item: + if kind is 'items': def truthy(v): # Avoid a Unicode warning by avoiding comparison # between a bytes object and the empty Unicode From 7132ad094b78ff05a3ff83638acd95fceeee8b1e Mon Sep 17 00:00:00 2001 From: Vrihub Date: Mon, 11 Dec 2017 19:32:53 +0100 Subject: [PATCH 07/27] First tentative fix for issue 2738. Don't ignore anymore filenames such as "01.mp3", instead use the number in the filename as track number. --- beetsplug/fromfilename.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/beetsplug/fromfilename.py b/beetsplug/fromfilename.py index 5e1b822c2..7e872ffa9 100644 --- a/beetsplug/fromfilename.py +++ b/beetsplug/fromfilename.py @@ -27,10 +27,6 @@ import six # Filename field extraction patterns. PATTERNS = [ - # "01 - Track 01" and "01": do nothing - r'^(\d+)\s*-\s*track\s*\d$', - r'^\d+$', - # Useful patterns. r'^(?P.+)-(?P.+)-(?P<tag>.*)$', r'^(?P<track>\d+)\s*-(?P<artist>.+)-(?P<title>.+)-(?P<tag>.*)$', @@ -45,6 +41,7 @@ PATTERNS = [ r'^(?P<track>\d+)\s*-\s*(?P<title>.+)$', r'^(?P<track>\d+)\s(?P<title>.+)$', r'^(?P<title>.+) by (?P<artist>.+)$', + r'^(?P<track>\d+).*$', ] # Titles considered "empty" and in need of replacement. From dd2b44ef20fd089fb0961a77e913ed6c033b387a Mon Sep 17 00:00:00 2001 From: Constantine Evans <cevans@evanslabs.org> Date: Mon, 11 Dec 2017 13:31:40 -0800 Subject: [PATCH 08/27] minor fixes and changelog entry --- beetsplug/duplicates.py | 4 ++-- docs/changelog.rst | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/beetsplug/duplicates.py b/beetsplug/duplicates.py index 6913aaef6..b316cfda6 100644 --- a/beetsplug/duplicates.py +++ b/beetsplug/duplicates.py @@ -258,14 +258,14 @@ class DuplicatesPlugin(BeetsPlugin): if tiebreak and kind in tiebreak.keys(): key = lambda x: tuple(getattr(x, k) for k in tiebreak[kind]) else: - if kind is 'items': + if kind == 'items': def truthy(v): # Avoid a Unicode warning by avoiding comparison # between a bytes object and the empty Unicode # string ''. return v is not None and \ (v != '' if isinstance(v, six.text_type) else True) - fields = kind.all_keys() + fields = Item.all_keys() key = lambda x: sum(1 for f in fields if truthy(getattr(x, f))) else: key = lambda x: len(x.items()) diff --git a/docs/changelog.rst b/docs/changelog.rst index edeaf8140..8752ff910 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -70,6 +70,8 @@ Fixes: Python 3 on Windows with non-ASCII filenames. :bug:`2671` * :doc:`/plugins/absubmit`: Fix an occasional crash on Python 3 when the AB analysis tool produced non-ASCII metadata. :bug:`2673` +* :doc:`/plugins/duplicates`: Use default tiebreak for any kind (item/album) that + does not have a tiebreak specified in the configuration. * :doc:`/plugins/duplicates`: Fix the `--key` command line option, which was ignored. * :doc:`/plugins/replaygain`: Fix album replaygain calculation with the From 2ba3c1bec32b81b22c582e968bcb818803873094 Mon Sep 17 00:00:00 2001 From: Adrian Sampson <adrian@radbox.org> Date: Tue, 12 Dec 2017 11:57:55 -0500 Subject: [PATCH 09/27] Add thanks & issue number for #2758 --- docs/changelog.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index 8752ff910..e5ecc2f89 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -72,6 +72,8 @@ Fixes: analysis tool produced non-ASCII metadata. :bug:`2673` * :doc:`/plugins/duplicates`: Use default tiebreak for any kind (item/album) that does not have a tiebreak specified in the configuration. + Thanks to :user:`cgevans`. + :bug:`2758` * :doc:`/plugins/duplicates`: Fix the `--key` command line option, which was ignored. * :doc:`/plugins/replaygain`: Fix album replaygain calculation with the From 0fd27e1c543ab23a4c205ba3913117f9c0fccf6e Mon Sep 17 00:00:00 2001 From: Adrian Sampson <adrian@radbox.org> Date: Sat, 16 Dec 2017 15:00:50 -0500 Subject: [PATCH 10/27] Fix tiny typo in #2755 --- 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 a4ed96699..4015a4fc2 100644 --- a/docs/reference/config.rst +++ b/docs/reference/config.rst @@ -481,7 +481,7 @@ from_scratch ~~~~~~~~~~~~ Either ``yes`` or ``no`` (default), controlling whether existing metadata is -discarded when a match is applied. This corresponds to the ``-from_scratch`` +discarded when a match is applied. This corresponds to the ``--from_scratch`` flag to ``beet import``. quiet_fallback From 31642cd7cc9327f84d67294ea0563ef3861b464c Mon Sep 17 00:00:00 2001 From: Adrian Sampson <adrian@radbox.org> Date: Sat, 16 Dec 2017 15:02:17 -0500 Subject: [PATCH 11/27] Changelog entry for #2755 (fixes #934) --- docs/changelog.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index e5ecc2f89..b220acc14 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -34,6 +34,10 @@ New features: * :doc:`/plugins/acousticbrainz`: The plugin can now be configured to write only a specific list of tags. Thanks to :user:`woparry`. +* A new :ref:`from_scratch` configuration option makes the importer remove old + metadata before applying new metadata. + Thanks to :user:`tummychow`. + :bug:`934` :bug:`2755` Fixes: From a0643dc5409a6e5b68bdcda36f4708fcf4e799e9 Mon Sep 17 00:00:00 2001 From: Michael Yoo <michael@yoo.id.au> Date: Mon, 18 Dec 2017 17:37:52 +1030 Subject: [PATCH 12/27] Remove unnecessary escape caret in ImageMagick convert argument, Fixes #2729 --- beets/util/artresizer.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/beets/util/artresizer.py b/beets/util/artresizer.py index e84b775dc..c32f0f37d 100644 --- a/beets/util/artresizer.py +++ b/beets/util/artresizer.py @@ -88,14 +88,13 @@ def im_resize(maxwidth, path_in, path_out=None): log.debug(u'artresizer: ImageMagick resizing {0} to {1}', util.displayable_path(path_in), util.displayable_path(path_out)) - # "-resize widthxheight>" shrinks images with dimension(s) larger - # than the corresponding width and/or height dimension(s). The > - # "only shrink" flag is prefixed by ^ escape char for Windows - # compatibility. + # "-resize WIDTHx>" shrinks images with the width larger + # than the given width while maintaining the aspect ratio + # with regards to the height. try: util.command_output([ 'convert', util.syspath(path_in, prefix=False), - '-resize', '{0}x^>'.format(maxwidth), + '-resize', '{0}x>'.format(maxwidth), util.syspath(path_out, prefix=False), ]) except subprocess.CalledProcessError: From 9ef0ec2a0642d9250c34cc2247dfd9dd1ef2f62f Mon Sep 17 00:00:00 2001 From: Michael Yoo <michael@yoo.id.au> Date: Tue, 19 Dec 2017 21:48:55 +1030 Subject: [PATCH 13/27] Add changelog for #2762 --- docs/changelog.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index b220acc14..5acd27f1f 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -88,6 +88,8 @@ Fixes: "Edit Candidates" option is used. :bug:`2734` * Fix a crash when numeric metadata fields contain just a minus or plus sign with no following numbers. Thanks to :user:`eigengrau`. :bug:`2741` +* Fixed an issue where images would be resized according to their longest edge, + instead of their width. Thanks to :user:`sekjun9878`. :bug:`2729` For developers: From 84cf3361cef52224be83516ebd369c4126919104 Mon Sep 17 00:00:00 2001 From: Vrihub <Vrihub@users.noreply.github.com> Date: Thu, 21 Dec 2017 14:47:41 +0100 Subject: [PATCH 14/27] Refactored some regular expressions. Added changelog entry Some more changes to the regular expressions in the "PATTERNS" list. Also allow "_" as a separator, where only "-" was allowed. Replaced similar regexps containing different combinations of \s, "-", "." with a single regexp using a set of characters [\s.\-_]. --- beetsplug/fromfilename.py | 18 ++++++------------ docs/changelog.rst | 2 ++ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/beetsplug/fromfilename.py b/beetsplug/fromfilename.py index 7e872ffa9..ea43129aa 100644 --- a/beetsplug/fromfilename.py +++ b/beetsplug/fromfilename.py @@ -28,18 +28,13 @@ import six # Filename field extraction patterns. PATTERNS = [ # Useful patterns. - r'^(?P<artist>.+)-(?P<title>.+)-(?P<tag>.*)$', - r'^(?P<track>\d+)\s*-(?P<artist>.+)-(?P<title>.+)-(?P<tag>.*)$', - r'^(?P<track>\d+)\s(?P<artist>.+)-(?P<title>.+)-(?P<tag>.*)$', - r'^(?P<artist>.+)-(?P<title>.+)$', - r'^(?P<track>\d+)\.\s*(?P<artist>.+)-(?P<title>.+)$', - r'^(?P<track>\d+)\s*-\s*(?P<artist>.+)-(?P<title>.+)$', - r'^(?P<track>\d+)\s*-(?P<artist>.+)-(?P<title>.+)$', - r'^(?P<track>\d+)\s(?P<artist>.+)-(?P<title>.+)$', + r'^(?P<artist>.+)[\-_](?P<title>.+)[\-_](?P<tag>.*)$', + r'^(?P<track>\d+)[\s.\-_]+(?P<artist>.+)[\-_](?P<title>.+)[\-_](?P<tag>.*)$', + r'^(?P<artist>.+)[\-_](?P<title>.+)$', + r'^(?P<track>\d+)[\s.\-_]+(?P<artist>.+)[\-_](?P<title>.+)$', r'^(?P<title>.+)$', - r'^(?P<track>\d+)\.\s*(?P<title>.+)$', - r'^(?P<track>\d+)\s*-\s*(?P<title>.+)$', - r'^(?P<track>\d+)\s(?P<title>.+)$', + r'^(?P<track>\d+)[\s.\-_]+(?P<title>.+)$', + r'^(?P<track>\d+)\s+(?P<title>.+)$', r'^(?P<title>.+) by (?P<artist>.+)$', r'^(?P<track>\d+).*$', ] @@ -47,7 +42,6 @@ PATTERNS = [ # Titles considered "empty" and in need of replacement. BAD_TITLE_PATTERNS = [ r'^$', - r'\d+?\s?-?\s*track\s*\d+', ] diff --git a/docs/changelog.rst b/docs/changelog.rst index edeaf8140..a5c065131 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -80,6 +80,8 @@ Fixes: "Edit Candidates" option is used. :bug:`2734` * Fix a crash when numeric metadata fields contain just a minus or plus sign with no following numbers. Thanks to :user:`eigengrau`. :bug:`2741` +* :doc:`/plugins/fromfilename`: Allow file names such as "01.mp3" to extract the track number. + Also allow "_" as a separator. Refactor some regular expressions. :bug:`2738` For developers: From 4ee5f2ca885457d6fad4439d285557234fc8b5ea Mon Sep 17 00:00:00 2001 From: Vrihub <Vrihub@users.noreply.github.com> Date: Thu, 21 Dec 2017 15:18:25 +0100 Subject: [PATCH 15/27] Fix "line too long" Travis CI error --- beetsplug/fromfilename.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/beetsplug/fromfilename.py b/beetsplug/fromfilename.py index ea43129aa..56b68f756 100644 --- a/beetsplug/fromfilename.py +++ b/beetsplug/fromfilename.py @@ -27,16 +27,16 @@ import six # Filename field extraction patterns. PATTERNS = [ - # Useful patterns. - r'^(?P<artist>.+)[\-_](?P<title>.+)[\-_](?P<tag>.*)$', - r'^(?P<track>\d+)[\s.\-_]+(?P<artist>.+)[\-_](?P<title>.+)[\-_](?P<tag>.*)$', - r'^(?P<artist>.+)[\-_](?P<title>.+)$', - r'^(?P<track>\d+)[\s.\-_]+(?P<artist>.+)[\-_](?P<title>.+)$', - r'^(?P<title>.+)$', - r'^(?P<track>\d+)[\s.\-_]+(?P<title>.+)$', - r'^(?P<track>\d+)\s+(?P<title>.+)$', - r'^(?P<title>.+) by (?P<artist>.+)$', - r'^(?P<track>\d+).*$', + # Useful patterns. + r'^(?P<artist>.+)[\-_](?P<title>.+)[\-_](?P<tag>.*)$', + r'^(?P<track>\d+)[\s.\-_]+(?P<artist>.+)[\-_](?P<title>.+)[\-_](?P<tag>.*)$', + r'^(?P<artist>.+)[\-_](?P<title>.+)$', + r'^(?P<track>\d+)[\s.\-_]+(?P<artist>.+)[\-_](?P<title>.+)$', + r'^(?P<title>.+)$', + r'^(?P<track>\d+)[\s.\-_]+(?P<title>.+)$', + r'^(?P<track>\d+)\s+(?P<title>.+)$', + r'^(?P<title>.+) by (?P<artist>.+)$', + r'^(?P<track>\d+).*$', ] # Titles considered "empty" and in need of replacement. From d939c3e648ee9ddd8d2540722f110203a0ac09d9 Mon Sep 17 00:00:00 2001 From: Adrian Sampson <adrian@radbox.org> Date: Thu, 21 Dec 2017 11:12:02 -0500 Subject: [PATCH 16/27] Expand changelog for #2759 (fix #2738) --- docs/changelog.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index dbcca7b4a..f81310467 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -88,8 +88,11 @@ Fixes: "Edit Candidates" option is used. :bug:`2734` * Fix a crash when numeric metadata fields contain just a minus or plus sign with no following numbers. Thanks to :user:`eigengrau`. :bug:`2741` -* :doc:`/plugins/fromfilename`: Allow file names such as "01.mp3" to extract the track number. - Also allow "_" as a separator. Refactor some regular expressions. :bug:`2738` +* :doc:`/plugins/fromfilename`: Recognize file names that contain *only* a + track number, such as `01.mp3`. Also, the plugin now allows underscores as a + separator between fields. + Thanks to :user:`Vrihub`. + :bug:`2738` :bug:`2759` * Fixed an issue where images would be resized according to their longest edge, instead of their width. Thanks to :user:`sekjun9878`. :bug:`2729` From 6a65722b375c98e0e281b8d7e435f90af69455f8 Mon Sep 17 00:00:00 2001 From: Adrian Sampson <adrian@radbox.org> Date: Thu, 21 Dec 2017 11:39:08 -0500 Subject: [PATCH 17/27] Switch to modd for live docs build --- docs/modd.conf | 7 +++++++ docs/serve.py | 10 ---------- 2 files changed, 7 insertions(+), 10 deletions(-) create mode 100644 docs/modd.conf delete mode 100644 docs/serve.py diff --git a/docs/modd.conf b/docs/modd.conf new file mode 100644 index 000000000..9067700d3 --- /dev/null +++ b/docs/modd.conf @@ -0,0 +1,7 @@ +**/*.rst { + prep: make html +} + +_build/html/** { + daemon: devd -m _build/html +} diff --git a/docs/serve.py b/docs/serve.py deleted file mode 100644 index 2bbf6b623..000000000 --- a/docs/serve.py +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from __future__ import division, absolute_import, print_function - -from livereload import Server, shell - -server = Server() -server.watch('*.rst', shell('make html')) -server.serve(root='_build/html') From 6ab73b38f244f0dd65e3aaa1df132cda0922bd7d Mon Sep 17 00:00:00 2001 From: Adrian Sampson <adrian@radbox.org> Date: Thu, 21 Dec 2017 11:57:07 -0500 Subject: [PATCH 18/27] Edit the changelog for release --- docs/changelog.rst | 111 +++++++++++++++++++++++++-------------------- 1 file changed, 63 insertions(+), 48 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index f81310467..56f23da49 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -4,67 +4,77 @@ Changelog 1.4.6 (in development) ---------------------- -New features: +There are some larger new features in this release: -* When the importer finds duplicate albums, you can now merge all the tracks - together and try importing them as a single album. +* When the importer finds duplicate albums, you can now merge all the + tracks---old and new---together and try importing them as a single, combined + album. Thanks to :user:`udiboy1209`. :bug:`112` :bug:`2725` * :doc:`/plugins/lyrics`: The plugin can now produce reStructuredText files for beautiful, readable books of lyrics. Thanks to :user:`anarcat`. :bug:`2628` -* :doc:`/plugins/convert`: Adds ``no_convert`` option which ignores transcoding - items matching provided query string. Thanks to :user:`Stunner`. +* A new :ref:`from_scratch` configuration option makes the importer remove old + metadata before applying new metadata. This new feature complements the + :doc:`zero </plugins/zero>` and :doc:`scrub </plugins/scrub>` plugins but is + slightly different: beets clears out all the old tags it knows about and + only keeps the new data it gets from the remote metadata source. + Thanks to :user:`tummychow`. + :bug:`934` :bug:`2755` + +There are also somewhat littler, but still great, new features: + +* :doc:`/plugins/convert`: A new ``no_convert`` option lets you skip + transcoding items matching a query. Instead, the files are just copied + as-is. Thanks to :user:`Stunner`. :bug:`2732` :bug:`2751` -* :doc:`/plugins/fetchart`: The plugin has now a quiet switch that will only - display missing album arts. Thanks to :user:`euri10`. +* :doc:`/plugins/fetchart`: A new quiet switch that only prints out messages + when album art is missing. + Thanks to :user:`euri10`. :bug:`2683` -* :doc:`/plugins/mbcollection`: The plugin now supports a custom MusicBrainz - collection via the ``collection`` configuration option. +* :doc:`/plugins/mbcollection`: You can configure a custom MusicBrainz + collection via the new ``collection`` configuration option. :bug:`2685` -* :doc:`/plugins/mbcollection`: The plugin now supports removing albums - from collections that are longer in the beets library. -* :doc:`/plugins/mpdstats`: The plugin now updates song stats when MPD switches - from a song to a stream and when it plays the same song consecutively. - :bug:`2707` +* :doc:`/plugins/mbcollection`: The collection update command can now remove + albums from collections that are longer in the beets library. * :doc:`/plugins/fetchart`: The ``clearart`` command now asks for confirmation before touching your files. Thanks to :user:`konman2`. :bug:`2708` :bug:`2427` +* :doc:`/plugins/mpdstats`: The plugin now correctly updates song statistics + when MPD switches from a song to a stream and when it plays the same song + multiple times consecutively. + :bug:`2707` * :doc:`/plugins/acousticbrainz`: The plugin can now be configured to write only a specific list of tags. Thanks to :user:`woparry`. -* A new :ref:`from_scratch` configuration option makes the importer remove old - metadata before applying new metadata. - Thanks to :user:`tummychow`. - :bug:`934` :bug:`2755` -Fixes: +There are lots and lots of bug fixes: -* :doc:`/plugins/hook`: Fixed a problem whereby accessing non-string properties of - objects such as item or album (e.g. item.track) would cause a crash. +* :doc:`/plugins/hook`: Fixed a problem where accessing non-string properties + of ``item`` or ``album`` (e.g., ``item.track``) would cause a crash. Thanks to :user:`broddo`. :bug:`2740` -* :doc:`/plugins/play`: When ``relative_to`` is set, correctly emit relative paths - even when querying for albums rather than tracks. +* :doc:`/plugins/play`: When ``relative_to`` is set, the plugin correctly + emits relative paths even when querying for albums rather than tracks. Thanks to :user:`j000`. :bug:`2702` -* Prevent Python from warning about a ``BrokenPipeError`` being ignored even - though we do take it into account. This was an issue when using beets in - simple shell scripts. +* We suppress a spurious Python warning about a ``BrokenPipeError`` being + ignored. This was an issue when using beets in simple shell scripts. Thanks to :user:`Azphreal`. :bug:`2622` :bug:`2631` * :doc:`/plugins/replaygain`: Fix a regression in the previous release related to the new R128 tags. :bug:`2615` :bug:`2623` -* :doc:`/plugins/lyrics`: The MusixMatch backend now detect and warns - the user when blocked on the server. Thanks to - :user:`anarcat`. :bug:`2634` :bug:`2632` +* :doc:`/plugins/lyrics`: The MusixMatch backend now detects and warns + when the server has blocked the client. + Thanks to :user:`anarcat`. :bug:`2634` :bug:`2632` * :doc:`/plugins/importfeeds`: Fix an error on Python 3 in certain configurations. Thanks to :user:`djl`. :bug:`2467` :bug:`2658` -* :doc:`/plugins/edit`: Fix a bug when editing items during a ``-L`` - re-import. Previously, diffs against against unrelated items could be - shown or beets could crash with a traceback. :bug:`2659` -* :doc:`/plugins/kodiupdate`: Fix server URL and add better error reporting. +* :doc:`/plugins/edit`: Fix a bug when editing items during a re-import with + the ``-L`` flag. Previously, diffs against against unrelated items could be + shown or beets could crash. :bug:`2659` +* :doc:`/plugins/kodiupdate`: Fix the server URL and add better error + reporting. :bug:`2662` * Fixed a problem where "no-op" modifications would reset files' mtimes, resulting in unnecessary writes. This most prominently affected the @@ -74,18 +84,20 @@ Fixes: Python 3 on Windows with non-ASCII filenames. :bug:`2671` * :doc:`/plugins/absubmit`: Fix an occasional crash on Python 3 when the AB analysis tool produced non-ASCII metadata. :bug:`2673` -* :doc:`/plugins/duplicates`: Use default tiebreak for any kind (item/album) that - does not have a tiebreak specified in the configuration. +* :doc:`/plugins/duplicates`: Use the default tiebreak for items or albums + when the configuration only specifies a tiebreak for the other kind of + entity. Thanks to :user:`cgevans`. :bug:`2758` -* :doc:`/plugins/duplicates`: Fix the `--key` command line option, which was +* :doc:`/plugins/duplicates`: Fix the ``--key`` command line option, which was ignored. -* :doc:`/plugins/replaygain`: Fix album replaygain calculation with the - gstreamer backend. :bug:`2636` +* :doc:`/plugins/replaygain`: Fix album ReplayGain calculation with the + GStreamer backend. :bug:`2636` * :doc:`/plugins/scrub`: Handle errors when manipulating files using newer versions of Mutagen. :bug:`2716` -* :doc:`/plugins/fetchart`: Fix: don't skip running the fetchart plugin during import, when the - "Edit Candidates" option is used. :bug:`2734` +* :doc:`/plugins/fetchart`: The plugin no longer gets skipped during import + when the "Edit Candidates" option is used from the :doc:`/plugins/edit`. + :bug:`2734` * Fix a crash when numeric metadata fields contain just a minus or plus sign with no following numbers. Thanks to :user:`eigengrau`. :bug:`2741` * :doc:`/plugins/fromfilename`: Recognize file names that contain *only* a @@ -93,19 +105,22 @@ Fixes: separator between fields. Thanks to :user:`Vrihub`. :bug:`2738` :bug:`2759` -* Fixed an issue where images would be resized according to their longest edge, - instead of their width. Thanks to :user:`sekjun9878`. :bug:`2729` +* Fixed an issue where images would be resized according to their longest + edge, instead of their width, when using the ``maxwidth`` config option in + the :doc:`/plugins/fetchart` and :doc:`/plugins/embedart`. Thanks to + :user:`sekjun9878`. :bug:`2729` +There are some changes for developers: -For developers: - -* Fixed fields in Album and Item objects are now more strict about translating +* "Fixed fields" in Album and Item objects are now more strict about translating missing values into type-specific null-like values. This should help in cases where a string field is unexpectedly `None` sometimes instead of just showing up as an empty string. :bug:`2605` -* Refactored the move functions in library.py and the `manipulate_files` function - in importer.py to use a single parameter describing the file operation instead - of multiple boolean flags. :bug:`2682` +* Refactored the move functions the `beets.library` module and the + `manipulate_files` function in `beets.importer` to use a single parameter + describing the file operation instead of multiple Boolean flags. + There is a new numerated type describing how to move, copy, or link files. + :bug:`2682` 1.4.5 (June 20, 2017) From 4488f69fede29a402e4e879ecf82aec8ed13ffa9 Mon Sep 17 00:00:00 2001 From: Adrian Sampson <adrian@radbox.org> Date: Thu, 21 Dec 2017 13:11:51 -0500 Subject: [PATCH 19/27] Changelog summary paragraph --- docs/changelog.rst | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 56f23da49..238305606 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -4,7 +4,12 @@ Changelog 1.4.6 (in development) ---------------------- -There are some larger new features in this release: +The highlight of this release is "album merging," an oft-requested option in +the importer to add new tracks to an existing album you already have in your +library. This way, you no longer need to resort to removing the partial album +from your library, combining the files manually, and importing again. + +Here are the larger new features in this release: * When the importer finds duplicate albums, you can now merge all the tracks---old and new---together and try importing them as a single, combined From 8a453b6ec8fc79ec938e302eb021cd83abf7fe51 Mon Sep 17 00:00:00 2001 From: Adrian Sampson <adrian@radbox.org> Date: Thu, 21 Dec 2017 13:12:11 -0500 Subject: [PATCH 20/27] Release date for 1.4.6 --- docs/changelog.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 238305606..d3cfa24c9 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,8 +1,8 @@ Changelog ========= -1.4.6 (in development) ----------------------- +1.4.6 (December 21, 2017) +------------------------- The highlight of this release is "album merging," an oft-requested option in the importer to add new tracks to an existing album you already have in your From 298050f369111d4752cf0e1f2c4664567a745414 Mon Sep 17 00:00:00 2001 From: Adrian Sampson <adrian@radbox.org> Date: Thu, 21 Dec 2017 13:15:54 -0500 Subject: [PATCH 21/27] Update Pandoc wrap CLI flag --- extra/release.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/release.py b/extra/release.py index ce3099a69..b0b7a96e0 100755 --- a/extra/release.py +++ b/extra/release.py @@ -166,7 +166,7 @@ def rst2md(text): """Use Pandoc to convert text from ReST to Markdown. """ pandoc = subprocess.Popen( - ['pandoc', '--from=rst', '--to=markdown', '--no-wrap'], + ['pandoc', '--from=rst', '--to=markdown', '--wrap=none'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) stdout, _ = pandoc.communicate(text.encode('utf-8')) From 61a752d234f1e7e63311bb46ca7175be33b0fc24 Mon Sep 17 00:00:00 2001 From: Adrian Sampson <adrian@radbox.org> Date: Thu, 21 Dec 2017 13:16:12 -0500 Subject: [PATCH 22/27] Version bump: 1.4.7 --- beets/__init__.py | 2 +- docs/changelog.rst | 6 ++++++ docs/conf.py | 2 +- setup.py | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/beets/__init__.py b/beets/__init__.py index ba2faec94..b8fe2a840 100644 --- a/beets/__init__.py +++ b/beets/__init__.py @@ -19,7 +19,7 @@ import os from beets.util import confit -__version__ = u'1.4.6' +__version__ = u'1.4.7' __author__ = u'Adrian Sampson <adrian@radbox.org>' diff --git a/docs/changelog.rst b/docs/changelog.rst index d3cfa24c9..bd084a890 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,6 +1,12 @@ Changelog ========= +1.4.7 (in development) +---------------------- + +Changelog goes here! + + 1.4.6 (December 21, 2017) ------------------------- diff --git a/docs/conf.py b/docs/conf.py index 9bfab940a..8f8e6f9ab 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -16,7 +16,7 @@ project = u'beets' copyright = u'2016, Adrian Sampson' version = '1.4' -release = '1.4.6' +release = '1.4.7' pygments_style = 'sphinx' diff --git a/setup.py b/setup.py index 24c571039..903f9d17f 100755 --- a/setup.py +++ b/setup.py @@ -56,7 +56,7 @@ if 'sdist' in sys.argv: setup( name='beets', - version='1.4.6', + version='1.4.7', description='music tagger and library organizer', author='Adrian Sampson', author_email='adrian@radbox.org', From 01573ce913c38567dd7fb96dfabb110816dbe21b Mon Sep 17 00:00:00 2001 From: translit <4024096+translit@users.noreply.github.com> Date: Sat, 30 Dec 2017 01:21:35 +0100 Subject: [PATCH 23/27] Word swap --- docs/plugins/thumbnails.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plugins/thumbnails.rst b/docs/plugins/thumbnails.rst index 67f83ce98..5753a9f7e 100644 --- a/docs/plugins/thumbnails.rst +++ b/docs/plugins/thumbnails.rst @@ -1,7 +1,7 @@ Thumbnails Plugin ================== -The ``thumbnails`` plugin creates thumbnails your for album folders with the +The ``thumbnails`` plugin creates thumbnails for your album folders with the album cover. This works on freedesktop.org-compliant file managers such as Nautilus or Thunar, and is therefore POSIX-only. From 3b491ce9b455bf2d07048a341280677869ee7113 Mon Sep 17 00:00:00 2001 From: Nicolas Guillaumin <nicolas+github@guillaumin.me> Date: Sat, 30 Dec 2017 12:16:39 -0800 Subject: [PATCH 24/27] Fixes #2688: Skip non-audio media from MusicBrainz Some releases have non-audio media, such as CD+DVD or CD+DVD-Video. Skip these media when fetching album info as they will never match audio tracks and will always report missing tracks. I took the naive approach of cherry-picking a list of media suspected to not contain audio from the MusicBrainz formats list: https://musicbrainz.org/doc/Release/Format --- beets/autotag/mb.py | 6 ++++++ docs/changelog.rst | 3 +++ test/test_mb.py | 25 +++++++++++++++++++++++-- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/beets/autotag/mb.py b/beets/autotag/mb.py index 5c484d2b3..b5ed4f358 100644 --- a/beets/autotag/mb.py +++ b/beets/autotag/mb.py @@ -36,6 +36,9 @@ if util.SNI_SUPPORTED: else: BASE_URL = 'http://musicbrainz.org/' +NON_AUDIO_FORMATS = ['Data CD', 'DVD', 'DVD-Video', 'Blu-ray', 'HD-DVD', 'VCD', + 'SVCD', 'UMD', 'VHS'] + musicbrainzngs.set_useragent('beets', beets.__version__, 'http://beets.io/') @@ -275,6 +278,9 @@ def album_info(release): disctitle = medium.get('title') format = medium.get('format') + if format in NON_AUDIO_FORMATS: + continue + all_tracks = medium['track-list'] if 'pregap' in medium: all_tracks.insert(0, medium['pregap']) diff --git a/docs/changelog.rst b/docs/changelog.rst index bd084a890..2a7349d65 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -6,6 +6,9 @@ Changelog Changelog goes here! +Fixes: +* Non-audio media (DVD-Video, etc.) are now skipped by the autotagger. :bug:`2688` + 1.4.6 (December 21, 2017) ------------------------- diff --git a/test/test_mb.py b/test/test_mb.py index ca1bf2a1a..9c51d0fe3 100644 --- a/test/test_mb.py +++ b/test/test_mb.py @@ -27,7 +27,7 @@ import mock class MBAlbumInfoTest(_common.TestCase): def _make_release(self, date_str='2009', tracks=None, track_length=None, - track_artist=False): + track_artist=False, medium_format='FORMAT'): release = { 'title': 'ALBUM TITLE', 'id': 'ALBUM ID', @@ -90,7 +90,7 @@ class MBAlbumInfoTest(_common.TestCase): release['medium-list'].append({ 'position': '1', 'track-list': track_list, - 'format': 'FORMAT', + 'format': medium_format, 'title': 'MEDIUM TITLE', }) return release @@ -324,6 +324,27 @@ class MBAlbumInfoTest(_common.TestCase): d = mb.album_info(release) self.assertEqual(d.data_source, 'MusicBrainz') + def test_skip_non_audio_dvd(self): + tracks = [self._make_track('TITLE ONE', 'ID ONE', 100.0 * 1000.0), + self._make_track('TITLE TWO', 'ID TWO', 200.0 * 1000.0)] + release = self._make_release(tracks=tracks, medium_format="DVD") + d = mb.album_info(release) + self.assertEqual(len(d.tracks), 0) + + def test_skip_non_audio_dvd_video(self): + tracks = [self._make_track('TITLE ONE', 'ID ONE', 100.0 * 1000.0), + self._make_track('TITLE TWO', 'ID TWO', 200.0 * 1000.0)] + release = self._make_release(tracks=tracks, medium_format="DVD-Video") + d = mb.album_info(release) + self.assertEqual(len(d.tracks), 0) + + def test_no_skip_dvd_audio(self): + tracks = [self._make_track('TITLE ONE', 'ID ONE', 100.0 * 1000.0), + self._make_track('TITLE TWO', 'ID TWO', 200.0 * 1000.0)] + release = self._make_release(tracks=tracks, medium_format="DVD-Audio") + d = mb.album_info(release) + self.assertEqual(len(d.tracks), 2) + class ParseIDTest(_common.TestCase): def test_parse_id_correct(self): From 71b4d5c7023a8c20d1308f05a70ba1d6f7882949 Mon Sep 17 00:00:00 2001 From: Nicolas Guillaumin <nicolas+github@guillaumin.me> Date: Sat, 30 Dec 2017 19:18:07 -0800 Subject: [PATCH 25/27] Fixes #1210: Skip non-audio tracks from MusicBrainz This ignores non-audio tracks during import: - Data tracks, based on their title `[data track]` (which seems to be the MusicBrainz convention, as there's no specific flag to indicate that a track is a data one), - Video tracks, based on the `video=true` attribute. It's similar to the Picard changes mentioned in #1210, except it doesn't deal with `[silence]` tracks: These ones will probably require a setting to let the user control if they should be imported or not. --- beets/autotag/mb.py | 11 +++++++++++ docs/changelog.rst | 3 +++ test/test_mb.py | 26 +++++++++++++++++++++++++- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/beets/autotag/mb.py b/beets/autotag/mb.py index b5ed4f358..6cf2818fd 100644 --- a/beets/autotag/mb.py +++ b/beets/autotag/mb.py @@ -39,6 +39,8 @@ else: NON_AUDIO_FORMATS = ['Data CD', 'DVD', 'DVD-Video', 'Blu-ray', 'HD-DVD', 'VCD', 'SVCD', 'UMD', 'VHS'] +SKIPPED_TRACKS = ['[data track]'] + musicbrainzngs.set_useragent('beets', beets.__version__, 'http://beets.io/') @@ -286,6 +288,15 @@ def album_info(release): all_tracks.insert(0, medium['pregap']) for track in all_tracks: + + if ('title' in track['recording'] and + track['recording']['title'] in SKIPPED_TRACKS): + continue + + if ('video' in track['recording'] and + track['recording']['video'] == 'true'): + continue + # Basic information from the recording. index += 1 ti = track_info( diff --git a/docs/changelog.rst b/docs/changelog.rst index 2a7349d65..4ff54b222 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -7,7 +7,10 @@ Changelog Changelog goes here! Fixes: + * Non-audio media (DVD-Video, etc.) are now skipped by the autotagger. :bug:`2688` +* Non-audio tracks (data tracks, video tracks, etc.) are now skipped by the + autotagger. :bug:`1210` 1.4.6 (December 21, 2017) diff --git a/test/test_mb.py b/test/test_mb.py index 9c51d0fe3..4683793f4 100644 --- a/test/test_mb.py +++ b/test/test_mb.py @@ -95,7 +95,7 @@ class MBAlbumInfoTest(_common.TestCase): }) return release - def _make_track(self, title, tr_id, duration, artist=False): + def _make_track(self, title, tr_id, duration, artist=False, video=False): track = { 'title': title, 'id': tr_id, @@ -113,6 +113,8 @@ class MBAlbumInfoTest(_common.TestCase): 'name': 'RECORDING ARTIST CREDIT', } ] + if video: + track['video'] = 'true' return track def test_parse_release_with_year(self): @@ -345,6 +347,28 @@ class MBAlbumInfoTest(_common.TestCase): d = mb.album_info(release) self.assertEqual(len(d.tracks), 2) + def test_skip_data_track(self): + tracks = [self._make_track('TITLE ONE', 'ID ONE', 100.0 * 1000.0), + self._make_track('[data track]', 'ID DATA TRACK', + 100.0 * 1000.0), + self._make_track('TITLE TWO', 'ID TWO', 200.0 * 1000.0)] + release = self._make_release(tracks=tracks) + d = mb.album_info(release) + self.assertEqual(len(d.tracks), 2) + self.assertEqual(d.tracks[0].title, 'TITLE ONE') + self.assertEqual(d.tracks[1].title, 'TITLE TWO') + + def test_skip_video_track(self): + tracks = [self._make_track('TITLE ONE', 'ID ONE', 100.0 * 1000.0), + self._make_track('TITLE VIDEO', 'ID VIDEO', 100.0 * 1000.0, + False, True), + self._make_track('TITLE TWO', 'ID TWO', 200.0 * 1000.0)] + release = self._make_release(tracks=tracks) + d = mb.album_info(release) + self.assertEqual(len(d.tracks), 2) + self.assertEqual(d.tracks[0].title, 'TITLE ONE') + self.assertEqual(d.tracks[1].title, 'TITLE TWO') + class ParseIDTest(_common.TestCase): def test_parse_id_correct(self): From d325bceb1d2d3d8d863839ac3258faa609401cec Mon Sep 17 00:00:00 2001 From: Nicolas Guillaumin <nicolas+github@guillaumin.me> Date: Sun, 31 Dec 2017 10:46:48 -0800 Subject: [PATCH 26/27] Added a setting to control if video tracks are ignored Users may want to keep tracking video tracks, for example if they rip the audio part of the video tracks. Added a setting to allow this. --- beets/autotag/mb.py | 3 ++- beets/config_default.yaml | 1 + docs/reference/config.rst | 11 +++++++++++ test/test_mb.py | 15 ++++++++++++++- 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/beets/autotag/mb.py b/beets/autotag/mb.py index 6cf2818fd..e32f73329 100644 --- a/beets/autotag/mb.py +++ b/beets/autotag/mb.py @@ -294,7 +294,8 @@ def album_info(release): continue if ('video' in track['recording'] and - track['recording']['video'] == 'true'): + track['recording']['video'] == 'true' and + config['match']['ignore_video_tracks'].get(bool) is True): continue # Basic information from the recording. diff --git a/beets/config_default.yaml b/beets/config_default.yaml index 942459738..01c1e0f65 100644 --- a/beets/config_default.yaml +++ b/beets/config_default.yaml @@ -126,5 +126,6 @@ match: original_year: no ignored: [] required: [] + ignore_video_tracks: yes track_length_grace: 10 track_length_max: 30 diff --git a/docs/reference/config.rst b/docs/reference/config.rst index 4015a4fc2..84f41a385 100644 --- a/docs/reference/config.rst +++ b/docs/reference/config.rst @@ -774,6 +774,17 @@ want to enforce to the ``required`` setting:: No tags are required by default. +.. _ignore_video_tracks: + +ignore_video_tracks +~~~~~~~~~~~~~~~~~~~ + +By default, video tracks within a release will be ignored. If you want them to +be included (for example if you would like to track the audio-only versions of +the video tracks), set it to ``no``. + +Default: ``yes``. + .. _path-format-config: Path Format Configuration diff --git a/test/test_mb.py b/test/test_mb.py index 4683793f4..35f7c3aa2 100644 --- a/test/test_mb.py +++ b/test/test_mb.py @@ -358,7 +358,7 @@ class MBAlbumInfoTest(_common.TestCase): self.assertEqual(d.tracks[0].title, 'TITLE ONE') self.assertEqual(d.tracks[1].title, 'TITLE TWO') - def test_skip_video_track(self): + def test_skip_video_tracks_by_default(self): tracks = [self._make_track('TITLE ONE', 'ID ONE', 100.0 * 1000.0), self._make_track('TITLE VIDEO', 'ID VIDEO', 100.0 * 1000.0, False, True), @@ -369,6 +369,19 @@ class MBAlbumInfoTest(_common.TestCase): self.assertEqual(d.tracks[0].title, 'TITLE ONE') self.assertEqual(d.tracks[1].title, 'TITLE TWO') + def test_no_skip_video_tracks_if_configured(self): + config['match']['ignore_video_tracks'] = False + tracks = [self._make_track('TITLE ONE', 'ID ONE', 100.0 * 1000.0), + self._make_track('TITLE VIDEO', 'ID VIDEO', 100.0 * 1000.0, + False, True), + self._make_track('TITLE TWO', 'ID TWO', 200.0 * 1000.0)] + release = self._make_release(tracks=tracks) + d = mb.album_info(release) + self.assertEqual(len(d.tracks), 3) + self.assertEqual(d.tracks[0].title, 'TITLE ONE') + self.assertEqual(d.tracks[1].title, 'TITLE VIDEO') + self.assertEqual(d.tracks[2].title, 'TITLE TWO') + class ParseIDTest(_common.TestCase): def test_parse_id_correct(self): From da8e17d2df040ffa4336ae8d8ffc74861b30c584 Mon Sep 17 00:00:00 2001 From: Nicolas Guillaumin <nicolas+github@guillaumin.me> Date: Sun, 31 Dec 2017 14:24:36 -0800 Subject: [PATCH 27/27] Simplify boolean check --- beets/autotag/mb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beets/autotag/mb.py b/beets/autotag/mb.py index e32f73329..eb7c30808 100644 --- a/beets/autotag/mb.py +++ b/beets/autotag/mb.py @@ -295,7 +295,7 @@ def album_info(release): if ('video' in track['recording'] and track['recording']['video'] == 'true' and - config['match']['ignore_video_tracks'].get(bool) is True): + config['match']['ignore_video_tracks']): continue # Basic information from the recording.