diff --git a/beets/autotag/mb.py b/beets/autotag/mb.py index 9ce449a8b..268baf766 100644 --- a/beets/autotag/mb.py +++ b/beets/autotag/mb.py @@ -281,6 +281,10 @@ def album_info(release): continue all_tracks = medium['track-list'] + if 'data-track-list' in medium: + all_tracks += medium['data-track-list'] + track_count = len(all_tracks) + if 'pregap' in medium: all_tracks.insert(0, medium['pregap']) @@ -302,7 +306,7 @@ def album_info(release): index, int(medium['position']), int(track['position']), - len(medium['track-list']), + track_count, ) ti.disctitle = disctitle ti.media = format diff --git a/docs/changelog.rst b/docs/changelog.rst index 12fee62c8..8b49b97a1 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -103,6 +103,9 @@ Fixes: to which a track belongs, not the total number of different mediums present on the release. :bug:`2887` Thanks to :user:`dbogdanov`. +* The importer now supports audio files contained in data tracks when they are + listed in MusicBrainz: the corresponding audio tracks are now merged into the + main track list. Thanks to :user:`jdetrey`. :bug:`1638` * :doc:`/plugins/keyfinder`: Avoid a crash when trying to process unmatched tracks. :bug:`2537` diff --git a/test/test_mb.py b/test/test_mb.py index 644e7f5de..55df22944 100644 --- a/test/test_mb.py +++ b/test/test_mb.py @@ -27,7 +27,8 @@ import mock class MBAlbumInfoTest(_common.TestCase): def _make_release(self, date_str='2009', tracks=None, track_length=None, - track_artist=False, medium_format='FORMAT'): + track_artist=False, data_tracks=None, + medium_format='FORMAT'): release = { 'title': 'ALBUM TITLE', 'id': 'ALBUM ID', @@ -62,8 +63,8 @@ class MBAlbumInfoTest(_common.TestCase): 'country': 'COUNTRY', 'status': 'STATUS', } + track_list = [] if tracks: - track_list = [] for i, recording in enumerate(tracks): track = { 'recording': recording, @@ -87,12 +88,22 @@ class MBAlbumInfoTest(_common.TestCase): } ] track_list.append(track) - release['medium-list'].append({ - 'position': '1', - 'track-list': track_list, - 'format': medium_format, - 'title': 'MEDIUM TITLE', - }) + data_track_list = [] + if data_tracks: + for i, recording in enumerate(data_tracks): + data_track = { + 'recording': recording, + 'position': len(track_list) + i + 1, + 'number': 'A1', + } + data_track_list.append(data_track) + release['medium-list'].append({ + 'position': '1', + 'track-list': track_list, + 'data-track-list': data_track_list, + 'format': medium_format, + 'title': 'MEDIUM TITLE', + }) return release def _make_track(self, title, tr_id, duration, artist=False, video=False): @@ -354,6 +365,18 @@ class MBAlbumInfoTest(_common.TestCase): self.assertEqual(d.tracks[0].title, 'TITLE ONE') self.assertEqual(d.tracks[1].title, 'TITLE TWO') + def test_no_skip_audio_data_tracks(self): + tracks = [self._make_track('TITLE ONE', 'ID ONE', 100.0 * 1000.0), + self._make_track('TITLE TWO', 'ID TWO', 200.0 * 1000.0)] + data_tracks = [self._make_track('TITLE AUDIO DATA', 'ID DATA TRACK', + 100.0 * 1000.0)] + release = self._make_release(tracks=tracks, data_tracks=data_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 TWO') + self.assertEqual(d.tracks[2].title, 'TITLE AUDIO DATA') + 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, @@ -365,6 +388,17 @@ class MBAlbumInfoTest(_common.TestCase): self.assertEqual(d.tracks[0].title, 'TITLE ONE') self.assertEqual(d.tracks[1].title, 'TITLE TWO') + def test_skip_video_data_tracks_by_default(self): + tracks = [self._make_track('TITLE ONE', 'ID ONE', 100.0 * 1000.0), + self._make_track('TITLE TWO', 'ID TWO', 200.0 * 1000.0)] + data_tracks = [self._make_track('TITLE VIDEO', 'ID VIDEO', + 100.0 * 1000.0, False, True)] + release = self._make_release(tracks=tracks, data_tracks=data_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_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), @@ -378,6 +412,19 @@ class MBAlbumInfoTest(_common.TestCase): self.assertEqual(d.tracks[1].title, 'TITLE VIDEO') self.assertEqual(d.tracks[2].title, 'TITLE TWO') + def test_no_skip_video_data_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 TWO', 'ID TWO', 200.0 * 1000.0)] + data_tracks = [self._make_track('TITLE VIDEO', 'ID VIDEO', + 100.0 * 1000.0, False, True)] + release = self._make_release(tracks=tracks, data_tracks=data_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 TWO') + self.assertEqual(d.tracks[2].title, 'TITLE VIDEO') + class ParseIDTest(_common.TestCase): def test_parse_id_correct(self):