Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PICARD-2130: Refactor cover art options #1757

Merged
merged 4 commits into from Mar 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion picard/__init__.py
Expand Up @@ -41,7 +41,7 @@
PICARD_DISPLAY_NAME = "MusicBrainz Picard"
PICARD_APP_ID = "org.musicbrainz.Picard"
PICARD_DESKTOP_NAME = PICARD_APP_ID + ".desktop"
PICARD_VERSION = Version(2, 6, 0, 'beta', 1)
PICARD_VERSION = Version(2, 6, 0, 'beta', 2)


# optional build version
Expand Down
9 changes: 8 additions & 1 deletion picard/config_upgrade.py
Expand Up @@ -5,7 +5,7 @@
# Copyright (C) 2013-2014 Michael Wiencek
# Copyright (C) 2013-2016, 2018-2019 Laurent Monin
# Copyright (C) 2014, 2017 Lukáš Lalinský
# Copyright (C) 2014, 2018-2020 Philipp Wolfer
# Copyright (C) 2014, 2018-2021 Philipp Wolfer
# Copyright (C) 2015 Ohm Patel
# Copyright (C) 2016 Suhas
# Copyright (C) 2016-2017 Sambhav Kothari
Expand Down Expand Up @@ -325,6 +325,12 @@ def upgrade_to_v2_6_0_dev_1(config):
config.setting['acoustid_fpcalc'] = ''


def upgrade_to_v2_6_0_beta_2(config):
"""Rename caa_image_type_as_filename and caa_save_single_front_image options"""
rename_option(config, "caa_image_type_as_filename", "image_type_as_filename", BoolOption, False)
rename_option(config, "caa_save_single_front_image", "save_only_one_front_image", BoolOption, False)


def rename_option(config, old_opt, new_opt, option_type, default):
_s = config.setting
if old_opt in _s:
Expand Down Expand Up @@ -352,4 +358,5 @@ def upgrade_config(config):
cfg.register_upgrade_hook(upgrade_to_v2_5_0_dev_1)
cfg.register_upgrade_hook(upgrade_to_v2_5_0_dev_2)
cfg.register_upgrade_hook(upgrade_to_v2_6_0_dev_1)
cfg.register_upgrade_hook(upgrade_to_v2_6_0_beta_2)
cfg.run_upgrade_hooks(log.debug)
12 changes: 7 additions & 5 deletions picard/coverart/image.py
Expand Up @@ -4,7 +4,7 @@
#
# Copyright (C) 2007 Oliver Charles
# Copyright (C) 2007, 2010-2011 Lukáš Lalinský
# Copyright (C) 2007-2011, 2014, 2018-2020 Philipp Wolfer
# Copyright (C) 2007-2011, 2014, 2018-2021 Philipp Wolfer
# Copyright (C) 2011 Michael Wiencek
# Copyright (C) 2011-2012, 2015 Wieland Hoffmann
# Copyright (C) 2013-2015, 2018-2019 Laurent Monin
Expand Down Expand Up @@ -41,7 +41,10 @@
)

