diff --git a/beets/config_default.yaml b/beets/config_default.yaml index c0bab8056..b0b495a22 100644 --- a/beets/config_default.yaml +++ b/beets/config_default.yaml @@ -7,7 +7,6 @@ statefile: state.pickle # --------------- Plugins --------------- plugins: [musicbrainz] - pluginpath: [] # --------------- Import --------------- diff --git a/beets/library/models.py b/beets/library/models.py index cbee2a411..95da619e3 100644 --- a/beets/library/models.py +++ b/beets/library/models.py @@ -361,6 +361,7 @@ class Album(LibModel): getters = plugins.album_field_getters() getters["path"] = Album.item_dir getters["albumtotal"] = Album._albumtotal + getters["media_types"] = lambda a: a.media_types return getters def items(self): diff --git a/beetsplug/discogs.py b/beetsplug/discogs.py index 29600a676..feaba4660 100644 --- a/beetsplug/discogs.py +++ b/beetsplug/discogs.py @@ -780,10 +780,21 @@ class DiscogsPlugin(MetadataSourcePlugin): featured_list, self.config["anv"]["artist_credit"] ) if featured: - artist += f" {self.config['featured_string']} {featured}" - artist_credit += ( - f" {self.config['featured_string']} {featured_credit}" - ) + featured_string = self.config["featured_string"].as_str() + token = f"{featured_string} {featured}".lower() + token_credit = f"{featured_string} {featured_credit}".lower() + + # Only append if this featured artist isn't already present + if token not in artist.lower(): + artist += f" {featured_string} {featured}" + + if token_credit not in artist_credit.lower(): + artist_credit += f" {featured_string} {featured_credit}" + # Previous code + # artist += f" {self.config['featured_string']} {featured}" + # artist_credit += ( + # f" {self.config['featured_string']} {featured_credit}" + # ) return IntermediateTrackInfo( title=title, track_id=track_id, diff --git a/docs/changelog.rst b/docs/changelog.rst index 76951a541..8eeefe2a5 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -27,6 +27,7 @@ New features: - :doc:`plugins/mbpseudo`: Add a new `mbpseudo` plugin to proactively receive MusicBrainz pseudo-releases as recommendations during import. - Added support for Python 3.13. +- Added album-level `$media` field derived from items’ media metadata. - :doc:`plugins/titlecase`: Add the `titlecase` plugin to allow users to resolve differences in metadata source styles. diff --git a/test/plugins/test_discogs.py b/test/plugins/test_discogs.py index eb65bc588..2cf5e924d 100644 --- a/test/plugins/test_discogs.py +++ b/test/plugins/test_discogs.py @@ -601,6 +601,30 @@ def test_anv_album_artist(): }, "NEW ARTIST, VOCALIST Feat. SOLOIST, PERFORMER, MUSICIAN", ), + ( + { + "type_": "track", + "title": "Infinite Regression", + "position": "6", + "duration": "5:00", + "artists": [ + { + "name": "Filteria Feat. Ukiro", + "tracks": "", + "id": 11146, + "join": "", + } + ], + "extraartists": [ + { + "name": "Ukiro", + "id": 3, + "role": "Featuring", + }, + ], + }, + "Filteria Feat. Ukiro", + ), ], ) @patch("beetsplug.discogs.DiscogsPlugin.setup", Mock()) diff --git a/test/test_media_field.py b/test/test_media_field.py new file mode 100644 index 000000000..8c2f1d846 --- /dev/null +++ b/test/test_media_field.py @@ -0,0 +1,48 @@ +# import unittest + +# from beets.library import Item, Library + + +# class MediaFieldTest(unittest.TestCase): +# def setUp(self): +# self.lib = Library(":memory:") +# self.lib.add_album = self.lib.add_album + +# def add_album_with_items(self, items_data): +# items = [] +# for data in items_data: +# item = Item(**data) +# items.append(item) +# album = self.lib.add_album(items) +# return album + +# def test_album_media_field_multiple_types(self): +# items_data = [ +# {"title": "Track 1", "artist": "Artist A", "media": "CD"}, +# {"title": "Track 2", "artist": "Artist A", "media": "Vinyl"}, +# ] +# album = self.add_album_with_items(items_data) +# media = album.media +# assert sorted(media) == ["CD", "Vinyl"] + +# def test_album_media_field_single_type(self): +# items_data = [ +# {"title": "Track 1", "artist": "Artist A", "media": "CD"}, +# {"title": "Track 2", "artist": "Artist A", "media": "CD"}, +# ] +# album = self.add_album_with_items(items_data) +# media = album.media +# assert media == ["CD"] + +# def test_album_with_no_media(self): +# items_data = [ +# {"title": "Track 1", "artist": "Artist A"}, +# {"title": "Track 2", "artist": "Artist A"}, +# ] +# album = self.add_album_with_items(items_data) +# media = album.media +# assert media == [] + + +# if __name__ == "__main__": +# unittest.main()