mirror of
https://github.com/beetbox/beets.git
synced 2026-01-09 09:22:55 +01:00
multi-artist sort names
This commit is contained in:
parent
711a1c1113
commit
c0da62c2b7
3 changed files with 51 additions and 8 deletions
|
|
@ -59,23 +59,41 @@ else:
|
|||
|
||||
def _flatten_artist_credit(credit):
|
||||
"""Given a list representing an ``artist-credit`` block, flatten the
|
||||
data into a pair of strings: the "canonical" joined artist name and
|
||||
the specific "credit" joined artist name.
|
||||
data into a triple of joined artist name strings: canonical, sort, and
|
||||
credit.
|
||||
"""
|
||||
artist_parts = []
|
||||
artist_sort_parts = []
|
||||
artist_credit_parts = []
|
||||
for el in credit:
|
||||
if isinstance(el, basestring):
|
||||
# Join phrase.
|
||||
artist_parts.append(el)
|
||||
artist_credit_parts.append(el)
|
||||
artist_sort_parts.append(el)
|
||||
|
||||
else:
|
||||
# An artist.
|
||||
cur_artist_name = el['artist']['name']
|
||||
artist_parts.append(cur_artist_name)
|
||||
if 'name' in el: # Special artist credit.
|
||||
|
||||
# Artist sort name.
|
||||
if 'sort-name' in el['artist']:
|
||||
artist_sort_parts.append(el['artist']['sort-name'])
|
||||
else:
|
||||
artist_sort_parts.append(cur_artist_name)
|
||||
|
||||
# Artist credit.
|
||||
if 'name' in el:
|
||||
artist_credit_parts.append(el['name'])
|
||||
else:
|
||||
artist_credit_parts.append(cur_artist_name)
|
||||
return ''.join(artist_parts), ''.join(artist_credit_parts)
|
||||
|
||||
return (
|
||||
''.join(artist_parts),
|
||||
''.join(artist_sort_parts),
|
||||
''.join(artist_credit_parts),
|
||||
)
|
||||
|
||||
def track_info(recording, medium=None, medium_index=None):
|
||||
"""Translates a MusicBrainz recording result dictionary into a beets
|
||||
|
|
@ -89,13 +107,12 @@ def track_info(recording, medium=None, medium_index=None):
|
|||
|
||||
if recording.get('artist-credit'):
|
||||
# Get the artist names.
|
||||
info.artist, info.artist_credit = \
|
||||
info.artist, info.artist_sort, info.artist_credit = \
|
||||
_flatten_artist_credit(recording['artist-credit'])
|
||||
|
||||
# Get the ID and sort name of the first artist.
|
||||
artist = recording['artist-credit'][0]['artist']
|
||||
info.artist_id = artist['id']
|
||||
info.artist_sort = artist['sort-name']
|
||||
|
||||
if recording.get('length'):
|
||||
info.length = int(recording['length'])/(1000.0)
|
||||
|
|
@ -117,7 +134,7 @@ def album_info(release):
|
|||
AlbumInfo object containing the interesting data about that release.
|
||||
"""
|
||||
# Get artist name using join phrases.
|
||||
artist_name, artist_credit_name = \
|
||||
artist_name, artist_sort_name, artist_credit_name = \
|
||||
_flatten_artist_credit(release['artist-credit'])
|
||||
|
||||
# Basic info.
|
||||
|
|
@ -141,7 +158,7 @@ def album_info(release):
|
|||
release['artist-credit'][0]['artist']['id'],
|
||||
track_infos,
|
||||
mediums=len(release['medium-list']),
|
||||
artist_sort=release['artist-credit'][0]['artist']['sort-name'],
|
||||
artist_sort=artist_sort_name,
|
||||
artist_credit=artist_credit_name,
|
||||
)
|
||||
info.va = info.artist_id == VARIOUS_ARTISTS_ID
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ Changelog
|
|||
copied. This solves a problem (introduced in 1.0b14) where beets could crash
|
||||
after adding files to the library but before finishing copying them; during
|
||||
the next import, the (external) files would be moved instead of copied.
|
||||
* Artist sort names are now populated correctly for multi-artist tracks and
|
||||
releases. (Previously, they only reflected the first artist.)
|
||||
* Fix ID3 tag name for the catalog number field.
|
||||
* :doc:`/plugins/chroma`: Fix occasional crash at end of fingerprint submission
|
||||
and give more context to "failed fingerprint generation" errors.
|
||||
|
|
|
|||
|
|
@ -269,6 +269,30 @@ class MBAlbumInfoTest(unittest.TestCase):
|
|||
self.assertEqual(track.artist_sort, 'TRACK ARTIST SORT NAME')
|
||||
self.assertEqual(track.artist_credit, 'TRACK ARTIST CREDIT')
|
||||
|
||||
class ArtistFlatteningTest(unittest.TestCase):
|
||||
def _credit_dict(self, suffix=''):
|
||||
return {
|
||||
'artist': {
|
||||
'name': 'NAME' + suffix,
|
||||
'sort-name': 'SORT' + suffix,
|
||||
},
|
||||
'name': 'CREDIT' + suffix,
|
||||
}
|
||||
|
||||
def test_single_artist(self):
|
||||
a, s, c = mb._flatten_artist_credit([self._credit_dict()])
|
||||
self.assertEqual(a, 'NAME')
|
||||
self.assertEqual(s, 'SORT')
|
||||
self.assertEqual(c, 'CREDIT')
|
||||
|
||||
def test_two_artists(self):
|
||||
a, s, c = mb._flatten_artist_credit(
|
||||
[self._credit_dict('a'), ' AND ', self._credit_dict('b')]
|
||||
)
|
||||
self.assertEqual(a, 'NAMEa AND NAMEb')
|
||||
self.assertEqual(s, 'SORTa AND SORTb')
|
||||
self.assertEqual(c, 'CREDITa AND CREDITb')
|
||||
|
||||
def suite():
|
||||
return unittest.TestLoader().loadTestsFromName(__name__)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue