Repository: beetbox/beets

Issue:
Ignore missing video tracks identified by MusicBrainz during import and in missing plugin
Musicbrainz albums sometimes have video tracks in them (example: http://musicbrainz.org/release/49da37ee-065a-4d7f-a204-9dda8047aad4 ) -- is it possible to ignore video tracks we importing or using `beet missing`?



Discussion:
Not currently, but (if there's a reliable way of identifying them) then this seems like a worthy goal.

Here's the XML: http://musicbrainz.org/ws/2/release/49da37ee-065a-4d7f-a204-9dda8047aad4?inc=artists+artist-credits+recordings+aliases

Looks like the track has `<video>true</video>` in the response.

Cool. If anyone's interested in taking this on, the first step will be propagating that information from MB to the beets database.

Related Picard issue: musicbrainz/picard#383 - note that this is not just videos, there are plenty of "enhanced" cds with e.g. bonus MP3s on the data section.


Resolving patch:
diff --git a/beets/autotag/mb.py b/beets/autotag/mb.py
--- a/beets/autotag/mb.py
+++ b/beets/autotag/mb.py
@@ -39,6 +39,8 @@
 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,16 @@ 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' and
+                    config['match']['ignore_video_tracks']):
+                continue
+
             # Basic information from the recording.
             index += 1
             ti = track_info(


Test patch:
diff --git a/test/test_mb.py b/test/test_mb.py
--- a/test/test_mb.py
+++ b/test/test_mb.py
@@ -95,7 +95,7 @@ def _make_release(self, date_str='2009', tracks=None, track_length=None,
             })
         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 @@ def _make_track(self, title, tr_id, duration, artist=False):
                     'name': 'RECORDING ARTIST CREDIT',
                 }
             ]
+        if video:
+            track['video'] = 'true'
         return track
 
     def test_parse_release_with_year(self):
@@ -345,6 +347,41 @@ def test_no_skip_dvd_audio(self):
         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_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),
+                  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_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):