diff --git a/picard/coverart/__init__.py b/picard/coverart/__init__.py index 04843ec02..2cf5f009b 100644 --- a/picard/coverart/__init__.py +++ b/picard/coverart/__init__.py @@ -49,6 +49,7 @@ from picard.extension_points.cover_art_processors import ( ) from picard.extension_points.metadata import register_album_metadata_processor from picard.i18n import N_ +from picard.util import imageinfo class CoverArt: @@ -59,6 +60,7 @@ class CoverArt: self.metadata = metadata self.release = release # not used in this class, but used by providers self.front_image_found = False + self.previous_images = album.orig_metadata.images.get_types_dict() def __repr__(self): return "%s for %r" % (self.__class__.__name__, self.album) @@ -99,6 +101,23 @@ class CoverArt: except (CoverArtImageIdentificationError, CoverArtProcessingError) as e: self.album.error_append(e) + def _should_save_image(self, coverartimage, data, info): + log.warning("image save check") + config = get_config() + if config.setting['dont_replace_with_smaller_cover']: + downloaded_types = coverartimage.normalized_types() + log.warning(downloaded_types) + log.warning(self.previous_images.keys()) + if downloaded_types in self.previous_images: + previous_image = self.previous_images[downloaded_types] + log.warning(previous_image) + if info.width < previous_image.width or info.height < previous_image.height: + log.debug("Discarding cover art. A bigger image with the same types is already embedded.") + return False + if coverartimage.can_be_filtered: + return run_image_filters(data) + return True + def _coverart_downloaded(self, coverartimage, data, http, error): """Handle finished download, save it to metadata""" self.album._requests -= 1 @@ -117,16 +136,14 @@ class CoverArt: }, echo=None ) - filters_result = True - if coverartimage.can_be_filtered: - filters_result = run_image_filters(data) - if filters_result: - try: + try: + info = imageinfo.identify(data) + if self._should_save_image(coverartimage, data, info): self._set_metadata(coverartimage, data) - except CoverArtImageIOError: - # It doesn't make sense to store/download more images if we can't - # save them in the temporary folder, abort. - return + except (CoverArtImageIOError, imageinfo.IdentificationError): + # It doesn't make sense to store/download more images if we can't + # save them in the temporary folder, abort. + return self.next_in_queue() diff --git a/picard/options.py b/picard/options.py index fe9b3a079..b10dcd438 100644 --- a/picard/options.py +++ b/picard/options.py @@ -166,6 +166,7 @@ TextOption('setting', 'cd_lookup_device', ','.join(DEFAULT_DRIVES)) ListOption('setting', 'ca_providers', DEFAULT_CA_PROVIDERS, title=N_("Cover art providers")) TextOption('setting', 'cover_image_filename', DEFAULT_COVER_IMAGE_FILENAME, title=N_("File name for images")) BoolOption('setting', 'embed_only_one_front_image', True, title=N_("Embed only a single front image")) +BoolOption('setting', 'dont_replace_with_smaller_cover', False, title=N_("Never replace front images with smaller ones")) BoolOption('setting', 'image_type_as_filename', False, title=N_("Always use the primary image type as the file name for non-front images")) BoolOption('setting', 'save_images_overwrite', False, title=N_("Overwrite existing image files")) BoolOption('setting', 'save_images_to_files', False, title=N_("Save cover images as separate files")) diff --git a/picard/ui/forms/ui_options_cover.py b/picard/ui/forms/ui_options_cover.py index 6a5742895..9eccc49a7 100644 --- a/picard/ui/forms/ui_options_cover.py +++ b/picard/ui/forms/ui_options_cover.py @@ -31,6 +31,9 @@ class Ui_CoverOptionsPage(object): self.cb_embed_front_only = QtWidgets.QCheckBox(parent=self.save_images_to_tags) self.cb_embed_front_only.setObjectName("cb_embed_front_only") self.vboxlayout.addWidget(self.cb_embed_front_only) + self.cb_dont_replace_with_smaller = QtWidgets.QCheckBox(parent=self.save_images_to_tags) + self.cb_dont_replace_with_smaller.setObjectName("cb_dont_replace_with_smaller") + self.vboxlayout.addWidget(self.cb_dont_replace_with_smaller) self.verticalLayout.addWidget(self.save_images_to_tags) self.save_images_to_files = QtWidgets.QGroupBox(parent=CoverOptionsPage) self.save_images_to_files.setCheckable(True) @@ -100,6 +103,7 @@ class Ui_CoverOptionsPage(object): def retranslateUi(self, CoverOptionsPage): self.save_images_to_tags.setTitle(_("Embed cover images into tags")) self.cb_embed_front_only.setText(_("Embed only a single front image")) + self.cb_dont_replace_with_smaller.setText(_("Never replace cover images with smaller ones")) self.save_images_to_files.setTitle(_("Save cover images as separate files")) self.label_use_filename.setText(_("Use the following file name for images:")) self.save_images_overwrite.setText(_("Overwrite the file if it already exists")) diff --git a/picard/ui/options/cover.py b/picard/ui/options/cover.py index 8009bfe8c..374368bf5 100644 --- a/picard/ui/options/cover.py +++ b/picard/ui/options/cover.py @@ -67,6 +67,7 @@ class CoverOptionsPage(OptionsPage): self.register_setting('save_images_to_tags', ['save_images_to_tags']) self.register_setting('embed_only_one_front_image', ['cb_embed_front_only']) + self.register_setting('dont_replace_with_smaller_cover', ['dont_replace_with_smaller_cover']) self.register_setting('save_images_to_files', ['save_images_to_files']) self.register_setting('cover_image_filename', ['cover_image_filename']) self.register_setting('save_images_overwrite', ['save_images_overwrite']) @@ -92,6 +93,7 @@ class CoverOptionsPage(OptionsPage): config = get_config() self.ui.save_images_to_tags.setChecked(config.setting['save_images_to_tags']) self.ui.cb_embed_front_only.setChecked(config.setting['embed_only_one_front_image']) + self.ui.cb_dont_replace_with_smaller.setChecked(config.setting['dont_replace_with_smaller_cover']) self.ui.save_images_to_files.setChecked(config.setting['save_images_to_files']) self.ui.cover_image_filename.setText(config.setting['cover_image_filename']) self.ui.save_images_overwrite.setChecked(config.setting['save_images_overwrite']) @@ -109,6 +111,7 @@ class CoverOptionsPage(OptionsPage): config = get_config() config.setting['save_images_to_tags'] = self.ui.save_images_to_tags.isChecked() config.setting['embed_only_one_front_image'] = self.ui.cb_embed_front_only.isChecked() + config.setting['dont_replace_with_smaller_cover'] = self.ui.cb_dont_replace_with_smaller.isChecked() config.setting['save_images_to_files'] = self.ui.save_images_to_files.isChecked() config.setting['cover_image_filename'] = self.ui.cover_image_filename.text() config.setting['save_images_overwrite'] = self.ui.save_images_overwrite.isChecked() diff --git a/picard/util/imagelist.py b/picard/util/imagelist.py index 0ed70c40d..dd186312b 100644 --- a/picard/util/imagelist.py +++ b/picard/util/imagelist.py @@ -101,3 +101,9 @@ class ImageList(MutableSequence): self._hash_dict = {img.datahash.hash(): img for img in self._images} self._dirty = False return self._hash_dict + + def get_types_dict(self): + types_dict = dict() + for image in self._images: + types_dict[image.normalized_types()] = image + return types_dict diff --git a/ui/options_cover.ui b/ui/options_cover.ui index 1af325c11..a61ea60b4 100644 --- a/ui/options_cover.ui +++ b/ui/options_cover.ui @@ -45,6 +45,13 @@ + + + + Never replace cover images with smaller ones + + + @@ -130,8 +137,7 @@ - - .. + Qt::ToolButtonIconOnly @@ -150,8 +156,7 @@ - - .. + Qt::ToolButtonIconOnly