Repository: beetbox/beets
Pull request: Add trackdisambig from musicbrainz.
fixes beetbox/beets#1904

## Description

Fixes #1904.

(...)

## To Do

- [x] Documentation. (If you've add a new command-line flag, for example, find the appropriate page under `docs/` to describe it.)
- [x] Changelog. (Add an entry to `docs/changelog.rst` near the top of the document.)
- [x] Tests. (Encouraged but not strictly required.)


Problem statement:
Fetch MusicBrainz track disambiguation field
I download a lot of singletons, and I use the track disambiguation notes frequently. I saw that Beets has a way to note the **album** disambig, but not the **track** disambig. Can this be inserted into a future release? This way, my beets.yaml config could look something like this:

`paths:
    default: $albumartist_sort/[$year] $album/$track. $artist- $title
    comp: Various Artists/[$year] $album/$track. $artist- $title
    singleton: $artist_sort/$artist- $title [$trackdisambig]
`

Hints from issue discussion:
Yes, sounds like a very reasonable addition.

Commit message: Attempt to address the comments from sampsyo

Undoes the changes to autotag/hooks.py

If trackdisambig is not set to None at some point in time, the
test case for a non-existent trackdisambig fails. as such, try
to get the disambiguation with a default of None when setting
trackdisambig. Not sure if this is reasonable.

Patch to review:
diff --git a/beets/autotag/mb.py b/beets/autotag/mb.py
index 03ea5b3825..740f0fcae5 100644
--- a/beets/autotag/mb.py
+++ b/beets/autotag/mb.py
@@ -223,6 +223,8 @@ def track_info(recording, index=None, medium=None, medium_index=None,
     if recording.get('length'):
         info.length = int(recording['length']) / (1000.0)
 
+    info.trackdisambig = recording.get('disambiguation', None)
+
     lyricist = []
     composer = []
     composer_sort = []
diff --git a/beets/library.py b/beets/library.py
index a060e93d6b..78552bb61e 100644
--- a/beets/library.py
+++ b/beets/library.py
@@ -477,6 +477,7 @@ class Item(LibModel):
         'mb_artistid':          types.STRING,
         'mb_albumartistid':     types.STRING,
         'mb_releasetrackid':    types.STRING,
+        'trackdisambig':        types.STRING,
         'albumtype':            types.STRING,
         'label':                types.STRING,
         'acoustid_fingerprint': types.STRING,
diff --git a/docs/changelog.rst b/docs/changelog.rst
index e2a62e6d82..ce1cc6c01b 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -178,6 +178,9 @@ New features:
   :bug:`3478`
 * Removes usage of the bs1770gain replaygain backend.
   Thanks to :user:`SamuelCook`.
+* Added ``trackdisambig`` which stores the recording disambiguation from
+  musicbrainz for each track.
+  :bug:`1904`
 
 Fixes:
 
diff --git a/test/test_mb.py b/test/test_mb.py
index de1ffd9a71..9eca57c808 100644
--- a/test/test_mb.py
+++ b/test/test_mb.py
@@ -111,7 +111,8 @@ def _make_release(self, date_str='2009', tracks=None, track_length=None,
         })
         return release
 
-    def _make_track(self, title, tr_id, duration, artist=False, video=False):
+    def _make_track(self, title, tr_id, duration, artist=False, video=False,
+                    disambiguation=None):
         track = {
             'title': title,
             'id': tr_id,
@@ -131,6 +132,8 @@ def _make_track(self, title, tr_id, duration, artist=False, video=False):
             ]
         if video:
             track['video'] = 'true'
+        if disambiguation:
+            track['disambiguation'] = disambiguation
         return track
 
     def test_parse_release_with_year(self):
@@ -445,6 +448,18 @@ def test_no_skip_video_data_tracks_if_configured(self):
         self.assertEqual(d.tracks[1].title, 'TITLE TWO')
         self.assertEqual(d.tracks[2].title, 'TITLE VIDEO')
 
+    def test_track_disambiguation(self):
+        tracks = [self._make_track('TITLE ONE', 'ID ONE', 100.0 * 1000.0),
+                  self._make_track('TITLE TWO', 'ID TWO', 200.0 * 1000.0,
+                                   disambiguation="SECOND TRACK")]
+        release = self._make_release(tracks=tracks)
+
+        d = mb.album_info(release)
+        t = d.tracks
+        self.assertEqual(len(t), 2)
+        self.assertEqual(t[0].trackdisambig, None)
+        self.assertEqual(t[1].trackdisambig, "SECOND TRACK")
+
 
 class ParseIDTest(_common.TestCase):
     def test_parse_id_correct(self):


Code review comments:
diff_hunk: @@ -223,6 +223,8 @@ def track_info(recording, index=None, medium=None, medium_index=None,
     if recording.get('length'):
         info.length = int(recording['length']) / (1000.0)
 
+    info.trackdisambig = recording.get('disambiguation', None)
path: beets/autotag/mb.py
text: @user1:
This seems like a perfectly fine way to do it, but it's exactly equivalent to `recording.get('disambiguation')` (the default default value is `None`!).