From b193f250ba6e6864e0e6873d1771602db9de5cce Mon Sep 17 00:00:00 2001 From: Dorian Soergel Date: Sun, 26 May 2019 00:18:24 +0200 Subject: [PATCH 01/14] add work, work-disambig and work_id tags --- beets/autotag/hooks.py | 9 ++++++++- beets/autotag/mb.py | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/beets/autotag/hooks.py b/beets/autotag/hooks.py index ec7047b7c7..942b8bd7fa 100644 --- a/beets/autotag/hooks.py +++ b/beets/autotag/hooks.py @@ -159,6 +159,9 @@ class TrackInfo(object): - ``composer_sort``: individual track composer sort name - ``arranger`: individual track arranger name - ``track_alt``: alternative track number (tape, vinyl, etc.) + - ``work`: individual track work title + - ``work_id`: individual track work id + - ``work_disambig`: individual track work diambiguation Only ``title`` and ``track_id`` are required. The rest of the fields may be None. The indices ``index``, ``medium``, and ``medium_index`` @@ -169,7 +172,8 @@ def __init__(self, title, track_id, release_track_id=None, artist=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, arranger=None, track_alt=None): + composer_sort=None, arranger=None, track_alt=None, + work=None, work_id=None, work_disambig=None): self.title = title self.track_id = track_id self.release_track_id = release_track_id @@ -191,6 +195,9 @@ def __init__(self, title, track_id, release_track_id=None, artist=None, self.composer_sort = composer_sort self.arranger = arranger self.track_alt = track_alt + self.work = work + self.work_id = work_id + self.work_disambig = work_disambig # 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 4ea56af7ff..23ee58b5a3 100644 --- a/beets/autotag/mb.py +++ b/beets/autotag/mb.py @@ -210,9 +210,18 @@ def track_info(recording, index=None, medium=None, medium_index=None, lyricist = [] composer = [] composer_sort = [] + work = [] + work_id = [] + work_disambig = [] for work_relation in recording.get('work-relation-list', ()): if work_relation['type'] != 'performance': continue + work.append(work_relation['work']['title']) + work_id.append(work_relation['work']['id']) + if 'disambiguation' in work_relation['work']: + work_disambig.append(work_relation['work']['disambiguation']) + else: + work_disambig.append('') for artist_relation in work_relation['work'].get( 'artist-relation-list', ()): if 'type' in artist_relation: @@ -237,6 +246,11 @@ def track_info(recording, index=None, medium=None, medium_index=None, arranger.append(artist_relation['artist']['name']) if arranger: info.arranger = u', '.join(arranger) + if work: + info.work = u', '.join(work) + info.work_id = u', '.join(work_id) + if all(dis for dis in work_disambig): + info.work_disambig = u', '.join(work_disambig) info.decode() return info From 4c197e6f19250c54bc0ee8b2bc0353ef41497a95 Mon Sep 17 00:00:00 2001 From: Dorian Soergel Date: Sun, 26 May 2019 00:38:38 +0200 Subject: [PATCH 02/14] completed library and test files --- beets/mediafile.py | 6 ++++++ test/_common.py | 3 +++ test/test_mediafile.py | 1 + 3 files changed, 10 insertions(+) diff --git a/beets/mediafile.py b/beets/mediafile.py index 32a32fe1d7..d1508b7624 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -1643,6 +1643,12 @@ def update(self, dict): StorageStyle('COMPOSERSORT'), ASFStorageStyle('WM/Composersortorder'), ) + work = MediaField( + MP3DescStorageStyle(u'Work'), + MP4StorageStyle('----:com.apple.iTunes:Work'), + StorageStyle('WORK'), + ASFStorageStyle('beets/Work'), + ) arranger = MediaField( MP3PeopleStorageStyle('TIPL', involvement='arranger'), MP4StorageStyle('----:com.apple.iTunes:Arranger'), diff --git a/test/_common.py b/test/_common.py index 99f2e968f4..26add0a18c 100644 --- a/test/_common.py +++ b/test/_common.py @@ -70,6 +70,9 @@ def item(lib=None): composer=u'the composer', arranger=u'the arranger', grouping=u'the grouping', + work=u'the work title', + work_id=u'the work musicbrainz id', + work_disambig=u'the work disambiguation', year=1, month=2, day=3, diff --git a/test/test_mediafile.py b/test/test_mediafile.py index 36a2c53ac3..9af4b428f1 100644 --- a/test/test_mediafile.py +++ b/test/test_mediafile.py @@ -352,6 +352,7 @@ class ReadWriteTestBase(ArtTestMixin, GenreListTestMixin, 'lyricist', 'composer', 'composer_sort', + 'work', 'arranger', 'grouping', 'year', From 5fe92730daf492c4ad6ae560e83be56f10fe5319 Mon Sep 17 00:00:00 2001 From: Dorian Soergel Date: Sun, 26 May 2019 00:40:13 +0200 Subject: [PATCH 03/14] completed autotag/__int__ --- beets/autotag/__init__.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/beets/autotag/__init__.py b/beets/autotag/__init__.py index a71b9b0a61..2f10333694 100644 --- a/beets/autotag/__init__.py +++ b/beets/autotag/__init__.py @@ -54,6 +54,12 @@ 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 + if track_info.work is not None: + item.work = track_info.work + if track_info.work_id is not None: + item.work_id = track_info.work_id + if track_info.work_disambig is not None: + item.work_disambig = track_info.work_disambig # At the moment, the other metadata is left intact (including album # and track number). Perhaps these should be emptied? From 42d10318f274269618a391235786ad7a474f6644 Mon Sep 17 00:00:00 2001 From: Dorian Soergel Date: Sun, 26 May 2019 11:56:38 +0200 Subject: [PATCH 04/14] removed useless checks for disambiguation --- beets/autotag/mb.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/beets/autotag/mb.py b/beets/autotag/mb.py index 23ee58b5a3..fb2878dbad 100644 --- a/beets/autotag/mb.py +++ b/beets/autotag/mb.py @@ -57,6 +57,7 @@ def get_message(self): self._reasonstr(), self.verb, repr(self.query) ) + log = logging.getLogger('beets') RELEASE_INCLUDES = ['artists', 'media', 'recordings', 'release-groups', @@ -220,8 +221,7 @@ def track_info(recording, index=None, medium=None, medium_index=None, work_id.append(work_relation['work']['id']) if 'disambiguation' in work_relation['work']: work_disambig.append(work_relation['work']['disambiguation']) - else: - work_disambig.append('') + for artist_relation in work_relation['work'].get( 'artist-relation-list', ()): if 'type' in artist_relation: @@ -249,8 +249,7 @@ def track_info(recording, index=None, medium=None, medium_index=None, if work: info.work = u', '.join(work) info.work_id = u', '.join(work_id) - if all(dis for dis in work_disambig): - info.work_disambig = u', '.join(work_disambig) + info.work_disambig = u', '.join(work_disambig) info.decode() return info From 2b64fd45fea59eecc090cd05d58cf59789a5206a Mon Sep 17 00:00:00 2001 From: Dorian Soergel Date: Sun, 26 May 2019 13:59:20 +0200 Subject: [PATCH 05/14] new changes since my first try --- beets/autotag/__init__.py | 3 +++ beets/library.py | 3 +++ 2 files changed, 6 insertions(+) diff --git a/beets/autotag/__init__.py b/beets/autotag/__init__.py index 2f10333694..e6153478a7 100644 --- a/beets/autotag/__init__.py +++ b/beets/autotag/__init__.py @@ -173,6 +173,9 @@ def apply_metadata(album_info, mapping): 'composer', 'composer_sort', 'arranger', + 'work', + 'work_id', + 'work_disambig', ) } diff --git a/beets/library.py b/beets/library.py index 9a9d95256a..36af5adf4f 100644 --- a/beets/library.py +++ b/beets/library.py @@ -451,6 +451,9 @@ class Item(LibModel): 'lyricist': types.STRING, 'composer': types.STRING, 'composer_sort': types.STRING, + 'work': types.STRING, + 'work_id': types.STRING, + 'work_disambig': types.STRING, 'arranger': types.STRING, 'grouping': types.STRING, 'year': types.PaddedInt(4), From 1d809aa433e29f2161e196c17b58f2f8e6a393b6 Mon Sep 17 00:00:00 2001 From: Dorian Soergel Date: Sun, 26 May 2019 15:03:23 +0200 Subject: [PATCH 06/14] update mediafile, small typos --- beets/autotag/mb.py | 1 - beets/library.py | 2 +- beets/mediafile.py | 12 +++++++++--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/beets/autotag/mb.py b/beets/autotag/mb.py index fb2878dbad..177411034d 100644 --- a/beets/autotag/mb.py +++ b/beets/autotag/mb.py @@ -57,7 +57,6 @@ def get_message(self): self._reasonstr(), self.verb, repr(self.query) ) - log = logging.getLogger('beets') RELEASE_INCLUDES = ['artists', 'media', 'recordings', 'release-groups', diff --git a/beets/library.py b/beets/library.py index 36af5adf4f..6d143ef166 100644 --- a/beets/library.py +++ b/beets/library.py @@ -452,7 +452,7 @@ class Item(LibModel): 'composer': types.STRING, 'composer_sort': types.STRING, 'work': types.STRING, - 'work_id': types.STRING, + 'mb_workid': types.STRING, 'work_disambig': types.STRING, 'arranger': types.STRING, 'grouping': types.STRING, diff --git a/beets/mediafile.py b/beets/mediafile.py index d1508b7624..1c07d64f8c 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -1644,10 +1644,16 @@ def update(self, dict): ASFStorageStyle('WM/Composersortorder'), ) work = MediaField( - MP3DescStorageStyle(u'Work'), - MP4StorageStyle('----:com.apple.iTunes:Work'), + MP3StorageStyle('TIT1'), + MP4StorageStyle('\xa9wrk'), StorageStyle('WORK'), - ASFStorageStyle('beets/Work'), + ASFStorageStyle('WM/Work'), + ) + mb_workid = MediaField( + MP3StorageStyle('TXXX:MusicBrainz Work Id'), + MP4StorageStyle('----:com.apple.iTunes:MusicBrainz Work Id'), + StorageStyle('MUSICBRAINZ_WORKID '), + ASFStorageStyle('MusicBrainz/Work Id'), ) arranger = MediaField( MP3PeopleStorageStyle('TIPL', involvement='arranger'), From f7205c09c3e6e231b483ef69b4c0c8c4767ba9ac Mon Sep 17 00:00:00 2001 From: Dorian Soergel Date: Sun, 26 May 2019 15:07:24 +0200 Subject: [PATCH 07/14] update mediafile: MP3 tag for mb_workid --- beets/mediafile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beets/mediafile.py b/beets/mediafile.py index 1c07d64f8c..d2a66379a6 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -1650,7 +1650,7 @@ def update(self, dict): ASFStorageStyle('WM/Work'), ) mb_workid = MediaField( - MP3StorageStyle('TXXX:MusicBrainz Work Id'), + MP3DescStorageStyle(u'MusicBrainz Work Id'), MP4StorageStyle('----:com.apple.iTunes:MusicBrainz Work Id'), StorageStyle('MUSICBRAINZ_WORKID '), ASFStorageStyle('MusicBrainz/Work Id'), From 0131d253ee676a5491f80952931e6bd34950acea Mon Sep 17 00:00:00 2001 From: Dorian Soergel Date: Sun, 26 May 2019 15:10:18 +0200 Subject: [PATCH 08/14] replace work_id by mb_workid everywhere --- beets/autotag/__init__.py | 6 +++--- beets/autotag/hooks.py | 6 +++--- beets/autotag/mb.py | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/beets/autotag/__init__.py b/beets/autotag/__init__.py index e6153478a7..ede4fbe128 100644 --- a/beets/autotag/__init__.py +++ b/beets/autotag/__init__.py @@ -56,8 +56,8 @@ def apply_item_metadata(item, track_info): item.arranger = track_info.arranger if track_info.work is not None: item.work = track_info.work - if track_info.work_id is not None: - item.work_id = track_info.work_id + if track_info.mb_workid is not None: + item.mb_workid = track_info.mb_workid if track_info.work_disambig is not None: item.work_disambig = track_info.work_disambig @@ -174,7 +174,7 @@ def apply_metadata(album_info, mapping): 'composer_sort', 'arranger', 'work', - 'work_id', + 'mb_workid', 'work_disambig', ) } diff --git a/beets/autotag/hooks.py b/beets/autotag/hooks.py index 942b8bd7fa..57cd1c3094 100644 --- a/beets/autotag/hooks.py +++ b/beets/autotag/hooks.py @@ -160,7 +160,7 @@ class TrackInfo(object): - ``arranger`: individual track arranger name - ``track_alt``: alternative track number (tape, vinyl, etc.) - ``work`: individual track work title - - ``work_id`: individual track work id + - ``mb_workid`: individual track work id - ``work_disambig`: individual track work diambiguation Only ``title`` and ``track_id`` are required. The rest of the fields @@ -173,7 +173,7 @@ def __init__(self, title, track_id, release_track_id=None, artist=None, disctitle=None, artist_credit=None, data_source=None, data_url=None, media=None, lyricist=None, composer=None, composer_sort=None, arranger=None, track_alt=None, - work=None, work_id=None, work_disambig=None): + work=None, mb_workid=None, work_disambig=None): self.title = title self.track_id = track_id self.release_track_id = release_track_id @@ -196,7 +196,7 @@ def __init__(self, title, track_id, release_track_id=None, artist=None, self.arranger = arranger self.track_alt = track_alt self.work = work - self.work_id = work_id + self.mb_workid = mb_workid self.work_disambig = work_disambig # As above, work around a bug in python-musicbrainz-ngs. diff --git a/beets/autotag/mb.py b/beets/autotag/mb.py index 177411034d..a7bb6566d0 100644 --- a/beets/autotag/mb.py +++ b/beets/autotag/mb.py @@ -211,13 +211,13 @@ def track_info(recording, index=None, medium=None, medium_index=None, composer = [] composer_sort = [] work = [] - work_id = [] + mb_workid = [] work_disambig = [] for work_relation in recording.get('work-relation-list', ()): if work_relation['type'] != 'performance': continue work.append(work_relation['work']['title']) - work_id.append(work_relation['work']['id']) + mb_workid.append(work_relation['work']['id']) if 'disambiguation' in work_relation['work']: work_disambig.append(work_relation['work']['disambiguation']) @@ -247,7 +247,7 @@ def track_info(recording, index=None, medium=None, medium_index=None, info.arranger = u', '.join(arranger) if work: info.work = u', '.join(work) - info.work_id = u', '.join(work_id) + info.mb_workid = u', '.join(mb_workid) info.work_disambig = u', '.join(work_disambig) info.decode() From 94ef7012cd696020a2577fc0c2be52c08c3ebd7f Mon Sep 17 00:00:00 2001 From: Dorian Soergel Date: Sun, 26 May 2019 15:21:49 +0200 Subject: [PATCH 09/14] update tag mapping to picard 2.1, tag conflict between work and grouping resolved --- beets/mediafile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beets/mediafile.py b/beets/mediafile.py index d2a66379a6..9443cada2f 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -1663,7 +1663,7 @@ def update(self, dict): ) grouping = MediaField( - MP3StorageStyle('TIT1'), + MP3StorageStyle('GRP1'), MP4StorageStyle('\xa9grp'), StorageStyle('GROUPING'), ASFStorageStyle('WM/ContentGroupDescription'), From 7ebcda0c3f80848560e579245238d93a02123c25 Mon Sep 17 00:00:00 2001 From: Dorian Soergel Date: Mon, 27 May 2019 10:04:54 +0200 Subject: [PATCH 10/14] revert changes to mediafile --- beets/mediafile.py | 15 +-------------- test/test_mediafile.py | 1 - 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/beets/mediafile.py b/beets/mediafile.py index 9443cada2f..941a2f8f17 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -1643,27 +1643,14 @@ def update(self, dict): StorageStyle('COMPOSERSORT'), ASFStorageStyle('WM/Composersortorder'), ) - work = MediaField( - MP3StorageStyle('TIT1'), - MP4StorageStyle('\xa9wrk'), - StorageStyle('WORK'), - ASFStorageStyle('WM/Work'), - ) - mb_workid = MediaField( - MP3DescStorageStyle(u'MusicBrainz Work Id'), - MP4StorageStyle('----:com.apple.iTunes:MusicBrainz Work Id'), - StorageStyle('MUSICBRAINZ_WORKID '), - ASFStorageStyle('MusicBrainz/Work Id'), - ) arranger = MediaField( MP3PeopleStorageStyle('TIPL', involvement='arranger'), MP4StorageStyle('----:com.apple.iTunes:Arranger'), StorageStyle('ARRANGER'), ASFStorageStyle('beets/Arranger'), ) - grouping = MediaField( - MP3StorageStyle('GRP1'), + MP3StorageStyle('TIT1'), MP4StorageStyle('\xa9grp'), StorageStyle('GROUPING'), ASFStorageStyle('WM/ContentGroupDescription'), diff --git a/test/test_mediafile.py b/test/test_mediafile.py index 9af4b428f1..36a2c53ac3 100644 --- a/test/test_mediafile.py +++ b/test/test_mediafile.py @@ -352,7 +352,6 @@ class ReadWriteTestBase(ArtTestMixin, GenreListTestMixin, 'lyricist', 'composer', 'composer_sort', - 'work', 'arranger', 'grouping', 'year', From f72ef0d563376024bb08c76c192e880b5994d04c Mon Sep 17 00:00:00 2001 From: Dorian Soergel Date: Mon, 27 May 2019 10:55:12 +0200 Subject: [PATCH 11/14] newline snuck in there --- beets/mediafile.py | 1 + 1 file changed, 1 insertion(+) diff --git a/beets/mediafile.py b/beets/mediafile.py index 941a2f8f17..111b4d73b4 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -1649,6 +1649,7 @@ def update(self, dict): StorageStyle('ARRANGER'), ASFStorageStyle('beets/Arranger'), ) + grouping = MediaField( MP3StorageStyle('TIT1'), MP4StorageStyle('\xa9grp'), From 76e754de41a7f9c0be49d62b9d4e192823e3cac7 Mon Sep 17 00:00:00 2001 From: Dorian Soergel Date: Mon, 27 May 2019 11:03:25 +0200 Subject: [PATCH 12/14] flake8 --- beets/mediafile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beets/mediafile.py b/beets/mediafile.py index 111b4d73b4..32a32fe1d7 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -1649,7 +1649,7 @@ def update(self, dict): StorageStyle('ARRANGER'), ASFStorageStyle('beets/Arranger'), ) - + grouping = MediaField( MP3StorageStyle('TIT1'), MP4StorageStyle('\xa9grp'), From f0d96dcadd103d7e821a79e0b13ef988f4702ef1 Mon Sep 17 00:00:00 2001 From: Dorian Soergel Date: Mon, 27 May 2019 11:59:11 +0200 Subject: [PATCH 13/14] replace work_id by mb_workid --- test/_common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/_common.py b/test/_common.py index 26add0a18c..7a3ece4d8b 100644 --- a/test/_common.py +++ b/test/_common.py @@ -71,7 +71,7 @@ def item(lib=None): arranger=u'the arranger', grouping=u'the grouping', work=u'the work title', - work_id=u'the work musicbrainz id', + mb_workid=u'the work musicbrainz id', work_disambig=u'the work disambiguation', year=1, month=2, From 5f88ec52a54319e0037a41aaa1fb328f8a820473 Mon Sep 17 00:00:00 2001 From: Dorian Soergel Date: Thu, 30 May 2019 22:34:40 +0200 Subject: [PATCH 14/14] fetch only one work --- beets/autotag/mb.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/beets/autotag/mb.py b/beets/autotag/mb.py index a7bb6566d0..b8f91f440c 100644 --- a/beets/autotag/mb.py +++ b/beets/autotag/mb.py @@ -210,16 +210,13 @@ def track_info(recording, index=None, medium=None, medium_index=None, lyricist = [] composer = [] composer_sort = [] - work = [] - mb_workid = [] - work_disambig = [] for work_relation in recording.get('work-relation-list', ()): if work_relation['type'] != 'performance': continue - work.append(work_relation['work']['title']) - mb_workid.append(work_relation['work']['id']) + info.work = work_relation['work']['title'] + info.mb_workid = work_relation['work']['id'] if 'disambiguation' in work_relation['work']: - work_disambig.append(work_relation['work']['disambiguation']) + info.work_disambig = work_relation['work']['disambiguation'] for artist_relation in work_relation['work'].get( 'artist-relation-list', ()): @@ -245,10 +242,6 @@ def track_info(recording, index=None, medium=None, medium_index=None, arranger.append(artist_relation['artist']['name']) if arranger: info.arranger = u', '.join(arranger) - if work: - info.work = u', '.join(work) - info.mb_workid = u', '.join(mb_workid) - info.work_disambig = u', '.join(work_disambig) info.decode() return info