diff --git a/picard/cluster.py b/picard/cluster.py index 746f8ad15..78c4f40af 100644 --- a/picard/cluster.py +++ b/picard/cluster.py @@ -27,7 +27,6 @@ from picard.metadata import Metadata from picard.similarity import similarity2, similarity from picard.ui.item import Item from picard.util import format_time -from picard.mbxml import artist_credit_from_node class Cluster(QtCore.QObject, Item): diff --git a/picard/formats/asf.py b/picard/formats/asf.py index 4ff5f4a43..e63a733a6 100644 --- a/picard/formats/asf.py +++ b/picard/formats/asf.py @@ -127,6 +127,7 @@ class ASFFile(File): 'asin': 'ASIN', 'djmixer': 'WM/DJMixer', 'mixer': 'WM/Mixer', + 'artists': 'WM/ARTISTS', } __RTRANS = dict([(b, a) for a, b in __TRANS.items()]) diff --git a/picard/formats/id3.py b/picard/formats/id3.py index b63a85b69..27fc53380 100644 --- a/picard/formats/id3.py +++ b/picard/formats/id3.py @@ -156,6 +156,7 @@ class ID3File(File): 'BARCODE': 'barcode', 'ASIN': 'asin', 'MusicMagic Fingerprint': 'musicip_fingerprint', + 'Artists': 'artists', } __rtranslate_freetext = dict([(v, k) for k, v in __translate_freetext.iteritems()]) diff --git a/picard/formats/mp4.py b/picard/formats/mp4.py index 410eb1b23..594a4cfd1 100644 --- a/picard/formats/mp4.py +++ b/picard/formats/mp4.py @@ -99,6 +99,7 @@ class MP4File(File): "----:com.apple.iTunes:MOOD": "mood", "----:com.apple.iTunes:SCRIPT": "script", "----:com.apple.iTunes:LANGUAGE": "language", + "----:com.apple.iTunes:ARTISTS": "artists", } __r_freeform_tags = dict([(v, k) for k, v in __freeform_tags.iteritems()]) diff --git a/picard/mbxml.py b/picard/mbxml.py index 1838e4abe..9e79b13e7 100644 --- a/picard/mbxml.py +++ b/picard/mbxml.py @@ -135,26 +135,30 @@ def _translate_artist_node(node): def artist_credit_from_node(node): artist = "" artistsort = "" + artists = [] + standardize_artists = config.setting["standardize_artists"] for credit in node.name_credit: a = credit.artist[0] - transl, translsort = _translate_artist_node(a) - if transl: - artist += transl + translated, translated_sort = _translate_artist_node(a) + if translated: + name = translated + elif 'name' in credit.children and not standardize_artists: + name = credit.name[0].text else: - if 'name' in credit.children and not config.setting["standardize_artists"]: - artist += credit.name[0].text - else: - artist += a.name[0].text - artistsort += translsort if translsort else a.sort_name[0].text + name = a.name[0].text + artist += name + artistsort += translated_sort if translated_sort else a.sort_name[0].text + artists.append(name) if 'joinphrase' in credit.attribs: artist += credit.joinphrase artistsort += credit.joinphrase - return (artist, artistsort) + return (artist, artistsort, artists) def artist_credit_to_metadata(node, m, release=False): ids = [n.artist[0].id for n in node.name_credit] - artist, artistsort = artist_credit_from_node(node) + artist, artistsort, artists = artist_credit_from_node(node) + m["artists"] = artists if release: m["musicbrainz_albumartistid"] = ids m["albumartist"] = artist diff --git a/picard/util/tags.py b/picard/util/tags.py index 9d099fa0d..a5705b1d0 100644 --- a/picard/util/tags.py +++ b/picard/util/tags.py @@ -86,6 +86,7 @@ TAG_NAMES = { 'script': N_('Script'), '~length': N_('Length'), '~rating': N_('Rating'), + 'artists': N_('Artists'), } diff --git a/test/test_mbxml.py b/test/test_mbxml.py index 495df5dc9..c0e7fd69c 100644 --- a/test/test_mbxml.py +++ b/test/test_mbxml.py @@ -2,7 +2,11 @@ import unittest import picard from picard import config from picard.metadata import Metadata -from picard.mbxml import track_to_metadata, release_to_metadata +from picard.mbxml import ( + track_to_metadata, + release_to_metadata, + artist_credit_from_node +) settings = { @@ -135,3 +139,26 @@ class ReleaseTest(unittest.TestCase): self.assertEqual('B123456789', m['asin']) self.assertEqual('ABC', m['label']) self.assertEqual('ABC 123', m['catalognumber']) + + +class ArtistTest(unittest.TestCase): + + def test_1(self): + config.setting = settings + node = XmlNode(children={ + 'name_credit': [XmlNode(attribs={'joinphrase': ' & '}, children={ + 'artist': [XmlNode(attribs={'id': '456'}, children={ + 'name': [XmlNode(text='Foo Bar')], + 'sort_name': [XmlNode(text='Bar, Foo')] + })] + }), XmlNode(children={ + 'artist': [XmlNode(attribs={'id': '789'}, children={ + 'name': [XmlNode(text='Baz')], + 'sort_name': [XmlNode(text='Baz')] + })] + })] + }) + artist, artist_sort, artists = artist_credit_from_node(node) + self.assertEqual(['Foo Bar', 'Baz'], artists) + self.assertEqual('Foo Bar & Baz', artist) + self.assertEqual('Bar, Foo & Baz', artist_sort)