diff --git a/beets/autotag/__init__.py b/beets/autotag/__init__.py index 4d107b3a1c..009d98108f 100644 --- a/beets/autotag/__init__.py +++ b/beets/autotag/__init__.py @@ -190,12 +190,21 @@ def apply_item_metadata(item: Item, track_info: TrackInfo): item.artist_credit = track_info.artist_credit item.artists_credit = track_info.artists_credit item.title = track_info.title + item.lyricists = track_info.lyricists + item.composers = track_info.composers + item.arrangers = track_info.arrangers item.mb_trackid = track_info.track_id item.mb_releasetrackid = track_info.release_track_id if track_info.artist_id: item.mb_artistid = track_info.artist_id if track_info.artists_ids: item.mb_artistids = track_info.artists_ids + if track_info.lyricists_ids: + item.mb_lyricistids = track_info.lyricists_ids + if track_info.composers_ids: + item.mb_composerids = track_info.composers_ids + if track_info.arrangers_ids: + item.mb_arrangerids = track_info.arrangers_ids _apply_metadata(track_info, item) correct_list_fields(item) diff --git a/beets/autotag/hooks.py b/beets/autotag/hooks.py index 7cd215fc49..d4125dae59 100644 --- a/beets/autotag/hooks.py +++ b/beets/autotag/hooks.py @@ -195,9 +195,15 @@ def __init__( data_url: str | None = None, media: str | None = None, lyricist: str | None = None, + lyricists: list[str] | None = None, + lyricists_ids: list[str] | None = None, composer: str | None = None, composer_sort: str | None = None, + composers: list[str] | None = None, + composers_ids: list[str] | None = None, arranger: str | None = None, + arrangers: list[str] | None = None, + arrangers_ids: list[str] | None = None, track_alt: str | None = None, work: str | None = None, mb_workid: str | None = None, @@ -229,9 +235,15 @@ def __init__( self.data_source = data_source self.data_url = data_url self.lyricist = lyricist + self.lyricists = lyricists or [] + self.lyricists_ids = lyricists_ids or [] self.composer = composer self.composer_sort = composer_sort + self.composers = composers or [] + self.composers_ids = composers_ids or [] self.arranger = arranger + self.arrangers = arrangers or [] + self.arrangers_ids = arrangers_ids or [] self.track_alt = track_alt self.work = work self.mb_workid = mb_workid diff --git a/beets/library/models.py b/beets/library/models.py index 7501513a1c..16f85b1ab5 100644 --- a/beets/library/models.py +++ b/beets/library/models.py @@ -648,12 +648,18 @@ class Item(LibModel): "discogs_artistid": types.INTEGER, "discogs_labelid": types.INTEGER, "lyricist": types.STRING, + "lyricists": types.MULTI_VALUE_DSV, + "lyricists_ids": types.MULTI_VALUE_DSV, "composer": types.STRING, "composer_sort": types.STRING, + "composers": types.MULTI_VALUE_DSV, + "composers_ids": types.MULTI_VALUE_DSV, "work": types.STRING, "mb_workid": types.STRING, "work_disambig": types.STRING, "arranger": types.STRING, + "arrangers": types.MULTI_VALUE_DSV, + "arrangers_ids": types.MULTI_VALUE_DSV, "grouping": types.STRING, "year": types.PaddedInt(4), "month": types.PaddedInt(2), @@ -670,6 +676,9 @@ class Item(LibModel): "mb_albumid": types.STRING, "mb_artistid": types.STRING, "mb_artistids": types.MULTI_VALUE_DSV, + "mb_lyricistids": types.MULTI_VALUE_DSV, + "mb_composerids": types.MULTI_VALUE_DSV, + "mb_arrangerids": types.MULTI_VALUE_DSV, "mb_albumartistid": types.STRING, "mb_albumartistids": types.MULTI_VALUE_DSV, "mb_releasetrackid": types.STRING, diff --git a/beetsplug/musicbrainz.py b/beetsplug/musicbrainz.py index b52e44b239..01d3666d46 100644 --- a/beetsplug/musicbrainz.py +++ b/beetsplug/musicbrainz.py @@ -454,8 +454,10 @@ def track_info( if recording.get("isrc-list"): info.isrc = ";".join(recording["isrc-list"]) - lyricist = [] - composer = [] + lyricists = [] + lyricists_ids = [] + composers = [] + composers_ids = [] composer_sort = [] for work_relation in recording.get("work-relation-list", ()): if work_relation["type"] != "performance": @@ -471,26 +473,36 @@ def track_info( if "type" in artist_relation: type = artist_relation["type"] if type == "lyricist": - lyricist.append(artist_relation["artist"]["name"]) + lyricists.append(artist_relation["artist"]["name"]) + lyricists_ids.append(artist_relation["artist"]["id"]) elif type == "composer": - composer.append(artist_relation["artist"]["name"]) + composers.append(artist_relation["artist"]["name"]) + composers_ids.append(artist_relation["artist"]["id"]) composer_sort.append( artist_relation["artist"]["sort-name"] ) - if lyricist: - info.lyricist = ", ".join(lyricist) - if composer: - info.composer = ", ".join(composer) + if lyricists: + info.lyricist = ", ".join(lyricists) + info.lyricists = lyricists + info.lyricists_ids = lyricists_ids + if composers: + info.composer = ", ".join(composers) + info.composers = composers + info.composers_ids = composers_ids info.composer_sort = ", ".join(composer_sort) - arranger = [] + arrangers = [] + arrangers_ids = [] for artist_relation in recording.get("artist-relation-list", ()): if "type" in artist_relation: type = artist_relation["type"] if type == "arranger": - arranger.append(artist_relation["artist"]["name"]) - if arranger: - info.arranger = ", ".join(arranger) + arrangers.append(artist_relation["artist"]["name"]) + arrangers_ids.append(artist_relation["artist"]["id"]) + if arrangers: + info.arranger = ", ".join(arrangers) + info.arrangers = arrangers + info.arrangers_ids = arrangers_ids # Supplementary fields provided by plugins extra_trackdatas = plugins.send("mb_track_extract", data=recording) diff --git a/docs/changelog.rst b/docs/changelog.rst index ab896a7ff3..4fd0fa7e48 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -32,6 +32,9 @@ New features: ``played_ratio_threshold``, to allow configuring the percentage the song must be played for it to be counted as played instead of skipped. - :doc:`plugins/web`: Display artist and album as part of the search results. +- :doc:`plugins/musicbrainz`: The MusicBrainz autotagger now also + imports composers, lyricists, and arrangers, as well as their MBIDs + as multi-valued tags (``composers``, ``lyricists``, ``mb_composerids``, …). Bug fixes: