diff --git a/beetsplug/discogs.py b/beetsplug/discogs.py index 344d67a243..0dc8e8a175 100644 --- a/beetsplug/discogs.py +++ b/beetsplug/discogs.py @@ -16,6 +16,8 @@ python3-discogs-client library. """ +from __future__ import annotations + import http.client import json import os @@ -30,6 +32,7 @@ from discogs_client import __version__ as dc_string from discogs_client.exceptions import DiscogsAPIError from requests.exceptions import ConnectionError +from typing_extensions import TypedDict import beets import beets.ui @@ -52,6 +55,12 @@ ) +class ReleaseFormat(TypedDict): + name: str + qty: int + descriptions: list[str] | None + + class DiscogsPlugin(BeetsPlugin): def __init__(self): super().__init__() @@ -363,6 +372,18 @@ def get_master_year(self, master_id): ) return None + @staticmethod + def get_media_and_albumtype( + formats: list[ReleaseFormat] | None, + ) -> tuple[str | None, str | None]: + media = albumtype = None + if formats and (first_format := formats[0]): + if descriptions := first_format["descriptions"]: + albumtype = ", ".join(descriptions) + media = first_format["name"] + + return media, albumtype + def get_album_info(self, result): """Returns an AlbumInfo object for a discogs Release object.""" # Explicitly reload the `Release` fields, as they might not be yet @@ -413,13 +434,11 @@ def get_album_info(self, result): # Extract information for the optional AlbumInfo fields that are # contained on nested discogs fields. - albumtype = media = label = catalogno = labelid = None - if result.data.get("formats"): - albumtype = ( - ", ".join(result.data["formats"][0].get("descriptions", [])) - or None - ) - media = result.data["formats"][0]["name"] + media, albumtype = self.get_media_and_albumtype( + result.data.get("formats") + ) + + label = catalogno = labelid = None if result.data.get("labels"): label = result.data["labels"][0].get("name") catalogno = result.data["labels"][0].get("catno") diff --git a/docs/changelog.rst b/docs/changelog.rst index 9474604b42..f0f7da7e9f 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -23,9 +23,9 @@ New features: Bug fixes: -* Improved naming of temporary files by separating the random part with the file extension. -* Fixed the ``auto`` value for the :ref:`reflink` config option. -* Fixed lyrics plugin only getting part of the lyrics from ``Genius.com`` :bug:`4815` +* Improve naming of temporary files by separating the random part with the file extension. +* Fix the ``auto`` value for the :ref:`reflink` config option. +* Fix lyrics plugin only getting part of the lyrics from ``Genius.com`` :bug:`4815` * Album flexible fields are now correctly saved. For instance MusicBrainz external links such as `bandcamp_album_id` will be available on albums in addition to tracks. For albums already in your library, a re-import is required for the fields to be added. @@ -34,6 +34,7 @@ Bug fixes: as a numpy array. Update ``librosa`` dependency constraint to prevent similar issues in the future. :bug:`5289` +* :doc:`plugins/discogs`: Fix the ``TypeError`` when there is no description. For packagers: diff --git a/test/plugins/test_discogs.py b/test/plugins/test_discogs.py index 634b3cdb96..8a4609e253 100644 --- a/test/plugins/test_discogs.py +++ b/test/plugins/test_discogs.py @@ -12,9 +12,9 @@ # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. -"""Tests for discogs plugin. -""" +"""Tests for discogs plugin.""" +import pytest from beets import config from beets.test._common import Bag @@ -423,3 +423,26 @@ def test_append_style_to_genre_no_style(self): d = DiscogsPlugin().get_album_info(release) assert d.genre == "GENRE1, GENRE2" assert d.style is None + + +@pytest.mark.parametrize( + "formats, expected_media, expected_albumtype", + [ + (None, None, None), + ( + [ + { + "descriptions": ['7"', "Single", "45 RPM"], + "name": "Vinyl", + "qty": 1, + } + ], + "Vinyl", + '7", Single, 45 RPM', + ), + ], +) +def test_get_media_and_albumtype(formats, expected_media, expected_albumtype): + result = DiscogsPlugin.get_media_and_albumtype(formats) + + assert result == (expected_media, expected_albumtype)