diff --git a/beets/autotag/__init__.py b/beets/autotag/__init__.py index 3e79a4498..822bb60ef 100644 --- a/beets/autotag/__init__.py +++ b/beets/autotag/__init__.py @@ -157,3 +157,5 @@ def apply_metadata(album_info, mapping): item.composer = track_info.composer if track_info.arranger is not None: item.arranger = track_info.arranger + + item.track_alt = track_info.track_alt diff --git a/beets/autotag/hooks.py b/beets/autotag/hooks.py index 40db6e8d3..3c403fcf4 100644 --- a/beets/autotag/hooks.py +++ b/beets/autotag/hooks.py @@ -145,6 +145,7 @@ class TrackInfo(object): - ``lyricist``: individual track lyricist name - ``composer``: individual track composer name - ``arranger`: individual track arranger name + - ``track_alt``: alternative track number (tape, vinyl, etc.) Only ``title`` and ``track_id`` are required. The rest of the fields may be None. The indices ``index``, ``medium``, and ``medium_index`` @@ -154,7 +155,8 @@ class TrackInfo(object): length=None, index=None, medium=None, medium_index=None, medium_total=None, artist_sort=None, disctitle=None, artist_credit=None, data_source=None, data_url=None, - media=None, lyricist=None, composer=None, arranger=None): + media=None, lyricist=None, composer=None, arranger=None, + track_alt=None): self.title = title self.track_id = track_id self.artist = artist @@ -173,6 +175,7 @@ class TrackInfo(object): self.lyricist = lyricist self.composer = composer self.arranger = arranger + self.track_alt = track_alt # As above, work around a bug in python-musicbrainz-ngs. def decode(self, codec='utf-8'): diff --git a/beets/autotag/mb.py b/beets/autotag/mb.py index da286332f..a0d4dc33a 100644 --- a/beets/autotag/mb.py +++ b/beets/autotag/mb.py @@ -269,6 +269,7 @@ def album_info(release): ) ti.disctitle = disctitle ti.media = format + ti.track_alt = track['number'] # Prefer track data, where present, over recording data. if track.get('title'): diff --git a/beetsplug/discogs.py b/beetsplug/discogs.py index cf10a2a36..3b3f5f201 100644 --- a/beetsplug/discogs.py +++ b/beetsplug/discogs.py @@ -314,7 +314,9 @@ class DiscogsPlugin(BeetsPlugin): # Only real tracks have `position`. Otherwise, it's an index track. if track['position']: index += 1 - tracks.append(self.get_track_info(track, index)) + track_info = self.get_track_info(track, index) + track_info.track_alt = track['position'] + tracks.append(track_info) else: index_tracks[index + 1] = track['title'] diff --git a/docs/changelog.rst b/docs/changelog.rst index 4e0d7405f..eaf8c7d5a 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -8,6 +8,11 @@ New features: * Added support for DSF files, once a future version of Mutagen is released that supports them. Thanks to :user:`docbobo`. :bug:`459` :bug:`2379` +* The MusicBrainz backend and :doc:`/plugins/discogs` now both provide a new + attribute called ``track_alt`` that stores more nuanced, possibly + non-numeric track index data. For example, some vinyl or tape media will + report the side of the record using a letter instead of a number in that + field. :bug:`1831` :bug:`2363` Fixes: diff --git a/test/test_importer.py b/test/test_importer.py index 500ca027d..87724f8da 100644 --- a/test/test_importer.py +++ b/test/test_importer.py @@ -1723,6 +1723,7 @@ def mocked_get_release_by_id(id_, includes=[], release_status=[], 'length': 59, }, 'position': 9, + 'number': 'A2' }], 'position': 5, }], diff --git a/test/test_mb.py b/test/test_mb.py index ecbcf3c59..ca1bf2a1a 100644 --- a/test/test_mb.py +++ b/test/test_mb.py @@ -68,6 +68,7 @@ class MBAlbumInfoTest(_common.TestCase): track = { 'recording': recording, 'position': i + 1, + 'number': 'A1', } if track_length: # Track lengths are distinct from recording lengths. @@ -182,6 +183,7 @@ class MBAlbumInfoTest(_common.TestCase): second_track_list = [{ 'recording': tracks[1], 'position': '1', + 'number': 'A1', }] release['medium-list'].append({ 'position': '2', @@ -454,6 +456,7 @@ class MBLibraryTest(unittest.TestCase): 'length': 42, }, 'position': 9, + 'number': 'A1', }], 'position': 5, }],