from picard import log
from picard.config import get_config
from picard.config import (
Option,
get_config,
)
from picard.coverart.utils import translate_caa_type
from picard.metadata import Metadata
from picard.util import (
Expand Down Expand Up @@ -289,7 +292,7 @@ def _make_image_filename(self, filename, dirname, _metadata):
metadata.add_unique("coverart_types", cover_type)
filename = script_to_filename(filename, metadata)
if not filename:
filename = "cover"
filename = Option.get('setting', 'cover_image_filename').default
if not is_absolute_path(filename):
filename = os.path.join(dirname, filename)
return encode_filename(filename)
Expand All @@ -305,8 +308,7 @@ def save(self, dirname, metadata, counters):
if not self.can_be_saved_to_disk:
return
config = get_config()
if (config.setting["caa_image_type_as_filename"]
and not self.is_front_image()):
if config.setting["image_type_as_filename"] and not self.is_front_image():
filename = self.maintype
log.debug("Make cover filename from types: %r -> %r",
self.types, filename)
Expand Down
10 changes: 1 addition & 9 deletions picard/coverart/providers/caa.py
Expand Up @@ -436,9 +436,7 @@ class ProviderOptionsCaa(ProviderOptions):
HELP_URL = '/config/options_cover_art_archive.html'

options = [
BoolOption("setting", "caa_save_single_front_image", False),
BoolOption("setting", "caa_approved_only", False),
BoolOption("setting", "caa_image_type_as_filename", False),
IntOption("setting", "caa_image_size", _CAA_IMAGE_SIZE_DEFAULT),
ListOption("setting", "caa_image_types", _CAA_IMAGE_TYPE_DEFAULT_INCLUDE),
BoolOption("setting", "caa_restrict_image_types", True),
Expand Down Expand Up @@ -469,9 +467,7 @@ def load(self):
index = self.ui.cb_image_size.findData(_CAA_IMAGE_SIZE_DEFAULT)
self.ui.cb_image_size.setCurrentIndex(index)

self.ui.cb_save_single_front_image.setChecked(config.setting["caa_save_single_front_image"])
self.ui.cb_approved_only.setChecked(config.setting["caa_approved_only"])
self.ui.cb_type_as_filename.setChecked(config.setting["caa_image_type_as_filename"])
self.ui.restrict_images_types.setChecked(
config.setting["caa_restrict_image_types"])
self.caa_image_types = config.setting["caa_image_types"]
Expand All @@ -482,12 +478,8 @@ def save(self):
config = get_config()
size = self.ui.cb_image_size.currentData()
config.setting["caa_image_size"] = size
config.setting["caa_save_single_front_image"] = \
self.ui.cb_save_single_front_image.isChecked()
config.setting["caa_approved_only"] = \
self.ui.cb_approved_only.isChecked()
config.setting["caa_image_type_as_filename"] = \
self.ui.cb_type_as_filename.isChecked()
config.setting["caa_restrict_image_types"] = \
self.ui.restrict_images_types.isChecked()
config.setting["caa_image_types"] = self.caa_image_types
Expand Down Expand Up @@ -665,7 +657,7 @@ def _caa_json_downloaded(self, data, http, error):
# PDFs cannot be saved to tags (as 2014/05/29)
coverartimage.can_be_saved_to_tags = False
self.queue_put(coverartimage)
if config.setting["caa_save_single_front_image"] and \
if config.setting["save_only_one_front_image"] and \
config.setting["save_images_to_files"] and \
image["front"]:
break
Expand Down
2 changes: 1 addition & 1 deletion picard/file.py
Expand Up @@ -516,7 +516,7 @@ def _save_images(self, dirname, metadata):
counters = defaultdict(lambda: 0)
images = []
config = get_config()
if config.setting["caa_save_single_front_image"]:
if config.setting["save_only_one_front_image"]:
front = metadata.images.get_front_image()
if front:
images.append(front)
Expand Down
32 changes: 13 additions & 19 deletions picard/ui/options/cover.py
Expand Up @@ -3,7 +3,7 @@
# Picard, the next-generation MusicBrainz tagger
#
# Copyright (C) 2006-2007 Lukáš Lalinský
# Copyright (C) 2010, 2018-2019 Philipp Wolfer
# Copyright (C) 2010, 2018-2019, 2021 Philipp Wolfer
# Copyright (C) 2012, 2014 Wieland Hoffmann
# Copyright (C) 2012-2014 Michael Wiencek
# Copyright (C) 2013-2015, 2018-2019 Laurent Monin
Expand All @@ -28,6 +28,7 @@
from picard.config import (
BoolOption,
ListOption,
Option,
TextOption,
get_config,
)
Expand Down Expand Up @@ -57,6 +58,8 @@ class CoverOptionsPage(OptionsPage):
BoolOption("setting", "save_images_to_files", False),
TextOption("setting", "cover_image_filename", "cover"),
BoolOption("setting", "save_images_overwrite", False),
BoolOption("setting", "save_only_one_front_image", False),
BoolOption("setting", "image_type_as_filename", False),
ListOption("setting", "ca_providers", [
('Cover Art Archive', True),
('UrlRelationships', True),
Expand All @@ -69,8 +72,10 @@ def __init__(self, parent=None):
super().__init__(parent)
self.ui = Ui_CoverOptionsPage()
self.ui.setupUi(self)
self.ui.save_images_to_files.clicked.connect(self.update_filename)
self.ui.save_images_to_tags.clicked.connect(self.update_save_images_to_tags)
self.ui.cover_image_filename.setPlaceholderText(Option.get('setting', 'cover_image_filename').default)
self.ui.save_images_to_files.clicked.connect(self.update_ca_providers_groupbox_state)
self.ui.save_images_to_tags.clicked.connect(self.update_ca_providers_groupbox_state)
self.ui.save_only_one_front_image.toggled.connect(self.ui.image_type_as_filename.setDisabled)
self.move_view = MoveableListView(self.ui.ca_providers_list, self.ui.up_button,
self.ui.down_button)

Expand Down Expand Up @@ -99,9 +104,11 @@ def load(self):
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"])
self.ui.save_only_one_front_image.setChecked(config.setting["save_only_one_front_image"])
self.ui.image_type_as_filename.setChecked(config.setting["image_type_as_filename"])
self.load_cover_art_providers()
self.ui.ca_providers_list.setCurrentRow(0)
self.update_all()
self.update_ca_providers_groupbox_state()

def save(self):
config = get_config()
Expand All @@ -110,27 +117,14 @@ def save(self):
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()
config.setting["save_only_one_front_image"] = self.ui.save_only_one_front_image.isChecked()
config.setting["image_type_as_filename"] = self.ui.image_type_as_filename.isChecked()
config.setting["ca_providers"] = self.ca_providers()

def update_all(self):
self.update_filename()
self.update_save_images_to_tags()

def update_ca_providers_groupbox_state(self):
files_enabled = self.ui.save_images_to_files.isChecked()
tags_enabled = self.ui.save_images_to_tags.isChecked()
self.ui.ca_providers_groupbox.setEnabled(files_enabled or tags_enabled)

def update_filename(self):
enabled = self.ui.save_images_to_files.isChecked()
self.ui.cover_image_filename.setEnabled(enabled)
self.ui.save_images_overwrite.setEnabled(enabled)
self.update_ca_providers_groupbox_state()

def update_save_images_to_tags(self):
enabled = self.ui.save_images_to_tags.isChecked()
self.ui.cb_embed_front_only.setEnabled(enabled)
self.update_ca_providers_groupbox_state()


register_options_page(CoverOptionsPage)
54 changes: 30 additions & 24 deletions picard/ui/ui_options_cover.py
Expand Up @@ -13,31 +13,40 @@ def setupUi(self, CoverOptionsPage):
CoverOptionsPage.resize(632, 560)
self.verticalLayout = QtWidgets.QVBoxLayout(CoverOptionsPage)
self.verticalLayout.setObjectName("verticalLayout")
self.location = QtWidgets.QGroupBox(CoverOptionsPage)
self.location.setObjectName("location")
self.vboxlayout = QtWidgets.QVBoxLayout(self.location)
self.save_images_to_tags = QtWidgets.QGroupBox(CoverOptionsPage)
self.save_images_to_tags.setCheckable(True)
self.save_images_to_tags.setChecked(False)
self.save_images_to_tags.setObjectName("save_images_to_tags")
self.vboxlayout = QtWidgets.QVBoxLayout(self.save_images_to_tags)
self.vboxlayout.setContentsMargins(9, 9, 9, 9)
self.vboxlayout.setSpacing(2)
self.vboxlayout.setObjectName("vboxlayout")
self.save_images_to_tags = QtWidgets.QCheckBox(self.location)
self.save_images_to_tags.setObjectName("save_images_to_tags")
self.vboxlayout.addWidget(self.save_images_to_tags)
self.cb_embed_front_only = QtWidgets.QCheckBox(self.location)
self.cb_embed_front_only = QtWidgets.QCheckBox(self.save_images_to_tags)
self.cb_embed_front_only.setObjectName("cb_embed_front_only")
self.vboxlayout.addWidget(self.cb_embed_front_only)
self.save_images_to_files = QtWidgets.QCheckBox(self.location)
self.verticalLayout.addWidget(self.save_images_to_tags)
self.save_images_to_files = QtWidgets.QGroupBox(CoverOptionsPage)
self.save_images_to_files.setCheckable(True)
self.save_images_to_files.setChecked(False)
self.save_images_to_files.setObjectName("save_images_to_files")
self.vboxlayout.addWidget(self.save_images_to_files)
self.label_use_filename = QtWidgets.QLabel(self.location)
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.save_images_to_files)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.label_use_filename = QtWidgets.QLabel(self.save_images_to_files)
self.label_use_filename.setObjectName("label_use_filename")
self.vboxlayout.addWidget(self.label_use_filename)
self.cover_image_filename = QtWidgets.QLineEdit(self.location)
self.verticalLayout_2.addWidget(self.label_use_filename)
self.cover_image_filename = QtWidgets.QLineEdit(self.save_images_to_files)
self.cover_image_filename.setObjectName("cover_image_filename")
self.vboxlayout.addWidget(self.cover_image_filename)
self.save_images_overwrite = QtWidgets.QCheckBox(self.location)
self.verticalLayout_2.addWidget(self.cover_image_filename)
self.save_images_overwrite = QtWidgets.QCheckBox(self.save_images_to_files)
self.save_images_overwrite.setObjectName("save_images_overwrite")
self.vboxlayout.addWidget(self.save_images_overwrite)
self.verticalLayout.addWidget(self.location)
self.verticalLayout_2.addWidget(self.save_images_overwrite)
self.save_only_one_front_image = QtWidgets.QCheckBox(self.save_images_to_files)
self.save_only_one_front_image.setObjectName("save_only_one_front_image")
self.verticalLayout_2.addWidget(self.save_only_one_front_image)
self.image_type_as_filename = QtWidgets.QCheckBox(self.save_images_to_files)
self.image_type_as_filename.setObjectName("image_type_as_filename")
self.verticalLayout_2.addWidget(self.image_type_as_filename)
self.verticalLayout.addWidget(self.save_images_to_files)
self.ca_providers_groupbox = QtWidgets.QGroupBox(CoverOptionsPage)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
Expand Down Expand Up @@ -80,19 +89,16 @@ def setupUi(self, CoverOptionsPage):

self.retranslateUi(CoverOptionsPage)
QtCore.QMetaObject.connectSlotsByName(CoverOptionsPage)
CoverOptionsPage.setTabOrder(self.save_images_to_tags, self.cb_embed_front_only)
CoverOptionsPage.setTabOrder(self.cb_embed_front_only, self.save_images_to_files)
CoverOptionsPage.setTabOrder(self.save_images_to_files, self.cover_image_filename)
CoverOptionsPage.setTabOrder(self.cover_image_filename, self.save_images_overwrite)

def retranslateUi(self, CoverOptionsPage):
_translate = QtCore.QCoreApplication.translate
self.location.setTitle(_("Location"))
self.save_images_to_tags.setText(_("Embed cover images into tags"))
self.cb_embed_front_only.setText(_("Only embed a front image"))
self.save_images_to_files.setText(_("Save cover images as separate files"))
self.save_images_to_tags.setTitle(_("Embed cover images into tags"))
self.cb_embed_front_only.setText(_("Embed only a single front image"))
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"))
self.save_only_one_front_image.setText(_("Save only a single front image as separate file"))
self.image_type_as_filename.setText(_("Always use the primary image type as the file name for non-front images"))
self.ca_providers_groupbox.setTitle(_("Cover Art Providers"))
self.move_label.setText(_("Reorder Priority: "))
self.up_button.setToolTip(_("Move selected item up"))
Expand Down
20 changes: 3 additions & 17 deletions picard/ui/ui_provider_options_caa.py
Expand Up @@ -3,8 +3,10 @@
# Automatically generated - don't edit.
# Use `python setup.py build_ui` to update it.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_CaaOptions(object):
def setupUi(self, CaaOptions):
CaaOptions.setObjectName("CaaOptions")
Expand Down Expand Up @@ -49,38 +51,22 @@ def setupUi(self, CaaOptions):
self.cb_image_size.setObjectName("cb_image_size")
self.horizontalLayout.addWidget(self.cb_image_size)
self.verticalLayout.addLayout(self.horizontalLayout)
self.cb_save_single_front_image = QtWidgets.QCheckBox(CaaOptions)
self.cb_save_single_front_image.setObjectName("cb_save_single_front_image")
self.verticalLayout.addWidget(self.cb_save_single_front_image)
self.cb_approved_only = QtWidgets.QCheckBox(CaaOptions)
self.cb_approved_only.setObjectName("cb_approved_only")
self.verticalLayout.addWidget(self.cb_approved_only)
self.cb_type_as_filename = QtWidgets.QCheckBox(CaaOptions)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.cb_type_as_filename.sizePolicy().hasHeightForWidth())
self.cb_type_as_filename.setSizePolicy(sizePolicy)
self.cb_type_as_filename.setObjectName("cb_type_as_filename")
self.verticalLayout.addWidget(self.cb_type_as_filename)
spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem2)

self.retranslateUi(CaaOptions)
QtCore.QMetaObject.connectSlotsByName(CaaOptions)
CaaOptions.setTabOrder(self.restrict_images_types, self.select_caa_types)
CaaOptions.setTabOrder(self.select_caa_types, self.cb_image_size)
CaaOptions.setTabOrder(self.cb_image_size, self.cb_save_single_front_image)
CaaOptions.setTabOrder(self.cb_save_single_front_image, self.cb_approved_only)
CaaOptions.setTabOrder(self.cb_approved_only, self.cb_type_as_filename)
CaaOptions.setTabOrder(self.cb_image_size, self.cb_approved_only)

def retranslateUi(self, CaaOptions):
_translate = QtCore.QCoreApplication.translate
CaaOptions.setWindowTitle(_("Form"))
self.restrict_images_types.setText(_("Download only cover art images matching selected types"))
self.select_caa_types.setText(_("Select types..."))
self.label.setText(_("Only use images of the following size:"))
self.cb_save_single_front_image.setText(_("Save only one front image as separate file"))
self.cb_approved_only.setText(_("Download only approved images"))
self.cb_type_as_filename.setText(_("Use the first image type as the filename. This will not change the filename of front images."))

15 changes: 14 additions & 1 deletion test/test_config_upgrade.py
Expand Up @@ -3,7 +3,7 @@
# Picard, the next-generation MusicBrainz tagger
#
# Copyright (C) 2019 Laurent Monin
# Copyright (C) 2019-2020 Philipp Wolfer
# Copyright (C) 2019-2021 Philipp Wolfer
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
Expand Down Expand Up @@ -51,6 +51,7 @@
upgrade_to_v2_4_0_beta_3,
upgrade_to_v2_5_0_dev_1,
upgrade_to_v2_5_0_dev_2,
upgrade_to_v2_6_0_beta_2,
upgrade_to_v2_6_0_dev_1,
)
from picard.const import (
Expand Down Expand Up @@ -317,3 +318,15 @@ def test_upgrade_to_v2_6_0_dev_1_frozen(self):
upgrade_to_v2_6_0_dev_1(self.config)
picard.config_upgrade.IS_FROZEN = False
self.assertEqual("", self.config.setting["acoustid_fpcalc"])

def test_upgrade_to_v2_6_0_beta_2(self):
BoolOption('setting', 'image_type_as_filename', False)
BoolOption('setting', 'save_only_one_front_image', False)

self.config.setting['caa_image_type_as_filename'] = True
self.config.setting['caa_save_single_front_image'] = True
upgrade_to_v2_6_0_beta_2(self.config)
self.assertNotIn('caa_image_type_as_filename', self.config.setting)
self.assertTrue(self.config.setting['image_type_as_filename'])
self.assertNotIn('caa_save_single_front_image', self.config.setting)
self.assertTrue(self.config.setting['save_only_one_front_image'])