Skip to content

Commit

Permalink
Merge pull request #4940 from AdrienCos/fix/fetchart-caa-use-maxwidth…
Browse files Browse the repository at this point in the history
…-presized-thumbs
  • Loading branch information
Serene-Arc committed Oct 14, 2023
2 parents ff36c7a + 96b89e7 commit 821e629
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 7 deletions.
15 changes: 10 additions & 5 deletions beetsplug/fetchart.py
Expand Up @@ -399,10 +399,15 @@ def get_image_urls(url, preferred_width=None):
if 'Front' not in item['types']:
continue

if preferred_width:
yield item['thumbnails'][preferred_width]
else:
yield item['image']
# If there is a pre-sized thumbnail of the desired size
# we select it. Otherwise, we return the raw image.
image_url: str = item["image"]
if preferred_width is not None:
if isinstance(item.get("thumbnails"), dict):
image_url = item["thumbnails"].get(
preferred_width, image_url
)
yield image_url
except KeyError:
pass

Expand All @@ -422,7 +427,7 @@ def get_image_urls(url, preferred_width=None):
yield self._candidate(url=url, match=Candidate.MATCH_EXACT)

if 'releasegroup' in self.match_by and album.mb_releasegroupid:
for url in get_image_urls(release_group_url):
for url in get_image_urls(release_group_url, preferred_width):
yield self._candidate(url=url, match=Candidate.MATCH_FALLBACK)


Expand Down
6 changes: 6 additions & 0 deletions docs/changelog.rst
Expand Up @@ -125,6 +125,12 @@ New features:
* :doc:`/plugins/autobpm`: Add the `autobpm` plugin which uses Librosa to
calculate the BPM of the audio.
:bug:`3856`
* :doc:`/plugins/fetchart`: Fix the error with CoverArtArchive where the
`maxwidth` option would not be used to download a pre-sized thumbnail for
release groups, as is already done with releases.
* :doc:`/plugins/fetchart`: Fix the error with CoverArtArchive where no cover
would be found when the `maxwidth` option matches a pre-sized thumbnail size,
but no thumbnail is provided by CAA. We now fallback to the raw image.

Bug fixes:

Expand Down
21 changes: 19 additions & 2 deletions docs/plugins/fetchart.rst
Expand Up @@ -41,7 +41,10 @@ file. The available options are:
considered as valid album art candidates. Default: 0.
- **maxwidth**: A maximum image width to downscale fetched images if they are
too big. The resize operation reduces image width to at most ``maxwidth``
pixels. The height is recomputed so that the aspect ratio is preserved.
pixels. The height is recomputed so that the aspect ratio is preserved. See
the section on :ref:`cover-art-archive-maxwidth` below for additional
information regarding the Cover Art Archive source.
Default: 0 (no maximum is enforced).
- **quality**: The JPEG quality level to use when compressing images (when
``maxwidth`` is set). This should be either a number from 1 to 100 or 0 to
use the default quality. 65–75 is usually a good starting point. The default
Expand Down Expand Up @@ -269,7 +272,21 @@ Spotify backend is enabled by default and will update album art if a valid Spoti
Cover Art URL
'''''''''''''

The `fetchart` plugin can also use a flexible attribute field ``cover_art_url`` where you can manually specify the image URL to be used as cover art. Any custom plugin can use this field to provide the cover art and ``fetchart`` will use it as a source.
The `fetchart` plugin can also use a flexible attribute field ``cover_art_url``
where you can manually specify the image URL to be used as cover art. Any custom
plugin can use this field to provide the cover art and ``fetchart`` will use it
as a source.

.. _cover-art-archive-maxwidth:

Cover Art Archive Pre-sized Thumbnails
--------------------------------------

The CAA provides pre-sized thumbnails of width 250, 500, and 1200 pixels. If you
set the `maxwidth` option to one of these values, the corresponding image will
be downloaded, saving `beets` the need to scale down the image. It can also
speed up the downloading process, as some cover arts can sometimes be very
large.

Storing the Artwork's Source
----------------------------
Expand Down
86 changes: 86 additions & 0 deletions test/test_art.py
Expand Up @@ -130,6 +130,39 @@ class CAAHelper():
}
],
"release": "https://musicbrainz.org/release/releaseid"
}"""
RESPONSE_RELEASE_WITHOUT_THUMBNAILS = """{
"images": [
{
"approved": false,
"back": false,
"comment": "GIF",
"edit": 12345,
"front": true,
"id": 12345,
"image": "http://coverartarchive.org/release/rid/12345.gif",
"types": [
"Front"
]
},
{
"approved": false,
"back": false,
"comment": "",
"edit": 12345,
"front": false,
"id": 12345,
"image": "http://coverartarchive.org/release/rid/12345.jpg",
"thumbnails": {
"large": "http://coverartarchive.org/release/rgid/12345-500.jpg",
"small": "http://coverartarchive.org/release/rgid/12345-250.jpg"
},
"types": [
"Front"
]
}
],
"release": "https://musicbrainz.org/release/releaseid"
}"""
RESPONSE_GROUP = """{
"images": [
Expand All @@ -155,6 +188,23 @@ class CAAHelper():
],
"release": "https://musicbrainz.org/release/release-id"
}"""
RESPONSE_GROUP_WITHOUT_THUMBNAILS = """{
"images": [
{
"approved": false,
"back": false,
"comment": "",
"edit": 12345,
"front": true,
"id": 12345,
"image": "http://coverartarchive.org/release/releaseid/12345.jpg",
"types": [
"Front"
]
}
],
"release": "https://musicbrainz.org/release/release-id"
}"""

def mock_caa_response(self, url, json):
responses.add(responses.GET, url, body=json,
Expand Down Expand Up @@ -521,6 +571,42 @@ def test_caa_finds_image(self):
self.assertEqual(len(responses.calls), 2)
self.assertEqual(responses.calls[0].request.url, self.RELEASE_URL)

def test_fetchart_uses_caa_pre_sized_maxwidth_thumbs(self):
# CAA provides pre-sized thumbnails of width 250px, 500px, and 1200px
# We only test with one of them here
maxwidth = 1200
self.settings = Settings(maxwidth=maxwidth)

album = _common.Bag(
mb_albumid=self.MBID_RELASE, mb_releasegroupid=self.MBID_GROUP
)
self.mock_caa_response(self.RELEASE_URL, self.RESPONSE_RELEASE)
self.mock_caa_response(self.GROUP_URL, self.RESPONSE_GROUP)
candidates = list(self.source.get(album, self.settings, []))
self.assertEqual(len(candidates), 3)
for candidate in candidates:
self.assertTrue(f"-{maxwidth}.jpg" in candidate.url)

def test_caa_finds_image_if_maxwidth_is_set_and_thumbnails_is_empty(self):
# CAA provides pre-sized thumbnails of width 250px, 500px, and 1200px
# We only test with one of them here
maxwidth = 1200
self.settings = Settings(maxwidth=maxwidth)

album = _common.Bag(
mb_albumid=self.MBID_RELASE, mb_releasegroupid=self.MBID_GROUP
)
self.mock_caa_response(
self.RELEASE_URL, self.RESPONSE_RELEASE_WITHOUT_THUMBNAILS
)
self.mock_caa_response(
self.GROUP_URL, self.RESPONSE_GROUP_WITHOUT_THUMBNAILS,
)
candidates = list(self.source.get(album, self.settings, []))
self.assertEqual(len(candidates), 3)
for candidate in candidates:
self.assertFalse(f"-{maxwidth}.jpg" in candidate.url)


class FanartTVTest(UseThePlugin):
RESPONSE_MULTIPLE = """{
Expand Down

0 comments on commit 821e629

Please sign in to comment.