From c51ecd46e3b7b97ea87d88ed6c041683cbc14eda Mon Sep 17 00:00:00 2001 From: dosoe Date: Fri, 28 Apr 2017 12:10:02 +0200 Subject: [PATCH 1/9] add composer_sort tag# --- beets/autotag/__init__.py | 6 +++++ beets/autotag/hooks.py | 6 +++-- beets/autotag/mb.py | 4 ++++ beets/library.py | 1 + beets/mediafile.py | 16 +++++++++++++ test/_common.py | 1 + test/test_mediafile.py | 48 ++++++++++++++++++++------------------- 7 files changed, 57 insertions(+), 25 deletions(-) diff --git a/beets/autotag/__init__.py b/beets/autotag/__init__.py index 822bb60efc..a820535cba 100644 --- a/beets/autotag/__init__.py +++ b/beets/autotag/__init__.py @@ -49,8 +49,12 @@ def apply_item_metadata(item, track_info): item.lyricist = track_info.lyricist if track_info.composer is not None: item.composer = track_info.composer + if track_info.composer_sort is not None: + item.composer_sort = track_info.composer_sort if track_info.arranger is not None: item.arranger = track_info.arranger + + # At the moment, the other metadata is left intact (including album # and track number). Perhaps these should be emptied? @@ -155,6 +159,8 @@ def apply_metadata(album_info, mapping): item.lyricist = track_info.lyricist if track_info.composer is not None: item.composer = track_info.composer + if track_info.composer_sort is not None: + item.composer_sort = track_info.composer_sort if track_info.arranger is not None: item.arranger = track_info.arranger diff --git a/beets/autotag/hooks.py b/beets/autotag/hooks.py index 3c403fcf42..0c3f78ad32 100644 --- a/beets/autotag/hooks.py +++ b/beets/autotag/hooks.py @@ -144,6 +144,7 @@ class TrackInfo(object): - ``data_url``: The data source release URL. - ``lyricist``: individual track lyricist name - ``composer``: individual track composer name + - ``composer_sort``: individual track composer sort name - ``arranger`: individual track arranger name - ``track_alt``: alternative track number (tape, vinyl, etc.) @@ -155,8 +156,8 @@ def __init__(self, title, track_id, artist=None, artist_id=None, 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, - track_alt=None): + media=None, lyricist=None, composer=None, composer_sort=None, + arranger=None, track_alt=None): self.title = title self.track_id = track_id self.artist = artist @@ -174,6 +175,7 @@ def __init__(self, title, track_id, artist=None, artist_id=None, self.data_url = data_url self.lyricist = lyricist self.composer = composer + self.composer_sort = composer_sort self.arranger = arranger self.track_alt = track_alt diff --git a/beets/autotag/mb.py b/beets/autotag/mb.py index 21dd8a715f..e0c2175133 100644 --- a/beets/autotag/mb.py +++ b/beets/autotag/mb.py @@ -207,6 +207,7 @@ def track_info(recording, index=None, medium=None, medium_index=None, lyricist = [] composer = [] + composer_sort = [] for work_relation in recording.get('work-relation-list', ()): if work_relation['type'] != 'performance': continue @@ -218,12 +219,15 @@ def track_info(recording, index=None, medium=None, medium_index=None, lyricist.append(artist_relation['artist']['name']) elif type == 'composer': composer.append(artist_relation['artist']['name']) + composer_sort.append(artist_relation['artist']['sort-name']) if lyricist: info.lyricist = u', '.join(lyricist) if composer: info.composer = u', '.join(composer) + info.composer_sort = u', '.join(composer_sort) arranger = [] + arranger_sort = [] for artist_relation in recording.get('artist-relation-list', ()): if 'type' in artist_relation: type = artist_relation['type'] diff --git a/beets/library.py b/beets/library.py index b263ecd646..094a85d6b3 100644 --- a/beets/library.py +++ b/beets/library.py @@ -417,6 +417,7 @@ class Item(LibModel): 'genre': types.STRING, 'lyricist': types.STRING, 'composer': types.STRING, + 'composer_sort': types.STRING, 'arranger': types.STRING, 'grouping': types.STRING, 'year': types.PaddedInt(4), diff --git a/beets/mediafile.py b/beets/mediafile.py index 13f1b2dfb0..fd94587a86 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -1632,12 +1632,28 @@ def update(self, dict): StorageStyle('LYRICIST'), ASFStorageStyle('WM/Writer'), ) + composer = MediaField( MP3StorageStyle('TCOM'), MP4StorageStyle('\xa9wrt'), StorageStyle('COMPOSER'), ASFStorageStyle('WM/Composer'), ) + + composer_sort = MediaField( + MP3StorageStyle('TSOC'), + MP4StorageStyle('soco'), + StorageStyle('COMPOSERSORT'), + ASFStorageStyle('WM/Composersort'), + ) + + arranger = MediaField( + MP3PeopleStorageStyle('TIPL', involvement='arranger'), + MP4StorageStyle('----:com.apple.iTunes:Arranger'), + StorageStyle('ARRANGER'), + ASFStorageStyle('beets/Arranger'), + ) + arranger = MediaField( MP3PeopleStorageStyle('TIPL', involvement='arranger'), MP4StorageStyle('----:com.apple.iTunes:Arranger'), diff --git a/test/_common.py b/test/_common.py index f3213ec31f..221903f682 100644 --- a/test/_common.py +++ b/test/_common.py @@ -68,6 +68,7 @@ def item(lib=None): genre=u'the genre', lyricist=u'the lyricist', composer=u'the composer', + composer_sort=u'the sortname of the composer', arranger=u'the arranger', grouping=u'the grouping', year=1, diff --git a/test/test_mediafile.py b/test/test_mediafile.py index 63df38b8e1..f11e060df4 100644 --- a/test/test_mediafile.py +++ b/test/test_mediafile.py @@ -318,29 +318,30 @@ class ReadWriteTestBase(ArtTestMixin, GenreListTestMixin, """ full_initial_tags = { - 'title': u'full', - 'artist': u'the artist', - 'album': u'the album', - 'genre': u'the genre', - 'composer': u'the composer', - 'grouping': u'the grouping', - 'year': 2001, - 'month': None, - 'day': None, - 'date': datetime.date(2001, 1, 1), - 'track': 2, - 'tracktotal': 3, - 'disc': 4, - 'disctotal': 5, - 'lyrics': u'the lyrics', - 'comments': u'the comments', - 'bpm': 6, - 'comp': True, - 'mb_trackid': '8b882575-08a5-4452-a7a7-cbb8a1531f9e', - 'mb_albumid': '9e873859-8aa4-4790-b985-5a953e8ef628', - 'mb_artistid': '7cf0ea9d-86b9-4dad-ba9e-2355a64899ea', - 'art': None, - 'label': u'the label', + 'title': u'full', + 'artist': u'the artist', + 'album': u'the album', + 'genre': u'the genre', + 'composer': u'the composer', + 'composer_sort' :u'the sortname of the composer', + 'grouping': u'the grouping', + 'year': 2001, + 'month': None, + 'day': None, + 'date': datetime.date(2001, 1, 1), + 'track': 2, + 'tracktotal': 3, + 'disc': 4, + 'disctotal': 5, + 'lyrics': u'the lyrics', + 'comments': u'the comments', + 'bpm': 6, + 'comp': True, + 'mb_trackid': '8b882575-08a5-4452-a7a7-cbb8a1531f9e', + 'mb_albumid': '9e873859-8aa4-4790-b985-5a953e8ef628', + 'mb_artistid': '7cf0ea9d-86b9-4dad-ba9e-2355a64899ea', + 'art': None, + 'label': u'the label', } tag_fields = [ @@ -350,6 +351,7 @@ class ReadWriteTestBase(ArtTestMixin, GenreListTestMixin, 'genre', 'lyricist', 'composer', + 'composer_sort', 'arranger', 'grouping', 'year', From e3c37981bba0ff3ee8e697188bedd706a4e091e3 Mon Sep 17 00:00:00 2001 From: dosoe Date: Fri, 28 Apr 2017 12:13:27 +0200 Subject: [PATCH 2/9] little indentation stuff --- test/test_mediafile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_mediafile.py b/test/test_mediafile.py index f11e060df4..aa7d6341e4 100644 --- a/test/test_mediafile.py +++ b/test/test_mediafile.py @@ -323,7 +323,7 @@ class ReadWriteTestBase(ArtTestMixin, GenreListTestMixin, 'album': u'the album', 'genre': u'the genre', 'composer': u'the composer', - 'composer_sort' :u'the sortname of the composer', + 'composer_sort': u'the sortname of the composer', 'grouping': u'the grouping', 'year': 2001, 'month': None, From 075e2432bfd5b7bbd386b642f128c318054c821a Mon Sep 17 00:00:00 2001 From: dosoe Date: Fri, 28 Apr 2017 12:15:37 +0200 Subject: [PATCH 3/9] deleted one duplicate block --- beets/autotag/mb.py | 1 - beets/mediafile.py | 7 ------- 2 files changed, 8 deletions(-) diff --git a/beets/autotag/mb.py b/beets/autotag/mb.py index e0c2175133..c2172d0ac4 100644 --- a/beets/autotag/mb.py +++ b/beets/autotag/mb.py @@ -227,7 +227,6 @@ def track_info(recording, index=None, medium=None, medium_index=None, info.composer_sort = u', '.join(composer_sort) arranger = [] - arranger_sort = [] for artist_relation in recording.get('artist-relation-list', ()): if 'type' in artist_relation: type = artist_relation['type'] diff --git a/beets/mediafile.py b/beets/mediafile.py index fd94587a86..c04cdb67b0 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -1647,13 +1647,6 @@ def update(self, dict): ASFStorageStyle('WM/Composersort'), ) - arranger = MediaField( - MP3PeopleStorageStyle('TIPL', involvement='arranger'), - MP4StorageStyle('----:com.apple.iTunes:Arranger'), - StorageStyle('ARRANGER'), - ASFStorageStyle('beets/Arranger'), - ) - arranger = MediaField( MP3PeopleStorageStyle('TIPL', involvement='arranger'), MP4StorageStyle('----:com.apple.iTunes:Arranger'), From 2a418a6350c9266181c715fd0f9dd8077f9fd1c0 Mon Sep 17 00:00:00 2001 From: dosoe Date: Fri, 28 Apr 2017 12:29:44 +0200 Subject: [PATCH 4/9] ASFStorageStyle corrected --- beets/mediafile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beets/mediafile.py b/beets/mediafile.py index c04cdb67b0..e5e7af3ece 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -1644,7 +1644,7 @@ def update(self, dict): MP3StorageStyle('TSOC'), MP4StorageStyle('soco'), StorageStyle('COMPOSERSORT'), - ASFStorageStyle('WM/Composersort'), + ASFStorageStyle('WM/Composersortorder'), ) arranger = MediaField( From d4ff82e46fef897dde4aee6ebe8781f563a6f39c Mon Sep 17 00:00:00 2001 From: dosoe Date: Fri, 28 Apr 2017 12:45:31 +0200 Subject: [PATCH 5/9] adding image stuff for composer_sort --- test/test_mediafile.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/test/test_mediafile.py b/test/test_mediafile.py index aa7d6341e4..179999dc69 100644 --- a/test/test_mediafile.py +++ b/test/test_mediafile.py @@ -141,6 +141,12 @@ def test_add_image_structure(self): type=ImageType.composer) mediafile.images += [image] mediafile.save() + + image = Image(data=self.png_data, desc=u'the sortname of the composer', + type=ImageType.composer_sort) + mediafile.images += [image] + mediafile.save() + mediafile = MediaFile(mediafile.path) self.assertEqual(len(mediafile.images), 3) @@ -150,6 +156,12 @@ def test_add_image_structure(self): self.assertExtendedImageAttributes( image, desc=u'the composer', type=ImageType.composer ) + + images = (i for i in mediafile.images if i.desc == u'the sortname of the composer') + image = next(images, None) + self.assertExtendedImageAttributes( + image, desc=u'the sortname of the composer', type=ImageType.composer_sort + ) def test_delete_image_structures(self): mediafile = self._mediafile_fixture('image') @@ -193,6 +205,11 @@ def test_add_tiff_image(self): type=ImageType.composer) mediafile.images += [image] mediafile.save() + + image = Image(data=self.tiff_data, desc=u'the sortname of the composer', + type=ImageType.composer_sort) + mediafile.images += [image] + mediafile.save() mediafile = MediaFile(mediafile.path) self.assertEqual(len(mediafile.images), 3) @@ -202,6 +219,11 @@ def test_add_tiff_image(self): mediafile.images))[0] self.assertExtendedImageAttributes( image, desc=u'the composer', type=ImageType.composer) + + image = list(filter(lambda i: i.mime_type == 'image/tiff', + mediafile.images))[0] + self.assertExtendedImageAttributes( + image, desc=u'the sortname of the composer', type=ImageType.composer_sort) class LazySaveTestMixin(object): From 4a17da8e10c64ad889bfa42a0941ae2c95c29443 Mon Sep 17 00:00:00 2001 From: dosoe Date: Fri, 28 Apr 2017 13:41:54 +0200 Subject: [PATCH 6/9] requested changes: where there is no artist_sort, there is no need for composer_sort; cleaning up whitespaces. --- beets/autotag/__init__.py | 2 -- beets/autotag/hooks.py | 2 +- beets/mediafile.py | 4 ---- test/test_mediafile.py | 24 ------------------------ 4 files changed, 1 insertion(+), 31 deletions(-) diff --git a/beets/autotag/__init__.py b/beets/autotag/__init__.py index a820535cba..4c5f09eb49 100644 --- a/beets/autotag/__init__.py +++ b/beets/autotag/__init__.py @@ -53,8 +53,6 @@ def apply_item_metadata(item, track_info): item.composer_sort = track_info.composer_sort if track_info.arranger is not None: item.arranger = track_info.arranger - - # At the moment, the other metadata is left intact (including album # and track number). Perhaps these should be emptied? diff --git a/beets/autotag/hooks.py b/beets/autotag/hooks.py index 0c3f78ad32..053d050c6c 100644 --- a/beets/autotag/hooks.py +++ b/beets/autotag/hooks.py @@ -156,7 +156,7 @@ def __init__(self, title, track_id, artist=None, artist_id=None, 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, composer_sort=None, + media=None, lyricist=None, composer=None, composer_sort=None, arranger=None, track_alt=None): self.title = title self.track_id = track_id diff --git a/beets/mediafile.py b/beets/mediafile.py index e5e7af3ece..9f37b70d53 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -1632,28 +1632,24 @@ def update(self, dict): StorageStyle('LYRICIST'), ASFStorageStyle('WM/Writer'), ) - composer = MediaField( MP3StorageStyle('TCOM'), MP4StorageStyle('\xa9wrt'), StorageStyle('COMPOSER'), ASFStorageStyle('WM/Composer'), ) - composer_sort = MediaField( MP3StorageStyle('TSOC'), MP4StorageStyle('soco'), StorageStyle('COMPOSERSORT'), ASFStorageStyle('WM/Composersortorder'), ) - arranger = MediaField( MP3PeopleStorageStyle('TIPL', involvement='arranger'), MP4StorageStyle('----:com.apple.iTunes:Arranger'), StorageStyle('ARRANGER'), ASFStorageStyle('beets/Arranger'), ) - grouping = MediaField( MP3StorageStyle('TIT1'), MP4StorageStyle('\xa9grp'), diff --git a/test/test_mediafile.py b/test/test_mediafile.py index 179999dc69..961d3d3bda 100644 --- a/test/test_mediafile.py +++ b/test/test_mediafile.py @@ -141,12 +141,6 @@ def test_add_image_structure(self): type=ImageType.composer) mediafile.images += [image] mediafile.save() - - image = Image(data=self.png_data, desc=u'the sortname of the composer', - type=ImageType.composer_sort) - mediafile.images += [image] - mediafile.save() - mediafile = MediaFile(mediafile.path) self.assertEqual(len(mediafile.images), 3) @@ -156,12 +150,6 @@ def test_add_image_structure(self): self.assertExtendedImageAttributes( image, desc=u'the composer', type=ImageType.composer ) - - images = (i for i in mediafile.images if i.desc == u'the sortname of the composer') - image = next(images, None) - self.assertExtendedImageAttributes( - image, desc=u'the sortname of the composer', type=ImageType.composer_sort - ) def test_delete_image_structures(self): mediafile = self._mediafile_fixture('image') @@ -205,11 +193,6 @@ def test_add_tiff_image(self): type=ImageType.composer) mediafile.images += [image] mediafile.save() - - image = Image(data=self.tiff_data, desc=u'the sortname of the composer', - type=ImageType.composer_sort) - mediafile.images += [image] - mediafile.save() mediafile = MediaFile(mediafile.path) self.assertEqual(len(mediafile.images), 3) @@ -219,11 +202,6 @@ def test_add_tiff_image(self): mediafile.images))[0] self.assertExtendedImageAttributes( image, desc=u'the composer', type=ImageType.composer) - - image = list(filter(lambda i: i.mime_type == 'image/tiff', - mediafile.images))[0] - self.assertExtendedImageAttributes( - image, desc=u'the sortname of the composer', type=ImageType.composer_sort) class LazySaveTestMixin(object): @@ -345,7 +323,6 @@ class ReadWriteTestBase(ArtTestMixin, GenreListTestMixin, 'album': u'the album', 'genre': u'the genre', 'composer': u'the composer', - 'composer_sort': u'the sortname of the composer', 'grouping': u'the grouping', 'year': 2001, 'month': None, @@ -373,7 +350,6 @@ class ReadWriteTestBase(ArtTestMixin, GenreListTestMixin, 'genre', 'lyricist', 'composer', - 'composer_sort', 'arranger', 'grouping', 'year', From 23f172d03d838d1119df09927e14d9f13cc14e59 Mon Sep 17 00:00:00 2001 From: dosoe Date: Fri, 28 Apr 2017 13:49:50 +0200 Subject: [PATCH 7/9] if there is no artist_sort, there should not be a composer_sort. --- test/_common.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/_common.py b/test/_common.py index 221903f682..f3213ec31f 100644 --- a/test/_common.py +++ b/test/_common.py @@ -68,7 +68,6 @@ def item(lib=None): genre=u'the genre', lyricist=u'the lyricist', composer=u'the composer', - composer_sort=u'the sortname of the composer', arranger=u'the arranger', grouping=u'the grouping', year=1, From 813b078d026f37268e89cd6bb782a2a42e7d32e3 Mon Sep 17 00:00:00 2001 From: dosoe Date: Sat, 29 Apr 2017 18:47:03 +0200 Subject: [PATCH 8/9] added composer_sort on test_mediafile.py since there is artist_sort --- test/test_mediafile.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test_mediafile.py b/test/test_mediafile.py index 961d3d3bda..5805847913 100644 --- a/test/test_mediafile.py +++ b/test/test_mediafile.py @@ -350,6 +350,7 @@ class ReadWriteTestBase(ArtTestMixin, GenreListTestMixin, 'genre', 'lyricist', 'composer', + 'composer_sort', 'arranger', 'grouping', 'year', From e4441437f5ab4c9ecb1f8976aaa6ac122c9a46e2 Mon Sep 17 00:00:00 2001 From: dosoe Date: Fri, 12 May 2017 11:36:30 +0200 Subject: [PATCH 9/9] Corrected line length --- beets/autotag/mb.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/beets/autotag/mb.py b/beets/autotag/mb.py index c2172d0ac4..9da7091604 100644 --- a/beets/autotag/mb.py +++ b/beets/autotag/mb.py @@ -219,7 +219,8 @@ def track_info(recording, index=None, medium=None, medium_index=None, lyricist.append(artist_relation['artist']['name']) elif type == 'composer': composer.append(artist_relation['artist']['name']) - composer_sort.append(artist_relation['artist']['sort-name']) + composer_sort.append( + artist_relation['artist']['sort-name']) if lyricist: info.lyricist = u', '.join(lyricist) if composer: