diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index d549136af0..7e97eedb52 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -97,7 +97,15 @@ print(d['small'])
In above example, `l1` contains identifiers (keys of dict `d`) while others are English words/phrases.
In the dict declaration, keys are single-quoted but values are double-quoted.
-Otherwise, choose whichever limit the number of escaped characters.
+URIs (and paths used in URIs) should be, in general, enclosed in double quotes,
+mainly because single quotes can appear in URI, unencoded, as sub-delimiters as specified
+by [RFC3986](https://www.rfc-editor.org/rfc/rfc3986#section-2.2).
+
+HTML/XML code often contains attributes that are enclosed by double quotes, so in this case,
+better use single quotes, e.g. `html = 'text'`.
+
+In doubt, choose whichever limit the number of escaped characters.
+Typically single quote strings that are meant to contain double quotes (e.g. `'The file is "{file}"'`).
## Git Work-flow
diff --git a/picard/acoustid/__init__.py b/picard/acoustid/__init__.py
index fce1b386ba..e319008e42 100644
--- a/picard/acoustid/__init__.py
+++ b/picard/acoustid/__init__.py
@@ -264,7 +264,7 @@ def _run_next_task(self):
# long path support is enabled. Ensure the path is properly prefixed.
if IS_WIN:
file_path = win_prefix_longpath(file_path)
- process.start(self._fpcalc, ["-json", "-length", "120", file_path])
+ process.start(self._fpcalc, ['-json', '-length', '120', file_path])
log.debug("Starting fingerprint calculator %r %r", self._fpcalc, task.file.filename)
def analyze(self, file, next_func):
@@ -273,7 +273,7 @@ def analyze(self, file, next_func):
config = get_config()
fingerprint = task.file.acoustid_fingerprint
- if not fingerprint and not config.setting["ignore_existing_acoustid_fingerprints"]:
+ if not fingerprint and not config.setting['ignore_existing_acoustid_fingerprints']:
# use cached fingerprint from file metadata
fingerprints = task.file.metadata.getall('acoustid_fingerprint')
if fingerprints:
diff --git a/picard/acoustid/manager.py b/picard/acoustid/manager.py
index 1478fab01b..23929684ed 100644
--- a/picard/acoustid/manager.py
+++ b/picard/acoustid/manager.py
@@ -206,7 +206,7 @@ def _batch_submit(self, submissions, errors=None):
log.debug("AcoustID: submitting batch of %d fingerprints (%d remaining)…",
len(batch), len(submissions))
self.tagger.window.set_statusbar_message(
- N_('Submitting AcoustIDs …'),
+ N_("Submitting AcoustIDs …"),
echo=None
)
if not errors:
@@ -228,7 +228,7 @@ def _batch_submit_finished(self, submissions, batch, previous_errors, document,
else:
try:
errordoc = load_json(document)
- message = errordoc["error"]["message"]
+ message = errordoc['error']['message']
except BaseException:
message = ""
mparms = {
@@ -241,7 +241,7 @@ def _batch_submit_finished(self, submissions, batch, previous_errors, document,
self.tagger.window.set_statusbar_message(
log_msg, mparms, echo=None, timeout=3000)
else:
- log.debug('AcoustID: %d fingerprints successfully submitted', len(batch))
+ log.debug("AcoustID: %d fingerprints successfully submitted", len(batch))
for file, submission in batch:
submission.orig_recordingid = submission.recordingid
file.update()
diff --git a/picard/album.py b/picard/album.py
index 896fe924d1..b5eaae2d20 100644
--- a/picard/album.py
+++ b/picard/album.py
@@ -154,7 +154,7 @@ def __init__(self, album_id, discid=None):
self.update_metadata_images_enabled = True
def __repr__(self):
- return '' % (self.id, self.metadata["album"])
+ return '' % (self.id, self.metadata['album'])
def iterfiles(self, save=False):
for track in self.tracks:
@@ -288,11 +288,11 @@ def _release_request_finished(self, document, http, error):
if error == QtNetwork.QNetworkReply.NetworkError.ContentNotFoundError:
config = get_config()
nats = False
- nat_name = config.setting["nat_name"]
+ nat_name = config.setting['nat_name']
files = list(self.unmatched_files.files)
for file in files:
- recordingid = file.metadata["musicbrainz_recordingid"]
- if mbid_validate(recordingid) and file.metadata["album"] == nat_name:
+ recordingid = file.metadata['musicbrainz_recordingid']
+ if mbid_validate(recordingid) and file.metadata['album'] == nat_name:
nats = True
self.tagger.move_file_to_nat(file, recordingid)
self.tagger.nats.update()
@@ -304,7 +304,7 @@ def _release_request_finished(self, document, http, error):
parse_result = self._parse_release(document)
config = get_config()
if parse_result == ParseResult.MISSING_TRACK_RELS:
- log.debug('Recording relationships not loaded in initial request for %r, issuing separate requests', self)
+ log.debug("Recording relationships not loaded in initial request for %r, issuing separate requests", self)
self._request_recording_relationships()
elif parse_result == ParseResult.PARSED:
self._run_album_metadata_processors()
@@ -327,7 +327,7 @@ def _request_recording_relationships(self, offset=0, limit=RECORDING_QUERY_LIMIT
'work-rels',
'work-level-rels',
)
- log.debug('Loading recording relationships for %r (offset=%i, limit=%i)', self, offset, limit)
+ log.debug("Loading recording relationships for %r (offset=%i, limit=%i)", self, offset, limit)
self._requests += 1
self.load_task = self.tagger.mb_api.browse_recordings(
self._recordings_request_finished,
@@ -400,7 +400,7 @@ def _finalize_loading_track(self, track_node, metadata, artists, extra_metadata=
track._customize_metadata()
self._new_metadata.length += tm.length
- artists.add(tm["artist"])
+ artists.add(tm['artist'])
if extra_metadata:
tm.update(extra_metadata)
@@ -426,7 +426,7 @@ def _load_track(node, mm, artists, extra_metadata):
va = self._new_metadata['musicbrainz_albumartistid'] == VARIOUS_ARTISTS_ID
djmix_ars = {}
- if hasattr(self._new_metadata, "_djmix_ars"):
+ if hasattr(self._new_metadata, '_djmix_ars'):
djmix_ars = self._new_metadata._djmix_ars
for medium_node in self._release_node['media']:
@@ -437,13 +437,13 @@ def _load_track(node, mm, artists, extra_metadata):
if fmt:
all_media.append(fmt)
- for dj in djmix_ars.get(mm["discnumber"], []):
- mm.add("djmixer", dj)
+ for dj in djmix_ars.get(mm['discnumber'], []):
+ mm.add('djmixer', dj)
if va:
- mm["compilation"] = "1"
+ mm['compilation'] = '1'
else:
- del mm["compilation"]
+ del mm['compilation']
if 'discs' in medium_node:
discids = [disc.get('id') for disc in medium_node['discs']]
@@ -468,9 +468,9 @@ def _load_track(node, mm, artists, extra_metadata):
multiartists = len(artists) > 1
for track in self._new_tracks:
- track.metadata["~totalalbumtracks"] = totalalbumtracks
+ track.metadata['~totalalbumtracks'] = totalalbumtracks
if multiartists:
- track.metadata["~multiartist"] = "1"
+ track.metadata['~multiartist'] = '1'
del self._release_node
del self._release_artist_nodes
self._tracks_loaded = True
@@ -535,10 +535,10 @@ def _finalize_loading(self, error):
import inspect
stack = inspect.stack()
args = [self]
- msg = 'Album._finalize_loading called for already loaded album %r'
+ msg = "Album._finalize_loading called for already loaded album %r"
if len(stack) > 1:
f = stack[1]
- msg += ' at %s:%d in %s'
+ msg += " at %s:%d in %s"
args.extend((f.filename, f.lineno, f.function))
log.warning(msg, *args)
return
@@ -570,7 +570,7 @@ def load(self, priority=False, refresh=False):
log.info("Not reloading, some requests are still active.")
return
self.tagger.window.set_statusbar_message(
- N_('Loading album %(id)s …'),
+ N_("Loading album %(id)s …"),
{'id': self.id}
)
self.loaded = False
@@ -863,18 +863,18 @@ def keep_original_images(self):
class NatAlbum(Album):
def __init__(self):
- super().__init__("NATS")
+ super().__init__('NATS')
self.loaded = True
self.update()
def update(self, update_tracks=True, update_selection=True):
config = get_config()
self.enable_update_metadata_images(False)
- old_album_title = self.metadata["album"]
- self.metadata["album"] = config.setting["nat_name"]
+ old_album_title = self.metadata['album']
+ self.metadata['album'] = config.setting['nat_name']
for track in self.tracks:
- if old_album_title == track.metadata["album"]:
- track.metadata["album"] = self.metadata["album"]
+ if old_album_title == track.metadata['album']:
+ track.metadata['album'] = self.metadata['album']
for file in track.files:
track.update_file_metadata(file)
self.enable_update_metadata_images(True)
diff --git a/picard/browser/addrelease.py b/picard/browser/addrelease.py
index 9b838c0026..03d9cd9cfd 100644
--- a/picard/browser/addrelease.py
+++ b/picard/browser/addrelease.py
@@ -37,7 +37,7 @@
import jwt
import jwt.exceptions
except ImportError:
- log.debug('PyJWT not available, addrelease functionality disabled')
+ log.debug("PyJWT not available, addrelease functionality disabled")
jwt = None
__key = token_bytes() # Generating a new secret on each startup
@@ -89,18 +89,18 @@ def submit_file(file, as_release=False):
def serve_form(token):
try:
payload = jwt.decode(token, __key, algorithms=__algorithm)
- log.debug('received JWT token %r', payload)
+ log.debug("received JWT token %r", payload)
tagger = QCoreApplication.instance()
tport = tagger.browser_integration.port
if 'cluster' in payload:
cluster = _find_cluster(tagger, payload['cluster'])
if not cluster:
- raise NotFoundError('Cluster not found')
+ raise NotFoundError("Cluster not found")
return _get_cluster_form(cluster, tport)
elif 'file' in payload:
file = _find_file(tagger, payload['file'])
if not file:
- raise NotFoundError('File not found')
+ raise NotFoundError("File not found")
if payload.get('as_release', False):
return _get_file_as_release_form(file, tport)
else:
@@ -141,9 +141,9 @@ def _find_file(tagger, path):
def _get_cluster_form(cluster, tport):
return _get_form(
- _('Add cluster as release'),
+ _("Add cluster as release"),
'/release/add',
- _('Add cluster as release…'),
+ _("Add cluster as release…"),
_get_cluster_data(cluster),
{'tport': tport}
)
@@ -151,9 +151,9 @@ def _get_cluster_form(cluster, tport):
def _get_file_as_release_form(file, tport):
return _get_form(
- _('Add file as release'),
+ _("Add file as release"),
'/release/add',
- _('Add file as release…'),
+ _("Add file as release…"),
_get_file_as_release_data(file),
{'tport': tport}
)
@@ -161,9 +161,9 @@ def _get_file_as_release_form(file, tport):
def _get_file_as_recording_form(file, tport):
return _get_form(
- _('Add file as recording'),
+ _("Add file as recording"),
'/recording/create',
- _('Add file as recording…'),
+ _("Add file as recording…"),
_get_file_as_recording_data(file),
{'tport': tport}
)
diff --git a/picard/browser/filelookup.py b/picard/browser/filelookup.py
index 07ca9a2774..48b3748b37 100644
--- a/picard/browser/filelookup.py
+++ b/picard/browser/filelookup.py
@@ -133,7 +133,7 @@ def mbid_lookup(self, string, type_=None, mbid_matched_callback=None, browser_fa
id = m.group('id')
if entity != 'cdtoc':
id = id.lower()
- log.debug('Lookup for %s:%s', entity, id)
+ log.debug("Lookup for %s:%s", entity, id)
if mbid_matched_callback:
mbid_matched_callback(entity, id)
if entity == 'release':
@@ -162,10 +162,10 @@ def tag_lookup(self, artist, release, track, tracknum, duration, filename):
'duration': duration,
'filename': os.path.basename(filename),
}
- return self._build_launch('/taglookup', params)
+ return self._build_launch("/taglookup", params)
def collection_lookup(self, userid):
- return self._build_launch('/user/%s/collections' % userid)
+ return self._build_launch("/user/%s/collections" % userid)
def search_entity(self, type_, query, adv=False, mbid_matched_callback=None, force_browser=False):
if not force_browser and self.mbid_lookup(query, type_, mbid_matched_callback=mbid_matched_callback):
@@ -178,4 +178,4 @@ def search_entity(self, type_, query, adv=False, mbid_matched_callback=None, for
}
if adv:
params['adv'] = 'on'
- return self._build_launch('/search/textsearch', params)
+ return self._build_launch("/search/textsearch", params)
diff --git a/picard/cluster.py b/picard/cluster.py
index 221f50fbd0..9d32ad5110 100644
--- a/picard/cluster.py
+++ b/picard/cluster.py
@@ -120,7 +120,7 @@ def __repr__(self):
if self.related_album:
return '' % (
self.related_album.id,
- self.related_album.metadata["album"] + '/' + self.metadata['album']
+ self.related_album.metadata['album'] + '/' + self.metadata['album']
)
return '' % self.metadata['album']
@@ -308,8 +308,8 @@ def cluster(files):
cluster_list = defaultdict(FileCluster)
for file in files:
- artist = file.metadata["albumartist"] or file.metadata["artist"]
- album = file.metadata["album"]
+ artist = file.metadata['albumartist'] or file.metadata['artist']
+ album = file.metadata['album']
# Improve clustering from directory structure if no existing tags
# Only used for grouping and to provide cluster title / artist - not added to file tags.
diff --git a/picard/collection.py b/picard/collection.py
index 2207139ebf..b03db3f766 100644
--- a/picard/collection.py
+++ b/picard/collection.py
@@ -121,12 +121,12 @@ def request_finished(document, reply, error):
echo=log.error
)
return
- if document and "collections" in document:
+ if document and 'collections' in document:
collection_list = document['collections']
new_collections = set()
for node in collection_list:
- if node["entity-type"] != "release":
+ if node['entity-type'] != 'release':
continue
col_id = node['id']
col_name = node['name']
@@ -152,10 +152,10 @@ def request_finished(document, reply, error):
def add_release_to_user_collections(release_node):
"""Add album to collections"""
# Check for empy collection list
- if "collections" in release_node:
+ if 'collections' in release_node:
release_id = release_node['id']
config = get_config()
- username = config.persist["oauth_username"].lower()
+ username = config.persist['oauth_username'].lower()
for node in release_node['collections']:
if node['editor'].lower() == username:
col_id = node['id']
diff --git a/picard/config.py b/picard/config.py
index ad279aced3..88783f46dd 100644
--- a/picard/config.py
+++ b/picard/config.py
@@ -143,8 +143,8 @@ class SettingConfigSection(ConfigSection):
@classmethod
def init_profile_options(cls):
- ListOption.add_if_missing("profiles", cls.PROFILES_KEY, [])
- Option.add_if_missing("profiles", cls.SETTINGS_KEY, {})
+ ListOption.add_if_missing('profiles', cls.PROFILES_KEY, [])
+ Option.add_if_missing('profiles', cls.SETTINGS_KEY, {})
def __init__(self, config, name):
super().__init__(config, name)
@@ -165,7 +165,7 @@ def _get_active_profile_ids(self):
return
for profile in profiles:
if profile['enabled']:
- yield profile["id"]
+ yield profile['id']
def _get_active_profile_settings(self):
for profile_id in self._get_active_profile_ids():
@@ -242,14 +242,14 @@ def __initialize(self):
:meth:`from_file`."""
self.setAtomicSyncRequired(False) # See comment in event()
- self.application = ConfigSection(self, "application")
- self.profiles = ConfigSection(self, "profiles")
- self.setting = SettingConfigSection(self, "setting")
- self.persist = ConfigSection(self, "persist")
+ self.application = ConfigSection(self, 'application')
+ self.profiles = ConfigSection(self, 'profiles')
+ self.setting = SettingConfigSection(self, 'setting')
+ self.persist = ConfigSection(self, 'persist')
if 'version' not in self.application or not self.application['version']:
- TextOption("application", "version", '0.0.0dev0')
- self._version = Version.from_string(self.application["version"])
+ TextOption('application', 'version', '0.0.0dev0')
+ self._version = Version.from_string(self.application['version'])
self._upgrade_hooks = dict()
def event(self, event):
@@ -258,7 +258,7 @@ def event(self, event):
# the Python GIL in PyQt up to 5.15.2. Workaround this by handling this ourselves
# with custom file locking.
# See also https: // tickets.metabrainz.org/browse/PICARD-2088
- log.debug('Config file update requested on thread %r', threading.get_ident())
+ log.debug("Config file update requested on thread %r", threading.get_ident())
self.sync()
return True
else:
@@ -367,7 +367,7 @@ def run_upgrade_hooks(self, outputfunc=None):
# hook is not applicable, mark as done
hook['done'] = True
- if all(map(itemgetter("done"), self._upgrade_hooks.values())):
+ if all(map(itemgetter('done'), self._upgrade_hooks.values())):
# all hooks were executed, ensure config is marked with latest version
self._version = PICARD_VERSION
self._write_version()
@@ -378,16 +378,16 @@ def _backup_settings(self):
self._save_backup(backup_path)
def _save_backup(self, backup_path):
- log.info('Backing up config file to %s', backup_path)
+ log.info("Backing up config file to %s", backup_path)
try:
shutil.copyfile(self.fileName(), backup_path)
except OSError:
- log.error('Failed backing up config file to %s', backup_path)
+ log.error("Failed backing up config file to %s", backup_path)
return False
return True
def _write_version(self):
- self.application["version"] = self._version.to_string()
+ self.application['version'] = self._version.to_string()
self.sync()
def _versioned_config_filename(self, version=None):
@@ -505,7 +505,7 @@ def load_new_config(filename=None):
try:
shutil.copy(filename, config_file)
except OSError:
- log.error('Failed restoring config file from %s', filename)
+ log.error("Failed restoring config file from %s", filename)
return False
setup_config(QtCore.QObject.tagger, config_file)
return True
diff --git a/picard/config_upgrade.py b/picard/config_upgrade.py
index 9646f1df43..6e45658542 100644
--- a/picard/config_upgrade.py
+++ b/picard/config_upgrade.py
@@ -63,18 +63,18 @@ def upgrade_to_v1_0_0_final_0(config, interactive=True, merge=True):
def remove_va_file_naming_format(merge=True):
if merge:
- _s["file_naming_format"] = (
+ _s['file_naming_format'] = (
"$if($eq(%%compilation%%,1),\n$noop(Various Artist "
"albums)\n%s,\n$noop(Single Artist Albums)\n%s)" % (
- _s.value("va_file_naming_format", TextOption),
- _s["file_naming_format"]
+ _s.value('va_file_naming_format', TextOption),
+ _s['file_naming_format']
))
- _s.remove("va_file_naming_format")
- _s.remove("use_va_format")
+ _s.remove('va_file_naming_format')
+ _s.remove('use_va_format')
- if "va_file_naming_format" in _s and "use_va_format" in _s:
+ if 'va_file_naming_format' in _s and 'use_va_format' in _s:
- if _s.value("use_va_format", BoolOption):
+ if _s.value('use_va_format', BoolOption):
remove_va_file_naming_format()
if interactive:
msgbox = QtWidgets.QMessageBox()
@@ -86,7 +86,7 @@ def remove_va_file_naming_format(merge=True):
"merged with that of single artist albums."),
QtWidgets.QMessageBox.StandardButton.Ok)
- elif (_s.value("va_file_naming_format", TextOption)
+ elif (_s.value('va_file_naming_format', TextOption)
!= r"$if2(%albumartist%,%artist%)/%album%/$if($gt(%totaldis"
"cs%,1),%discnumber%-,)$num(%tracknumber%,2) %artist% - "
"%title%"):
@@ -100,8 +100,8 @@ def remove_va_file_naming_format(merge=True):
"Do you want to remove it or merge it with your file "
"naming scheme for single artist albums?"))
msgbox.setIcon(QtWidgets.QMessageBox.Icon.Question)
- merge_button = msgbox.addButton(_('Merge'), QtWidgets.QMessageBox.ButtonRole.AcceptRole)
- msgbox.addButton(_('Remove'), QtWidgets.QMessageBox.ButtonRole.DestructiveRole)
+ merge_button = msgbox.addButton(_("Merge"), QtWidgets.QMessageBox.ButtonRole.AcceptRole)
+ msgbox.addButton(_("Remove"), QtWidgets.QMessageBox.ButtonRole.DestructiveRole)
msgbox.exec_()
merge = msgbox.clickedButton() == merge_button
remove_va_file_naming_format(merge=merge)
@@ -113,8 +113,8 @@ def remove_va_file_naming_format(merge=True):
def upgrade_to_v1_3_0_dev_1(config):
"""Option "windows_compatible_filenames" was renamed "windows_compatibility" (PICARD-110).
"""
- old_opt = "windows_compatible_filenames"
- new_opt = "windows_compatibility"
+ old_opt = 'windows_compatible_filenames'
+ new_opt = 'windows_compatibility'
rename_option(config, old_opt, new_opt, BoolOption, True)
@@ -122,7 +122,7 @@ def upgrade_to_v1_3_0_dev_2(config):
"""Option "preserved_tags" is now using comma instead of spaces as tag separator (PICARD-536)
"""
_s = config.setting
- opt = "preserved_tags"
+ opt = 'preserved_tags'
if opt in _s and isinstance(_s[opt], str):
_s[opt] = re.sub(r"\s+", ",", _s[opt].strip())
@@ -132,11 +132,11 @@ def upgrade_to_v1_3_0_dev_3(config):
"""
_s = config.setting
option_separators = {
- "preferred_release_countries": " ",
- "preferred_release_formats": " ",
- "enabled_plugins": None,
- "caa_image_types": None,
- "metadata_box_sizes": None,
+ 'preferred_release_countries': ' ',
+ 'preferred_release_formats': ' ',
+ 'enabled_plugins': None,
+ 'caa_image_types': None,
+ 'metadata_box_sizes': None,
}
for (opt, sep) in option_separators.items():
if opt in _s:
@@ -162,7 +162,7 @@ def load_release_type_scores(setting):
scores.append((values[i], score))
return scores
- opt = "release_type_scores"
+ opt = 'release_type_scores'
if opt in _s:
try:
_s[opt] = load_release_type_scores(_s.raw_value(opt, qtype='QString'))
@@ -176,7 +176,7 @@ def upgrade_to_v1_4_0_dev_2(config):
"""
_s = config.setting
- opts = ["username", "password"]
+ opts = ['username', 'password']
for opt in opts:
_s.remove(opt)
@@ -209,8 +209,8 @@ def upgrade_to_v1_4_0_dev_3(config):
def upgrade_to_v1_4_0_dev_4(config):
"""Adds trailing comma to default file names for scripts"""
_s = config.setting
- if _s["file_naming_format"] == OLD_DEFAULT_FILE_NAMING_FORMAT_v1_3:
- _s["file_naming_format"] = DEFAULT_FILE_NAMING_FORMAT
+ if _s['file_naming_format'] == OLD_DEFAULT_FILE_NAMING_FORMAT_v1_3:
+ _s['file_naming_format'] = DEFAULT_FILE_NAMING_FORMAT
def upgrade_to_v1_4_0_dev_5(config):
@@ -221,37 +221,37 @@ def upgrade_to_v1_4_0_dev_5(config):
def upgrade_to_v1_4_0_dev_6(config):
"""Adds support for multiple and selective tagger scripts"""
_s = config.setting
- old_enabled_option = "enable_tagger_script"
- old_script_text_option = "tagger_script"
+ old_enabled_option = 'enable_tagger_script'
+ old_script_text_option = 'tagger_script'
list_of_scripts = []
if old_enabled_option in _s:
- _s["enable_tagger_scripts"] = _s.value(old_enabled_option, BoolOption, False)
+ _s['enable_tagger_scripts'] = _s.value(old_enabled_option, BoolOption, False)
if old_script_text_option in _s:
old_script_text = _s.value(old_script_text_option, TextOption, "")
if old_script_text:
old_script = (
0,
unique_numbered_title(gettext_constants(DEFAULT_SCRIPT_NAME), list_of_scripts),
- _s["enable_tagger_scripts"],
+ _s['enable_tagger_scripts'],
old_script_text,
)
list_of_scripts.append(old_script)
- _s["list_of_scripts"] = list_of_scripts
+ _s['list_of_scripts'] = list_of_scripts
_s.remove(old_enabled_option)
_s.remove(old_script_text_option)
def upgrade_to_v1_4_0_dev_7(config):
"""Option "save_only_front_images_to_tags" was renamed to "embed_only_one_front_image"."""
- old_opt = "save_only_front_images_to_tags"
- new_opt = "embed_only_one_front_image"
+ old_opt = 'save_only_front_images_to_tags'
+ new_opt = 'embed_only_one_front_image'
rename_option(config, old_opt, new_opt, BoolOption, True)
def upgrade_to_v2_0_0_dev_3(config):
"""Option "caa_image_size" value has different meaning."""
_s = config.setting
- opt = "caa_image_size"
+ opt = 'caa_image_size'
if opt in _s:
# caa_image_size option was storing index of a combobox item as size
# therefore it depends on items order and/or number, which is bad
@@ -270,25 +270,25 @@ def upgrade_to_v2_0_0_dev_3(config):
def upgrade_to_v2_1_0_dev_1(config):
"""Upgrade genre related options"""
_s = config.setting
- if "folksonomy_tags" in _s and _s["folksonomy_tags"]:
- _s["use_genres"] = True
- rename_option(config, "max_tags", "max_genres", IntOption, 5)
- rename_option(config, "min_tag_usage", "min_genre_usage", IntOption, 90)
- rename_option(config, "ignore_tags", "ignore_genres", TextOption, "")
- rename_option(config, "join_tags", "join_genres", TextOption, "")
- rename_option(config, "only_my_tags", "only_my_genres", BoolOption, False)
- rename_option(config, "artists_tags", "artists_genres", BoolOption, False)
+ if 'folksonomy_tags' in _s and _s['folksonomy_tags']:
+ _s['use_genres'] = True
+ rename_option(config, 'max_tags', 'max_genres', IntOption, 5)
+ rename_option(config, 'min_tag_usage', 'min_genre_usage', IntOption, 90)
+ rename_option(config, 'ignore_tags', 'ignore_genres', TextOption, '')
+ rename_option(config, 'join_tags', 'join_genres', TextOption, '')
+ rename_option(config, 'only_my_tags', 'only_my_genres', BoolOption, False)
+ rename_option(config, 'artists_tags', 'artists_genres', BoolOption, False)
def upgrade_to_v2_2_0_dev_3(config):
"""Option ignore_genres was replaced by option genres_filter"""
_s = config.setting
- old_opt = "ignore_genres"
+ old_opt = 'ignore_genres'
if old_opt in _s:
if _s[old_opt]:
- new_opt = "genres_filter"
- tags = ["-" + e.strip().lower() for e in _s[old_opt].split(',')]
- _s[new_opt] = "\n".join(tags)
+ new_opt = 'genres_filter'
+ tags = ['-' + e.strip().lower() for e in _s[old_opt].split(',')]
+ _s[new_opt] = '\n'.join(tags)
_s.remove(old_opt)
@@ -303,8 +303,8 @@ def upgrade_to_v2_2_0_dev_3(config):
def upgrade_to_v2_2_0_dev_4(config):
"""Improved default file naming script"""
_s = config.setting
- if _s["file_naming_format"] == OLD_DEFAULT_FILE_NAMING_FORMAT_v2_1:
- _s["file_naming_format"] = DEFAULT_FILE_NAMING_FORMAT
+ if _s['file_naming_format'] == OLD_DEFAULT_FILE_NAMING_FORMAT_v2_1:
+ _s['file_naming_format'] = DEFAULT_FILE_NAMING_FORMAT
def upgrade_to_v2_4_0_beta_3(config):
@@ -327,8 +327,8 @@ def upgrade_to_v2_5_0_dev_1(config):
def upgrade_to_v2_5_0_dev_2(config):
"""Reset main view splitter states"""
- config.persist["splitter_state"] = b''
- config.persist["bottom_splitter_state"] = b''
+ config.persist['splitter_state'] = b''
+ config.persist['bottom_splitter_state'] = b''
def upgrade_to_v2_6_0_dev_1(config):
@@ -339,18 +339,18 @@ def upgrade_to_v2_6_0_dev_1(config):
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)
+ 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 upgrade_to_v2_6_0_beta_3(config):
"""Replace use_system_theme with ui_theme options"""
from picard.ui.theme import UiTheme
_s = config.setting
- TextOption("setting", "ui_theme", str(UiTheme.DEFAULT))
- if _s["use_system_theme"]:
- _s["ui_theme"] = str(UiTheme.SYSTEM)
- _s.remove("use_system_theme")
+ TextOption('setting', 'ui_theme', str(UiTheme.DEFAULT))
+ if _s['use_system_theme']:
+ _s['ui_theme'] = str(UiTheme.SYSTEM)
+ _s.remove('use_system_theme')
def upgrade_to_v2_7_0_dev_2(config):
@@ -364,12 +364,12 @@ def upgrade_persisted_splitter(new_persist_key, key_map):
if _p[old_splitter_key] is not None:
splitter_dict[new_splitter_key] = bytearray(_p[old_splitter_key])
_p.remove(old_splitter_key)
- Option("persist", new_persist_key, {})
+ Option('persist', new_persist_key, {})
_p[new_persist_key] = splitter_dict
# MainWindow splitters
upgrade_persisted_splitter(
- new_persist_key="splitters_MainWindow",
+ new_persist_key='splitters_MainWindow',
key_map=[
('bottom_splitter_state', 'main_window_bottom_splitter'),
('splitter_state', 'main_panel_splitter'),
@@ -378,7 +378,7 @@ def upgrade_persisted_splitter(new_persist_key, key_map):
# ScriptEditorDialog splitters
upgrade_persisted_splitter(
- new_persist_key="splitters_ScriptEditorDialog",
+ new_persist_key='splitters_ScriptEditorDialog',
key_map=[
('script_editor_splitter_samples', 'splitter_between_editor_and_examples'),
('script_editor_splitter_samples_before_after', 'splitter_between_before_and_after'),
@@ -388,7 +388,7 @@ def upgrade_persisted_splitter(new_persist_key, key_map):
# OptionsDialog splitters
upgrade_persisted_splitter(
- new_persist_key="splitters_OptionsDialog",
+ new_persist_key='splitters_OptionsDialog',
key_map=[
('options_splitter', 'dialog_splitter'),
('scripting_splitter', 'scripting_options_splitter'),
@@ -404,54 +404,54 @@ def upgrade_to_v2_7_0_dev_3(config):
FileNamingScript,
ScriptImportError,
)
- Option("setting", "file_renaming_scripts", {})
- ListOption("setting", "file_naming_scripts", [])
- TextOption("setting", "file_naming_format", DEFAULT_FILE_NAMING_FORMAT)
- TextOption("setting", "selected_file_naming_script_id", "")
+ Option('setting', 'file_renaming_scripts', {})
+ ListOption('setting', 'file_naming_scripts', [])
+ TextOption('setting', 'file_naming_format', DEFAULT_FILE_NAMING_FORMAT)
+ TextOption('setting', 'selected_file_naming_script_id', '')
scripts = {}
- for item in config.setting["file_naming_scripts"]:
+ for item in config.setting['file_naming_scripts']:
try:
script_item = FileNamingScript().create_from_yaml(item, create_new_id=False)
- scripts[script_item["id"]] = script_item.to_dict()
+ scripts[script_item['id']] = script_item.to_dict()
except ScriptImportError:
log.error("Error converting file naming script")
- script_list = set(scripts.keys()) | set(map(lambda item: item["id"], get_file_naming_script_presets()))
- if config.setting["selected_file_naming_script_id"] not in script_list:
+ script_list = set(scripts.keys()) | set(map(lambda item: item['id'], get_file_naming_script_presets()))
+ if config.setting['selected_file_naming_script_id'] not in script_list:
script_item = FileNamingScript(
- script=config.setting["file_naming_format"],
+ script=config.setting['file_naming_format'],
title=_("Primary file naming script"),
readonly=False,
deletable=True,
)
- scripts[script_item["id"]] = script_item.to_dict()
- config.setting["selected_file_naming_script_id"] = script_item["id"]
- config.setting["file_renaming_scripts"] = scripts
- config.setting.remove("file_naming_scripts")
- config.setting.remove("file_naming_format")
+ scripts[script_item['id']] = script_item.to_dict()
+ config.setting['selected_file_naming_script_id'] = script_item['id']
+ config.setting['file_renaming_scripts'] = scripts
+ config.setting.remove('file_naming_scripts')
+ config.setting.remove('file_naming_format')
def upgrade_to_v2_7_0_dev_4(config):
"""Replace artist_script_exception with artist_script_exceptions"""
_s = config.setting
- ListOption("setting", "artist_script_exceptions", [])
- if _s["artist_script_exception"]:
- _s["artist_script_exceptions"] = [_s["artist_script_exception"]]
- _s.remove("artist_script_exception")
- ListOption("setting", "artist_locales", ['en'])
- if _s["artist_locale"]:
- _s["artist_locales"] = [_s["artist_locale"]]
- _s.remove("artist_locale")
+ ListOption('setting', 'artist_script_exceptions', [])
+ if _s['artist_script_exception']:
+ _s['artist_script_exceptions'] = [_s['artist_script_exception']]
+ _s.remove('artist_script_exception')
+ ListOption('setting', 'artist_locales', ['en'])
+ if _s['artist_locale']:
+ _s['artist_locales'] = [_s['artist_locale']]
+ _s.remove('artist_locale')
def upgrade_to_v2_7_0_dev_5(config):
"""Replace artist_script_exceptions with script_exceptions and remove artist_script_exception_weighting"""
_s = config.setting
- ListOption("setting", "script_exceptions", [])
- weighting = _s["artist_script_exception_weighting"] or 0
- artist_script_exceptions = _s["artist_script_exceptions"] or []
- _s["script_exceptions"] = [(script_exception, weighting) for script_exception in artist_script_exceptions]
- _s.remove("artist_script_exceptions")
- _s.remove("artist_script_exception_weighting")
+ ListOption('setting', 'script_exceptions', [])
+ weighting = _s['artist_script_exception_weighting'] or 0
+ artist_script_exceptions = _s['artist_script_exceptions'] or []
+ _s['script_exceptions'] = [(script_exception, weighting) for script_exception in artist_script_exceptions]
+ _s.remove('artist_script_exceptions')
+ _s.remove('artist_script_exception_weighting')
def upgrade_to_v2_8_0_dev_2(config):
@@ -467,10 +467,10 @@ def upgrade_to_v2_8_0_dev_2(config):
def upgrade_to_v2_9_0_alpha_2(config):
"""Add preset file naming scripts to editable user scripts disctionary"""
from picard.script import get_file_naming_script_presets
- scripts = config.setting["file_renaming_scripts"]
+ scripts = config.setting['file_renaming_scripts']
for item in get_file_naming_script_presets():
- scripts[item["id"]] = item.to_dict()
- config.setting["file_renaming_scripts"] = scripts
+ scripts[item['id']] = item.to_dict()
+ config.setting['file_renaming_scripts'] = scripts
def rename_option(config, old_opt, new_opt, option_type, default):
@@ -481,13 +481,13 @@ def rename_option(config, old_opt, new_opt, option_type, default):
_p = config.profiles
_s.init_profile_options()
- all_settings = _p["user_profile_settings"]
- for profile in _p["user_profiles"]:
- id = profile["id"]
+ all_settings = _p['user_profile_settings']
+ for profile in _p['user_profiles']:
+ id = profile['id']
if id in all_settings and old_opt in all_settings[id]:
all_settings[id][new_opt] = all_settings[id][old_opt]
all_settings[id].pop(old_opt)
- _p["user_profile_settings"] = all_settings
+ _p['user_profile_settings'] = all_settings
def upgrade_config(config):
diff --git a/picard/const/__init__.py b/picard/const/__init__.py
index 133b1c23c1..799e56aed3 100644
--- a/picard/const/__init__.py
+++ b/picard/const/__init__.py
@@ -78,12 +78,12 @@
'home': "https://picard.musicbrainz.org/",
'license': "https://www.gnu.org/licenses/gpl-2.0.html",
'documentation_server': DOCS_SERVER_URL, # Shows latest version and tries to match the user's language if available.
- 'documentation': DOCS_BASE_URL + '/',
- 'troubleshooting': DOCS_BASE_URL + '/troubleshooting/troubleshooting.html',
- 'doc_options': DOCS_BASE_URL + '/config/configuration.html',
- 'doc_scripting': DOCS_BASE_URL + '/extending/scripting.html',
- 'doc_tags_from_filenames': DOCS_BASE_URL + '/usage/tags_from_file_names.html',
- 'doc_naming_script_edit': DOCS_BASE_URL + '/config/options_filerenaming_editor.html',
+ 'documentation': DOCS_BASE_URL + "/",
+ 'troubleshooting': DOCS_BASE_URL + "/troubleshooting/troubleshooting.html",
+ 'doc_options': DOCS_BASE_URL + "/config/configuration.html",
+ 'doc_scripting': DOCS_BASE_URL + "/extending/scripting.html",
+ 'doc_tags_from_filenames': DOCS_BASE_URL + "/usage/tags_from_file_names.html",
+ 'doc_naming_script_edit': DOCS_BASE_URL + "/config/options_filerenaming_editor.html",
'doc_cover_art_types': "https://musicbrainz.org/doc/Cover_Art/Types",
'plugins': "https://picard.musicbrainz.org/plugins/",
'forum': "https://community.metabrainz.org/c/picard",
@@ -166,19 +166,19 @@
(
0, {
'name': 'stable',
- 'title': N_('Stable releases only'),
+ 'title': N_("Stable releases only"),
}
),
(
1, {
'name': 'beta',
- 'title': N_('Stable and Beta releases'),
+ 'title': N_("Stable and Beta releases"),
}
),
(
2, {
'name': 'dev',
- 'title': N_('Stable, Beta and Dev releases'),
+ 'title': N_("Stable, Beta and Dev releases"),
}
),
]
@@ -197,7 +197,7 @@
DEFAULT_SCRIPT_NAME = N_("My script")
-DEFAULT_COVER_IMAGE_FILENAME = "cover"
+DEFAULT_COVER_IMAGE_FILENAME = 'cover'
DEFAULT_PROFILE_NAME = N_("My profile")
DEFAULT_COPY_TEXT = N_("(copy)")
DEFAULT_NUMBERED_TITLE_FORMAT = N_("{title} ({count})")
diff --git a/picard/coverart/image.py b/picard/coverart/image.py
index ae31000188..6b246796bb 100644
--- a/picard/coverart/image.py
+++ b/picard/coverart/image.py
@@ -81,7 +81,7 @@ def __init__(self, data, prefix='picard', suffix=''):
if self._hash not in _datafiles:
(fd, self._filename) = tempfile.mkstemp(prefix=prefix, suffix=suffix)
QObject.tagger.register_cleanup(self.delete_file)
- with os.fdopen(fd, "wb") as imagefile:
+ with os.fdopen(fd, 'wb') as imagefile:
imagefile.write(data)
_datafiles[self._hash] = self._filename
periodictouch.register_file(self._filename)
@@ -116,7 +116,7 @@ def delete_file(self):
@property
def data(self):
if self._filename:
- with open(self._filename, "rb") as imagefile:
+ with open(self._filename, 'rb') as imagefile:
return imagefile.read()
return None
@@ -148,7 +148,7 @@ class CoverArtImage:
# `is_front` has to be explicitly set, it is used to handle CAA is_front
# indicator
is_front = None
- sourceprefix = "URL"
+ sourceprefix = 'URL'
def __init__(self, url=None, types=None, comment='', data=None, support_types=None,
support_multi_types=None, id3_type=None):
@@ -310,12 +310,12 @@ def id3_type(self, type):
def _make_image_filename(self, filename, dirname, _metadata, win_compat, win_shorten_path):
metadata = Metadata()
metadata.copy(_metadata)
- metadata["coverart_maintype"] = self.maintype
- metadata["coverart_comment"] = self.comment
+ metadata['coverart_maintype'] = self.maintype
+ metadata['coverart_comment'] = self.comment
if self.is_front:
- metadata.add_unique("coverart_types", "front")
+ metadata.add_unique('coverart_types', 'front')
for cover_type in self.types:
- metadata.add_unique("coverart_types", cover_type)
+ metadata.add_unique('coverart_types', cover_type)
filename = script_to_filename(filename, metadata)
if not filename:
filename = DEFAULT_COVER_IMAGE_FILENAME
@@ -344,19 +344,19 @@ def save(self, dirname, metadata, counters):
if not self.can_be_saved_to_disk:
return
config = get_config()
- win_compat = IS_WIN or config.setting["windows_compatibility"]
+ win_compat = IS_WIN or config.setting['windows_compatibility']
win_shorten_path = win_compat and not config.setting['windows_long_paths']
- if config.setting["image_type_as_filename"] and not self.is_front_image():
+ if config.setting['image_type_as_filename'] and not self.is_front_image():
filename = sanitize_filename(self.maintype, win_compat=win_compat)
log.debug("Make cover filename from types: %r -> %r",
self.types, filename)
else:
- filename = config.setting["cover_image_filename"]
+ filename = config.setting['cover_image_filename']
log.debug("Using default cover image filename %r", filename)
filename = self._make_image_filename(
filename, dirname, metadata, win_compat, win_shorten_path)
- overwrite = config.setting["save_images_overwrite"]
+ overwrite = config.setting['save_images_overwrite']
ext = encode_filename(self.extension)
image_filename = self._next_filename(filename, counters)
while os.path.exists(image_filename + ext) and not overwrite:
@@ -430,7 +430,7 @@ class CaaCoverArtImage(CoverArtImage):
support_types = True
support_multi_types = True
- sourceprefix = "CAA"
+ sourceprefix = 'CAA'
def __init__(self, url, types=None, is_front=False, comment='', data=None):
super().__init__(url=url, types=types, comment=comment, data=data)
diff --git a/picard/coverart/providers/caa.py b/picard/coverart/providers/caa.py
index e88f23fa8b..7807b2eb8e 100644
--- a/picard/coverart/providers/caa.py
+++ b/picard/coverart/providers/caa.py
@@ -83,7 +83,7 @@
_CAA_IMAGE_TYPE_DEFAULT_EXCLUDE = ['matrix/runout', 'raw/unedited', 'watermark']
ratecontrol.set_minimum_delay_for_url(CAA_URL, 0)
-ratecontrol.set_minimum_delay_for_url('https://archive.org', 0)
+ratecontrol.set_minimum_delay_for_url("https://archive.org", 0)
def caa_url_fallback_list(desired_size, thumbnails):
@@ -118,14 +118,14 @@ class ProviderOptionsCaa(ProviderOptions):
"""
TITLE = N_("Cover Art Archive")
- HELP_URL = '/config/options_cover_art_archive.html'
+ HELP_URL = "/config/options_cover_art_archive.html"
options = [
- BoolOption("setting", "caa_approved_only", 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),
- ListOption("setting", "caa_image_types_to_omit", _CAA_IMAGE_TYPE_DEFAULT_EXCLUDE),
+ BoolOption('setting', 'caa_approved_only', 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),
+ ListOption('setting', 'caa_image_types_to_omit', _CAA_IMAGE_TYPE_DEFAULT_EXCLUDE),
]
_options_ui = Ui_CaaOptions
@@ -146,29 +146,29 @@ def load(self):
self.ui.cb_image_size.addItem(_(item.label), userData=item_id)
config = get_config()
- size = config.setting["caa_image_size"]
+ size = config.setting['caa_image_size']
index = self.ui.cb_image_size.findData(size)
if index < 0:
index = self.ui.cb_image_size.findData(_CAA_IMAGE_SIZE_DEFAULT)
self.ui.cb_image_size.setCurrentIndex(index)
- self.ui.cb_approved_only.setChecked(config.setting["caa_approved_only"])
+ self.ui.cb_approved_only.setChecked(config.setting['caa_approved_only'])
self.ui.restrict_images_types.setChecked(
- config.setting["caa_restrict_image_types"])
- self.caa_image_types = config.setting["caa_image_types"]
- self.caa_image_types_to_omit = config.setting["caa_image_types_to_omit"]
+ config.setting['caa_restrict_image_types'])
+ self.caa_image_types = config.setting['caa_image_types']
+ self.caa_image_types_to_omit = config.setting['caa_image_types_to_omit']
self.update_caa_types()
def save(self):
config = get_config()
size = self.ui.cb_image_size.currentData()
- config.setting["caa_image_size"] = size
- config.setting["caa_approved_only"] = \
+ config.setting['caa_image_size'] = size
+ config.setting['caa_approved_only'] = \
self.ui.cb_approved_only.isChecked()
- config.setting["caa_restrict_image_types"] = \
+ config.setting['caa_restrict_image_types'] = \
self.ui.restrict_images_types.isChecked()
- config.setting["caa_image_types"] = self.caa_image_types
- config.setting["caa_image_types_to_omit"] = self.caa_image_types_to_omit
+ config.setting['caa_image_types'] = self.caa_image_types
+ config.setting['caa_image_types_to_omit'] = self.caa_image_types_to_omit
def update_caa_types(self):
enabled = self.ui.restrict_images_types.isChecked()
@@ -194,7 +194,7 @@ class CoverArtProviderCaa(CoverArtProvider):
"""Get cover art from Cover Art Archive using release mbid"""
NAME = "Cover Art Archive"
- TITLE = N_('Cover Art Archive: Release')
+ TITLE = N_("Cover Art Archive: Release")
OPTIONS = ProviderOptionsCaa
ignore_json_not_found_error = False
@@ -215,14 +215,14 @@ def _has_suitable_artwork(self):
# MB web service indicates if CAA has artwork
# https://tickets.metabrainz.org/browse/MBS-4536
if 'cover-art-archive' not in self.release:
- log.debug('No Cover Art Archive information for %s', self.release['id'])
+ log.debug("No Cover Art Archive information for %s", self.release['id'])
return False
caa_node = self.release['cover-art-archive']
caa_has_suitable_artwork = caa_node['artwork']
if not caa_has_suitable_artwork:
- log.debug('There are no images in the Cover Art Archive for %s', self.release['id'])
+ log.debug("There are no images in the Cover Art Archive for %s", self.release['id'])
return False
if self.restrict_types:
@@ -251,9 +251,9 @@ def _has_suitable_artwork(self):
caa_has_suitable_artwork = front_in_caa or back_in_caa
if not caa_has_suitable_artwork:
- log.debug('There are no suitable images in the Cover Art Archive for %s', self.release['id'])
+ log.debug("There are no suitable images in the Cover Art Archive for %s", self.release['id'])
else:
- log.debug('There are suitable images in the Cover Art Archive for %s', self.release['id'])
+ log.debug("There are suitable images in the Cover Art Archive for %s", self.release['id'])
return caa_has_suitable_artwork
@@ -262,13 +262,13 @@ def enabled(self):
if not super().enabled():
return False
if self.restrict_types and not self.included_types_count:
- log.debug('User disabled all Cover Art Archive types')
+ log.debug("User disabled all Cover Art Archive types")
return False
return self._has_suitable_artwork
@property
def _caa_path(self):
- return "/release/%s/" % self.metadata["musicbrainz_albumid"]
+ return "/release/%s/" % self.metadata['musicbrainz_albumid']
def queue_images(self):
self.album.tagger.webservice.get_url(
@@ -287,10 +287,10 @@ def _caa_json_downloaded(self, data, http, error):
self.album._requests -= 1
if error:
if not (error == QNetworkReply.NetworkError.ContentNotFoundError and self.ignore_json_not_found_error):
- self.error('CAA JSON error: %s' % (http.errorString()))
+ self.error("CAA JSON error: %s" % (http.errorString()))
else:
if self.restrict_types:
- log.debug('CAA types: included: %s, excluded: %s', self.included_types, self.excluded_types)
+ log.debug("CAA types: included: %s, excluded: %s", self.included_types, self.excluded_types)
try:
config = get_config()
for image in data['images']:
@@ -298,7 +298,7 @@ def _caa_json_downloaded(self, data, http, error):
continue
is_pdf = image['image'].endswith('.pdf')
if is_pdf and not config.setting['save_images_to_files']:
- log.debug("Skipping pdf cover art : %s", image["image"])
+ log.debug("Skipping pdf cover art : %s", image['image'])
continue
# if image has no type set, we still want it to match
# pseudo type 'unknown'
@@ -310,7 +310,7 @@ def _caa_json_downloaded(self, data, http, error):
if self.restrict_types:
# accept only if image types matches according to included/excluded types
accepted = bool(set(image['types']).intersection(self.included_types).difference(self.excluded_types))
- log.debug('CAA image %s: %s %s',
+ log.debug("CAA image %s: %s %s",
('accepted' if accepted else 'rejected'),
image['image'],
image['types']
@@ -350,6 +350,6 @@ def _caa_json_downloaded(self, data, http, error):
image['front']:
break
except (AttributeError, KeyError, TypeError) as e:
- self.error('CAA JSON error: %s' % e)
+ self.error("CAA JSON error: %s" % e)
self.next_in_queue()
diff --git a/picard/coverart/providers/caa_release_group.py b/picard/coverart/providers/caa_release_group.py
index 9a4c85be0a..cd3655c6e5 100644
--- a/picard/coverart/providers/caa_release_group.py
+++ b/picard/coverart/providers/caa_release_group.py
@@ -54,4 +54,4 @@ def enabled(self):
@property
def _caa_path(self):
- return "/release-group/%s/" % self.metadata["musicbrainz_releasegroupid"]
+ return "/release-group/%s/" % self.metadata['musicbrainz_releasegroupid']
diff --git a/picard/coverart/providers/local.py b/picard/coverart/providers/local.py
index 563b0614e4..fb56eef639 100644
--- a/picard/coverart/providers/local.py
+++ b/picard/coverart/providers/local.py
@@ -48,7 +48,7 @@ class ProviderOptionsLocal(ProviderOptions):
_DEFAULT_LOCAL_COVER_ART_REGEX = r'^(?:cover|folder|albumart)(.*)\.(?:jpe?g|png|gif|tiff?|webp)$'
options = [
- TextOption("setting", "local_cover_regex", _DEFAULT_LOCAL_COVER_ART_REGEX),
+ TextOption('setting', 'local_cover_regex', _DEFAULT_LOCAL_COVER_ART_REGEX),
]
_options_ui = Ui_LocalOptions
@@ -63,11 +63,11 @@ def set_local_cover_regex_default(self):
def load(self):
config = get_config()
- self.ui.local_cover_regex_edit.setText(config.setting["local_cover_regex"])
+ self.ui.local_cover_regex_edit.setText(config.setting['local_cover_regex'])
def save(self):
config = get_config()
- config.setting["local_cover_regex"] = self.ui.local_cover_regex_edit.text()
+ config.setting['local_cover_regex'] = self.ui.local_cover_regex_edit.text()
class CoverArtProviderLocal(CoverArtProvider):
diff --git a/picard/coverart/providers/urlrels.py b/picard/coverart/providers/urlrels.py
index b07b9897b1..a9fac7b377 100644
--- a/picard/coverart/providers/urlrels.py
+++ b/picard/coverart/providers/urlrels.py
@@ -36,7 +36,7 @@ class CoverArtProviderUrlRelationships(CoverArtProvider):
cover art"""
NAME = "UrlRelationships"
- TITLE = N_('Allowed Cover Art URLs')
+ TITLE = N_("Allowed Cover Art URLs")
def queue_images(self):
self.match_url_relations(('cover art link', 'has_cover_art_at'),
diff --git a/picard/coverart/utils.py b/picard/coverart/utils.py
index 0dd0df901d..13d4ec5653 100644
--- a/picard/coverart/utils.py
+++ b/picard/coverart/utils.py
@@ -35,7 +35,7 @@
CAA_TYPES.append({'name': v.lower(), 'title': v})
# pseudo type, used for the no type case
-CAA_TYPES.append({'name': "unknown", 'title': N_("Unknown")})
+CAA_TYPES.append({'name': 'unknown', 'title': N_("Unknown")})
CAA_TYPES_TR = {}
for t in CAA_TYPES:
@@ -76,23 +76,23 @@ class Id3ImageType(IntEnum):
__ID3_IMAGE_TYPE_MAP = {
- "obi": Id3ImageType.OTHER,
- "tray": Id3ImageType.OTHER,
- "spine": Id3ImageType.OTHER,
- "sticker": Id3ImageType.OTHER,
- "other": Id3ImageType.OTHER,
- "front": Id3ImageType.COVER_FRONT,
- "back": Id3ImageType.COVER_BACK,
- "booklet": Id3ImageType.LEAFLET_PAGE,
- "track": Id3ImageType.MEDIA,
- "medium": Id3ImageType.MEDIA,
+ 'obi': Id3ImageType.OTHER,
+ 'tray': Id3ImageType.OTHER,
+ 'spine': Id3ImageType.OTHER,
+ 'sticker': Id3ImageType.OTHER,
+ 'other': Id3ImageType.OTHER,
+ 'front': Id3ImageType.COVER_FRONT,
+ 'back': Id3ImageType.COVER_BACK,
+ 'booklet': Id3ImageType.LEAFLET_PAGE,
+ 'track': Id3ImageType.MEDIA,
+ 'medium': Id3ImageType.MEDIA,
}
__ID3_REVERSE_IMAGE_TYPE_MAP = {v: k for k, v in __ID3_IMAGE_TYPE_MAP.items()}
def image_type_from_id3_num(id3type):
- return __ID3_REVERSE_IMAGE_TYPE_MAP.get(id3type, "other")
+ return __ID3_REVERSE_IMAGE_TYPE_MAP.get(id3type, 'other')
def image_type_as_id3_num(texttype):
diff --git a/picard/disc/__init__.py b/picard/disc/__init__.py
index b7e3986b67..d5084b9a28 100644
--- a/picard/disc/__init__.py
+++ b/picard/disc/__init__.py
@@ -93,7 +93,7 @@ def _set_disc_details(self, disc):
@property
def submission_url(self):
if self.id and self.tracks and self.toc_string:
- return build_submission_url('/cdtoc/attach', query_args={
+ return build_submission_url("/cdtoc/attach", query_args={
'id': self.id,
'tracks': self.tracks,
'toc': self.toc_string.replace(' ', '+'),
diff --git a/picard/disc/dbpoweramplog.py b/picard/disc/dbpoweramplog.py
index 685bb55eb0..b243df57c2 100644
--- a/picard/disc/dbpoweramplog.py
+++ b/picard/disc/dbpoweramplog.py
@@ -43,7 +43,7 @@ def filter_toc_entries(lines):
if m:
track_num = int(m['num'])
if last_track_num + 1 != track_num:
- raise NotSupportedTOCError(f'Non consecutive track numbers ({last_track_num} => {track_num}) in dBPoweramp log. Likely a partial rip, disc ID cannot be calculated')
+ raise NotSupportedTOCError(f"Non consecutive track numbers ({last_track_num} => {track_num}) in dBPoweramp log. Likely a partial rip, disc ID cannot be calculated")
last_track_num = track_num
yield TocEntry(track_num, int(m['start_sector']), int(m['end_sector'])-1)
diff --git a/picard/file.py b/picard/file.py
index 1a059febe6..9c4078dc1e 100644
--- a/picard/file.py
+++ b/picard/file.py
@@ -135,16 +135,16 @@ class File(QtCore.QObject, Item):
FILE_INFO_TAGS = ('~bitrate', '~sample_rate', '~channels', '~bits_per_sample', '~format')
comparison_weights = {
- "title": 13,
- "artist": 4,
- "album": 5,
- "length": 10,
- "totaltracks": 4,
- "releasetype": 14,
- "releasecountry": 2,
- "format": 2,
- "isvideo": 2,
- "date": 4,
+ 'title': 13,
+ 'artist': 4,
+ 'album': 5,
+ 'length': 10,
+ 'totaltracks': 4,
+ 'releasetype': 14,
+ 'releasecountry': 2,
+ 'format': 2,
+ 'isvideo': 2,
+ 'date': 4,
}
class PreserveTimesStatError(Exception):
@@ -213,7 +213,7 @@ def _set_error(self, error):
self.state = File.ERROR
if any_exception_isinstance(error, MutagenError):
self.error_type = FileErrorType.PARSER
- self.error_append(_('The file failed to parse, either the file is damaged or has an unsupported file format.'))
+ self.error_append(_("The file failed to parse, either the file is damaged or has an unsupported file format."))
elif any_exception_isinstance(error, FileNotFoundError):
self.error_type = FileErrorType.NOTFOUND
elif any_exception_isinstance(error, PermissionError):
@@ -261,7 +261,7 @@ def _loading_finished(self, callback, result=None, error=None):
if alternative_file:
# Do not retry reloading exactly the same file format
if type(alternative_file) != type(self): # pylint: disable=unidiomatic-typecheck # noqa: E721
- log.debug('Loading %r failed, retrying as %r', self, alternative_file)
+ log.debug("Loading %r failed, retrying as %r", self, alternative_file)
self.remove()
alternative_file.load(callback)
return
@@ -270,18 +270,18 @@ def _loading_finished(self, callback, result=None, error=None):
from picard.formats import supported_extensions
file_name, file_extension = os.path.splitext(self.base_filename)
if file_extension not in supported_extensions():
- log.error('Unsupported media file %r wrongly loaded. Removing …', self)
+ log.error("Unsupported media file %r wrongly loaded. Removing …", self)
callback(self, remove_file=True)
return
else:
self.clear_errors()
self.state = self.NORMAL
postprocessors = []
- if config.setting["guess_tracknumber_and_title"]:
+ if config.setting['guess_tracknumber_and_title']:
postprocessors.append(self._guess_tracknumber_and_title)
self._copy_loaded_metadata(result, postprocessors)
# use cached fingerprint from file metadata
- if not config.setting["ignore_existing_acoustid_fingerprints"]:
+ if not config.setting['ignore_existing_acoustid_fingerprints']:
fingerprints = self.metadata.getall('acoustid_fingerprint')
if fingerprints:
self.set_acoustid_fingerprint(fingerprints[0])
@@ -382,9 +382,9 @@ def _save_and_rename(self, old_filename, metadata):
log.debug("File not saved because %s is stopping: %r", PICARD_APP_NAME, self.filename)
return None
new_filename = old_filename
- if not config.setting["dont_write_tags"]:
+ if not config.setting['dont_write_tags']:
save = partial(self._save, old_filename, metadata)
- if config.setting["preserve_timestamps"]:
+ if config.setting['preserve_timestamps']:
try:
self._preserve_times(old_filename, save)
except self.PreserveTimesUtimeError as why:
@@ -392,12 +392,12 @@ def _save_and_rename(self, old_filename, metadata):
else:
save()
# Rename files
- if config.setting["rename_files"] or config.setting["move_files"]:
+ if config.setting['rename_files'] or config.setting['move_files']:
new_filename = self._rename(old_filename, metadata, config.setting)
# Move extra files (images, playlists, etc.)
self._move_additional_files(old_filename, new_filename, config)
# Delete empty directories
- if config.setting["delete_empty_dirs"]:
+ if config.setting['delete_empty_dirs']:
dirname = os.path.dirname(old_filename)
try:
emptydir.rm_empty_dir(dirname)
@@ -412,7 +412,7 @@ def _save_and_rename(self, old_filename, metadata):
except emptydir.SkipRemoveDir as why:
log.debug("Not removing empty directory: %s", why)
# Save cover art images
- if config.setting["save_images_to_files"]:
+ if config.setting['save_images_to_files']:
self._save_images(os.path.dirname(new_filename), metadata)
return new_filename
@@ -436,7 +436,7 @@ def _saving_finished(self, result=None, error=None):
# conversions (e.g. for ID3v2.3)
config = get_config()
new_metadata = self._format_specific_copy(self.metadata, config.setting)
- if config.setting["clear_existing_tags"]:
+ if config.setting['clear_existing_tags']:
self.orig_metadata = new_metadata
else:
self.orig_metadata.update(new_metadata)
@@ -474,7 +474,7 @@ def _script_to_filename(self, naming_format, file_metadata, file_extension, sett
config = get_config()
settings = config.setting
metadata = Metadata()
- if settings["clear_existing_tags"]:
+ if settings['clear_existing_tags']:
# script_to_filename_with_metadata guarantees this is not modified
metadata = file_metadata
else:
@@ -538,15 +538,15 @@ def make_filename(self, filename, metadata, settings=None, naming_format=None):
settings = config.setting
if naming_format is None:
naming_format = get_file_naming_script(settings)
- if settings["move_files"]:
- new_dirname = settings["move_files_to"]
+ if settings['move_files']:
+ new_dirname = settings['move_files_to']
if not is_absolute_path(new_dirname):
new_dirname = os.path.join(os.path.dirname(filename), new_dirname)
else:
new_dirname = os.path.dirname(filename)
new_filename = os.path.basename(filename)
- if settings["rename_files"] or settings["move_files"]:
+ if settings['rename_files'] or settings['move_files']:
new_filename = self._format_filename(new_dirname, new_filename, metadata, settings, naming_format)
new_path = os.path.join(new_dirname, new_filename)
@@ -572,7 +572,7 @@ def _save_images(self, dirname, metadata):
counters = Counter()
images = []
config = get_config()
- if config.setting["save_only_one_front_image"]:
+ if config.setting['save_only_one_front_image']:
front = metadata.images.get_front_image()
if front:
images.append(front)
@@ -583,11 +583,11 @@ def _save_images(self, dirname, metadata):
def _move_additional_files(self, old_filename, new_filename, config):
"""Move extra files, like images, playlists…"""
- if config.setting["move_files"] and config.setting["move_additional_files"]:
+ if config.setting['move_files'] and config.setting['move_additional_files']:
new_path = os.path.dirname(new_filename)
old_path = os.path.dirname(old_filename)
if new_path != old_path:
- patterns_string = config.setting["move_additional_files_pattern"]
+ patterns_string = config.setting['move_additional_files_pattern']
patterns = self._compile_move_additional_files_pattern(patterns_string)
try:
moves = self._get_additional_files_moves(old_path, new_path, patterns)
@@ -705,8 +705,8 @@ def _tags_to_update(self, ignored_tags):
def update(self, signal=True):
if not (self.state == File.ERROR and self.errors):
config = get_config()
- clear_existing_tags = config.setting["clear_existing_tags"]
- ignored_tags = set(config.setting["compare_ignore_tags"])
+ clear_existing_tags = config.setting['clear_existing_tags']
+ ignored_tags = set(config.setting['compare_ignore_tags'])
for name in self._tags_to_update(ignored_tags):
new_values = self.format_specific_metadata(self.metadata, name, config.setting)
@@ -812,9 +812,9 @@ def state(self, state):
def column(self, column):
m = self.metadata
- if column == "title" and not m["title"]:
+ if column == 'title' and not m['title']:
return self.base_filename
- elif column == "covercount":
+ elif column == 'covercount':
return self.cover_art_description()
return m[column]
diff --git a/picard/formats/apev2.py b/picard/formats/apev2.py
index d152e22c75..1d29b7718c 100644
--- a/picard/formats/apev2.py
+++ b/picard/formats/apev2.py
@@ -95,33 +95,33 @@ class APEv2File(File):
_File = None
__translate = {
- "albumartist": "Album Artist",
- "remixer": "MixArtist",
- "director": "Director",
- "website": "Weblink",
- "discsubtitle": "DiscSubtitle",
- "bpm": "BPM",
- "isrc": "ISRC",
- "catalognumber": "CatalogNumber",
- "barcode": "Barcode",
- "encodedby": "EncodedBy",
- "language": "Language",
- "movementnumber": "MOVEMENT",
- "movement": "MOVEMENTNAME",
- "movementtotal": "MOVEMENTTOTAL",
- "showmovement": "SHOWMOVEMENT",
- "releasestatus": "MUSICBRAINZ_ALBUMSTATUS",
- "releasetype": "MUSICBRAINZ_ALBUMTYPE",
- "musicbrainz_recordingid": "musicbrainz_trackid",
- "musicbrainz_trackid": "musicbrainz_releasetrackid",
- "originalartist": "Original Artist",
- "replaygain_album_gain": "REPLAYGAIN_ALBUM_GAIN",
- "replaygain_album_peak": "REPLAYGAIN_ALBUM_PEAK",
- "replaygain_album_range": "REPLAYGAIN_ALBUM_RANGE",
- "replaygain_track_gain": "REPLAYGAIN_TRACK_GAIN",
- "replaygain_track_peak": "REPLAYGAIN_TRACK_PEAK",
- "replaygain_track_range": "REPLAYGAIN_TRACK_RANGE",
- "replaygain_reference_loudness": "REPLAYGAIN_REFERENCE_LOUDNESS",
+ 'albumartist': 'Album Artist',
+ 'remixer': 'MixArtist',
+ 'director': 'Director',
+ 'website': 'Weblink',
+ 'discsubtitle': 'DiscSubtitle',
+ 'bpm': 'BPM',
+ 'isrc': 'ISRC',
+ 'catalognumber': 'CatalogNumber',
+ 'barcode': 'Barcode',
+ 'encodedby': 'EncodedBy',
+ 'language': 'Language',
+ 'movementnumber': 'MOVEMENT',
+ 'movement': 'MOVEMENTNAME',
+ 'movementtotal': 'MOVEMENTTOTAL',
+ 'showmovement': 'SHOWMOVEMENT',
+ 'releasestatus': 'MUSICBRAINZ_ALBUMSTATUS',
+ 'releasetype': 'MUSICBRAINZ_ALBUMTYPE',
+ 'musicbrainz_recordingid': 'musicbrainz_trackid',
+ 'musicbrainz_trackid': 'musicbrainz_releasetrackid',
+ 'originalartist': 'Original Artist',
+ 'replaygain_album_gain': 'REPLAYGAIN_ALBUM_GAIN',
+ 'replaygain_album_peak': 'REPLAYGAIN_ALBUM_PEAK',
+ 'replaygain_album_range': 'REPLAYGAIN_ALBUM_RANGE',
+ 'replaygain_track_gain': 'REPLAYGAIN_TRACK_GAIN',
+ 'replaygain_track_peak': 'REPLAYGAIN_TRACK_PEAK',
+ 'replaygain_track_range': 'REPLAYGAIN_TRACK_RANGE',
+ 'replaygain_reference_loudness': 'REPLAYGAIN_REFERENCE_LOUDNESS',
}
__rtranslate = {v.lower(): k for k, v in __translate.items()}
@@ -138,7 +138,7 @@ def _load(self, filename):
for origname, values in file.tags.items():
name_lower = origname.lower()
if (values.kind == mutagen.apev2.BINARY
- and name_lower.startswith("cover art")):
+ and name_lower.startswith('cover art')):
if b'\0' in values.value:
descr, data = values.value.split(b'\0', 1)
try:
@@ -148,7 +148,7 @@ def _load(self, filename):
data=data,
)
except CoverArtImageError as e:
- log.error('Cannot load image from %r: %s', filename, e)
+ log.error("Cannot load image from %r: %s", filename, e)
else:
metadata.images.append(coverartimage)
@@ -157,20 +157,20 @@ def _load(self, filename):
continue
for value in values:
name = name_lower
- if name == "year":
- name = "date"
+ if name == 'year':
+ name = 'date'
value = sanitize_date(value)
- elif name == "track":
- name = "tracknumber"
- track = value.split("/")
+ elif name == 'track':
+ name = 'tracknumber'
+ track = value.split('/')
if len(track) > 1:
- metadata["totaltracks"] = track[1]
+ metadata['totaltracks'] = track[1]
value = track[0]
- elif name == "disc":
- name = "discnumber"
- disc = value.split("/")
+ elif name == 'disc':
+ name = 'discnumber'
+ disc = value.split('/')
if len(disc) > 1:
- metadata["totaldiscs"] = disc[1]
+ metadata['totaldiscs'] = disc[1]
value = disc[0]
elif name in {'performer', 'comment'}:
if value.endswith(')'):
@@ -194,7 +194,7 @@ def _save(self, filename, metadata):
except mutagen.apev2.APENoHeaderError:
tags = mutagen.apev2.APEv2()
images_to_save = list(metadata.images.to_be_saved_to_tags())
- if config.setting["clear_existing_tags"]:
+ if config.setting['clear_existing_tags']:
preserved = []
if config.setting['preserve_images']:
preserved = list(self._iter_cover_art_tags(tags))
@@ -206,7 +206,7 @@ def _save(self, filename, metadata):
del tags[name]
temp = {}
for name, value in metadata.items():
- if name.startswith("~") or not self.supports_tag(name):
+ if name.startswith('~') or not self.supports_tag(name):
continue
real_name = self._get_tag_name(name)
# tracknumber/totaltracks => Track
@@ -326,7 +326,7 @@ def _move_or_rename_wvc(self, old_filename, new_filename):
def _move_additional_files(self, old_filename, new_filename, config):
"""Includes an additional check for WavPack correction files"""
- if config.setting["rename_files"] or config.setting["move_files"]:
+ if config.setting['rename_files'] or config.setting['move_files']:
self._move_or_rename_wvc(old_filename, new_filename)
return super()._move_additional_files(old_filename, new_filename, config)
@@ -384,7 +384,7 @@ def _save(self, filename, metadata):
try:
mutagen.apev2.delete(encode_filename(filename))
except BaseException:
- log.exception('Error removing APEv2 tags from %s', filename)
+ log.exception("Error removing APEv2 tags from %s", filename)
@classmethod
def supports_tag(cls, name):
diff --git a/picard/formats/asf.py b/picard/formats/asf.py
index 3db2a14088..c10e2af03b 100644
--- a/picard/formats/asf.py
+++ b/picard/formats/asf.py
@@ -59,32 +59,32 @@ def unpack_image(data):
The image data in the given length
"""
try:
- (type_, size) = struct.unpack_from(" 1:
- metadata["totaldiscs"] = disc[1]
+ metadata['totaldiscs'] = disc[1]
values[0] = disc[0]
name_lower = name.lower()
if name in self.__RTRANS:
diff --git a/picard/formats/id3.py b/picard/formats/id3.py
index 2f993ea113..e3ce1b7cf6 100644
--- a/picard/formats/id3.py
+++ b/picard/formats/id3.py
@@ -89,7 +89,7 @@ def id3text(text, encoding):
"""
if encoding == Id3Encoding.LATIN1:
- return text.encode("latin1", "replace").decode("latin1")
+ return text.encode('latin1', 'replace').decode('latin1')
return text
@@ -220,9 +220,9 @@ class ID3File(File):
}
_rtipl_roles = {v: k for k, v in _tipl_roles.items()}
- __other_supported_tags = ("discnumber", "tracknumber",
- "totaldiscs", "totaltracks",
- "movementnumber", "movementtotal")
+ __other_supported_tags = ('discnumber', 'tracknumber',
+ 'totaldiscs', 'totaltracks',
+ 'movementnumber', 'movementtotal')
__tag_re_parse = {
'TRCK': re.compile(r'^(?P\d+)(?:/(?P\d+))?$'),
'TPOS': re.compile(r'^(?P\d+)(?:/(?P\d+))?$'),
@@ -262,7 +262,7 @@ def _load(self, filename):
frameid = frame.FrameID
if frameid in self.__translate:
name = self.__translate[frameid]
- if frameid.startswith('T') or frameid in {"GRP1", "MVNM"}:
+ if frameid.startswith('T') or frameid in {'GRP1', 'MVNM'}:
for text in frame.text:
if text:
metadata.add(name, text)
@@ -281,7 +281,7 @@ def _load(self, filename):
for text in frame.text:
if text:
metadata.add(name, text)
- elif frameid == "TMCL":
+ elif frameid == 'TMCL':
for role, name in frame.people:
if role == 'performer':
role = ''
@@ -289,7 +289,7 @@ def _load(self, filename):
metadata.add('performer:%s' % role, name)
else:
metadata.add('performer', name)
- elif frameid == "TIPL":
+ elif frameid == 'TIPL':
# If file is ID3v2.3, TIPL tag could contain TMCL
# so we will test for TMCL values and add to TIPL if not TMCL
for role, name in frame.people:
@@ -330,7 +330,7 @@ def _load(self, filename):
if frame.desc:
name += ':%s' % frame.desc
metadata.add(name, frame.text)
- elif frameid == 'UFID' and frame.owner == 'http://musicbrainz.org':
+ elif frameid == 'UFID' and frame.owner == "http://musicbrainz.org":
metadata['musicbrainz_recordingid'] = frame.data.decode('ascii', 'ignore')
elif frameid in self.__tag_re_parse.keys():
m = self.__tag_re_parse[frameid].search(frame.text[0])
@@ -352,7 +352,7 @@ def _load(self, filename):
id3_type=frame.type,
)
except CoverArtImageError as e:
- log.error('Cannot load image from %r: %s', filename, e)
+ log.error("Cannot load image from %r: %s", filename, e)
else:
metadata.images.append(coverartimage)
elif frameid == 'POPM':
@@ -375,7 +375,7 @@ def _save(self, filename, metadata):
tags = self._get_tags(filename)
config = get_config()
if config.setting['clear_existing_tags']:
- cover = tags.getall('APIC') if config.setting["preserve_images"] else None
+ cover = tags.getall('APIC') if config.setting['preserve_images'] else None
tags.clear()
if cover:
tags.setall('APIC', cover)
@@ -463,7 +463,7 @@ def _save(self, filename, metadata):
for value in values:
tipl.people.append([self._rtipl_roles[name], value])
elif name == 'musicbrainz_recordingid':
- tags.add(id3.UFID(owner='http://musicbrainz.org', data=bytes(values[0], 'ascii')))
+ tags.add(id3.UFID(owner="http://musicbrainz.org", data=bytes(values[0], 'ascii')))
elif name == '~rating':
rating_user_email = id3text(config.setting['rating_user_email'], Id3Encoding.LATIN1)
# Search for an existing POPM frame to get the current playcount
@@ -538,7 +538,7 @@ def _save(self, filename, metadata):
if frameclass:
tags.add(frameclass(encoding=encoding, text=values))
# don't save private / already stored tags
- elif not name.startswith("~") and name not in self.__other_supported_tags:
+ elif not name.startswith('~') and name not in self.__other_supported_tags:
tags.add(self.build_TXXX(encoding, name, values))
if tmcl.people:
@@ -550,7 +550,7 @@ def _save(self, filename, metadata):
self._save_tags(tags, encode_filename(filename))
- if self._IsMP3 and config.setting["remove_ape_from_mp3"]:
+ if self._IsMP3 and config.setting['remove_ape_from_mp3']:
try:
mutagen.apev2.delete(encode_filename(filename))
except BaseException:
@@ -585,7 +585,7 @@ def _remove_deleted_tags(self, metadata, tags):
_remove_people_with_role(tags, ['TIPL', 'IPLS'], role)
elif name == 'musicbrainz_recordingid':
for key, frame in list(tags.items()):
- if frame.FrameID == 'UFID' and frame.owner == 'http://musicbrainz.org':
+ if frame.FrameID == 'UFID' and frame.owner == "http://musicbrainz.org":
del tags[key]
elif name == 'license':
tags.delall(real_name)
@@ -603,9 +603,9 @@ def _remove_deleted_tags(self, metadata, tags):
tags.delall('TXXX:' + real_name)
if real_name in self.__rrename_freetext:
tags.delall('TXXX:' + self.__rrename_freetext[real_name])
- elif not name.startswith("~id3:") and name not in self.__other_supported_tags:
+ elif not name.startswith('~id3:') and name not in self.__other_supported_tags:
tags.delall('TXXX:' + name)
- elif name.startswith("~id3:"):
+ elif name.startswith('~id3:'):
frameid = name[5:]
tags.delall(frameid)
elif name in self.__other_supported_tags:
@@ -615,9 +615,9 @@ def _remove_deleted_tags(self, metadata, tags):
@classmethod
def supports_tag(cls, name):
- return ((name and not name.startswith("~") and name not in UNSUPPORTED_TAGS)
- or name == "~rating"
- or name.startswith("~id3"))
+ return ((name and not name.startswith('~') and name not in UNSUPPORTED_TAGS)
+ or name == '~rating'
+ or name.startswith('~id3'))
def _get_tag_name(self, name):
if name in self.__rtranslate:
@@ -663,23 +663,23 @@ def format_specific_metadata(self, metadata, tag, settings=None):
if not settings:
settings = get_config().setting
- if not settings["write_id3v23"]:
+ if not settings['write_id3v23']:
return super().format_specific_metadata(metadata, tag, settings)
values = metadata.getall(tag)
if not values:
return values
- if tag == "originaldate":
+ if tag == 'originaldate':
values = [v[:4] for v in values]
- elif tag == "date":
+ elif tag == 'date':
values = [(v[:4] if len(v) < 10 else v) for v in values]
# If this is a multi-valued field, then it needs to be flattened,
# unless it's TIPL or TMCL which can still be multi-valued.
if (len(values) > 1 and tag not in ID3File._rtipl_roles
- and not tag.startswith("performer:")):
- join_with = settings["id3v23_join_with"]
+ and not tag.startswith('performer:')):
+ join_with = settings['id3v23_join_with']
values = [join_with.join(values)]
return values
diff --git a/picard/formats/mp4.py b/picard/formats/mp4.py
index ca2c8de82c..82a2291b43 100644
--- a/picard/formats/mp4.py
+++ b/picard/formats/mp4.py
@@ -51,7 +51,7 @@
def _add_text_values_to_metadata(metadata, name, values):
for value in values:
- metadata.add(name, value.decode("utf-8", "replace").strip("\x00"))
+ metadata.add(name, value.decode('utf-8', 'replace').strip('\x00'))
_VALID_KEY_CHARS = re.compile('^[\x00-\xff]+$')
@@ -71,106 +71,106 @@ class MP4File(File):
_File = MP4
__text_tags = {
- "\xa9ART": "artist",
- "\xa9nam": "title",
- "\xa9alb": "album",
- "\xa9wrt": "composer",
- "aART": "albumartist",
- "\xa9grp": "grouping",
- "\xa9day": "date",
- "\xa9gen": "genre",
- "\xa9lyr": "lyrics",
- "\xa9cmt": "comment",
- "\xa9too": "encodedby",
- "\xa9dir": "director",
- "cprt": "copyright",
- "soal": "albumsort",
- "soaa": "albumartistsort",
- "soar": "artistsort",
- "sonm": "titlesort",
- "soco": "composersort",
- "sosn": "showsort",
- "tvsh": "show",
- "purl": "podcasturl",
- "\xa9mvn": "movement",
- "\xa9wrk": "work",
+ '\xa9ART': 'artist',
+ '\xa9nam': 'title',
+ '\xa9alb': 'album',
+ '\xa9wrt': 'composer',
+ 'aART': 'albumartist',
+ '\xa9grp': 'grouping',
+ '\xa9day': 'date',
+ '\xa9gen': 'genre',
+ '\xa9lyr': 'lyrics',
+ '\xa9cmt': 'comment',
+ '\xa9too': 'encodedby',
+ '\xa9dir': 'director',
+ 'cprt': 'copyright',
+ 'soal': 'albumsort',
+ 'soaa': 'albumartistsort',
+ 'soar': 'artistsort',
+ 'sonm': 'titlesort',
+ 'soco': 'composersort',
+ 'sosn': 'showsort',
+ 'tvsh': 'show',
+ 'purl': 'podcasturl',
+ '\xa9mvn': 'movement',
+ '\xa9wrk': 'work',
}
__r_text_tags = {v: k for k, v in __text_tags.items()}
__bool_tags = {
- "pcst": "podcast",
- "cpil": "compilation",
- "pgap": "gapless",
+ 'pcst': 'podcast',
+ 'cpil': 'compilation',
+ 'pgap': 'gapless',
}
__r_bool_tags = {v: k for k, v in __bool_tags.items()}
__int_tags = {
- "tmpo": "bpm",
- "\xa9mvi": "movementnumber",
- "\xa9mvc": "movementtotal",
- "shwm": "showmovement",
+ 'tmpo': 'bpm',
+ '\xa9mvi': 'movementnumber',
+ '\xa9mvc': 'movementtotal',
+ 'shwm': 'showmovement',
}
__r_int_tags = {v: k for k, v in __int_tags.items()}
__freeform_tags = {
- "----:com.apple.iTunes:MusicBrainz Track Id": "musicbrainz_recordingid",
- "----:com.apple.iTunes:MusicBrainz Artist Id": "musicbrainz_artistid",
- "----:com.apple.iTunes:MusicBrainz Album Id": "musicbrainz_albumid",
- "----:com.apple.iTunes:MusicBrainz Album Artist Id": "musicbrainz_albumartistid",
- "----:com.apple.iTunes:MusicIP PUID": "musicip_puid",
- "----:com.apple.iTunes:MusicBrainz Album Status": "releasestatus",
- "----:com.apple.iTunes:MusicBrainz Album Release Country": "releasecountry",
- "----:com.apple.iTunes:MusicBrainz Album Type": "releasetype",
- "----:com.apple.iTunes:MusicBrainz Disc Id": "musicbrainz_discid",
- "----:com.apple.iTunes:MusicBrainz TRM Id": "musicbrainz_trmid",
- "----:com.apple.iTunes:MusicBrainz Work Id": "musicbrainz_workid",
- "----:com.apple.iTunes:MusicBrainz Release Group Id": "musicbrainz_releasegroupid",
- "----:com.apple.iTunes:MusicBrainz Release Track Id": "musicbrainz_trackid",
- "----:com.apple.iTunes:MusicBrainz Original Album Id": "musicbrainz_originalalbumid",
- "----:com.apple.iTunes:MusicBrainz Original Artist Id": "musicbrainz_originalartistid",
- "----:com.apple.iTunes:Acoustid Fingerprint": "acoustid_fingerprint",
- "----:com.apple.iTunes:Acoustid Id": "acoustid_id",
- "----:com.apple.iTunes:ASIN": "asin",
- "----:com.apple.iTunes:BARCODE": "barcode",
- "----:com.apple.iTunes:PRODUCER": "producer",
- "----:com.apple.iTunes:LYRICIST": "lyricist",
- "----:com.apple.iTunes:CONDUCTOR": "conductor",
- "----:com.apple.iTunes:ENGINEER": "engineer",
- "----:com.apple.iTunes:MIXER": "mixer",
- "----:com.apple.iTunes:DJMIXER": "djmixer",
- "----:com.apple.iTunes:REMIXER": "remixer",
- "----:com.apple.iTunes:ISRC": "isrc",
- "----:com.apple.iTunes:MEDIA": "media",
- "----:com.apple.iTunes:LABEL": "label",
- "----:com.apple.iTunes:LICENSE": "license",
- "----:com.apple.iTunes:CATALOGNUMBER": "catalognumber",
- "----:com.apple.iTunes:SUBTITLE": "subtitle",
- "----:com.apple.iTunes:DISCSUBTITLE": "discsubtitle",
- "----:com.apple.iTunes:MOOD": "mood",
- "----:com.apple.iTunes:SCRIPT": "script",
- "----:com.apple.iTunes:LANGUAGE": "language",
- "----:com.apple.iTunes:ARTISTS": "artists",
- "----:com.apple.iTunes:WORK": "work",
- "----:com.apple.iTunes:initialkey": "key",
+ '----:com.apple.iTunes:MusicBrainz Track Id': 'musicbrainz_recordingid',
+ '----:com.apple.iTunes:MusicBrainz Artist Id': 'musicbrainz_artistid',
+ '----:com.apple.iTunes:MusicBrainz Album Id': 'musicbrainz_albumid',
+ '----:com.apple.iTunes:MusicBrainz Album Artist Id': 'musicbrainz_albumartistid',
+ '----:com.apple.iTunes:MusicIP PUID': 'musicip_puid',
+ '----:com.apple.iTunes:MusicBrainz Album Status': 'releasestatus',
+ '----:com.apple.iTunes:MusicBrainz Album Release Country': 'releasecountry',
+ '----:com.apple.iTunes:MusicBrainz Album Type': 'releasetype',
+ '----:com.apple.iTunes:MusicBrainz Disc Id': 'musicbrainz_discid',
+ '----:com.apple.iTunes:MusicBrainz TRM Id': 'musicbrainz_trmid',
+ '----:com.apple.iTunes:MusicBrainz Work Id': 'musicbrainz_workid',
+ '----:com.apple.iTunes:MusicBrainz Release Group Id': 'musicbrainz_releasegroupid',
+ '----:com.apple.iTunes:MusicBrainz Release Track Id': 'musicbrainz_trackid',
+ '----:com.apple.iTunes:MusicBrainz Original Album Id': 'musicbrainz_originalalbumid',
+ '----:com.apple.iTunes:MusicBrainz Original Artist Id': 'musicbrainz_originalartistid',
+ '----:com.apple.iTunes:Acoustid Fingerprint': 'acoustid_fingerprint',
+ '----:com.apple.iTunes:Acoustid Id': 'acoustid_id',
+ '----:com.apple.iTunes:ASIN': 'asin',
+ '----:com.apple.iTunes:BARCODE': 'barcode',
+ '----:com.apple.iTunes:PRODUCER': 'producer',
+ '----:com.apple.iTunes:LYRICIST': 'lyricist',
+ '----:com.apple.iTunes:CONDUCTOR': 'conductor',
+ '----:com.apple.iTunes:ENGINEER': 'engineer',
+ '----:com.apple.iTunes:MIXER': 'mixer',
+ '----:com.apple.iTunes:DJMIXER': 'djmixer',
+ '----:com.apple.iTunes:REMIXER': 'remixer',
+ '----:com.apple.iTunes:ISRC': 'isrc',
+ '----:com.apple.iTunes:MEDIA': 'media',
+ '----:com.apple.iTunes:LABEL': 'label',
+ '----:com.apple.iTunes:LICENSE': 'license',
+ '----:com.apple.iTunes:CATALOGNUMBER': 'catalognumber',
+ '----:com.apple.iTunes:SUBTITLE': 'subtitle',
+ '----:com.apple.iTunes:DISCSUBTITLE': 'discsubtitle',
+ '----:com.apple.iTunes:MOOD': 'mood',
+ '----:com.apple.iTunes:SCRIPT': 'script',
+ '----:com.apple.iTunes:LANGUAGE': 'language',
+ '----:com.apple.iTunes:ARTISTS': 'artists',
+ '----:com.apple.iTunes:WORK': 'work',
+ '----:com.apple.iTunes:initialkey': 'key',
}
__r_freeform_tags = {v: k for k, v in __freeform_tags.items()}
# Tags to load case insensitive. Case is preserved, but the specified case
# is written if it is unset.
__r_freeform_tags_ci = {
- "replaygain_album_gain": "----:com.apple.iTunes:REPLAYGAIN_ALBUM_GAIN",
- "replaygain_album_peak": "----:com.apple.iTunes:REPLAYGAIN_ALBUM_PEAK",
- "replaygain_album_range": "----:com.apple.iTunes:REPLAYGAIN_ALBUM_RANGE",
- "replaygain_track_gain": "----:com.apple.iTunes:REPLAYGAIN_TRACK_GAIN",
- "replaygain_track_peak": "----:com.apple.iTunes:REPLAYGAIN_TRACK_PEAK",
- "replaygain_track_range": "----:com.apple.iTunes:REPLAYGAIN_TRACK_RANGE",
- "replaygain_reference_loudness": "----:com.apple.iTunes:REPLAYGAIN_REFERENCE_LOUDNESS",
- "releasedate": "----:com.apple.iTunes:RELEASEDATE",
+ 'replaygain_album_gain': '----:com.apple.iTunes:REPLAYGAIN_ALBUM_GAIN',
+ 'replaygain_album_peak': '----:com.apple.iTunes:REPLAYGAIN_ALBUM_PEAK',
+ 'replaygain_album_range': '----:com.apple.iTunes:REPLAYGAIN_ALBUM_RANGE',
+ 'replaygain_track_gain': '----:com.apple.iTunes:REPLAYGAIN_TRACK_GAIN',
+ 'replaygain_track_peak': '----:com.apple.iTunes:REPLAYGAIN_TRACK_PEAK',
+ 'replaygain_track_range': '----:com.apple.iTunes:REPLAYGAIN_TRACK_RANGE',
+ 'replaygain_reference_loudness': '----:com.apple.iTunes:REPLAYGAIN_REFERENCE_LOUDNESS',
+ 'releasedate': '----:com.apple.iTunes:RELEASEDATE',
}
__freeform_tags_ci = {b.lower(): a for a, b in __r_freeform_tags_ci.items()}
- __other_supported_tags = ("discnumber", "tracknumber",
- "totaldiscs", "totaltracks")
+ __other_supported_tags = ('discnumber', 'tracknumber',
+ 'totaldiscs', 'totaltracks')
def __init__(self, filename):
super().__init__(filename)
@@ -199,24 +199,24 @@ def _load(self, filename):
tag_name = self.__freeform_tags_ci[name_lower]
self.__casemap[tag_name] = name
_add_text_values_to_metadata(metadata, tag_name, values)
- elif name == "----:com.apple.iTunes:fingerprint":
+ elif name == '----:com.apple.iTunes:fingerprint':
for value in values:
- value = value.decode("utf-8", "replace").strip("\x00")
- if value.startswith("MusicMagic Fingerprint"):
- metadata.add("musicip_fingerprint", value[22:])
- elif name == "trkn":
+ value = value.decode('utf-8', 'replace').strip('\x00')
+ if value.startswith('MusicMagic Fingerprint'):
+ metadata.add('musicip_fingerprint', value[22:])
+ elif name == 'trkn':
try:
- metadata["tracknumber"] = values[0][0]
- metadata["totaltracks"] = values[0][1]
+ metadata['tracknumber'] = values[0][0]
+ metadata['totaltracks'] = values[0][1]
except IndexError:
- log.debug('trkn is invalid, ignoring')
- elif name == "disk":
+ log.debug("trkn is invalid, ignoring")
+ elif name == 'disk':
try:
- metadata["discnumber"] = values[0][0]
- metadata["totaldiscs"] = values[0][1]
+ metadata['discnumber'] = values[0][0]
+ metadata['totaldiscs'] = values[0][1]
except IndexError:
- log.debug('disk is invalid, ignoring')
- elif name == "covr":
+ log.debug("disk is invalid, ignoring")
+ elif name == 'covr':
for value in values:
if value.imageformat not in {value.FORMAT_JPEG, value.FORMAT_PNG}:
continue
@@ -227,7 +227,7 @@ def _load(self, filename):
data=value,
)
except CoverArtImageError as e:
- log.error('Cannot load image from %r: %s', filename, e)
+ log.error("Cannot load image from %r: %s", filename, e)
else:
metadata.images.append(coverartimage)
# Read other freeform tags always case insensitive
@@ -253,7 +253,7 @@ def _save(self, filename, metadata):
file.add_tags()
tags = file.tags
- if config.setting["clear_existing_tags"]:
+ if config.setting['clear_existing_tags']:
cover = tags.get('covr') if config.setting['preserve_images'] else None
tags.clear()
if cover:
@@ -274,59 +274,59 @@ def _save(self, filename, metadata):
except ValueError:
pass
elif name in self.__r_freeform_tags:
- values = [v.encode("utf-8") for v in values]
+ values = [v.encode('utf-8') for v in values]
tags[self.__r_freeform_tags[name]] = values
elif name in self.__r_freeform_tags_ci:
- values = [v.encode("utf-8") for v in values]
+ values = [v.encode('utf-8') for v in values]
delall_ci(tags, self.__r_freeform_tags_ci[name])
if name in self.__casemap:
name = self.__casemap[name]
else:
name = self.__r_freeform_tags_ci[name]
tags[name] = values
- elif name == "musicip_fingerprint":
- tags["----:com.apple.iTunes:fingerprint"] = [b"MusicMagic Fingerprint%s" % v.encode('ascii') for v in values]
+ elif name == 'musicip_fingerprint':
+ tags['----:com.apple.iTunes:fingerprint'] = [b'MusicMagic Fingerprint%s' % v.encode('ascii') for v in values]
elif self.supports_tag(name) and name not in self.__other_supported_tags:
- values = [v.encode("utf-8") for v in values]
+ values = [v.encode('utf-8') for v in values]
name = self.__casemap.get(name, name)
tags['----:com.apple.iTunes:' + name] = values
- if "tracknumber" in metadata:
+ if 'tracknumber' in metadata:
try:
- tracknumber = int(metadata["tracknumber"])
+ tracknumber = int(metadata['tracknumber'])
except ValueError:
pass
else:
totaltracks = 0
- if "totaltracks" in metadata:
+ if 'totaltracks' in metadata:
try:
- totaltracks = int(metadata["totaltracks"])
+ totaltracks = int(metadata['totaltracks'])
except ValueError:
pass
- tags["trkn"] = [(tracknumber, totaltracks)]
+ tags['trkn'] = [(tracknumber, totaltracks)]
- if "discnumber" in metadata:
+ if 'discnumber' in metadata:
try:
- discnumber = int(metadata["discnumber"])
+ discnumber = int(metadata['discnumber'])
except ValueError:
pass
else:
totaldiscs = 0
- if "totaldiscs" in metadata:
+ if 'totaldiscs' in metadata:
try:
- totaldiscs = int(metadata["totaldiscs"])
+ totaldiscs = int(metadata['totaldiscs'])
except ValueError:
pass
- tags["disk"] = [(discnumber, totaldiscs)]
+ tags['disk'] = [(discnumber, totaldiscs)]
covr = []
for image in metadata.images.to_be_saved_to_tags():
- if image.mimetype == "image/jpeg":
+ if image.mimetype == 'image/jpeg':
covr.append(MP4Cover(image.data, MP4Cover.FORMAT_JPEG))
- elif image.mimetype == "image/png":
+ elif image.mimetype == 'image/png':
covr.append(MP4Cover(image.data, MP4Cover.FORMAT_PNG))
if covr:
- tags["covr"] = covr
+ tags['covr'] = covr
self._remove_deleted_tags(metadata, tags)
@@ -337,13 +337,13 @@ def _remove_deleted_tags(self, metadata, tags):
for tag in metadata.deleted_tags:
real_name = self._get_tag_name(tag)
if real_name and real_name in tags:
- if tag not in {"totaltracks", "totaldiscs"}:
+ if tag not in {'totaltracks', 'totaldiscs'}:
del tags[real_name]
@classmethod
def supports_tag(cls, name):
return (name
- and not name.startswith("~")
+ and not name.startswith('~')
and name not in UNSUPPORTED_TAGS
and not (name.startswith('comment:') and len(name) > 9)
and not name.startswith('performer:')
@@ -362,12 +362,12 @@ def _get_tag_name(self, name):
return self.__r_freeform_tags[name]
elif name in self.__r_freeform_tags_ci:
return self.__r_freeform_tags_ci[name]
- elif name == "musicip_fingerprint":
- return "----:com.apple.iTunes:fingerprint"
- elif name in {"tracknumber", "totaltracks"}:
- return "trkn"
- elif name in {"discnumber", "totaldiscs"}:
- return "disk"
+ elif name == 'musicip_fingerprint':
+ return '----:com.apple.iTunes:fingerprint'
+ elif name in {'tracknumber', 'totaltracks'}:
+ return 'trkn'
+ elif name in {'discnumber', 'totaldiscs'}:
+ return 'disk'
elif self.supports_tag(name) and name not in self.__other_supported_tags:
name = self.__casemap.get(name, name)
return '----:com.apple.iTunes:' + name
diff --git a/picard/formats/util.py b/picard/formats/util.py
index bce9784510..777d447881 100644
--- a/picard/formats/util.py
+++ b/picard/formats/util.py
@@ -59,7 +59,7 @@ def guess_format(filename, options=_formats):
results = []
# Since we are reading only 128 bytes and then immediately closing the file,
# use unbuffered mode.
- with open(filename, "rb", 0) as fileobj:
+ with open(filename, 'rb', 0) as fileobj:
header = fileobj.read(128)
# Calls the score method of a particular format's associated filetype
# and assigns a positive score depending on how closely the fileobj's header matches
diff --git a/picard/formats/vorbis.py b/picard/formats/vorbis.py
index 0061c56304..0e59da0914 100644
--- a/picard/formats/vorbis.py
+++ b/picard/formats/vorbis.py
@@ -122,11 +122,11 @@ class VCommentFile(File):
_File = None
__translate = {
- "movement": "movementnumber",
- "movementname": "movement",
- "musicbrainz_releasetrackid": "musicbrainz_trackid",
- "musicbrainz_trackid": "musicbrainz_recordingid",
- "waveformatextensible_channel_mask": "~waveformatextensible_channel_mask",
+ 'movement': 'movementnumber',
+ 'movementname': 'movement',
+ 'musicbrainz_releasetrackid': 'musicbrainz_trackid',
+ 'musicbrainz_trackid': 'musicbrainz_recordingid',
+ 'waveformatextensible_channel_mask': '~waveformatextensible_channel_mask',
}
__rtranslate = {v: k for k, v in __translate.items()}
@@ -170,18 +170,18 @@ def _load(self, filename):
value = str(round((float(value) * (config.setting['rating_steps'] - 1))))
except ValueError:
log.warning('Invalid rating value in %r: %s', filename, value)
- elif name == "fingerprint" and value.startswith("MusicMagic Fingerprint"):
- name = "musicip_fingerprint"
+ elif name == 'fingerprint' and value.startswith('MusicMagic Fingerprint'):
+ name = 'musicip_fingerprint'
value = value[22:]
- elif name == "tracktotal":
- if "totaltracks" in file.tags:
+ elif name == 'tracktotal':
+ if 'totaltracks' in file.tags:
continue
- name = "totaltracks"
- elif name == "disctotal":
- if "totaldiscs" in file.tags:
+ name = 'totaltracks'
+ elif name == 'disctotal':
+ if 'totaldiscs' in file.tags:
continue
- name = "totaldiscs"
- elif name == "metadata_block_picture":
+ name = 'totaldiscs'
+ elif name == 'metadata_block_picture':
try:
image = mutagen.flac.Picture(base64.standard_b64decode(value))
coverartimage = TagCoverArtImage(
@@ -194,7 +194,7 @@ def _load(self, filename):
id3_type=image.type
)
except (CoverArtImageError, TypeError, ValueError, mutagen.flac.error) as e:
- log.error('Cannot load image from %r: %s', filename, e)
+ log.error("Cannot load image from %r: %s", filename, e)
else:
metadata.images.append(coverartimage)
continue
@@ -214,14 +214,14 @@ def _load(self, filename):
id3_type=image.type
)
except CoverArtImageError as e:
- log.error('Cannot load image from %r: %s', filename, e)
+ log.error("Cannot load image from %r: %s", filename, e)
else:
metadata.images.append(coverartimage)
# Read the unofficial COVERART tags, for backward compatibility only
- if "metadata_block_picture" not in file.tags:
+ if 'metadata_block_picture' not in file.tags:
try:
- for data in file["COVERART"]:
+ for data in file['COVERART']:
try:
coverartimage = TagCoverArtImage(
file=filename,
@@ -229,7 +229,7 @@ def _load(self, filename):
data=base64.standard_b64decode(data)
)
except (CoverArtImageError, TypeError, ValueError) as e:
- log.error('Cannot load image from %r: %s', filename, e)
+ log.error("Cannot load image from %r: %s", filename, e)
else:
metadata.images.append(coverartimage)
except KeyError:
@@ -245,9 +245,9 @@ def _save(self, filename, metadata):
file = self._File(encode_filename(filename))
if file.tags is None:
file.add_tags()
- if config.setting["clear_existing_tags"]:
+ if config.setting['clear_existing_tags']:
preserve_tags = ['waveformatextensible_channel_mask']
- if not is_flac and config.setting["preserve_images"]:
+ if not is_flac and config.setting['preserve_images']:
preserve_tags.append('metadata_block_picture')
preserve_tags.append('coverart')
preserved_values = {}
@@ -259,8 +259,8 @@ def _save(self, filename, metadata):
file.tags[name] = value
images_to_save = list(metadata.images.to_be_saved_to_tags())
if is_flac and (images_to_save
- or (config.setting["clear_existing_tags"]
- and not config.setting["preserve_images"])):
+ or (config.setting['clear_existing_tags']
+ and not config.setting['preserve_images'])):
file.clear_pictures()
tags = {}
@@ -293,10 +293,10 @@ def _save(self, filename, metadata):
name = self.__rtranslate[name]
tags.setdefault(name.upper(), []).append(value.rstrip('\0'))
- if "totaltracks" in metadata:
- tags.setdefault("TRACKTOTAL", []).append(metadata["totaltracks"])
- if "totaldiscs" in metadata:
- tags.setdefault("DISCTOTAL", []).append(metadata["totaldiscs"])
+ if 'totaltracks' in metadata:
+ tags.setdefault('TRACKTOTAL', []).append(metadata['totaltracks'])
+ if 'totaldiscs' in metadata:
+ tags.setdefault('DISCTOTAL', []).append(metadata['totaldiscs'])
for image in images_to_save:
picture = mutagen.flac.Picture()
@@ -312,12 +312,12 @@ def _save(self, filename, metadata):
+ len(picture.mime)
+ len(picture.desc.encode('UTF-8')))
if expected_block_size > FLAC_MAX_BLOCK_SIZE:
- log.error('Failed saving image to %r: Image size of %d bytes exceeds maximum FLAC block size of %d bytes',
+ log.error("Failed saving image to %r: Image size of %d bytes exceeds maximum FLAC block size of %d bytes",
filename, expected_block_size, FLAC_MAX_BLOCK_SIZE)
continue
file.add_picture(picture)
else:
- tags.setdefault("METADATA_BLOCK_PICTURE", []).append(
+ tags.setdefault('METADATA_BLOCK_PICTURE', []).append(
base64.b64encode(picture.write()).decode('ascii'))
file.tags.update(tags)
@@ -327,10 +327,10 @@ def _save(self, filename, metadata):
kwargs = {}
if is_flac:
flac_sort_pics_after_tags(file.metadata_blocks)
- if config.setting["fix_missing_seekpoints_flac"]:
+ if config.setting['fix_missing_seekpoints_flac']:
flac_remove_empty_seektable(file)
- if config.setting["remove_id3_from_flac"]:
- kwargs["deleteid3"] = True
+ if config.setting['remove_id3_from_flac']:
+ kwargs['deleteid3'] = True
try:
file.save(**kwargs)
except TypeError:
diff --git a/picard/metadata.py b/picard/metadata.py
index 5eadad7723..8fe0f7ff57 100644
--- a/picard/metadata.py
+++ b/picard/metadata.py
@@ -253,18 +253,18 @@ def compare_to_release_parts(self, release, weights):
parts = []
with self._lock.lock_for_read():
- if "album" in self and "album" in weights:
+ if 'album' in self and 'album' in weights:
b = release['title']
- parts.append((similarity2(self["album"], b), weights["album"]))
+ parts.append((similarity2(self['album'], b), weights['album']))
- if "albumartist" in self and "albumartist" in weights:
- a = self["albumartist"]
+ if 'albumartist' in self and 'albumartist' in weights:
+ a = self['albumartist']
b = artist_credit_from_node(release['artist-credit'])[0]
- parts.append((similarity2(a, b), weights["albumartist"]))
+ parts.append((similarity2(a, b), weights['albumartist']))
- if "totaltracks" in weights:
+ if 'totaltracks' in weights:
try:
- a = int(self["totaltracks"])
+ a = int(self['totaltracks'])
if 'media' in release:
score = 0.0
for media in release['media']:
@@ -275,25 +275,25 @@ def compare_to_release_parts(self, release, weights):
else:
b = release['track-count']
score = trackcount_score(a, b)
- parts.append((score, weights["totaltracks"]))
+ parts.append((score, weights['totaltracks']))
except (ValueError, KeyError):
pass
- if "totalalbumtracks" in weights:
+ if 'totalalbumtracks' in weights:
try:
- a = int(self["~totalalbumtracks"] or self["totaltracks"])
+ a = int(self['~totalalbumtracks'] or self['totaltracks'])
b = release['track-count']
score = trackcount_score(a, b)
- parts.append((score, weights["totalalbumtracks"]))
+ parts.append((score, weights['totalalbumtracks']))
except (ValueError, KeyError):
pass
# Date Logic
date_match_factor = 0.0
- if "date" in weights:
- if "date" in release and release['date'] != '':
+ if 'date' in weights:
+ if 'date' in release and release['date'] != '':
release_date = release['date']
- if "date" in self:
+ if 'date' in self:
metadata_date = self['date']
if release_date == metadata_date:
# release has a date and it matches what our metadata had exactly.
@@ -326,20 +326,20 @@ def compare_to_release_parts(self, release, weights):
parts.append((date_match_factor, weights['date']))
config = get_config()
- if "releasecountry" in weights:
+ if 'releasecountry' in weights:
weights_from_preferred_countries(parts, release,
- config.setting["preferred_release_countries"],
- weights["releasecountry"])
+ config.setting['preferred_release_countries'],
+ weights['releasecountry'])
- if "format" in weights:
+ if 'format' in weights:
weights_from_preferred_formats(parts, release,
- config.setting["preferred_release_formats"],
- weights["format"])
+ config.setting['preferred_release_formats'],
+ weights['format'])
- if "releasetype" in weights:
+ if 'releasetype' in weights:
weights_from_release_type_scores(parts, release,
- config.setting["release_type_scores"],
- weights["releasetype"])
+ config.setting['release_type_scores'],
+ weights['releasetype'])
rg = QObject.tagger.get_release_group_by_id(release['release-group']['id'])
if release['id'] in rg.loaded_albums:
diff --git a/picard/oauth.py b/picard/oauth.py
index 971a0f9f63..79d26ae8e0 100644
--- a/picard/oauth.py
+++ b/picard/oauth.py
@@ -67,59 +67,59 @@ def port(self):
@property
def refresh_token(self):
- return self.persist["oauth_refresh_token"]
+ return self.persist['oauth_refresh_token']
@refresh_token.setter
def refresh_token(self, value):
- self.persist["oauth_refresh_token"] = value
+ self.persist['oauth_refresh_token'] = value
@refresh_token.deleter
def refresh_token(self):
- self.persist.remove("oauth_refresh_token")
+ self.persist.remove('oauth_refresh_token')
@property
def refresh_token_scopes(self):
- return self.persist["oauth_refresh_token_scopes"]
+ return self.persist['oauth_refresh_token_scopes']
@refresh_token_scopes.setter
def refresh_token_scopes(self, value):
- self.persist["oauth_refresh_token_scopes"] = value
+ self.persist['oauth_refresh_token_scopes'] = value
@refresh_token_scopes.deleter
def refresh_token_scopes(self):
- self.persist.remove("oauth_refresh_token_scopes")
+ self.persist.remove('oauth_refresh_token_scopes')
@property
def access_token(self):
- return self.persist["oauth_access_token"]
+ return self.persist['oauth_access_token']
@access_token.setter
def access_token(self, value):
- self.persist["oauth_access_token"] = value
+ self.persist['oauth_access_token'] = value
@access_token.deleter
def access_token(self):
- self.persist.remove("oauth_access_token")
+ self.persist.remove('oauth_access_token')
@property
def access_token_expires(self):
- return self.persist["oauth_access_token_expires"]
+ return self.persist['oauth_access_token_expires']
@access_token_expires.setter
def access_token_expires(self, value):
- self.persist["oauth_access_token_expires"] = value
+ self.persist['oauth_access_token_expires'] = value
@access_token_expires.deleter
def access_token_expires(self):
- self.persist.remove("oauth_access_token_expires")
+ self.persist.remove('oauth_access_token_expires')
@property
def username(self):
- return self.persist["oauth_username"]
+ return self.persist['oauth_username']
@username.setter
def username(self, value):
- self.persist["oauth_username"] = value
+ self.persist['oauth_username'] = value
def is_authorized(self):
return bool(self.refresh_token and self.refresh_token_scopes)
@@ -158,10 +158,10 @@ def url(self, path=None, params=None):
def get_authorization_url(self, scopes):
params = {
- "response_type": "code",
- "client_id": MUSICBRAINZ_OAUTH_CLIENT_ID,
- "redirect_uri": "urn:ietf:wg:oauth:2.0:oob",
- "scope": scopes,
+ 'response_type': 'code',
+ 'client_id': MUSICBRAINZ_OAUTH_CLIENT_ID,
+ 'redirect_uri': "urn:ietf:wg:oauth:2.0:oob",
+ 'scope': scopes,
}
return bytes(self.url(path="/oauth2/authorize", params=params).toEncoded()).decode()
@@ -182,10 +182,10 @@ def _query_data(params):
def refresh_access_token(self, callback):
log.debug("OAuth: refreshing access_token with a refresh_token %s", self.refresh_token)
params = {
- "grant_type": "refresh_token",
- "refresh_token": self.refresh_token,
- "client_id": MUSICBRAINZ_OAUTH_CLIENT_ID,
- "client_secret": MUSICBRAINZ_OAUTH_CLIENT_SECRET,
+ 'grant_type': 'refresh_token',
+ 'refresh_token': self.refresh_token,
+ 'client_id': MUSICBRAINZ_OAUTH_CLIENT_ID,
+ 'client_secret': MUSICBRAINZ_OAUTH_CLIENT_SECRET,
}
self.webservice.post_url(
url=self.url(path="/oauth2/token"),
@@ -194,7 +194,7 @@ def refresh_access_token(self, callback):
mblogin=True,
priority=True,
important=True,
- request_mimetype="application/x-www-form-urlencoded",
+ request_mimetype='application/x-www-form-urlencoded',
)
def on_refresh_access_token_finished(self, callback, data, http, error):
@@ -204,24 +204,24 @@ def on_refresh_access_token_finished(self, callback, data, http, error):
log.error("OAuth: access_token refresh failed: %s", data)
if self._http_code(http) == 400:
response = load_json(data)
- if response["error"] == "invalid_grant":
+ if response['error'] == 'invalid_grant':
self.forget_refresh_token()
else:
- access_token = data["access_token"]
- self.set_access_token(access_token, data["expires_in"])
+ access_token = data['access_token']
+ self.set_access_token(access_token, data['expires_in'])
except Exception as e:
- log.error('OAuth: Unexpected error handling access token response: %r', e)
+ log.error("OAuth: Unexpected error handling access token response: %r", e)
finally:
callback(access_token=access_token)
def exchange_authorization_code(self, authorization_code, scopes, callback):
log.debug("OAuth: exchanging authorization_code %s for an access_token", authorization_code)
params = {
- "grant_type": "authorization_code",
- "code": authorization_code,
- "client_id": MUSICBRAINZ_OAUTH_CLIENT_ID,
- "client_secret": MUSICBRAINZ_OAUTH_CLIENT_SECRET,
- "redirect_uri": "urn:ietf:wg:oauth:2.0:oob",
+ 'grant_type': 'authorization_code',
+ 'code': authorization_code,
+ 'client_id': MUSICBRAINZ_OAUTH_CLIENT_ID,
+ 'client_secret': MUSICBRAINZ_OAUTH_CLIENT_SECRET,
+ 'redirect_uri': "urn:ietf:wg:oauth:2.0:oob",
}
self.webservice.post_url(
url=self.url(path="/oauth2/token"),
@@ -230,7 +230,7 @@ def exchange_authorization_code(self, authorization_code, scopes, callback):
mblogin=True,
priority=True,
important=True,
- request_mimetype="application/x-www-form-urlencoded",
+ request_mimetype='application/x-www-form-urlencoded',
)
def on_exchange_authorization_code_finished(self, scopes, callback, data, http, error):
@@ -241,12 +241,12 @@ def on_exchange_authorization_code_finished(self, scopes, callback, data, http,
log.error("OAuth: authorization_code exchange failed: %s", data)
error_msg = self._extract_error_description(http, data)
else:
- self.set_refresh_token(data["refresh_token"], scopes)
- self.set_access_token(data["access_token"], data["expires_in"])
+ self.set_refresh_token(data['refresh_token'], scopes)
+ self.set_access_token(data['access_token'], data['expires_in'])
successful = True
except Exception as e:
- log.error('OAuth: Unexpected error handling authorization code response: %r', e)
- error_msg = _('Unexpected authentication error')
+ log.error("OAuth: Unexpected error handling authorization code response: %r", e)
+ error_msg = _("Unexpected authentication error")
finally:
callback(successful=successful, error_msg=error_msg)
@@ -268,12 +268,12 @@ def on_fetch_username_finished(self, callback, data, http, error):
log.error("OAuth: username fetching failed: %s", data)
error_msg = self._extract_error_description(http, data)
else:
- self.username = data["sub"]
+ self.username = data['sub']
log.debug("OAuth: got username %s", self.username)
successful = True
except Exception as e:
- log.error('OAuth: Unexpected error handling username fetch response: %r', e)
- error_msg = _('Unexpected authentication error')
+ log.error("OAuth: Unexpected error handling username fetch response: %r", e)
+ error_msg = _("Unexpected authentication error")
finally:
callback(successful=successful, error_msg=error_msg)
@@ -285,4 +285,4 @@ def _extract_error_description(self, http, data):
response = load_json(data)
return response['error_description']
except (JSONDecodeError, KeyError, TypeError):
- return _('Unexpected request error (HTTP code %s)') % self._http_code(http)
+ return _("Unexpected request error (HTTP code %s)") % self._http_code(http)
diff --git a/picard/plugin.py b/picard/plugin.py
index 634f2f81d8..d3cadeb1a5 100644
--- a/picard/plugin.py
+++ b/picard/plugin.py
@@ -102,7 +102,7 @@ def unregister_module(self, name):
def __iter__(self):
config = get_config()
- enabled_plugins = config.setting["enabled_plugins"] if config else []
+ enabled_plugins = config.setting['enabled_plugins'] if config else []
for name in self.__dict:
if name is None or name in enabled_plugins:
yield from self.__dict[name]
@@ -216,7 +216,7 @@ def __getattribute__(self, name):
try:
return super().__getattribute__(name)
except AttributeError:
- log.debug('Attribute %r not found for plugin %r', name, self.module_name)
+ log.debug("Attribute %r not found for plugin %r", name, self.module_name)
return None
@property
diff --git a/picard/pluginmanager.py b/picard/pluginmanager.py
index 0e2a3bfae8..0f912b643a 100644
--- a/picard/pluginmanager.py
+++ b/picard/pluginmanager.py
@@ -244,7 +244,7 @@ def handle_plugin_updates(self):
for source_path, target_path, plugin_name in self._marked_for_update():
self._remove_plugin(plugin_name)
os.rename(source_path, target_path)
- log.debug('Updating plugin %r (%r))', plugin_name, target_path)
+ log.debug("Updating plugin %r (%r))", plugin_name, target_path)
def load_plugins_from_directory(self, plugindir):
plugindir = os.path.normpath(plugindir)
diff --git a/picard/profile.py b/picard/profile.py
index 5056306d5c..bb3065ce77 100644
--- a/picard/profile.py
+++ b/picard/profile.py
@@ -42,216 +42,216 @@ class UserProfileGroups():
SETTINGS_GROUPS = OrderedDict() # Add groups in the order they should be displayed
# Each item in "settings" is a tuple of the setting key, the display title, and a list of the names of the widgets to highlight
- SETTINGS_GROUPS["general"] = {
- "title": N_("General"),
- "settings": [
- SettingDesc("server_host", N_("Server address"), ["server_host"]),
- SettingDesc("server_port", N_("Port"), ["server_port"]),
- SettingDesc("analyze_new_files", N_("Automatically scan all new files"), ["analyze_new_files"]),
- SettingDesc("cluster_new_files", N_("Automatically cluster all new files"), ["cluster_new_files"]),
- SettingDesc("ignore_file_mbids", N_("Ignore MBIDs when loading new files"), ["ignore_file_mbids"]),
- SettingDesc("check_for_plugin_updates", N_("Check for plugin updates during startup"), ["check_for_plugin_updates"]),
- SettingDesc("check_for_updates", N_("Check for program updates during startup"), ["check_for_updates"]),
- SettingDesc("update_check_days", N_("Days between update checks"), ["update_check_days"]),
- SettingDesc("update_level", N_("Updates to check"), ["update_level"]),
+ SETTINGS_GROUPS['general'] = {
+ 'title': N_("General"),
+ 'settings': [
+ SettingDesc('server_host', N_("Server address"), ['server_host']),
+ SettingDesc('server_port', N_("Port"), ['server_port']),
+ SettingDesc('analyze_new_files', N_("Automatically scan all new files"), ['analyze_new_files']),
+ SettingDesc('cluster_new_files', N_("Automatically cluster all new files"), ['cluster_new_files']),
+ SettingDesc('ignore_file_mbids', N_("Ignore MBIDs when loading new files"), ['ignore_file_mbids']),
+ SettingDesc('check_for_plugin_updates', N_("Check for plugin updates during startup"), ['check_for_plugin_updates']),
+ SettingDesc('check_for_updates', N_("Check for program updates during startup"), ['check_for_updates']),
+ SettingDesc('update_check_days', N_("Days between update checks"), ['update_check_days']),
+ SettingDesc('update_level', N_("Updates to check"), ['update_level']),
],
}
- SETTINGS_GROUPS["metadata"] = {
- "title": N_("Metadata"),
- "settings": [
+ SETTINGS_GROUPS['metadata'] = {
+ 'title': N_("Metadata"),
+ 'settings': [
# Main Metadata Page
- SettingDesc("translate_artist_names", N_("Translate artist names"), ["translate_artist_names"]),
- SettingDesc("artist_locales", N_("Translation locales"), ["selected_locales"]),
- SettingDesc("translate_artist_names_script_exception", N_("Translate artist names exception"), ["translate_artist_names_script_exception"]),
- SettingDesc("script_exceptions", N_("Translation script exceptions"), ["selected_scripts"]),
- SettingDesc("standardize_artists", N_("Use standardized artist names"), ["standardize_artists"]),
- SettingDesc("standardize_instruments", N_("Use standardized instrument and vocal credits"), ["standardize_instruments"]),
- SettingDesc("convert_punctuation", N_("Convert Unicode punctuation characters to ASCII"), ["convert_punctuation"]),
- SettingDesc("release_ars", N_("Use release relationships"), ["release_ars"]),
- SettingDesc("track_ars", N_("Use track relationships"), ["track_ars"]),
- SettingDesc("guess_tracknumber_and_title", N_("Guess track number and title from filename if empty"), ["guess_tracknumber_and_title"]),
- SettingDesc("va_name", N_("Various Artists name"), ["va_name"]),
- SettingDesc("nat_name", N_("Standalone recordings name"), ["nat_name"]),
+ SettingDesc('translate_artist_names', N_("Translate artist names"), ['translate_artist_names']),
+ SettingDesc('artist_locales', N_("Translation locales"), ['selected_locales']),
+ SettingDesc('translate_artist_names_script_exception', N_("Translate artist names exception"), ['translate_artist_names_script_exception']),
+ SettingDesc('script_exceptions', N_("Translation script exceptions"), ['selected_scripts']),
+ SettingDesc('standardize_artists', N_("Use standardized artist names"), ['standardize_artists']),
+ SettingDesc('standardize_instruments', N_("Use standardized instrument and vocal credits"), ['standardize_instruments']),
+ SettingDesc('convert_punctuation', N_("Convert Unicode punctuation characters to ASCII"), ['convert_punctuation']),
+ SettingDesc('release_ars', N_("Use release relationships"), ['release_ars']),
+ SettingDesc('track_ars', N_("Use track relationships"), ['track_ars']),
+ SettingDesc('guess_tracknumber_and_title', N_("Guess track number and title from filename if empty"), ['guess_tracknumber_and_title']),
+ SettingDesc('va_name', N_("Various Artists name"), ['va_name']),
+ SettingDesc('nat_name', N_("Standalone recordings name"), ['nat_name']),
# Preferred Releases Page
- SettingDesc("release_type_scores", N_("Preferred release types"), ["type_group"]),
- SettingDesc("preferred_release_countries", N_("Preferred release countries"), ["country_group"]),
- SettingDesc("preferred_release_formats", N_("Preferred medium formats"), ["format_group"]),
+ SettingDesc('release_type_scores', N_("Preferred release types"), ['type_group']),
+ SettingDesc('preferred_release_countries', N_("Preferred release countries"), ['country_group']),
+ SettingDesc('preferred_release_formats', N_("Preferred medium formats"), ['format_group']),
# Genres Page
- SettingDesc("use_genres", N_("Use genres from MusicBrainz"), []), # No highlight specified because the "use_genres"
+ SettingDesc('use_genres', N_("Use genres from MusicBrainz"), []), # No highlight specified because the 'use_genres'
# object is a QGroupBox and it highlights all sub
# options, even if the sub options are not selected.
- SettingDesc("only_my_genres", N_("Use only my genres"), ["only_my_genres"]),
- SettingDesc("artists_genres", N_("Use album artist genres"), ["artists_genres"]),
- SettingDesc("folksonomy_tags", N_("Use folksonomy tags as genre"), ["folksonomy_tags"]),
- SettingDesc("min_genre_usage", N_("Minimal genre usage"), ["min_genre_usage"]),
- SettingDesc("max_genres", N_("Maximum number of genres"), ["max_genres"]),
- SettingDesc("join_genres", N_("Join multiple genres with"), ["join_genres"]),
- SettingDesc("genres_filter", N_("Genres to include or exclude"), ["genres_filter"]),
+ SettingDesc('only_my_genres', N_("Use only my genres"), ['only_my_genres']),
+ SettingDesc('artists_genres', N_("Use album artist genres"), ['artists_genres']),
+ SettingDesc('folksonomy_tags', N_("Use folksonomy tags as genre"), ['folksonomy_tags']),
+ SettingDesc('min_genre_usage', N_("Minimal genre usage"), ['min_genre_usage']),
+ SettingDesc('max_genres', N_("Maximum number of genres"), ['max_genres']),
+ SettingDesc('join_genres', N_("Join multiple genres with"), ['join_genres']),
+ SettingDesc('genres_filter', N_("Genres to include or exclude"), ['genres_filter']),
# Ratings Page
- SettingDesc("enable_ratings", N_("Enable track ratings"), []), # No highlight specified because the "enable_ratings"
+ SettingDesc('enable_ratings', N_("Enable track ratings"), []), # No highlight specified because the 'enable_ratings'
# object is a QGroupBox and it highlights all sub options,
# even if the sub options are not selected.
- SettingDesc("rating_user_email", N_("Email to use when saving ratings"), ["rating_user_email"]),
- SettingDesc("submit_ratings", N_("Submit ratings to MusicBrainz"), ["submit_ratings"]),
+ SettingDesc('rating_user_email', N_("Email to use when saving ratings"), ['rating_user_email']),
+ SettingDesc('submit_ratings', N_("Submit ratings to MusicBrainz"), ['submit_ratings']),
],
}
- SETTINGS_GROUPS["tags"] = {
- "title": N_("Tags"),
- "settings": [
+ SETTINGS_GROUPS['tags'] = {
+ 'title': N_("Tags"),
+ 'settings': [
# Main Tags Page
- SettingDesc("dont_write_tags", N_("Don't write tags"), ["write_tags"]),
- SettingDesc("preserve_timestamps", N_("Preserve timestamps of tagged files"), ["preserve_timestamps"]),
- SettingDesc("clear_existing_tags", N_("Clear existing tags"), ["clear_existing_tags"]),
- SettingDesc("preserve_images", N_("Keep embedded images when clearing tags"), ["preserve_images"]),
- SettingDesc("remove_id3_from_flac", N_("Remove ID3 tags from FLAC files"), ["remove_id3_from_flac"]),
- SettingDesc("remove_ape_from_mp3", N_("Remove APEv2 tags from MP3 files"), ["remove_ape_from_mp3"]),
- SettingDesc("fix_missing_seekpoints_flac", N_("Fix missing seekpoints for FLAC files"), ["fix_missing_seekpoints_flac"]),
- SettingDesc("preserved_tags", N_("Preserved tags list"), ["preserved_tags"]),
+ SettingDesc('dont_write_tags', N_("Don't write tags"), ['write_tags']),
+ SettingDesc('preserve_timestamps', N_("Preserve timestamps of tagged files"), ['preserve_timestamps']),
+ SettingDesc('clear_existing_tags', N_("Clear existing tags"), ['clear_existing_tags']),
+ SettingDesc('preserve_images', N_("Keep embedded images when clearing tags"), ['preserve_images']),
+ SettingDesc('remove_id3_from_flac', N_("Remove ID3 tags from FLAC files"), ['remove_id3_from_flac']),
+ SettingDesc('remove_ape_from_mp3', N_("Remove APEv2 tags from MP3 files"), ['remove_ape_from_mp3']),
+ SettingDesc('fix_missing_seekpoints_flac', N_("Fix missing seekpoints for FLAC files"), ['fix_missing_seekpoints_flac']),
+ SettingDesc('preserved_tags', N_("Preserved tags list"), ['preserved_tags']),
# ID3 Tags Page
- SettingDesc("write_id3v23", N_("ID3v2 version to write"), ["write_id3v23", "write_id3v24"]),
- SettingDesc("id3v2_encoding", N_("ID3v2 text encoding"), ["enc_utf8", "enc_utf16", "enc_iso88591"]),
- SettingDesc("id3v23_join_with", N_("ID3v2.3 join character"), ["id3v23_join_with"]),
- SettingDesc("itunes_compatible_grouping", N_("Save iTunes compatible grouping and work"), ["itunes_compatible_grouping"]),
- SettingDesc("write_id3v1", N_("Write ID3v1 tags"), ["write_id3v1"]),
+ SettingDesc('write_id3v23', N_("ID3v2 version to write"), ['write_id3v23', 'write_id3v24']),
+ SettingDesc('id3v2_encoding', N_("ID3v2 text encoding"), ['enc_utf8', 'enc_utf16', 'enc_iso88591']),
+ SettingDesc('id3v23_join_with', N_("ID3v2.3 join character"), ['id3v23_join_with']),
+ SettingDesc('itunes_compatible_grouping', N_("Save iTunes compatible grouping and work"), ['itunes_compatible_grouping']),
+ SettingDesc('write_id3v1', N_("Write ID3v1 tags"), ['write_id3v1']),
# AAC Tags Page
- SettingDesc("aac_save_ape", N_("Save APEv2 tags to AAC"), ["aac_save_ape", "aac_no_tags"]),
- SettingDesc("remove_ape_from_aac", N_("Remove APEv2 tags from AAC files"), ["remove_ape_from_aac"]),
+ SettingDesc('aac_save_ape', N_("Save APEv2 tags to AAC"), ['aac_save_ape', 'aac_no_tags']),
+ SettingDesc('remove_ape_from_aac', N_("Remove APEv2 tags from AAC files"), ['remove_ape_from_aac']),
# AC3 Tags Page
- SettingDesc("ac3_save_ape", N_("Save APEv2 tags to AC3"), ["ac3_save_ape", "ac3_no_tags"]),
- SettingDesc("remove_ape_from_ac3", N_("Remove APEv2 tags from AC3 files"), ["remove_ape_from_ac3"]),
+ SettingDesc('ac3_save_ape', N_("Save APEv2 tags to AC3"), ['ac3_save_ape', 'ac3_no_tags']),
+ SettingDesc('remove_ape_from_ac3', N_("Remove APEv2 tags from AC3 files"), ['remove_ape_from_ac3']),
# WAVE Tags Page
- SettingDesc("write_wave_riff_info", N_("Write RIFF INFO tags to WAVE files"), ["write_wave_riff_info"]),
- SettingDesc("remove_wave_riff_info", N_("Remove existing RIFF INFO tags from WAVE files"), ["remove_wave_riff_info"]),
- SettingDesc("wave_riff_info_encoding", N_("RIFF INFO text encoding"), ["wave_riff_info_enc_cp1252", "wave_riff_info_enc_utf8"]),
+ SettingDesc('write_wave_riff_info', N_("Write RIFF INFO tags to WAVE files"), ['write_wave_riff_info']),
+ SettingDesc('remove_wave_riff_info', N_("Remove existing RIFF INFO tags from WAVE files"), ['remove_wave_riff_info']),
+ SettingDesc('wave_riff_info_encoding', N_("RIFF INFO text encoding"), ['wave_riff_info_enc_cp1252', 'wave_riff_info_enc_utf8']),
],
}
- SETTINGS_GROUPS["cover"] = {
- "title": N_("Cover Art"),
- "settings": [
- SettingDesc("save_images_to_tags", N_("Embed cover images into tags"), ["save_images_to_tags"]),
- SettingDesc("embed_only_one_front_image", N_("Embed only a single front image"), ["cb_embed_front_only"]),
- SettingDesc("save_images_to_files", N_("Save cover images as separate files"), ["save_images_to_files"]),
- SettingDesc("cover_image_filename", N_("File name for images"), ["cover_image_filename"]),
- SettingDesc("save_images_overwrite", N_("Overwrite existing image files"), ["save_images_overwrite"]),
- SettingDesc("save_only_one_front_image", N_("Save only a single front image as separate file"), ["save_only_one_front_image"]),
- SettingDesc("image_type_as_filename", N_("Always use the primary image type as the file name for non-front images"), ["image_type_as_filename"]),
- SettingDesc("ca_providers", N_("Cover art providers"), ["ca_providers_list"]),
+ SETTINGS_GROUPS['cover'] = {
+ 'title': N_("Cover Art"),
+ 'settings': [
+ SettingDesc('save_images_to_tags', N_("Embed cover images into tags"), ['save_images_to_tags']),
+ SettingDesc('embed_only_one_front_image', N_("Embed only a single front image"), ['cb_embed_front_only']),
+ SettingDesc('save_images_to_files', N_("Save cover images as separate files"), ['save_images_to_files']),
+ SettingDesc('cover_image_filename', N_("File name for images"), ['cover_image_filename']),
+ SettingDesc('save_images_overwrite', N_("Overwrite existing image files"), ['save_images_overwrite']),
+ SettingDesc('save_only_one_front_image', N_("Save only a single front image as separate file"), ['save_only_one_front_image']),
+ SettingDesc('image_type_as_filename', N_("Always use the primary image type as the file name for non-front images"), ['image_type_as_filename']),
+ SettingDesc('ca_providers', N_("Cover art providers"), ['ca_providers_list']),
],
}
- SETTINGS_GROUPS["filerenaming"] = {
- "title": N_("File Naming"),
- "settings": [
+ SETTINGS_GROUPS['filerenaming'] = {
+ 'title': N_("File Naming"),
+ 'settings': [
# Main File Naming Page
- SettingDesc("move_files", N_("Move files"), ["move_files"]),
- SettingDesc("move_files_to", N_("Destination directory"), ["move_files_to"]),
- SettingDesc("move_additional_files", N_("Move additional files"), ["move_additional_files"]),
- SettingDesc("move_additional_files_pattern", N_("Additional file patterns"), ["move_additional_files_pattern"]),
- SettingDesc("delete_empty_dirs", N_("Delete empty directories"), ["delete_empty_dirs"]),
- SettingDesc("rename_files", N_("Rename files"), ["rename_files"]),
- SettingDesc("selected_file_naming_script_id", N_("Selected file naming script"), ["naming_script_selector"]),
+ SettingDesc('move_files', N_("Move files"), ['move_files']),
+ SettingDesc('move_files_to', N_("Destination directory"), ['move_files_to']),
+ SettingDesc('move_additional_files', N_("Move additional files"), ['move_additional_files']),
+ SettingDesc('move_additional_files_pattern', N_("Additional file patterns"), ['move_additional_files_pattern']),
+ SettingDesc('delete_empty_dirs', N_("Delete empty directories"), ['delete_empty_dirs']),
+ SettingDesc('rename_files', N_("Rename files"), ['rename_files']),
+ SettingDesc('selected_file_naming_script_id', N_("Selected file naming script"), ['naming_script_selector']),
# File Naming Compatibility Page
- SettingDesc("ascii_filenames", N_("Replace non-ASCII characters"), ["ascii_filenames"]),
- SettingDesc("windows_compatibility", N_("Windows compatibility"), ["windows_compatibility"]),
- SettingDesc("win_compat_replacements", N_("Replacement characters used for Windows compatibility"), ["win_compat_replacements"]),
- SettingDesc("windows_long_paths", N_("Windows long path support"), ["windows_long_paths"]),
- SettingDesc("replace_spaces_with_underscores", N_("Replace spaces with underscores"), ["replace_spaces_with_underscores"]),
- SettingDesc("replace_dir_separator", N_("Replacement character to use for directory separators"), ["replace_dir_separator"]),
+ SettingDesc('ascii_filenames', N_("Replace non-ASCII characters"), ['ascii_filenames']),
+ SettingDesc('windows_compatibility', N_("Windows compatibility"), ['windows_compatibility']),
+ SettingDesc('win_compat_replacements', N_("Replacement characters used for Windows compatibility"), ['win_compat_replacements']),
+ SettingDesc('windows_long_paths', N_("Windows long path support"), ['windows_long_paths']),
+ SettingDesc('replace_spaces_with_underscores', N_("Replace spaces with underscores"), ['replace_spaces_with_underscores']),
+ SettingDesc('replace_dir_separator', N_("Replacement character to use for directory separators"), ['replace_dir_separator']),
],
}
- SETTINGS_GROUPS["scripting"] = {
- "title": N_("Scripting"),
- "settings": [
- SettingDesc("enable_tagger_scripts", N_("Enable tagger scripts"), ["enable_tagger_scripts"]),
- SettingDesc("list_of_scripts", N_("Tagger scripts"), ["script_list"]),
+ SETTINGS_GROUPS['scripting'] = {
+ 'title': N_("Scripting"),
+ 'settings': [
+ SettingDesc('enable_tagger_scripts', N_("Enable tagger scripts"), ['enable_tagger_scripts']),
+ SettingDesc('list_of_scripts', N_("Tagger scripts"), ['script_list']),
],
}
- SETTINGS_GROUPS["interface"] = {
- "title": N_("User Interface"),
- "settings": [
+ SETTINGS_GROUPS['interface'] = {
+ 'title': N_("User Interface"),
+ 'settings': [
# Main User Interface Page
- SettingDesc("toolbar_show_labels", N_("Show text labels under icons"), ["toolbar_show_labels"]),
- SettingDesc("show_menu_icons", N_("Show icons in menus"), ["show_menu_icons"]),
- SettingDesc("ui_language", N_("User interface language"), ["ui_language"]),
- SettingDesc("ui_theme", N_("User interface color theme"), ["ui_theme"]),
- SettingDesc("toolbar_multiselect", N_("Allow selection of multiple directories"), ["toolbar_multiselect"]),
- SettingDesc("builtin_search", N_("Use builtin search rather than looking in browser"), ["builtin_search"]),
- SettingDesc("use_adv_search_syntax", N_("Use advanced search syntax"), ["use_adv_search_syntax"]),
- SettingDesc("show_new_user_dialog", N_("Show a usage warning dialog when Picard starts"), ["new_user_dialog"]),
- SettingDesc("quit_confirmation", N_("Show a quit confirmation dialog for unsaved changes"), ["quit_confirmation"]),
- SettingDesc("file_save_warning", N_("Show a confirmation dialog when saving files"), ["file_save_warning"]),
- SettingDesc("filebrowser_horizontal_autoscroll", N_("Adjust horizontal position in file browser automatically"), ["filebrowser_horizontal_autoscroll"]),
- SettingDesc("starting_directory", N_("Begin browsing in a specific directory"), ["starting_directory"]),
- SettingDesc("starting_directory_path", N_("Directory to begin browsing"), ["starting_directory_path"]),
+ SettingDesc('toolbar_show_labels', N_("Show text labels under icons"), ['toolbar_show_labels']),
+ SettingDesc('show_menu_icons', N_("Show icons in menus"), ['show_menu_icons']),
+ SettingDesc('ui_language', N_("User interface language"), ['ui_language']),
+ SettingDesc('ui_theme', N_("User interface color theme"), ['ui_theme']),
+ SettingDesc('toolbar_multiselect', N_("Allow selection of multiple directories"), ['toolbar_multiselect']),
+ SettingDesc('builtin_search', N_("Use builtin search rather than looking in browser"), ['builtin_search']),
+ SettingDesc('use_adv_search_syntax', N_("Use advanced search syntax"), ['use_adv_search_syntax']),
+ SettingDesc('show_new_user_dialog', N_("Show a usage warning dialog when Picard starts"), ['new_user_dialog']),
+ SettingDesc('quit_confirmation', N_("Show a quit confirmation dialog for unsaved changes"), ['quit_confirmation']),
+ SettingDesc('file_save_warning', N_("Show a confirmation dialog when saving files"), ['file_save_warning']),
+ SettingDesc('filebrowser_horizontal_autoscroll', N_("Adjust horizontal position in file browser automatically"), ['filebrowser_horizontal_autoscroll']),
+ SettingDesc('starting_directory', N_("Begin browsing in a specific directory"), ['starting_directory']),
+ SettingDesc('starting_directory_path', N_("Directory to begin browsing"), ['starting_directory_path']),
# User Interface Colors Page
- SettingDesc("interface_colors", N_("Colors to use for light theme"), ["colors"]),
- SettingDesc("interface_colors_dark", N_("Colors to use for dark theme"), ["colors"]),
+ SettingDesc('interface_colors', N_("Colors to use for light theme"), ['colors']),
+ SettingDesc('interface_colors_dark', N_("Colors to use for dark theme"), ['colors']),
# User Interface Top Tags Page
- SettingDesc("metadatabox_top_tags", N_("Tags to show at the top"), ["top_tags_groupBox"]),
+ SettingDesc('metadatabox_top_tags', N_("Tags to show at the top"), ['top_tags_groupBox']),
# User Interface Action Toolbar Page
- SettingDesc("toolbar_layout", N_("Layout of the tool bar"), ["toolbar_layout_list"]),
+ SettingDesc('toolbar_layout', N_("Layout of the tool bar"), ['toolbar_layout_list']),
],
}
- SETTINGS_GROUPS["advanced"] = {
- "title": N_("Advanced"),
- "settings": [
+ SETTINGS_GROUPS['advanced'] = {
+ 'title': N_("Advanced"),
+ 'settings': [
# Main Advanced Options Page
- SettingDesc("ignore_regex", N_("Ignore file paths matching a regular expression"), ["ignore_regex"]),
- SettingDesc("ignore_hidden_files", N_("Ignore hidden files"), ["ignore_hidden_files"]),
- SettingDesc("recursively_add_files", N_("Include sub-folders when adding files from folder"), ["recursively_add_files"]),
+ SettingDesc('ignore_regex', N_("Ignore file paths matching a regular expression"), ['ignore_regex']),
+ SettingDesc('ignore_hidden_files', N_("Ignore hidden files"), ['ignore_hidden_files']),
+ SettingDesc('recursively_add_files', N_("Include sub-folders when adding files from folder"), ['recursively_add_files']),
SettingDesc(
- "ignore_track_duration_difference_under",
+ 'ignore_track_duration_difference_under',
N_("Ignore track duration difference under x seconds"),
- ["ignore_track_duration_difference_under", "label_track_duration_diff"]
+ ['ignore_track_duration_difference_under', 'label_track_duration_diff']
),
SettingDesc(
- "query_limit",
+ 'query_limit',
N_("Maximum number of entities to return per MusicBrainz query"),
- ["query_limit", "label_query_limit"]
+ ['query_limit', 'label_query_limit']
),
- SettingDesc("completeness_ignore_videos", N_("Completeness check ignore: Video tracks"), ["completeness_ignore_videos"]),
- SettingDesc("completeness_ignore_pregap", N_("Completeness check ignore: Pregap tracks"), ["completeness_ignore_pregap"]),
- SettingDesc("completeness_ignore_data", N_("Completeness check ignore: Data tracks"), ["completeness_ignore_data"]),
- SettingDesc("completeness_ignore_silence", N_("Completeness check ignore: Silent tracks"), ["completeness_ignore_silence"]),
- SettingDesc("compare_ignore_tags", N_("Tags to ignore for comparison"), ["groupBox_2"]),
+ SettingDesc('completeness_ignore_videos', N_("Completeness check ignore: Video tracks"), ['completeness_ignore_videos']),
+ SettingDesc('completeness_ignore_pregap', N_("Completeness check ignore: Pregap tracks"), ['completeness_ignore_pregap']),
+ SettingDesc('completeness_ignore_data', N_("Completeness check ignore: Data tracks"), ['completeness_ignore_data']),
+ SettingDesc('completeness_ignore_silence', N_("Completeness check ignore: Silent tracks"), ['completeness_ignore_silence']),
+ SettingDesc('compare_ignore_tags', N_("Tags to ignore for comparison"), ['groupBox_2']),
# Network Options Page
- SettingDesc("use_proxy", N_("Use a web proxy server"), []), # No highlight specified because the "use_proxy"
+ SettingDesc('use_proxy', N_("Use a web proxy server"), []), # No highlight specified because the 'use_proxy'
# object is a QGroupBox and it highlights all sub
# options, even if the sub options are not selected.
- SettingDesc("proxy_type", N_("type of proxy server"), ["proxy_type_socks", "proxy_type_http"]),
- SettingDesc("proxy_server_host", N_("Proxy server address"), ["server_host"]),
- SettingDesc("proxy_server_port", N_("Proxy server port"), ["server_port"]),
- SettingDesc("proxy_username", N_("Proxy username"), ["username"]),
- SettingDesc("proxy_password", N_("Proxy password"), ["password"]),
- SettingDesc("network_transfer_timeout_seconds", N_("Request timeout in seconds"), ["transfer_timeout"]),
- SettingDesc("browser_integration", N_("Browser integration"), []), # No highlight specified because the "browser_integration"
+ SettingDesc('proxy_type', N_("type of proxy server"), ['proxy_type_socks', 'proxy_type_http']),
+ SettingDesc('proxy_server_host', N_("Proxy server address"), ['server_host']),
+ SettingDesc('proxy_server_port', N_("Proxy server port"), ['server_port']),
+ SettingDesc('proxy_username', N_("Proxy username"), ['username']),
+ SettingDesc('proxy_password', N_("Proxy password"), ['password']),
+ SettingDesc('network_transfer_timeout_seconds', N_("Request timeout in seconds"), ['transfer_timeout']),
+ SettingDesc('browser_integration', N_("Browser integration"), []), # No highlight specified because the 'browser_integration'
# object is a QGroupBox and it highlights all sub options,
# even if the sub options are not selected.
- SettingDesc("browser_integration_port", N_("Default listening port"), ["browser_integration_port"]),
- SettingDesc("browser_integration_localhost_only", N_("Listen only on localhost"), ["browser_integration_localhost_only"]),
+ SettingDesc('browser_integration_port', N_("Default listening port"), ['browser_integration_port']),
+ SettingDesc('browser_integration_localhost_only', N_("Listen only on localhost"), ['browser_integration_localhost_only']),
# Matching Options Page
- SettingDesc("file_lookup_threshold", N_("Minimal similarity for file lookups"), ["file_lookup_threshold"]),
- SettingDesc("cluster_lookup_threshold", N_("Minimal similarity for cluster lookups"), ["cluster_lookup_threshold"]),
- SettingDesc("track_matching_threshold", N_("Minimal similarity for matching files to tracks"), ["track_matching_threshold"]),
+ SettingDesc('file_lookup_threshold', N_("Minimal similarity for file lookups"), ['file_lookup_threshold']),
+ SettingDesc('cluster_lookup_threshold', N_("Minimal similarity for cluster lookups"), ['cluster_lookup_threshold']),
+ SettingDesc('track_matching_threshold', N_("Minimal similarity for matching files to tracks"), ['track_matching_threshold']),
],
}
diff --git a/picard/releasegroup.py b/picard/releasegroup.py
index f8b2b6d60a..0fdcf986d0 100644
--- a/picard/releasegroup.py
+++ b/picard/releasegroup.py
@@ -56,7 +56,7 @@ def __init__(self, rg_id):
self.refcount = 0
def load_versions(self, callback):
- kwargs = {"release-group": self.id, "limit": 100}
+ kwargs = {'release-group': self.id, 'limit': 100}
self.tagger.mb_api.browse_releases(partial(self._request_finished, callback), **kwargs)
def _parse_versions(self, document):
@@ -64,17 +64,17 @@ def _parse_versions(self, document):
del self.versions[:]
data = []
- namekeys = ("tracks", "year", "country", "format", "label", "catnum")
+ namekeys = ('tracks', 'year', 'country', 'format', 'label', 'catnum')
headings = {
- "tracks": N_('Tracks'),
- "year": N_('Year'),
- "country": N_('Country'),
- "format": N_('Format'),
- "label": N_('Label'),
- "catnum": N_('Cat No'),
+ 'tracks': N_("Tracks"),
+ 'year': N_("Year"),
+ 'country': N_("Country"),
+ 'format': N_("Format"),
+ 'label': N_("Label"),
+ 'catnum': N_("Cat No"),
}
# additional keys displayed only for disambiguation
- extrakeys = ("packaging", "barcode", "disambiguation")
+ extrakeys = ('packaging', 'barcode', 'disambiguation')
try:
releases = document['releases']
@@ -97,23 +97,23 @@ def _parse_versions(self, document):
tracks = "+".join(str(m['track-count']) for m in node['media'])
formats = []
for medium in node['media']:
- if "format" in medium:
+ if 'format' in medium:
formats.append(medium['format'])
release = {
- "id": node['id'],
- "year": node['date'][:4] if "date" in node else "????",
- "country": country_label,
- "format": media_formats_from_node(node['media']),
- "label": ", ".join(' '.join(x.split(' ')[:2]) for x in set(labels)),
- "catnum": ", ".join(set(catnums)),
- "tracks": tracks,
- "barcode": node.get('barcode', '') or _('[no barcode]'),
- "packaging": node.get('packaging', '') or '??',
- "disambiguation": node.get('disambiguation', ''),
- "_disambiguate_name": list(),
- "totaltracks": sum(m['track-count'] for m in node['media']),
- "countries": countries,
- "formats": formats,
+ 'id': node['id'],
+ 'year': node['date'][:4] if 'date' in node else '????',
+ 'country': country_label,
+ 'format': media_formats_from_node(node['media']),
+ 'label': ', '.join(' '.join(x.split(' ')[:2]) for x in set(labels)),
+ 'catnum': ', '.join(set(catnums)),
+ 'tracks': tracks,
+ 'barcode': node.get('barcode', '') or _('[no barcode]'),
+ 'packaging': node.get('packaging', '') or '??',
+ 'disambiguation': node.get('disambiguation', ''),
+ '_disambiguate_name': list(),
+ 'totaltracks': sum(m['track-count'] for m in node['media']),
+ 'countries': countries,
+ 'formats': formats,
}
data.append(release)
@@ -122,7 +122,7 @@ def _parse_versions(self, document):
# Group versions by same display name
for release in data:
name = " / ".join(release[k] for k in namekeys)
- if name == release["tracks"]:
+ if name == release['tracks']:
name = "%s / %s" % (_('[no release info]'), name)
versions[name].append(release)
diff --git a/picard/script/__init__.py b/picard/script/__init__.py
index 5715ee261a..3d7294b5d3 100644
--- a/picard/script/__init__.py
+++ b/picard/script/__init__.py
@@ -104,9 +104,9 @@ def enabled_tagger_scripts_texts():
"""Returns an iterator over the enabled tagger scripts.
For each script, you'll get a tuple consisting of the script name and text"""
config = get_config()
- if not config.setting["enable_tagger_scripts"]:
+ if not config.setting['enable_tagger_scripts']:
return []
- return [(s_name, s_text) for _s_pos, s_name, s_enabled, s_text in config.setting["list_of_scripts"] if s_enabled and s_text]
+ return [(s_name, s_text) for _s_pos, s_name, s_enabled, s_text in config.setting['list_of_scripts'] if s_enabled and s_text]
def get_file_naming_script(settings):
@@ -119,14 +119,14 @@ def get_file_naming_script(settings):
str: The text of the file naming script if available, otherwise None
"""
from picard.script import get_file_naming_script_presets
- scripts = settings["file_renaming_scripts"]
- selected_id = settings["selected_file_naming_script_id"]
+ scripts = settings['file_renaming_scripts']
+ selected_id = settings['selected_file_naming_script_id']
if selected_id:
if scripts and selected_id in scripts:
- return scripts[selected_id]["script"]
+ return scripts[selected_id]['script']
for item in get_file_naming_script_presets():
- if item["id"] == selected_id:
- return str(item["script"])
+ if item['id'] == selected_id:
+ return str(item['script'])
log.error("Unable to retrieve the file naming script '%s'", selected_id)
return None
diff --git a/picard/script/functions.py b/picard/script/functions.py
index e687ab1dba..8652fcb488 100644
--- a/picard/script/functions.py
+++ b/picard/script/functions.py
@@ -64,7 +64,7 @@
markdown = None
-Bound = namedtuple("Bound", ["lower", "upper"])
+Bound = namedtuple('Bound', ['lower', 'upper'])
class FunctionRegistryItem:
@@ -227,7 +227,7 @@ def func_left(parser, text, length):
try:
return text[:int(length)]
except ValueError:
- return ""
+ return ''
@script_function(documentation=N_(
@@ -239,7 +239,7 @@ def func_right(parser, text, length):
try:
return text[-int(length):]
except ValueError:
- return ""
+ return ''
@script_function(documentation=N_(
@@ -270,7 +270,7 @@ def func_pad(parser, text, length, char):
try:
return char * (int(length) - len(text)) + text
except ValueError:
- return ""
+ return ''
@script_function(documentation=N_(
@@ -324,9 +324,9 @@ def func_replacemulti(parser, multi, search, replace, separator=MULTI_VALUED_JOI
))
def func_in(parser, text, needle):
if needle in text:
- return "1"
+ return '1'
else:
- return ""
+ return ''
@script_function(eval_args=False, documentation=N_(
@@ -368,13 +368,13 @@ def func_rsearch(parser, text, pattern):
try:
match = re.search(pattern, text)
except re.error:
- return ""
+ return ''
if match:
try:
return match.group(1)
except IndexError:
return match.group(0)
- return ""
+ return ''
@script_function(documentation=N_(
@@ -386,7 +386,7 @@ def func_num(parser, text, length):
try:
format_ = "%%0%dd" % max(0, min(int(length), 20))
except ValueError:
- return ""
+ return ''
try:
value = int(text)
except ValueError:
@@ -409,9 +409,9 @@ def func_unset(parser, name):
for key in list(parser.context.keys()):
if key.startswith(name):
parser.context.unset(key)
- return ""
+ return ''
parser.context.unset(name)
- return ""
+ return ''
@script_function(documentation=N_(
@@ -426,7 +426,7 @@ def func_unset(parser, name):
))
def func_delete(parser, name):
parser.context.delete(normalize_tagname(name))
- return ""
+ return ''
@script_function(documentation=N_(
@@ -444,7 +444,7 @@ def func_set(parser, name, value):
parser.context[normalize_tagname(name)] = value
else:
func_unset(parser, name)
- return ""
+ return ''
@script_function(documentation=N_(
@@ -488,7 +488,7 @@ def func_copy(parser, new, old):
new = normalize_tagname(new)
old = normalize_tagname(old)
parser.context[new] = parser.context.getall(old)[:]
- return ""
+ return ''
@script_function(documentation=N_(
@@ -508,7 +508,7 @@ def func_copymerge(parser, new, old, keep_duplicates=False):
newvals = parser.context.getall(new)
oldvals = parser.context.getall(old)
parser.context[new] = newvals + oldvals if keep_duplicates else uniqify(newvals + oldvals)
- return ""
+ return ''
@script_function(documentation=N_(
@@ -539,7 +539,7 @@ def func_add(parser, x, y, *args):
try:
return _compute_int(operator.add, x, y, *args)
except ValueError:
- return ""
+ return ''
@script_function(documentation=N_(
@@ -557,7 +557,7 @@ def func_sub(parser, x, y, *args):
try:
return _compute_int(operator.sub, x, y, *args)
except ValueError:
- return ""
+ return ''
@script_function(documentation=N_(
@@ -575,9 +575,9 @@ def func_div(parser, x, y, *args):
try:
return _compute_int(operator.floordiv, x, y, *args)
except ValueError:
- return ""
+ return ''
except ZeroDivisionError:
- return ""
+ return ''
@script_function(documentation=N_(
@@ -595,7 +595,7 @@ def func_mod(parser, x, y, *args):
try:
return _compute_int(operator.mod, x, y, *args)
except (ValueError, ZeroDivisionError):
- return ""
+ return ''
@script_function(documentation=N_(
@@ -613,7 +613,7 @@ def func_mul(parser, x, y, *args):
try:
return _compute_int(operator.mul, x, y, *args)
except ValueError:
- return ""
+ return ''
@script_function(documentation=N_(
@@ -625,9 +625,9 @@ def func_mul(parser, x, y, *args):
))
def func_or(parser, x, y, *args):
if _compute_logic(any, x, y, *args):
- return "1"
+ return '1'
else:
- return ""
+ return ''
@script_function(documentation=N_(
@@ -639,9 +639,9 @@ def func_or(parser, x, y, *args):
))
def func_and(parser, x, y, *args):
if _compute_logic(all, x, y, *args):
- return "1"
+ return '1'
else:
- return ""
+ return ''
@script_function(documentation=N_(
@@ -651,9 +651,9 @@ def func_and(parser, x, y, *args):
))
def func_not(parser, x):
if not x:
- return "1"
+ return '1'
else:
- return ""
+ return ''
@script_function(documentation=N_(
@@ -663,9 +663,9 @@ def func_not(parser, x):
))
def func_eq(parser, x, y):
if x == y:
- return "1"
+ return '1'
else:
- return ""
+ return ''
@script_function(documentation=N_(
@@ -675,9 +675,9 @@ def func_eq(parser, x, y):
))
def func_ne(parser, x, y):
if x != y:
- return "1"
+ return '1'
else:
- return ""
+ return ''
def _cmp(op, x, y, _type):
@@ -697,9 +697,9 @@ def _cmp(op, x, y, _type):
except ValueError:
pass
if _type == 'text':
- return "1" if op(x, y) else ""
+ return '1' if op(x, y) else ""
elif _type == 'nocase':
- return "1" if op(x.lower(), y.lower()) else ""
+ return '1' if op(x.lower(), y.lower()) else ""
elif _type == 'float':
_typer = float
elif _type == 'int':
@@ -707,10 +707,10 @@ def _cmp(op, x, y, _type):
if _typer is not None:
try:
if op(_typer(x), _typer(y)):
- return "1"
+ return '1'
except ValueError:
pass
- return ""
+ return ''
@script_function(documentation=N_(
@@ -836,7 +836,7 @@ def func_matchedtracks(parser, *args):
file = parser.file
if file and file.parent and hasattr(file.parent, 'album') and file.parent.album:
return str(parser.file.parent.album.get_num_matched_tracks())
- return "0"
+ return '0'
@script_function(documentation=N_(
@@ -850,8 +850,8 @@ def func_is_complete(parser):
file = parser.file
if (file and file.parent and hasattr(file.parent, 'album') and file.parent.album
and file.parent.album.is_complete()):
- return "1"
- return ""
+ return '1'
+ return ''
@script_function(documentation=N_(
@@ -881,7 +881,7 @@ def func_firstalphachar(parser, text="", nonalpha="#"):
_Since Picard 0.12_"""
))
def func_initials(parser, text=""):
- return "".join(a[:1] for a in text.split(" ") if a[:1].isalpha())
+ return ''.join(a[:1] for a in text.split(" ") if a[:1].isalpha())
@script_function(documentation=N_(
@@ -916,8 +916,8 @@ def func_firstwords(parser, text, length):
))
def func_startswith(parser, text, prefix):
if text.startswith(prefix):
- return "1"
- return ""
+ return '1'
+ return ''
@script_function(documentation=N_(
@@ -929,8 +929,8 @@ def func_startswith(parser, text, prefix):
))
def func_endswith(parser, text, suffix):
if text.endswith(suffix):
- return "1"
- return ""
+ return '1'
+ return ''
@script_function(documentation=N_(
@@ -1102,7 +1102,7 @@ def iswbound(char):
# from https://github.com/metabrainz/picard-plugins/blob/2.0/plugins/titlecase/titlecase.py
""" Checks whether the given character is a word boundary """
category = unicodedata.category(char)
- return "Zs" == category or "Sk" == category or "P" == category[0]
+ return 'Zs' == category or 'Sk' == category or 'P' == category[0]
@script_function(documentation=N_(
@@ -1114,9 +1114,9 @@ def iswbound(char):
))
def func_is_audio(parser):
if func_is_video(parser) == "1":
- return ""
+ return ''
else:
- return "1"
+ return '1'
@script_function(documentation=N_(
@@ -1128,9 +1128,9 @@ def func_is_audio(parser):
))
def func_is_video(parser):
if parser.context['~video'] and parser.context['~video'] != '0':
- return "1"
+ return '1'
else:
- return ""
+ return ''
@script_function(documentation=N_(
@@ -1553,7 +1553,7 @@ def func_cleanmulti(parser, multi):
name = normalize_tagname(multi)
values = [str(value) for value in parser.context.getall(name) if value or value == 0]
parser.context[name] = values
- return ""
+ return ''
def _type_args(_type, *args):
@@ -1592,7 +1592,7 @@ def _extract(_func, _type, *args):
try:
haystack = _type_args(_type, *args)
except ValueError:
- return ""
+ return ''
if _type == 'nocase':
op = operator.lt if _func == min else operator.gt
diff --git a/picard/script/parser.py b/picard/script/parser.py
index 73a74bd2c6..8393248ac4 100644
--- a/picard/script/parser.py
+++ b/picard/script/parser.py
@@ -104,12 +104,12 @@ def __init__(self, line, column, name=None):
def __str__(self):
if self.name is None:
- return '{line:d}:{column:d}'.format(
+ return "{line:d}:{column:d}".format(
line=self.line,
column=self.column
)
else:
- return '{line:d}:{column:d}:{name}'.format(
+ return "{line:d}:{column:d}:{name}".format(
line=self.line,
column=self.column,
name=self.name
@@ -124,7 +124,7 @@ def eval(self, state):
def normalize_tagname(name):
if name.startswith('_'):
- return "~" + name[1:]
+ return '~' + name[1:]
return name
@@ -134,7 +134,7 @@ def __init__(self, name):
self.name = name
def __repr__(self):
- return '' % self.name
+ return "" % self.name
def eval(self, state):
return state.context.get(normalize_tagname(self.name), "")
@@ -427,7 +427,7 @@ def insert(self, index, value):
return self._multi.insert(index, value)
def __repr__(self):
- return '%s(%r, %r, %r)' % (self.__class__.__name__, self.parser, self._multi, self.separator)
+ return "%s(%r, %r, %r)" % (self.__class__.__name__, self.parser, self._multi, self.separator)
def __str__(self):
return self.separator.join(x for x in self if x)
diff --git a/picard/script/serializer.py b/picard/script/serializer.py
index 7b73b94561..e073aabc94 100644
--- a/picard/script/serializer.py
+++ b/picard/script/serializer.py
@@ -72,7 +72,7 @@ class MultilineLiteral(str):
def yaml_presenter(dumper, data):
if data:
data = data.rstrip() + '\n'
- return dumper.represent_scalar("tag:yaml.org,2002:str", data, style="|")
+ return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='|')
yaml.add_representer(MultilineLiteral, MultilineLiteral.yaml_presenter)
@@ -191,8 +191,8 @@ def to_dict(self):
dict: Dictionary of the object's OUTPUT_FIELDS
"""
items = {key: getattr(self, key) for key in self.OUTPUT_FIELDS}
- items["description"] = str(items["description"])
- items["script"] = str(items["script"])
+ items['description'] = str(items['description'])
+ items['script'] = str(items['script'])
return items
def export_script(self, parent=None):
@@ -216,13 +216,13 @@ def export_script(self, parent=None):
(name, ext) = os.path.splitext(filename)
if ext and str(name).endswith('.' + ext):
filename = name
- log.debug('Exporting script file: %s', filename)
+ log.debug("Exporting script file: %s", filename)
if file_type == self._file_types()['package']:
script_text = self.to_yaml()
else:
script_text = self.script + "\n"
try:
- with open(filename, 'w', encoding='utf8') as o_file:
+ with open(filename, 'w', encoding='utf-8') as o_file:
o_file.write(script_text)
except OSError as error:
raise ScriptImportExportError(format=FILE_ERROR_EXPORT, filename=filename, error_msg=error.strerror)
@@ -250,14 +250,14 @@ def import_script(cls, parent=None):
filename, file_type = QtWidgets.QFileDialog.getOpenFileName(parent, dialog_title, default_script_directory, dialog_file_types, options=options)
if not filename:
return None
- log.debug('Importing script file: %s', filename)
+ log.debug("Importing script file: %s", filename)
try:
- with open(filename, 'r', encoding='utf8') as i_file:
+ with open(filename, 'r', encoding='utf-8') as i_file:
file_content = i_file.read()
except OSError as error:
raise ScriptImportExportError(format=FILE_ERROR_IMPORT, filename=filename, error_msg=error.strerror)
if not file_content.strip():
- raise ScriptImportExportError(format=FILE_ERROR_IMPORT, filename=filename, error_msg=N_('The file was empty'))
+ raise ScriptImportExportError(format=FILE_ERROR_IMPORT, filename=filename, error_msg=N_("The file was empty"))
if file_type == cls._file_types()['package']:
try:
return cls().create_from_yaml(file_content)
@@ -285,7 +285,7 @@ def create_from_dict(cls, script_dict, create_new_id=True):
if not isinstance(script_dict, Mapping):
raise ScriptImportError(N_("Argument is not a dictionary"))
if 'title' not in script_dict or 'script' not in script_dict:
- raise ScriptImportError(N_('Invalid script package'))
+ raise ScriptImportError(N_("Invalid script package"))
new_object.update_from_dict(script_dict)
if create_new_id or not new_object['id']:
new_object._set_new_id()
@@ -329,7 +329,7 @@ def create_from_yaml(cls, yaml_string, create_new_id=True):
if not isinstance(yaml_dict, dict):
raise ScriptImportError(N_("File content not a dictionary"))
if 'title' not in yaml_dict or 'script' not in yaml_dict:
- raise ScriptImportError(N_('Invalid script package'))
+ raise ScriptImportError(N_("Invalid script package"))
new_object.update_from_dict(yaml_dict)
if create_new_id or not new_object['id']:
new_object._set_new_id()
diff --git a/picard/tagger.py b/picard/tagger.py
index 6b95327a0e..ff4c852e93 100644
--- a/picard/tagger.py
+++ b/picard/tagger.py
@@ -189,12 +189,12 @@ def __init__(self, items):
log.debug(f"Parsed: {repr(parsed)}")
if not parsed.scheme:
self.files.add(item)
- if parsed.scheme == "file":
+ if parsed.scheme == 'file':
# remove file:// prefix safely
self.files.add(item[7:])
- elif parsed.scheme == "mbid":
+ elif parsed.scheme == 'mbid':
self.mbids.add(parsed.netloc + parsed.path)
- elif parsed.scheme in {"http", "https"}:
+ elif parsed.scheme in {'http', 'https'}:
# .path returns / before actual link
self.urls.add(parsed.path[1:])
elif IS_WIN and self.WINDOWS_DRIVE_TEST.match(item):
@@ -254,7 +254,7 @@ def __init__(self, picard_args, localedir, autoupdate, pipe_handler=None):
self.set_log_level(config.setting['log_verbosity'])
- if picard_args.debug or "PICARD_DEBUG" in os.environ:
+ if picard_args.debug or 'PICARD_DEBUG' in os.environ:
self.set_log_level(logging.DEBUG)
if picard_args.audit:
@@ -330,7 +330,7 @@ def __init__(self, picard_args, localedir, autoupdate, pipe_handler=None):
# Must be before config upgrade because upgrade dialogs need to be
# translated
- setup_gettext(localedir, config.setting["ui_language"], log.debug)
+ setup_gettext(localedir, config.setting['ui_language'], log.debug)
upgrade_config(config)
@@ -390,9 +390,9 @@ def pipe_server(self):
def _pipe_server_finished(self, result=None, error=None):
if error:
- log.error('pipe server failed: %r', error)
+ log.error("pipe server failed: %r", error)
else:
- log.debug('pipe server stopped')
+ log.debug("pipe server stopped")
def start_process_commands(self):
if not self._command_thread_running:
@@ -455,9 +455,9 @@ def run_commands(self):
def _run_commands_finished(self, result=None, error=None):
if error:
- log.error('command executor failed: %r', error)
+ log.error("command executor failed: %r", error)
else:
- log.debug('command executor stopped')
+ log.debug("command executor stopped")
def load_to_picard(self, items):
commands = []
@@ -615,7 +615,7 @@ def handle_command_submit_fingerprints(self, argstring):
def handle_command_write_logs(self, argstring):
try:
- with open(argstring, 'w', encoding='utf8') as f:
+ with open(argstring, 'w', encoding='utf-8') as f:
for x in self.window.log_dialog.log_tail.contents():
f.write(f"{x.message}\n")
except Exception as e:
@@ -649,7 +649,7 @@ def _mb_login_dialog(self, parent):
return None
def mb_login(self, callback, parent=None):
- scopes = "profile tag rating collection submit_isrc submit_barcode"
+ scopes = 'profile tag rating collection submit_isrc submit_barcode'
authorization_url = self.webservice.oauth_manager.get_authorization_url(scopes)
webbrowser2.open(authorization_url)
authorization_code = self._mb_login_dialog(parent)
@@ -696,7 +696,7 @@ def move_file_to_track(self, file, albumid, recordingid):
def create_nats(self):
if self.nats is None:
self.nats = NatAlbum()
- self.albums["NATS"] = self.nats
+ self.albums['NATS'] = self.nats
self.album_added.emit(self.nats)
self.nats.item.setExpanded(True)
return self.nats
@@ -750,7 +750,7 @@ def run(self):
def update_browser_integration(self):
config = get_config()
- if config.setting["browser_integration"]:
+ if config.setting['browser_integration']:
self.browser_integration.start()
else:
self.browser_integration.stop()
@@ -787,7 +787,7 @@ def _file_loaded(self, file, target=None, remove_file=False, unmatched_files=Non
return
file_moved = False
- if not config.setting["ignore_file_mbids"]:
+ if not config.setting['ignore_file_mbids']:
recordingid = file.metadata.getall('musicbrainz_recordingid')
recordingid = recordingid[0] if recordingid else ''
is_valid_recordingid = mbid_validate(recordingid)
@@ -826,7 +826,7 @@ def _file_loaded(self, file, target=None, remove_file=False, unmatched_files=Non
self.analyze([file])
# Auto cluster newly added files if they are not explicitly moved elsewhere
- if self._pending_files_count == 0 and unmatched_files and config.setting["cluster_new_files"]:
+ if self._pending_files_count == 0 and unmatched_files and config.setting['cluster_new_files']:
self.cluster(unmatched_files)
def move_file(self, file, target):
@@ -948,8 +948,8 @@ def add_paths(self, paths, target=None):
def get_file_lookup(self):
"""Return a FileLookup object."""
config = get_config()
- return FileLookup(self, config.setting["server_host"],
- config.setting["server_port"],
+ return FileLookup(self, config.setting['server_host'],
+ config.setting['server_port'],
self.browser_integration.port)
def search(self, text, search_type, adv=False, mbid_matched_callback=None, force_browser=False):
@@ -988,7 +988,7 @@ def collection_lookup(self):
"""Lookup the users collections on the MusicBrainz website."""
lookup = self.get_file_lookup()
config = get_config()
- lookup.collection_lookup(config.persist["oauth_username"])
+ lookup.collection_lookup(config.persist['oauth_username'])
def browser_lookup(self, item):
"""Lookup the object's metadata on the MusicBrainz website."""
@@ -1003,10 +1003,10 @@ def browser_lookup(self, item):
lookup.album_lookup(itemid)
else:
lookup.tag_lookup(
- metadata["albumartist"] if item.is_album_like() else metadata["artist"],
- metadata["album"],
- metadata["title"],
- metadata["tracknumber"],
+ metadata['albumartist'] if item.is_album_like() else metadata['artist'],
+ metadata['album'],
+ metadata['title'],
+ metadata['tracknumber'],
'' if item.is_album_like() else str(metadata.length),
item.filename if isinstance(item, File) else '')
@@ -1029,7 +1029,7 @@ def load_mbid(self, type, mbid):
elif type == 'nat':
self.load_nat(mbid)
else:
- log.warning('Unknown type to load: %s', type)
+ log.warning("Unknown type to load: %s", type)
def load_album(self, album_id, discid=None):
album_id = self.mbid_redirects.get(album_id, album_id)
@@ -1162,8 +1162,8 @@ def lookup_cd(self, action):
return self.lookup_discid_from_logfile()
else:
device = data
- elif config.setting["cd_lookup_device"] != '':
- device = config.setting["cd_lookup_device"].split(",", 1)[0]
+ elif config.setting['cd_lookup_device'] != '':
+ device = config.setting['cd_lookup_device'].split(',', 1)[0]
else:
# rely on python-discid auto detection
device = None
@@ -1215,7 +1215,7 @@ def _parse_disc_ripping_log(self, disc, path):
@property
def use_acoustid(self):
config = get_config()
- return config.setting["fingerprinting_system"] == "acoustid"
+ return config.setting['fingerprinting_system'] == 'acoustid'
def analyze(self, objs):
"""Analyze the file(s)."""
@@ -1266,7 +1266,7 @@ def _do_clustering(self, files):
def _clustering_finished(self, callback, result=None, error=None):
if error:
- log.error('Error while clustering: %r', error)
+ log.error("Error while clustering: %r", error)
return
self.window.set_sorting(False)
@@ -1285,7 +1285,7 @@ def _clustering_finished(self, callback, result=None, error=None):
def load_cluster(self, name, artist):
for cluster in self.clusters:
cm = cluster.metadata
- if name == cm["album"] and artist == cm["albumartist"]:
+ if name == cm['album'] and artist == cm['albumartist']:
return cluster
cluster = Cluster(name, artist)
self.clusters.append(cluster)
@@ -1401,7 +1401,7 @@ def print_help_for_commands():
maxwidth = 80
informative_text = []
- message = """usage: picard -e [command] [arguments ...]
+ message = """Usage: picard -e [command] [arguments ...]
or picard -e [command 1] [arguments ...] -e [command 2] [arguments ...]
List of the commands available to execute in Picard from the command-line:
@@ -1435,38 +1435,38 @@ def process_picard_args():
)
# Qt default arguments. Parse them so Picard does not interpret the
# arguments as file names to load.
- parser.add_argument("-style", nargs=1, help=argparse.SUPPRESS)
- parser.add_argument("-stylesheet", nargs=1, help=argparse.SUPPRESS)
+ parser.add_argument('-style', nargs=1, help=argparse.SUPPRESS)
+ parser.add_argument('-stylesheet', nargs=1, help=argparse.SUPPRESS)
# Same for default X arguments
- parser.add_argument("-display", nargs=1, help=argparse.SUPPRESS)
+ parser.add_argument('-display', nargs=1, help=argparse.SUPPRESS)
# Picard specific arguments
- parser.add_argument("-a", "--audit", action='store',
+ parser.add_argument('-a', '--audit', action='store',
default=None,
help="audit events passed as a comma-separated list, prefixes supported, "
"use all to match any (see https://docs.python.org/3/library/audit_events.html#audit-events)")
- parser.add_argument("-c", "--config-file", action='store',
+ parser.add_argument('-c', '--config-file', action='store',
default=None,
help="location of the configuration file")
- parser.add_argument("-d", "--debug", action='store_true',
+ parser.add_argument('-d', '--debug', action='store_true',
help="enable debug-level logging")
- parser.add_argument("-e", "--exec", nargs="+", action='append',
+ parser.add_argument('-e', '--exec', nargs='+', action='append',
help="send command (arguments can be entered after space) to a running instance "
"(use `-e help` for a list of the available commands)",
- metavar="COMMAND")
- parser.add_argument("-M", "--no-player", action='store_true',
+ metavar='COMMAND')
+ parser.add_argument('-M', '--no-player', action='store_true',
help="disable built-in media player")
- parser.add_argument("-N", "--no-restore", action='store_true',
+ parser.add_argument('-N', '--no-restore', action='store_true',
help="do not restore positions and/or sizes")
- parser.add_argument("-P", "--no-plugins", action='store_true',
+ parser.add_argument('-P', '--no-plugins', action='store_true',
help="do not load any plugins")
- parser.add_argument("--no-crash-dialog", action='store_true',
+ parser.add_argument('--no-crash-dialog', action='store_true',
help="disable the crash dialog")
- parser.add_argument("-s", "--stand-alone-instance", action='store_true',
+ parser.add_argument('-s', '--stand-alone-instance', action='store_true',
help="force Picard to create a new, stand-alone instance")
parser.add_argument('-v', '--version', action='store_true',
help="display version information and exit")
- parser.add_argument("-V", "--long-version", action='store_true',
+ parser.add_argument('-V', '--long-version', action='store_true',
help="display long version information and exit")
parser.add_argument('FILE_OR_URL', nargs='*',
help="the file(s), URL(s) and MBID(s) to load")
@@ -1488,7 +1488,7 @@ def process_picard_args():
if args.exec:
for e in args.exec:
- args.remote_commands_help = args.remote_commands_help or "HELP" in {x.upper().strip() for x in e}
+ args.remote_commands_help = args.remote_commands_help or 'HELP' in {x.upper().strip() for x in e}
remote_command_args = e[1:] or ['']
for arg in remote_command_args:
args.processable.append(f"{e[0]} {arg}")
@@ -1533,7 +1533,7 @@ def main(localedir=None, autoupdate=True):
identifier = uuid4().hex
else:
if picard_args.config_file:
- identifier = blake2b(picard_args.config_file.encode('utf8'), digest_size=16).hexdigest()
+ identifier = blake2b(picard_args.config_file.encode('utf-8'), digest_size=16).hexdigest()
else:
identifier = 'main'
if picard_args.no_plugins:
@@ -1571,10 +1571,10 @@ def main(localedir=None, autoupdate=True):
locale = QtCore.QLocale()
translation_path = QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.LibraryLocation.TranslationsPath)
log.debug("Looking for Qt locale %s in %s", locale.name(), translation_path)
- if translator.load(locale, "qtbase_", directory=translation_path):
+ if translator.load(locale, 'qtbase_', directory=translation_path):
tagger.installTranslator(translator)
else:
- log.debug('Qt locale %s not available', locale.name())
+ log.debug("Qt locale %s not available", locale.name())
tagger.startTimer(1000)
exit_code = tagger.run()
diff --git a/picard/track.py b/picard/track.py
index fbdbe06fbe..e60736f574 100644
--- a/picard/track.py
+++ b/picard/track.py
@@ -176,7 +176,7 @@ def update_file_metadata(self, file):
# Run the scripts for the file to allow usage of
# file specific metadata and variables
config = get_config()
- if config.setting["clear_existing_tags"]:
+ if config.setting['clear_existing_tags']:
metadata = Metadata(self.orig_metadata)
metadata_proxy = MultiMetadataProxy(metadata, file.metadata)
self.run_scripts(metadata_proxy)
@@ -394,22 +394,22 @@ def load(self, priority=False, refresh=False):
config = get_config()
require_authentication = False
inc = {
- "aliases",
- "artist-credits",
- "artists",
+ 'aliases',
+ 'artist-credits',
+ 'artists',
}
- if config.setting["track_ars"]:
+ if config.setting['track_ars']:
inc |= {
- "artist-rels",
- "recording-rels",
- "url-rels",
- "work-level-rels",
- "work-rels",
+ 'artist-rels',
+ 'recording-rels',
+ 'url-rels',
+ 'work-level-rels',
+ 'work-rels',
}
require_authentication = self.set_genre_inc_params(inc, config) or require_authentication
- if config.setting["enable_ratings"]:
+ if config.setting['enable_ratings']:
require_authentication = True
- inc |= {"user-ratings"}
+ inc |= {'user-ratings'}
self.tagger.mb_api.get_track_by_id(
self.id,
self._recording_request_finished,
diff --git a/picard/ui/__init__.py b/picard/ui/__init__.py
index deec2391ce..20bff96f26 100644
--- a/picard/ui/__init__.py
+++ b/picard/ui/__init__.py
@@ -65,8 +65,8 @@ class PreserveGeometry:
defaultsize = None
def __init__(self):
- Option.add_if_missing("persist", self.opt_name(), QtCore.QByteArray())
- Option.add_if_missing("persist", self.splitters_name(), {})
+ Option.add_if_missing('persist', self.opt_name(), QtCore.QByteArray())
+ Option.add_if_missing('persist', self.splitters_name(), {})
if getattr(self, 'finished', None):
self.finished.connect(self.save_geometry)
diff --git a/picard/ui/aboutdialog.py b/picard/ui/aboutdialog.py
index 79d93d11c8..6f7074666c 100644
--- a/picard/ui/aboutdialog.py
+++ b/picard/ui/aboutdialog.py
@@ -71,12 +71,12 @@ def _update_content(self):
])
# TR: Replace this with your name to have it appear in the "About" dialog.
- args["translator_credits"] = _("translator-credits")
- if args["translator_credits"] != "translator-credits":
+ args['translator_credits'] = _('translator-credits')
+ if args['translator_credits'] != 'translator-credits':
# TR: Replace LANG with language you are translating to.
- args["translator_credits"] = _("
Translated to LANG by %s") % args["translator_credits"].replace("\n", "
")
+ args['translator_credits'] = _("
Translated to LANG by %s") % args['translator_credits'].replace("\n", "
")
else:
- args["translator_credits"] = ""
+ args['translator_credits'] = ""
args['icons_credits'] = _(
'Icons made by Sambhav Kothari '
'and Madebyoliver, '
diff --git a/picard/ui/cdlookup.py b/picard/ui/cdlookup.py
index 503a1bd77a..89345bd9d1 100644
--- a/picard/ui/cdlookup.py
+++ b/picard/ui/cdlookup.py
@@ -53,10 +53,10 @@
class CDLookupDialog(PicardDialog):
- dialog_header_state = "cdlookupdialog_header_state"
+ dialog_header_state = 'cdlookupdialog_header_state'
options = [
- Option("persist", dialog_header_state, QtCore.QByteArray())
+ Option('persist', dialog_header_state, QtCore.QByteArray())
]
def __init__(self, releases, disc, parent=None):
@@ -126,7 +126,7 @@ def lookup(self):
lookup = self.tagger.get_file_lookup()
lookup.discid_submission(submission_url)
else:
- log.error('No submission URL for disc ID "%s"', self.disc.id)
+ log.error("No submission URL for disc ID %s", self.disc.id)
super().accept()
@restore_method
diff --git a/picard/ui/coverartbox.py b/picard/ui/coverartbox.py
index 968b1a3acc..07d88eae30 100644
--- a/picard/ui/coverartbox.py
+++ b/picard/ui/coverartbox.py
@@ -96,7 +96,7 @@ def __init__(self, active=False, drops=False, pixmap_cache=None, *args, **kwargs
def screen_changed(self, screen):
pixel_ratio = screen.devicePixelRatio()
- log.debug('screen changed, pixel ratio %s', pixel_ratio)
+ log.debug("screen changed, pixel ratio %s", pixel_ratio)
if pixel_ratio != self.pixel_ratio:
self.pixel_ratio = pixel_ratio
self._update_default_pixmaps()
@@ -107,8 +107,8 @@ def screen_changed(self, screen):
def _update_default_pixmaps(self):
w, h = self.scaled(THUMBNAIL_WIDTH, THUMBNAIL_WIDTH)
- self.shadow = self._load_cached_default_pixmap(':/images/CoverArtShadow.png', w, h)
- self.file_missing_pixmap = self._load_cached_default_pixmap(':/images/image-missing.png', w, h)
+ self.shadow = self._load_cached_default_pixmap(":/images/CoverArtShadow.png", w, h)
+ self.file_missing_pixmap = self._load_cached_default_pixmap(":/images/image-missing.png", w, h)
def _load_cached_default_pixmap(self, pixmap_path, w, h):
key = hash((pixmap_path, self.pixel_ratio))
@@ -291,7 +291,7 @@ def calculate_cover_coordinates(pixmap, cx, cy):
if not has_common_images:
# Draw a golden highlight around the first cover to indicate that
# images are not common to all selected items
- color = QtGui.QColor("darkgoldenrod")
+ color = QtGui.QColor('darkgoldenrod')
border_length = 10
for k in range(border_length):
color.setAlpha(255 - k * 255 // border_length)
@@ -322,7 +322,7 @@ def set_metadata(self, metadata):
self.set_data(data, has_common_images=has_common_images)
release = None
if metadata:
- release = metadata.get("musicbrainz_albumid", None)
+ release = metadata.get('musicbrainz_albumid', None)
if release:
self.setActive(True)
text = _("View release on MusicBrainz")
@@ -550,7 +550,7 @@ def _try_load_remote_image(self, url, data):
)
config = get_config()
- if config.setting["load_image_behavior"] == 'replace':
+ if config.setting['load_image_behavior'] == 'replace':
set_image = set_image_replace
debug_info = "Replacing with dropped %r in %r"
else:
@@ -616,7 +616,7 @@ def choose_local_file(self):
def set_load_image_behavior(self, behavior):
config = get_config()
- config.setting["load_image_behavior"] = behavior
+ config.setting['load_image_behavior'] = behavior
def keep_original_images(self):
self.item.keep_original_images()
@@ -626,19 +626,19 @@ def keep_original_images(self):
def contextMenuEvent(self, event):
menu = QtWidgets.QMenu(self)
if self.show_details_button.isVisible():
- name = _('Show more details…')
+ name = _("Show more details…")
show_more_details_action = QtWidgets.QAction(name, self.parent)
show_more_details_action.triggered.connect(self.show_cover_art_info)
menu.addAction(show_more_details_action)
if self.orig_cover_art.isVisible():
- name = _('Keep original cover art')
+ name = _("Keep original cover art")
use_orig_value_action = QtWidgets.QAction(name, self.parent)
use_orig_value_action.triggered.connect(self.keep_original_images)
menu.addAction(use_orig_value_action)
if self.item and self.item.can_show_coverart:
- name = _('Choose local file…')
+ name = _("Choose local file…")
choose_local_file_action = QtWidgets.QAction(name, self.parent)
choose_local_file_action.triggered.connect(self.choose_local_file)
menu.addAction(choose_local_file_action)
@@ -647,20 +647,20 @@ def contextMenuEvent(self, event):
menu.addSeparator()
load_image_behavior_group = QtWidgets.QActionGroup(self.parent)
- action = QtWidgets.QAction(_('Replace front cover art'), self.parent)
+ action = QtWidgets.QAction(_("Replace front cover art"), self.parent)
action.setCheckable(True)
action.triggered.connect(partial(self.set_load_image_behavior, behavior='replace'))
load_image_behavior_group.addAction(action)
config = get_config()
- if config.setting["load_image_behavior"] == 'replace':
+ if config.setting['load_image_behavior'] == 'replace':
action.setChecked(True)
menu.addAction(action)
- action = QtWidgets.QAction(_('Append front cover art'), self.parent)
+ action = QtWidgets.QAction(_("Append front cover art"), self.parent)
action.setCheckable(True)
action.triggered.connect(partial(self.set_load_image_behavior, behavior='append'))
load_image_behavior_group.addAction(action)
- if config.setting["load_image_behavior"] == 'append':
+ if config.setting['load_image_behavior'] == 'append':
action.setChecked(True)
menu.addAction(action)
diff --git a/picard/ui/edittagdialog.py b/picard/ui/edittagdialog.py
index b674e78dda..61a6953454 100644
--- a/picard/ui/edittagdialog.py
+++ b/picard/ui/edittagdialog.py
@@ -66,9 +66,9 @@ def createEditor(self, parent, option, index):
editor = super().createEditor(parent, option, index)
completer = None
if tag in {'date', 'originaldate', 'releasedate'}:
- editor.setPlaceholderText(_('YYYY-MM-DD'))
+ editor.setPlaceholderText(_("YYYY-MM-DD"))
elif tag == 'originalyear':
- editor.setPlaceholderText(_('YYYY'))
+ editor.setPlaceholderText(_("YYYY"))
elif tag == 'releasetype':
completer = QtWidgets.QCompleter(AUTOCOMPLETE_RELEASE_TYPES, editor)
elif tag == 'releasestatus':
diff --git a/picard/ui/filebrowser.py b/picard/ui/filebrowser.py
index 55b603225f..9a1c1c48a3 100644
--- a/picard/ui/filebrowser.py
+++ b/picard/ui/filebrowser.py
@@ -50,19 +50,19 @@
def _macos_find_root_volume():
try:
- for entry in os.scandir('/Volumes/'):
- if entry.is_symlink() and os.path.realpath(entry.path) == '/':
+ for entry in os.scandir("/Volumes/"):
+ if entry.is_symlink() and os.path.realpath(entry.path) == "/":
return entry.path
except OSError:
- log.warning('Could not detect macOS boot volume', exc_info=True)
+ log.warning("Could not detect macOS boot volume", exc_info=True)
return None
def _macos_extend_root_volume_path(path):
- if not path.startswith('/Volumes/'):
+ if not path.startswith("/Volumes/"):
root_volume = _macos_find_root_volume()
if root_volume:
- if path.startswith('/'):
+ if path.startswith("/"):
path = path[1:]
path = os.path.join(root_volume, path)
return path
@@ -77,8 +77,8 @@ def _macos_extend_root_volume_path(path):
class FileBrowser(QtWidgets.QTreeView):
options = [
- TextOption("persist", "current_browser_path", _default_current_browser_path),
- BoolOption("persist", "show_hidden_files", False),
+ TextOption('persist', 'current_browser_path', _default_current_browser_path),
+ BoolOption('persist', 'show_hidden_files', False),
]
def __init__(self, parent):
@@ -94,7 +94,7 @@ def __init__(self, parent):
self.toggle_hidden_action = QtWidgets.QAction(_("Show &hidden files"), self)
self.toggle_hidden_action.setCheckable(True)
config = get_config()
- self.toggle_hidden_action.setChecked(config.persist["show_hidden_files"])
+ self.toggle_hidden_action.setChecked(config.persist['show_hidden_files'])
self.toggle_hidden_action.toggled.connect(self.show_hidden)
self.addAction(self.toggle_hidden_action)
self.set_as_starting_directory_action = QtWidgets.QAction(_("&Set as starting directory"), self)
@@ -143,7 +143,7 @@ def _set_model(self):
def _set_model_filter(self):
config = get_config()
model_filter = QtCore.QDir.Filter.AllDirs | QtCore.QDir.Filter.Files | QtCore.QDir.Filter.Drives | QtCore.QDir.Filter.NoDotAndDotDot
- if config.persist["show_hidden_files"]:
+ if config.persist['show_hidden_files']:
model_filter |= QtCore.QDir.Filter.Hidden
self.model().setFilter(model_filter)
@@ -188,7 +188,7 @@ def focusInEvent(self, event):
def show_hidden(self, state):
config = get_config()
- config.persist["show_hidden_files"] = state
+ config.persist['show_hidden_files'] = state
self._set_model_filter()
def save_state(self):
@@ -196,18 +196,18 @@ def save_state(self):
if indexes:
path = self.model().filePath(indexes[0])
config = get_config()
- config.persist["current_browser_path"] = os.path.normpath(path)
+ config.persist['current_browser_path'] = os.path.normpath(path)
def restore_state(self):
pass
def _restore_state(self):
config = get_config()
- if config.setting["starting_directory"]:
- path = config.setting["starting_directory_path"]
+ if config.setting['starting_directory']:
+ path = config.setting['starting_directory_path']
scrolltype = QtWidgets.QAbstractItemView.ScrollHint.PositionAtTop
else:
- path = config.persist["current_browser_path"]
+ path = config.persist['current_browser_path']
scrolltype = QtWidgets.QAbstractItemView.ScrollHint.PositionAtCenter
if path:
index = self.model().index(find_existing_path(path))
@@ -241,11 +241,11 @@ def move_files_here(self):
return
config = get_config()
path = self.model().filePath(indexes[0])
- config.setting["move_files_to"] = self._get_destination_from_path(path)
+ config.setting['move_files_to'] = self._get_destination_from_path(path)
def set_as_starting_directory(self):
indexes = self.selectedIndexes()
if indexes:
config = get_config()
path = self.model().filePath(indexes[0])
- config.setting["starting_directory_path"] = self._get_destination_from_path(path)
+ config.setting['starting_directory_path'] = self._get_destination_from_path(path)
diff --git a/picard/ui/infodialog.py b/picard/ui/infodialog.py
index 4e75c677f3..a5d37c9375 100644
--- a/picard/ui/infodialog.py
+++ b/picard/ui/infodialog.py
@@ -146,7 +146,7 @@ def __init__(self, obj, parent=None):
# Add the ArtworkTable to the ui
self.ui.artwork_table = ArtworkTable(self.display_existing_artwork)
- self.ui.artwork_table.setObjectName("artwork_table")
+ self.ui.artwork_table.setObjectName('artwork_table')
self.ui.artwork_tab.layout().addWidget(self.ui.artwork_table)
self.setTabOrder(self.ui.tabWidget, self.ui.artwork_table)
self.setTabOrder(self.ui.artwork_table, self.ui.buttonBox)
@@ -168,7 +168,7 @@ def _display_error_tab(self):
def _show_errors(self, errors):
if errors:
- color = interface_colors.get_color("log_error")
+ color = interface_colors.get_color('log_error')
text = '
'.join(map(
lambda s: '%s' % (color, text_as_html(s)), errors))
self.ui.error.setText(text + '
')
@@ -283,38 +283,38 @@ def show_item(self, item):
def format_file_info(file_):
info = []
- info.append((_('Filename:'), file_.filename))
+ info.append((_("Filename:"), file_.filename))
if '~format' in file_.orig_metadata:
- info.append((_('Format:'), file_.orig_metadata['~format']))
+ info.append((_("Format:"), file_.orig_metadata['~format']))
try:
size = os.path.getsize(encode_filename(file_.filename))
sizestr = "%s (%s)" % (bytes2human.decimal(size), bytes2human.binary(size))
- info.append((_('Size:'), sizestr))
+ info.append((_("Size:"), sizestr))
except BaseException:
pass
if file_.orig_metadata.length:
- info.append((_('Length:'), format_time(file_.orig_metadata.length)))
+ info.append((_("Length:"), format_time(file_.orig_metadata.length)))
if '~bitrate' in file_.orig_metadata:
- info.append((_('Bitrate:'), '%s kbps' % file_.orig_metadata['~bitrate']))
+ info.append((_("Bitrate:"), "%s kbps" % file_.orig_metadata['~bitrate']))
if '~sample_rate' in file_.orig_metadata:
- info.append((_('Sample rate:'), '%s Hz' % file_.orig_metadata['~sample_rate']))
+ info.append((_("Sample rate:"), "%s Hz" % file_.orig_metadata['~sample_rate']))
if '~bits_per_sample' in file_.orig_metadata:
- info.append((_('Bits per sample:'), str(file_.orig_metadata['~bits_per_sample'])))
+ info.append((_("Bits per sample:"), str(file_.orig_metadata['~bits_per_sample'])))
if '~channels' in file_.orig_metadata:
ch = file_.orig_metadata['~channels']
if ch == '1':
- ch = _('Mono')
+ ch = _("Mono")
elif ch == '2':
- ch = _('Stereo')
- info.append((_('Channels:'), ch))
+ ch = _("Stereo")
+ info.append((_("Channels:"), ch))
return '
'.join(map(lambda i: '%s %s' %
(escape(i[0]), escape(i[1])), info))
def format_tracklist(cluster):
info = []
- info.append("%s %s" % (_('Album:'), escape(cluster.metadata["album"])))
- info.append("%s %s" % (_('Artist:'), escape(cluster.metadata["albumartist"])))
+ info.append('%s %s' % (_("Album:"), escape(cluster.metadata['album'])))
+ info.append('%s %s' % (_("Artist:"), escape(cluster.metadata['albumartist'])))
info.append("")
TrackListItem = namedtuple('TrackListItem', 'number, title, artist, length')
tracklists = defaultdict(list)
@@ -324,9 +324,9 @@ def format_tracklist(cluster):
objlist = cluster.iterfiles(False)
for obj_ in objlist:
m = obj_.metadata
- artist = m["artist"] or m["albumartist"] or cluster.metadata["albumartist"]
- track = TrackListItem(m["tracknumber"], m["title"], artist,
- m["~length"])
+ artist = m['artist'] or m['albumartist'] or cluster.metadata['albumartist']
+ track = TrackListItem(m['tracknumber'], m['title'], artist,
+ m['~length'])
tracklists[obj_.discnumber].append(track)
def sorttracknum(track):
@@ -344,9 +344,9 @@ def sorttracknum(track):
for discnumber in sorted(tracklists):
tracklist = tracklists[discnumber]
if ndiscs > 1:
- info.append("%s" % (_('Disc %d') % discnumber))
- lines = ["%s %s - %s (%s)" % item for item in sorted(tracklist, key=sorttracknum)]
- info.append("%s
%s
" % (_('Tracklist:'),
+ info.append('%s' % (_("Disc %d") % discnumber))
+ lines = ['%s %s - %s (%s)' % item for item in sorted(tracklist, key=sorttracknum)]
+ info.append('%s
%s
' % (_("Tracklist:"),
'
'.join(escape(s).replace(' ', ' ') for s in lines)))
return '
'.join(info)
diff --git a/picard/ui/infostatus.py b/picard/ui/infostatus.py
index 6b3a871087..e1c270b5ce 100644
--- a/picard/ui/infostatus.py
+++ b/picard/ui/infostatus.py
@@ -60,7 +60,7 @@ def _init_labels(self):
self._init_tooltips()
def _create_icons(self):
- self.icon_eta = QtGui.QIcon(':/images/22x22/hourglass.png')
+ self.icon_eta = QtGui.QIcon(":/images/22x22/hourglass.png")
self.icon_cd = icontheme.lookup('media-optical')
self.icon_file = QtGui.QIcon(":/images/file.png")
self.icon_file_pending = QtGui.QIcon(":/images/file-pending.png")
diff --git a/picard/ui/item.py b/picard/ui/item.py
index 44a9c391ce..95cea7f39d 100644
--- a/picard/ui/item.py
+++ b/picard/ui/item.py
@@ -86,7 +86,7 @@ def load(self, priority=False, refresh=False):
def tracknumber(self):
"""The track number as an int."""
try:
- return int(self.metadata["tracknumber"])
+ return int(self.metadata['tracknumber'])
except BaseException:
return 0
@@ -94,7 +94,7 @@ def tracknumber(self):
def discnumber(self):
"""The disc number as an int."""
try:
- return int(self.metadata["discnumber"])
+ return int(self.metadata['discnumber'])
except BaseException:
return 0
@@ -105,7 +105,7 @@ def errors(self):
return self._errors
def error_append(self, msg):
- log.error('%r: %s', self, msg)
+ log.error("%r: %s", self, msg)
self.errors.append(msg)
def clear_errors(self):
diff --git a/picard/ui/itemviews.py b/picard/ui/itemviews.py
index 64b52e3068..a0c3a5dcc8 100644
--- a/picard/ui/itemviews.py
+++ b/picard/ui/itemviews.py
@@ -158,24 +158,24 @@ class MainPanel(QtWidgets.QSplitter):
options = []
columns = [
- (N_('Title'), 'title'),
- (N_('Length'), '~length'),
- (N_('Artist'), 'artist'),
- (N_('Album Artist'), 'albumartist'),
- (N_('Composer'), 'composer'),
- (N_('Album'), 'album'),
- (N_('Disc Subtitle'), 'discsubtitle'),
- (N_('Track No.'), 'tracknumber'),
- (N_('Disc No.'), 'discnumber'),
- (N_('Catalog No.'), 'catalognumber'),
- (N_('Barcode'), 'barcode'),
- (N_('Media'), 'media'),
- (N_('Genre'), 'genre'),
- (N_('Fingerprint status'), '~fingerprint'),
- (N_('Date'), 'date'),
- (N_('Original Release Date'), 'originaldate'),
- (N_('Release Date'), 'releasedate'),
- (N_('Cover'), 'covercount'),
+ (N_("Title"), 'title'),
+ (N_("Length"), '~length'),
+ (N_("Artist"), 'artist'),
+ (N_("Album Artist"), 'albumartist'),
+ (N_("Composer"), 'composer'),
+ (N_("Album"), 'album'),
+ (N_("Disc Subtitle"), 'discsubtitle'),
+ (N_("Track No."), 'tracknumber'),
+ (N_("Disc No."), 'discnumber'),
+ (N_("Catalog No."), 'catalognumber'),
+ (N_("Barcode"), 'barcode'),
+ (N_("Media"), 'media'),
+ (N_("Genre"), 'genre'),
+ (N_("Fingerprint status"), '~fingerprint'),
+ (N_("Date"), 'date'),
+ (N_("Original Release Date"), 'originaldate'),
+ (N_("Release Date"), 'releasedate'),
+ (N_("Cover"), 'covercount'),
]
_column_indexes = {column[1]: i for i, column in enumerate(columns)}
@@ -396,12 +396,12 @@ def contextMenuEvent(self, event):
menu.addAction(action)
menu.addSeparator()
- restore_action = QtWidgets.QAction(_('Restore default columns'), parent)
+ restore_action = QtWidgets.QAction(_("Restore default columns"), parent)
restore_action.setEnabled(not self.is_locked)
restore_action.triggered.connect(self.restore_defaults)
menu.addAction(restore_action)
- lock_action = QtWidgets.QAction(_('Lock columns'), parent)
+ lock_action = QtWidgets.QAction(_("Lock columns"), parent)
lock_action.setCheckable(True)
lock_action.setChecked(self.is_locked)
lock_action.toggled.connect(self.lock)
@@ -543,9 +543,9 @@ def contextMenuEvent(self, event):
releases_menu = QtWidgets.QMenu(_("&Other versions"), menu)
menu.addSeparator()
menu.addMenu(releases_menu)
- loading = releases_menu.addAction(_('Loading…'))
+ loading = releases_menu.addAction(_("Loading…"))
loading.setDisabled(True)
- action_more = releases_menu.addAction(_('Show &more details…'))
+ action_more = releases_menu.addAction(_("Show &more details…"))
action_more.triggered.connect(self.window.album_other_versions_action.trigger)
bottom_separator = True
@@ -562,8 +562,8 @@ def _add_other_versions():
versions = obj.release_group.versions
album_tracks_count = obj.get_num_total_files() or len(obj.tracks)
- preferred_countries = set(config.setting["preferred_release_countries"])
- preferred_formats = set(config.setting["preferred_release_formats"])
+ preferred_countries = set(config.setting['preferred_release_countries'])
+ preferred_formats = set(config.setting['preferred_release_formats'])
ORDER_BEFORE, ORDER_AFTER = 0, 1
alternatives = []
@@ -610,7 +610,7 @@ def _add_other_versions():
else:
releases_menu.setEnabled(False)
- if config.setting["enable_ratings"] and \
+ if config.setting['enable_ratings'] and \
len(self.window.selected_objects) == 1 and isinstance(obj, Track):
menu.addSeparator()
action = QtWidgets.QWidgetAction(menu)
@@ -626,7 +626,7 @@ def _add_other_versions():
menu.addSeparator()
menu.addMenu(CollectionMenu(selected_albums, _("Collections"), menu))
- scripts = config.setting["list_of_scripts"]
+ scripts = config.setting['list_of_scripts']
if plugin_actions or scripts:
menu.addSeparator()
@@ -692,7 +692,7 @@ def supportedDropActions(self):
def mimeTypes(self):
"""List of MIME types accepted by this view."""
- return ["text/uri-list", "application/picard.album-list"]
+ return ['text/uri-list', 'application/picard.album-list']
def dragEnterEvent(self, event):
super().dragEnterEvent(event)
@@ -733,7 +733,7 @@ def mimeData(self, items):
elif obj.iterfiles:
files.extend([url(f.filename) for f in obj.iterfiles()])
mimeData = QtCore.QMimeData()
- mimeData.setData("application/picard.album-list", "\n".join(album_ids).encode())
+ mimeData.setData('application/picard.album-list', '\n'.join(album_ids).encode())
if files:
mimeData.setUrls(files)
return mimeData
@@ -753,14 +753,14 @@ def drop_urls(urls, target, move_to_multi_tracks=True):
tagger = QtCore.QObject.tagger
for url in urls:
log.debug("Dropped the URL: %r", url.toString(QtCore.QUrl.UrlFormattingOption.RemoveUserInfo))
- if url.scheme() == "file" or not url.scheme():
- filename = normpath(url.toLocalFile().rstrip("\0"))
+ if url.scheme() == 'file' or not url.scheme():
+ filename = normpath(url.toLocalFile().rstrip('\0'))
file = tagger.files.get(filename)
if file:
files.append(file)
else:
new_paths.append(filename)
- elif url.scheme() in {"http", "https"}:
+ elif url.scheme() in {'http', 'https'}:
file_lookup = tagger.get_file_lookup()
file_lookup.mbid_lookup(url.path(), browser_fallback=False)
if files:
@@ -804,7 +804,7 @@ def dropMimeData(self, parent, index, data, action):
QtCore.QTimer.singleShot(0, partial(self.drop_urls, urls, target, self._move_to_multi_tracks))
handled = True
# application/picard.album-list
- albums = data.data("application/picard.album-list")
+ albums = data.data('application/picard.album-list')
if albums:
album_ids = bytes(albums).decode().split("\n")
log.debug("Dropped albums = %r", album_ids)
@@ -843,8 +843,8 @@ def moveCursor(self, action, modifiers):
class FileTreeView(BaseTreeView):
- header_state = Option("persist", "file_view_header_state", QtCore.QByteArray())
- header_locked = BoolOption("persist", "file_view_header_locked", False)
+ header_state = Option('persist', 'file_view_header_state', QtCore.QByteArray())
+ header_locked = BoolOption('persist', 'file_view_header_locked', False)
def __init__(self, window, parent=None):
super().__init__(window, parent)
@@ -869,13 +869,13 @@ def remove_file_cluster(self, cluster):
self.set_clusters_text()
def set_clusters_text(self):
- self.clusters.setText(MainPanel.TITLE_COLUMN, '%s (%d)' % (_("Clusters"), len(self.tagger.clusters)))
+ self.clusters.setText(MainPanel.TITLE_COLUMN, "%s (%d)" % (_("Clusters"), len(self.tagger.clusters)))
class AlbumTreeView(BaseTreeView):
- header_state = Option("persist", "album_view_header_state", QtCore.QByteArray())
- header_locked = BoolOption("persist", "album_view_header_locked", False)
+ header_state = Option('persist', 'album_view_header_state', QtCore.QByteArray())
+ header_locked = BoolOption('persist', 'album_view_header_locked', False)
def __init__(self, window, parent=None):
super().__init__(window, parent)
@@ -1194,10 +1194,10 @@ def decide_fingerprint_icon_info(file):
if getattr(file, 'acoustid_fingerprint', None):
if QtCore.QObject.tagger.acoustidmanager.is_submitted(file):
icon = FileItem.icon_fingerprint_gray
- tooltip = _('Fingerprint has already been submitted')
+ tooltip = _("Fingerprint has already been submitted")
else:
icon = FileItem.icon_fingerprint
- tooltip = _('Unsubmitted fingerprint')
+ tooltip = _("Unsubmitted fingerprint")
else:
icon = QtGui.QIcon()
tooltip = _('No fingerprint was calculated for this file, use "Scan" or "Generate AcoustID Fingerprints" to calculate the fingerprint.')
diff --git a/picard/ui/logview.py b/picard/ui/logview.py
index 365932de37..8dfbb83a1f 100644
--- a/picard/ui/logview.py
+++ b/picard/ui/logview.py
@@ -162,7 +162,7 @@ def set_verbosity(self, level):
class LogView(LogViewCommon):
options = [
- IntOption("setting", "log_verbosity", logging.WARNING),
+ IntOption('setting', 'log_verbosity', logging.WARNING),
]
def __init__(self, parent=None):
@@ -271,7 +271,7 @@ def _save_log_as_do(self):
return
writer = QtGui.QTextDocumentWriter(path)
- writer.setFormat(b"plaintext")
+ writer.setFormat(b'plaintext')
success = writer.write(self.doc)
if not success:
QtWidgets.QMessageBox.critical(
diff --git a/picard/ui/mainwindow.py b/picard/ui/mainwindow.py
index 418d12c597..cb009a35df 100644
--- a/picard/ui/mainwindow.py
+++ b/picard/ui/mainwindow.py
@@ -177,15 +177,15 @@ class MainWindow(QtWidgets.QMainWindow, PreserveGeometry):
ready_for_display = QtCore.pyqtSignal()
options = [
- Option("persist", "window_state", QtCore.QByteArray()),
- BoolOption("persist", "window_maximized", False),
- BoolOption("persist", "view_metadata_view", True),
- BoolOption("persist", "view_cover_art", True),
- BoolOption("persist", "view_toolbar", True),
- BoolOption("persist", "view_file_browser", False),
- TextOption("persist", "current_directory", ""),
- FloatOption("persist", "mediaplayer_playback_rate", 1.0),
- IntOption("persist", "mediaplayer_volume", 50),
+ Option('persist', 'window_state', QtCore.QByteArray()),
+ BoolOption('persist', 'window_maximized', False),
+ BoolOption('persist', 'view_metadata_view', True),
+ BoolOption('persist', 'view_cover_art', True),
+ BoolOption('persist', 'view_toolbar', True),
+ BoolOption('persist', 'view_file_browser', False),
+ TextOption('persist', 'current_directory', ""),
+ FloatOption('persist', 'mediaplayer_playback_rate', 1.0),
+ IntOption('persist', 'mediaplayer_volume', 50),
]
def __init__(self, parent=None, disable_player=False):
@@ -316,7 +316,7 @@ def showEvent(self, event):
def closeEvent(self, event):
config = get_config()
- if config.setting["quit_confirmation"] and not self.show_quit_confirmation():
+ if config.setting['quit_confirmation'] and not self.show_quit_confirmation():
event.ignore()
return
if self.player:
@@ -367,14 +367,14 @@ def show_quit_confirmation(self):
def saveWindowState(self):
config = get_config()
- config.persist["window_state"] = self.saveState()
+ config.persist['window_state'] = self.saveState()
isMaximized = int(self.windowState()) & QtCore.Qt.WindowState.WindowMaximized != 0
self.save_geometry()
- config.persist["window_maximized"] = isMaximized
- config.persist["view_metadata_view"] = self.show_metadata_view_action.isChecked()
- config.persist["view_cover_art"] = self.show_cover_art_action.isChecked()
- config.persist["view_toolbar"] = self.show_toolbar_action.isChecked()
- config.persist["view_file_browser"] = self.show_file_browser_action.isChecked()
+ config.persist['window_maximized'] = isMaximized
+ config.persist['view_metadata_view'] = self.show_metadata_view_action.isChecked()
+ config.persist['view_cover_art'] = self.show_cover_art_action.isChecked()
+ config.persist['view_toolbar'] = self.show_toolbar_action.isChecked()
+ config.persist['view_file_browser'] = self.show_file_browser_action.isChecked()
self.file_browser.save_state()
self.panel.save_state()
self.metadata_box.save_state()
@@ -382,11 +382,11 @@ def saveWindowState(self):
@restore_method
def restoreWindowState(self):
config = get_config()
- self.restoreState(config.persist["window_state"])
+ self.restoreState(config.persist['window_state'])
self.restore_geometry()
- if config.persist["window_maximized"]:
+ if config.persist['window_maximized']:
self.setWindowState(QtCore.Qt.WindowState.WindowMaximized)
- splitters = config.persist["splitters_MainWindow"]
+ splitters = config.persist['splitters_MainWindow']
if splitters is None or 'main_window_bottom_splitter' not in splitters:
self.centralWidget().setSizes([366, 194])
self.file_browser.restore_state()
@@ -480,7 +480,7 @@ def isdict(obj):
def _on_submit_acoustid(self):
if self.tagger.use_acoustid:
config = get_config()
- if not config.setting["acoustid_apikey"]:
+ if not config.setting['acoustid_apikey']:
msg = QtWidgets.QMessageBox(self)
msg.setIcon(QtWidgets.QMessageBox.Icon.Information)
msg.setWindowModality(QtCore.Qt.WindowModality.WindowModal)
@@ -493,7 +493,7 @@ def _on_submit_acoustid(self):
msg.addButton(open_options, QtWidgets.QMessageBox.ButtonRole.YesRole)
msg.exec_()
if msg.clickedButton() == open_options:
- self.show_options("fingerprinting")
+ self.show_options('fingerprinting')
else:
self.tagger.acoustidmanager.submit()
@@ -705,7 +705,7 @@ def _create_show_file_browser_action(self):
config = get_config()
action = QtWidgets.QAction(_("File &Browser"), self)
action.setCheckable(True)
- if config.persist["view_file_browser"]:
+ if config.persist['view_file_browser']:
action.setChecked(True)
action.setShortcut(QtGui.QKeySequence(_("Ctrl+B")))
action.triggered.connect(self.show_file_browser)
@@ -716,7 +716,7 @@ def _create_show_metadata_view_action(self):
config = get_config()
action = QtWidgets.QAction(_("&Metadata"), self)
action.setCheckable(True)
- if config.persist["view_metadata_view"]:
+ if config.persist['view_metadata_view']:
action.setChecked(True)
action.setShortcut(QtGui.QKeySequence(_("Ctrl+Shift+M")))
action.triggered.connect(self.show_metadata_view)
@@ -727,7 +727,7 @@ def _create_show_cover_art_action(self):
config = get_config()
action = QtWidgets.QAction(_("&Cover Art"), self)
action.setCheckable(True)
- if config.persist["view_cover_art"]:
+ if config.persist['view_cover_art']:
action.setChecked(True)
action.setEnabled(self.show_metadata_view_action.isChecked())
action.triggered.connect(self.show_cover_art)
@@ -738,7 +738,7 @@ def _create_show_toolbar_action(self):
config = get_config()
action = QtWidgets.QAction(_("&Actions"), self)
action.setCheckable(True)
- if config.persist["view_toolbar"]:
+ if config.persist['view_toolbar']:
action.setChecked(True)
action.triggered.connect(self.show_toolbar)
self.show_toolbar_action = action
@@ -775,7 +775,7 @@ def _create_analyze_action(self):
action = QtWidgets.QAction(icontheme.lookup('picard-analyze'), _("&Scan"), self)
action.setStatusTip(_("Use AcoustID audio fingerprint to identify the files by the actual music, even if they have no metadata"))
action.setEnabled(False)
- action.setToolTip(_('Identify the file using its AcoustID audio fingerprint'))
+ action.setToolTip(_("Identify the file using its AcoustID audio fingerprint"))
# TR: Keyboard shortcut for "Analyze"
action.setShortcut(QtGui.QKeySequence(_("Ctrl+Y")))
action.triggered.connect(self.analyze)
@@ -787,7 +787,7 @@ def _create_generate_fingerprints_action(self):
action.setIconText(_("Generate Fingerprints"))
action.setStatusTip(_("Generate the AcoustID audio fingerprints for the selected files without doing a lookup"))
action.setEnabled(False)
- action.setToolTip(_('Generate the AcoustID audio fingerprints for the selected files'))
+ action.setToolTip(_("Generate the AcoustID audio fingerprints for the selected files"))
action.setShortcut(QtGui.QKeySequence(_("Ctrl+Shift+Y")))
action.triggered.connect(self.generate_fingerprints)
self.generate_fingerprints_action = action
@@ -835,7 +835,7 @@ def _create_enable_renaming_action(self):
config = get_config()
action = QtWidgets.QAction(_("&Rename Files"), self)
action.setCheckable(True)
- action.setChecked(config.setting["rename_files"])
+ action.setChecked(config.setting['rename_files'])
action.triggered.connect(self.toggle_rename_files)
self.enable_renaming_action = action
@@ -844,7 +844,7 @@ def _create_enable_moving_action(self):
config = get_config()
action = QtWidgets.QAction(_("&Move Files"), self)
action.setCheckable(True)
- action.setChecked(config.setting["move_files"])
+ action.setChecked(config.setting['move_files'])
action.triggered.connect(self.toggle_move_files)
self.enable_moving_action = action
@@ -853,7 +853,7 @@ def _create_enable_tag_saving_action(self):
config = get_config()
action = QtWidgets.QAction(_("Save &Tags"), self)
action.setCheckable(True)
- action.setChecked(not config.setting["dont_write_tags"])
+ action.setChecked(not config.setting['dont_write_tags'])
action.triggered.connect(self.toggle_tag_saving)
self.enable_tag_saving_action = action
@@ -861,7 +861,7 @@ def _create_enable_tag_saving_action(self):
def _create_tags_from_filenames_action(self):
action = QtWidgets.QAction(icontheme.lookup('picard-tags-from-filename'), _("Tags From &File Names…"), self)
action.setIconText(_("Parse File Names…"))
- action.setToolTip(_('Set tags based on the file names'))
+ action.setToolTip(_("Set tags based on the file names"))
action.setShortcut(QtGui.QKeySequence(_("Ctrl+Shift+T")))
action.setEnabled(False)
action.triggered.connect(self.open_tags_from_filenames)
@@ -871,7 +871,7 @@ def _create_tags_from_filenames_action(self):
def _create_open_collection_in_browser_action(self):
config = get_config()
action = QtWidgets.QAction(_("&Open My Collections in Browser"), self)
- action.setEnabled(config.setting["username"] != '')
+ action.setEnabled(config.setting['username'] != '')
action.triggered.connect(self.open_collection_in_browser)
self.open_collection_in_browser_action = action
@@ -938,7 +938,7 @@ def update_cd_lookup_drives(self, drives):
log.warning(DISCID_NOT_LOADED_MESSAGE)
else:
config = get_config()
- shortcut_drive = config.setting["cd_lookup_device"].split(",")[0] if len(drives) > 1 else ""
+ shortcut_drive = config.setting['cd_lookup_device'].split(",")[0] if len(drives) > 1 else ""
for drive in drives:
action = self.cd_lookup_menu.addAction(drive)
action.setData(drive)
@@ -950,7 +950,7 @@ def update_cd_lookup_drives(self, drives):
def _set_cd_lookup_from_file_actions(self, drives):
if self.cd_lookup_menu.actions():
self.cd_lookup_menu.addSeparator()
- action = self.cd_lookup_menu.addAction(_('From CD ripper &log file…'))
+ action = self.cd_lookup_menu.addAction(_("From CD ripper &log file…"))
if not drives:
self._update_cd_lookup_default_action(action)
action.setData('logfile:eac')
@@ -974,17 +974,17 @@ def _update_cd_lookup_button(self):
def toggle_rename_files(self, checked):
config = get_config()
- config.setting["rename_files"] = checked
+ config.setting['rename_files'] = checked
self.update_script_editor_examples()
def toggle_move_files(self, checked):
config = get_config()
- config.setting["move_files"] = checked
+ config.setting['move_files'] = checked
self.update_script_editor_examples()
def toggle_tag_saving(self, checked):
config = get_config()
- config.setting["dont_write_tags"] = not checked
+ config.setting['dont_write_tags'] = not checked
def get_selected_or_unmatched_files(self):
if self.selected_objects:
@@ -1084,7 +1084,7 @@ def create_menus(self):
def update_toolbar_style(self):
config = get_config()
style = QtCore.Qt.ToolButtonStyle.ToolButtonIconOnly
- if config.setting["toolbar_show_labels"]:
+ if config.setting['toolbar_show_labels']:
style = QtCore.Qt.ToolButtonStyle.ToolButtonTextUnderIcon
self.toolbar.setToolButtonStyle(style)
if self.player:
@@ -1103,7 +1103,7 @@ def create_action_toolbar(self):
self.removeToolBar(self.toolbar)
self.toolbar = toolbar = QtWidgets.QToolBar(_("Actions"))
self.insertToolBar(self.search_toolbar, self.toolbar)
- toolbar.setObjectName("main_toolbar")
+ toolbar.setObjectName('main_toolbar')
if self._is_wayland:
toolbar.setFloatable(False) # https://bugreports.qt.io/browse/QTBUG-92191
if IS_MACOS:
@@ -1126,7 +1126,7 @@ def add_toolbar_action(action):
try:
add_toolbar_action(getattr(self, action))
except AttributeError:
- log.warning('Warning: Unknown action name "%r" found in config. Ignored.', action)
+ log.warning("Warning: Unknown action name '%r' found in config. Ignored.", action)
self.show_toolbar()
def create_player_toolbar(self):
@@ -1142,7 +1142,7 @@ def create_search_toolbar(self):
config = get_config()
self.search_toolbar = toolbar = self.addToolBar(_("Search"))
self.search_toolbar_toggle_action = self.search_toolbar.toggleViewAction()
- toolbar.setObjectName("search_toolbar")
+ toolbar.setObjectName('search_toolbar')
if self._is_wayland:
toolbar.setFloatable(False) # https://bugreports.qt.io/browse/QTBUG-92191
if IS_MACOS:
@@ -1151,9 +1151,9 @@ def create_search_toolbar(self):
search_panel = QtWidgets.QWidget(toolbar)
hbox = QtWidgets.QHBoxLayout(search_panel)
self.search_combo = QtWidgets.QComboBox(search_panel)
- self.search_combo.addItem(_("Album"), "album")
- self.search_combo.addItem(_("Artist"), "artist")
- self.search_combo.addItem(_("Track"), "track")
+ self.search_combo.addItem(_("Album"), 'album')
+ self.search_combo.addItem(_("Artist"), 'artist')
+ self.search_combo.addItem(_("Track"), 'track')
hbox.addWidget(self.search_combo, 0)
self.search_edit = QtWidgets.QLineEdit(search_panel)
self.search_edit.setClearButtonEnabled(True)
@@ -1243,7 +1243,7 @@ def search(self):
entity = self.search_combo.itemData(self.search_combo.currentIndex())
config = get_config()
self.tagger.search(text, entity,
- config.setting["use_adv_search_syntax"],
+ config.setting['use_adv_search_syntax'],
mbid_matched_callback=self.search_mbid_found)
def add_files(self):
@@ -1271,7 +1271,7 @@ def add_files(self):
files, _filter = QtWidgets.QFileDialog.getOpenFileNames(self, "", current_directory, ";;".join(formats))
if files:
config = get_config()
- config.persist["current_directory"] = os.path.dirname(files[0])
+ config.persist['current_directory'] = os.path.dirname(files[0])
self.tagger.add_files(files)
def add_directory(self):
@@ -1280,7 +1280,7 @@ def add_directory(self):
dir_list = []
config = get_config()
- if not config.setting["toolbar_multiselect"]:
+ if not config.setting['toolbar_multiselect']:
directory = QtWidgets.QFileDialog.getExistingDirectory(self, "", current_directory)
if directory:
dir_list.append(directory)
@@ -1292,7 +1292,7 @@ def add_directory(self):
dir_count = len(dir_list)
if dir_count:
parent = os.path.dirname(dir_list[0]) if dir_count > 1 else dir_list[0]
- config.persist["current_directory"] = parent
+ config.persist['current_directory'] = parent
if dir_count > 1:
self.set_statusbar_message(
N_("Adding multiple directories from '%(directory)s' …"),
@@ -1357,11 +1357,11 @@ def open_donation_page(self):
def save(self):
"""Tell the tagger to save the selected objects."""
config = get_config()
- if config.setting["file_save_warning"]:
+ if config.setting['file_save_warning']:
count = len(self.tagger.get_files_from_objects(self.selected_objects))
msg = SaveWarningDialog(self, count)
proceed_with_save, disable_warning = msg.show()
- config.setting["file_save_warning"] = not disable_warning
+ config.setting['file_save_warning'] = not disable_warning
else:
proceed_with_save = True
if proceed_with_save:
@@ -1405,7 +1405,7 @@ def _ensure_fingerprinting_configured(self, callback):
def on_finished(result):
callback(config.setting['fingerprinting_system'])
- dialog = self.show_options("fingerprinting")
+ dialog = self.show_options('fingerprinting')
dialog.finished.connect(on_finished)
else:
callback(config.setting['fingerprinting_system'])
@@ -1438,7 +1438,7 @@ def show_more_tracks(self):
if isinstance(obj, Track) and obj.files:
obj = obj.files[0]
if not isinstance(obj, File):
- log.debug('show_more_tracks expected a File, got %r', obj)
+ log.debug("show_more_tracks expected a File, got %r", obj)
return
dialog = TrackSearchDialog(self, force_advanced_search=True)
dialog.show_similar_tracks(obj)
@@ -1447,7 +1447,7 @@ def show_more_tracks(self):
def show_more_albums(self):
obj = self.get_first_obj_with_type(Cluster)
if not obj:
- log.debug('show_more_albums expected a Cluster, got %r', obj)
+ log.debug("show_more_albums expected a Cluster, got %r", obj)
return
dialog = AlbumSearchDialog(self, force_advanced_search=True)
dialog.show_similar_albums(obj)
@@ -1532,13 +1532,13 @@ def _check_add_release(self):
QtWidgets.QMessageBox.StandardButton.Yes)
if ret == QtWidgets.QMessageBox.StandardButton.Yes:
config = get_config()
- config.setting["browser_integration"] = True
+ config.setting['browser_integration'] = True
self.tagger.update_browser_integration()
if addrelease.is_enabled():
return True
else:
# Something went wrong, let the user configure browser integration manually
- self.show_options("network")
+ self.show_options('network')
return False
else:
return False
@@ -1735,12 +1735,12 @@ def show_password_dialog(self, reply, authenticator):
def on_mb_login_finished(self, successful, error_msg):
if successful:
- log.debug('MusicBrainz authentication finished successfully')
+ log.debug("MusicBrainz authentication finished successfully")
else:
- log.info('MusicBrainz authentication failed: %s', error_msg)
+ log.info("MusicBrainz authentication failed: %s", error_msg)
QtWidgets.QMessageBox.critical(self,
_("Authentication failed"),
- _('Login failed: %s') % error_msg)
+ _("Login failed: %s") % error_msg)
def show_proxy_dialog(self, proxy, authenticator):
dialog = ProxyDialog(authenticator, proxy, parent=self)
@@ -1783,7 +1783,7 @@ def auto_update_check(self):
update_level = config.setting['update_level']
today = datetime.date.today().toordinal()
do_auto_update_check = check_for_updates and update_check_days > 0 and today >= last_update_check + update_check_days
- log.debug('%(check_status)s startup check for program updates. Today: %(today_date)s, Last check: %(last_check)s (Check interval: %(check_interval)s days), Update level: %(update_level)s (%(update_level_name)s)', {
+ log.debug("%(check_status)s startup check for program updates. Today: %(today_date)s, Last check: %(last_check)s (Check interval: %(check_interval)s days), Update level: %(update_level)s (%(update_level_name)s)", {
'check_status': 'Initiating' if do_auto_update_check else 'Skipping',
'today_date': datetime.date.today(),
'last_check': str(datetime.date.fromordinal(last_update_check)) if last_update_check > 0 else 'never',
@@ -1824,29 +1824,29 @@ def check_and_repair_profiles(self):
Checks that there is a settings dictionary for each profile, and that no profiles
reference a non-existant file naming script.
"""
- script_id_key = "selected_file_naming_script_id"
+ script_id_key = 'selected_file_naming_script_id'
config = get_config()
- naming_scripts = config.setting["file_renaming_scripts"]
+ naming_scripts = config.setting['file_renaming_scripts']
naming_script_ids = set(naming_scripts.keys())
profile_settings = deepcopy(config.profiles[SettingConfigSection.SETTINGS_KEY])
for profile in config.profiles[SettingConfigSection.PROFILES_KEY]:
- p_id = profile["id"]
+ p_id = profile['id']
# Add empty settings if none found for a profile
if p_id not in profile_settings:
log.warning(
- "No settings dict found for profile '%s' (\"%s\"). Adding empty dict.",
+ "No settings dict found for profile '%s' ('%s'). Adding empty dict.",
p_id,
- profile["title"],
+ profile['title'],
)
profile_settings[p_id] = {}
# Remove any invalid naming script ids from profiles
if script_id_key in profile_settings[p_id]:
if profile_settings[p_id][script_id_key] not in naming_script_ids:
log.warning(
- "Removing invalid naming script id '%s' from profile '%s' (\"%s\")",
+ "Removing invalid naming script id '%s' from profile '%s' ('%s')",
profile_settings[p_id][script_id_key],
p_id,
- profile["title"],
+ profile['title'],
)
profile_settings[p_id][script_id_key] = None
config.profiles[SettingConfigSection.SETTINGS_KEY] = profile_settings
@@ -1856,8 +1856,8 @@ def make_script_selector_menu(self):
"""
if self.script_editor_dialog is None or not isinstance(self.script_editor_dialog, ScriptEditorDialog):
config = get_config()
- naming_scripts = config.setting["file_renaming_scripts"]
- selected_script_id = config.setting["selected_file_naming_script_id"]
+ naming_scripts = config.setting['file_renaming_scripts']
+ selected_script_id = config.setting['selected_file_naming_script_id']
else:
naming_scripts = self.script_editor_dialog.naming_scripts
selected_script_id = self.script_editor_dialog.selected_script_id
@@ -1886,7 +1886,7 @@ def select_new_naming_script(self, id):
"""
config = get_config()
log.debug("Setting naming script to: %s", id)
- config.setting["selected_file_naming_script_id"] = id
+ config.setting['selected_file_naming_script_id'] = id
self.make_script_selector_menu()
if self.script_editor_dialog:
self.script_editor_dialog.set_selected_script_id(id)
@@ -1993,9 +1993,9 @@ def update_profile_selection(self, profile_id):
def show_new_user_dialog(self):
config = get_config()
- if config.setting["show_new_user_dialog"]:
+ if config.setting['show_new_user_dialog']:
msg = NewUserDialog(self)
- config.setting["show_new_user_dialog"] = msg.show()
+ config.setting['show_new_user_dialog'] = msg.show()
def check_for_plugin_update(self):
config = get_config()
diff --git a/picard/ui/metadatabox.py b/picard/ui/metadatabox.py
index 1aa94cd005..eb96fb1b66 100644
--- a/picard/ui/metadatabox.py
+++ b/picard/ui/metadatabox.py
@@ -85,7 +85,7 @@ class TagStatus:
class TagCounter(dict):
- __slots__ = ("parent", "counts", "different")
+ __slots__ = ('parent', 'counts', 'different')
def __init__(self, parent):
self.parent = parent
@@ -111,7 +111,7 @@ def display_value(self, tag):
if tag in self.different:
return (ngettext("(different across %d item)", "(different across %d items)", count) % count, True)
else:
- if tag == "~length":
+ if tag == '~length':
msg = format_time(self.get(tag, 0))
else:
msg = MULTI_VALUED_JOINER.join(self[tag])
@@ -124,7 +124,7 @@ def display_value(self, tag):
class TagDiff(object):
- __slots__ = ("tag_names", "new", "orig", "status", "objects", "max_length_delta_ms")
+ __slots__ = ('tag_names', 'new', 'orig', 'status', 'objects', 'max_length_delta_ms')
def __init__(self, max_length_diff=2):
self.tag_names = []
@@ -135,7 +135,7 @@ def __init__(self, max_length_diff=2):
self.max_length_delta_ms = max_length_diff * 1000
def __tag_ne(self, tag, orig, new):
- if tag == "~length":
+ if tag == '~length':
return abs(float(orig) - float(new)) > self.max_length_delta_ms
else:
return orig != new
@@ -204,8 +204,8 @@ def get_tag_name(self, index):
class MetadataBox(QtWidgets.QTableWidget):
options = (
- Option("persist", "metadatabox_header_state", QtCore.QByteArray()),
- BoolOption("persist", "show_changes_first", False)
+ Option('persist', 'metadatabox_header_state', QtCore.QByteArray()),
+ BoolOption('persist', 'show_changes_first', False)
)
COLUMN_ORIG = 1
@@ -242,7 +242,7 @@ def __init__(self, parent):
self.add_tag_action.triggered.connect(partial(self.edit_tag, ""))
self.changes_first_action = QtWidgets.QAction(_("Show Changes First"), parent)
self.changes_first_action.setCheckable(True)
- self.changes_first_action.setChecked(config.persist["show_changes_first"])
+ self.changes_first_action.setChecked(config.persist['show_changes_first'])
self.changes_first_action.toggled.connect(self.toggle_changes_first)
# TR: Keyboard shortcut for "Add New Tag…"
self.add_tag_shortcut = QtWidgets.QShortcut(QtGui.QKeySequence(_("Alt+Shift+A")), self, partial(self.edit_tag, ""))
@@ -260,22 +260,22 @@ def __init__(self, parent):
def get_file_lookup(self):
"""Return a FileLookup object."""
config = get_config()
- return FileLookup(self, config.setting["server_host"],
- config.setting["server_port"],
+ return FileLookup(self, config.setting['server_host'],
+ config.setting['server_port'],
self.tagger.browser_integration.port)
def lookup_tags(self):
lookup = self.get_file_lookup()
LOOKUP_TAGS = {
- "musicbrainz_recordingid": lookup.recording_lookup,
- "musicbrainz_trackid": lookup.track_lookup,
- "musicbrainz_albumid": lookup.album_lookup,
- "musicbrainz_workid": lookup.work_lookup,
- "musicbrainz_artistid": lookup.artist_lookup,
- "musicbrainz_albumartistid": lookup.artist_lookup,
- "musicbrainz_releasegroupid": lookup.release_group_lookup,
- "musicbrainz_discid": lookup.discid_lookup,
- "acoustid_id": lookup.acoust_lookup
+ 'musicbrainz_recordingid': lookup.recording_lookup,
+ 'musicbrainz_trackid': lookup.track_lookup,
+ 'musicbrainz_albumid': lookup.album_lookup,
+ 'musicbrainz_workid': lookup.work_lookup,
+ 'musicbrainz_artistid': lookup.artist_lookup,
+ 'musicbrainz_albumartistid': lookup.artist_lookup,
+ 'musicbrainz_releasegroupid': lookup.release_group_lookup,
+ 'musicbrainz_discid': lookup.discid_lookup,
+ 'acoustid_id': lookup.acoust_lookup
}
return LOOKUP_TAGS
@@ -469,7 +469,7 @@ def edit_selected_tag(self):
def toggle_changes_first(self, checked):
config = get_config()
- config.persist["show_changes_first"] = checked
+ config.persist['show_changes_first'] = checked
self.update()
def set_tag_values(self, tag, values, objects=None):
@@ -557,8 +557,8 @@ def _update_tags(self, new_selection=True, drop_album_caches=False):
return None
if new_selection or drop_album_caches:
- self._single_file_album = len({file.metadata["album"] for file in files}) == 1
- self._single_track_album = len({track.metadata["album"] for track in tracks}) == 1
+ self._single_file_album = len({file.metadata['album'] for file in files}) == 1
+ self._single_track_album = len({track.metadata['album'] for track in tracks}) == 1
while not new_selection: # Just an if with multiple exit points
# If we are dealing with the same selection
@@ -582,12 +582,12 @@ def _update_tags(self, new_selection=True, drop_album_caches=False):
}
config = get_config()
- tag_diff = TagDiff(max_length_diff=config.setting["ignore_track_duration_difference_under"])
+ tag_diff = TagDiff(max_length_diff=config.setting['ignore_track_duration_difference_under'])
orig_tags = tag_diff.orig
new_tags = tag_diff.new
tag_diff.objects = len(files)
- clear_existing_tags = config.setting["clear_existing_tags"]
+ clear_existing_tags = config.setting['clear_existing_tags']
top_tags = config.setting['metadatabox_top_tags']
top_tags_set = set(top_tags)
@@ -608,7 +608,7 @@ def _update_tags(self, new_selection=True, drop_album_caches=False):
removed = name in new_metadata.deleted_tags
tag_diff.add(name, orig_values, new_values, True, removed, top_tags=top_tags_set)
- tag_diff.add("~length", str(orig_metadata.length), str(new_metadata.length),
+ tag_diff.add('~length', str(orig_metadata.length), str(new_metadata.length),
removable=False, readonly=True)
for track in tracks:
@@ -622,7 +622,7 @@ def _update_tags(self, new_selection=True, drop_album_caches=False):
tag_diff.add(name, orig_values, new_values, True)
length = str(track.metadata.length)
- tag_diff.add("~length", length, length, removable=False, readonly=True)
+ tag_diff.add('~length', length, length, removable=False, readonly=True)
tag_diff.objects += 1
@@ -631,7 +631,7 @@ def _update_tags(self, new_selection=True, drop_album_caches=False):
tag_names = common_tags + sorted(all_tags.difference(common_tags),
key=lambda x: display_tag_name(x).lower())
- if config.persist["show_changes_first"]:
+ if config.persist['show_changes_first']:
tags_by_status = {}
for tag in tag_names:
@@ -685,7 +685,7 @@ def _update_items(self, result=None, error=None):
self.setItem(i, 2, new_item)
tag_item.setText(display_tag_name(name))
self.set_item_value(orig_item, self.tag_diff.orig, name)
- if name == "~length":
+ if name == '~length':
new_item.setFlags(orig_flags)
else:
new_item.setFlags(new_flags)
@@ -723,7 +723,7 @@ def set_item_value(self, item, tags, name):
@restore_method
def restore_state(self):
config = get_config()
- state = config.persist["metadatabox_header_state"]
+ state = config.persist['metadatabox_header_state']
header = self.horizontalHeader()
header.restoreState(state)
header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeMode.Interactive)
@@ -732,4 +732,4 @@ def save_state(self):
config = get_config()
header = self.horizontalHeader()
state = header.saveState()
- config.persist["metadatabox_header_state"] = state
+ config.persist['metadatabox_header_state'] = state
diff --git a/picard/ui/options/advanced.py b/picard/ui/options/advanced.py
index 35cb862f35..8052e6f0f0 100644
--- a/picard/ui/options/advanced.py
+++ b/picard/ui/options/advanced.py
@@ -40,24 +40,24 @@
class AdvancedOptionsPage(OptionsPage):
- NAME = "advanced"
+ NAME = 'advanced'
TITLE = N_("Advanced")
PARENT = None
SORT_ORDER = 90
ACTIVE = True
- HELP_URL = '/config/options_advanced.html'
+ HELP_URL = "/config/options_advanced.html"
options = [
- TextOption("setting", "ignore_regex", ""),
- BoolOption("setting", "ignore_hidden_files", False),
- BoolOption("setting", "recursively_add_files", True),
- IntOption("setting", "ignore_track_duration_difference_under", 2),
- IntOption("setting", "query_limit", QUERY_LIMIT),
- BoolOption("setting", "completeness_ignore_videos", False),
- BoolOption("setting", "completeness_ignore_pregap", False),
- BoolOption("setting", "completeness_ignore_data", False),
- BoolOption("setting", "completeness_ignore_silence", False),
- ListOption("setting", "compare_ignore_tags", []),
+ TextOption('setting', 'ignore_regex', ''),
+ BoolOption('setting', 'ignore_hidden_files', False),
+ BoolOption('setting', 'recursively_add_files', True),
+ IntOption('setting', 'ignore_track_duration_difference_under', 2),
+ IntOption('setting', 'query_limit', QUERY_LIMIT),
+ BoolOption('setting', 'completeness_ignore_videos', False),
+ BoolOption('setting', 'completeness_ignore_pregap', False),
+ BoolOption('setting', 'completeness_ignore_data', False),
+ BoolOption('setting', 'completeness_ignore_silence', False),
+ ListOption('setting', 'compare_ignore_tags', []),
]
def __init__(self, parent=None):
@@ -68,32 +68,32 @@ def __init__(self, parent=None):
def load(self):
config = get_config()
- self.ui.ignore_regex.setText(config.setting["ignore_regex"])
- self.ui.ignore_hidden_files.setChecked(config.setting["ignore_hidden_files"])
- self.ui.recursively_add_files.setChecked(config.setting["recursively_add_files"])
- self.ui.ignore_track_duration_difference_under.setValue(config.setting["ignore_track_duration_difference_under"])
- self.ui.query_limit.setCurrentText(str(config.setting["query_limit"]))
- self.ui.completeness_ignore_videos.setChecked(config.setting["completeness_ignore_videos"])
- self.ui.completeness_ignore_pregap.setChecked(config.setting["completeness_ignore_pregap"])
- self.ui.completeness_ignore_data.setChecked(config.setting["completeness_ignore_data"])
- self.ui.completeness_ignore_silence.setChecked(config.setting["completeness_ignore_silence"])
- self.ui.compare_ignore_tags.update(config.setting["compare_ignore_tags"])
+ self.ui.ignore_regex.setText(config.setting['ignore_regex'])
+ self.ui.ignore_hidden_files.setChecked(config.setting['ignore_hidden_files'])
+ self.ui.recursively_add_files.setChecked(config.setting['recursively_add_files'])
+ self.ui.ignore_track_duration_difference_under.setValue(config.setting['ignore_track_duration_difference_under'])
+ self.ui.query_limit.setCurrentText(str(config.setting['query_limit']))
+ self.ui.completeness_ignore_videos.setChecked(config.setting['completeness_ignore_videos'])
+ self.ui.completeness_ignore_pregap.setChecked(config.setting['completeness_ignore_pregap'])
+ self.ui.completeness_ignore_data.setChecked(config.setting['completeness_ignore_data'])
+ self.ui.completeness_ignore_silence.setChecked(config.setting['completeness_ignore_silence'])
+ self.ui.compare_ignore_tags.update(config.setting['compare_ignore_tags'])
self.ui.compare_ignore_tags.set_user_sortable(False)
def save(self):
config = get_config()
- config.setting["ignore_regex"] = self.ui.ignore_regex.text()
- config.setting["ignore_hidden_files"] = self.ui.ignore_hidden_files.isChecked()
- config.setting["recursively_add_files"] = self.ui.recursively_add_files.isChecked()
- config.setting["ignore_track_duration_difference_under"] = self.ui.ignore_track_duration_difference_under.value()
- config.setting["query_limit"] = self.ui.query_limit.currentText()
- config.setting["completeness_ignore_videos"] = self.ui.completeness_ignore_videos.isChecked()
- config.setting["completeness_ignore_pregap"] = self.ui.completeness_ignore_pregap.isChecked()
- config.setting["completeness_ignore_data"] = self.ui.completeness_ignore_data.isChecked()
- config.setting["completeness_ignore_silence"] = self.ui.completeness_ignore_silence.isChecked()
+ config.setting['ignore_regex'] = self.ui.ignore_regex.text()
+ config.setting['ignore_hidden_files'] = self.ui.ignore_hidden_files.isChecked()
+ config.setting['recursively_add_files'] = self.ui.recursively_add_files.isChecked()
+ config.setting['ignore_track_duration_difference_under'] = self.ui.ignore_track_duration_difference_under.value()
+ config.setting['query_limit'] = self.ui.query_limit.currentText()
+ config.setting['completeness_ignore_videos'] = self.ui.completeness_ignore_videos.isChecked()
+ config.setting['completeness_ignore_pregap'] = self.ui.completeness_ignore_pregap.isChecked()
+ config.setting['completeness_ignore_data'] = self.ui.completeness_ignore_data.isChecked()
+ config.setting['completeness_ignore_silence'] = self.ui.completeness_ignore_silence.isChecked()
tags = list(self.ui.compare_ignore_tags.tags)
- if tags != config.setting["compare_ignore_tags"]:
- config.setting["compare_ignore_tags"] = tags
+ if tags != config.setting['compare_ignore_tags']:
+ config.setting['compare_ignore_tags'] = tags
def restore_defaults(self):
self.ui.compare_ignore_tags.clear()
diff --git a/picard/ui/options/cdlookup.py b/picard/ui/options/cdlookup.py
index 556b0d2aba..253d53ec8e 100644
--- a/picard/ui/options/cdlookup.py
+++ b/picard/ui/options/cdlookup.py
@@ -48,15 +48,15 @@
class CDLookupOptionsPage(OptionsPage):
- NAME = "cdlookup"
+ NAME = 'cdlookup'
TITLE = N_("CD Lookup")
PARENT = None
SORT_ORDER = 50
ACTIVE = True
- HELP_URL = '/config/options_cdlookup.html'
+ HELP_URL = "/config/options_cdlookup.html"
options = [
- TextOption("setting", "cd_lookup_device", ",".join(DEFAULT_DRIVES)),
+ TextOption('setting', 'cd_lookup_device', ','.join(DEFAULT_DRIVES)),
]
def __init__(self, parent=None):
@@ -69,7 +69,7 @@ def __init__(self, parent=None):
def load(self):
config = get_config()
- device = config.setting["cd_lookup_device"]
+ device = config.setting['cd_lookup_device']
if AUTO_DETECT_DRIVES:
try:
self.ui.cd_lookup_device.setCurrentIndex(self._device_list.index(device))
@@ -86,7 +86,7 @@ def save(self):
else:
device = self.ui.cd_lookup_device.text()
device_list = [device]
- config.setting["cd_lookup_device"] = device
+ config.setting['cd_lookup_device'] = device
self.tagger.window.update_cd_lookup_drives(device_list)
diff --git a/picard/ui/options/cover.py b/picard/ui/options/cover.py
index d38a9cb42b..862c037e33 100644
--- a/picard/ui/options/cover.py
+++ b/picard/ui/options/cover.py
@@ -48,22 +48,22 @@
class CoverOptionsPage(OptionsPage):
- NAME = "cover"
+ NAME = 'cover'
TITLE = N_("Cover Art")
PARENT = None
SORT_ORDER = 35
ACTIVE = True
- HELP_URL = '/config/options_cover.html'
+ HELP_URL = "/config/options_cover.html"
options = [
- BoolOption("setting", "save_images_to_tags", True),
- BoolOption("setting", "embed_only_one_front_image", True),
- BoolOption("setting", "save_images_to_files", False),
- TextOption("setting", "cover_image_filename", DEFAULT_COVER_IMAGE_FILENAME),
- 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", [
+ BoolOption('setting', 'save_images_to_tags', True),
+ BoolOption('setting', 'embed_only_one_front_image', True),
+ BoolOption('setting', 'save_images_to_files', False),
+ TextOption('setting', 'cover_image_filename', DEFAULT_COVER_IMAGE_FILENAME),
+ 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),
('CaaReleaseGroup', True),
@@ -97,13 +97,13 @@ def _load_cover_art_providers(self):
def load(self):
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.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.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.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_ca_providers_groupbox_state()
@@ -114,14 +114,14 @@ def _ca_providers(self):
def save(self):
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["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"] = list(self._ca_providers())
+ 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['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'] = list(self._ca_providers())
def update_ca_providers_groupbox_state(self):
files_enabled = self.ui.save_images_to_files.isChecked()
diff --git a/picard/ui/options/dialog.py b/picard/ui/options/dialog.py
index 9ef978bbfd..c73b20da95 100644
--- a/picard/ui/options/dialog.py
+++ b/picard/ui/options/dialog.py
@@ -92,8 +92,8 @@
class OptionsDialog(PicardDialog, SingletonDialog):
options = [
- TextOption("persist", "options_last_active_page", ""),
- ListOption("persist", "options_pages_tree_state", []),
+ TextOption('persist', 'options_last_active_page', ''),
+ ListOption('persist', 'options_pages_tree_state', []),
]
suspend_signals = False
@@ -159,12 +159,12 @@ def __init__(self, default_page=None, parent=None):
page.set_dialog(self)
self.pages.append(page)
except Exception:
- log.exception('Failed initializing options page %r', Page)
+ log.exception("Failed initializing options page %r", Page)
self.item_to_page = {}
self.page_to_item = {}
self.default_item = None
if not default_page:
- default_page = config.persist["options_last_active_page"]
+ default_page = config.persist['options_last_active_page']
self.add_pages(None, default_page, self.ui.pages_tree)
# work-around to set optimal option pane width
@@ -200,7 +200,7 @@ def load_all_pages(self):
try:
page.load()
except Exception:
- log.exception('Failed loading options page %r', page)
+ log.exception("Failed loading options page %r", page)
self.disable_page(page.NAME)
def page_has_profile_options(self, page):
@@ -241,8 +241,8 @@ def show_attached_profiles_dialog(self):
def _get_profile_title_from_id(self, profile_id):
config = get_config()
for item in config.profiles[SettingConfigSection.PROFILES_KEY]:
- if item["id"] == profile_id:
- return item["title"]
+ if item['id'] == profile_id:
+ return item['title']
return _('Unknown profile')
def update_from_profile_changes(self):
@@ -285,9 +285,9 @@ def _check_and_highlight_option(self, obj, option_name, working_profiles, workin
obj.setStyleSheet(None)
obj.setToolTip(None)
for item in working_profiles:
- if item["enabled"]:
- profile_id = item["id"]
- profile_title = item["title"]
+ if item['enabled']:
+ profile_id = item['id']
+ profile_title = item['title']
if profile_id in working_settings:
profile_settings = working_settings[profile_id]
else:
@@ -325,7 +325,7 @@ def page_has_attached_profiles(self, page, enabled_profiles_only=False):
for item in working_profiles:
if enabled_profiles_only and not item["enabled"]:
continue
- profile_id = item["id"]
+ profile_id = item['id']
if opt.name in working_settings[profile_id]:
return True
return False
@@ -342,7 +342,7 @@ def switch_page(self):
if items:
config = get_config()
page = self.item_to_page[items[0]]
- config.persist["options_last_active_page"] = page.NAME
+ config.persist['options_last_active_page'] = page.NAME
self.set_profiles_button_and_highlight(page)
def disable_page(self, name):
@@ -369,7 +369,7 @@ def accept(self):
self._show_page_error(page, e)
return
except Exception as e:
- log.exception('Failed checking options page %r', page)
+ log.exception("Failed checking options page %r", page)
self._show_page_error(page, e)
return
self.profile_page.save()
@@ -378,14 +378,14 @@ def accept(self):
if page != self.profile_page:
page.save()
except Exception as e:
- log.exception('Failed saving options page %r', page)
+ log.exception("Failed saving options page %r", page)
self._show_page_error(page, e)
return
super().accept()
def _show_page_error(self, page, error):
if not isinstance(error, OptionsCheckError):
- error = OptionsCheckError(_('Unexpected error'), str(error))
+ error = OptionsCheckError(_("Unexpected error"), str(error))
self.ui.pages_tree.setCurrentItem(self.page_to_item[page.NAME])
page.display_error(error)
@@ -396,14 +396,14 @@ def saveWindowState(self):
is_expanded = self.ui.pages_tree.isExpanded(index)
expanded_pages.append((page, is_expanded))
config = get_config()
- config.persist["options_pages_tree_state"] = expanded_pages
+ config.persist['options_pages_tree_state'] = expanded_pages
config.setting.set_profiles_override()
config.setting.set_settings_override()
@restore_method
def restoreWindowState(self):
config = get_config()
- pages_tree_state = config.persist["options_pages_tree_state"]
+ pages_tree_state = config.persist['options_pages_tree_state']
if not pages_tree_state:
self.ui.pages_tree.expandAll()
else:
@@ -420,7 +420,7 @@ def restore_all_defaults(self):
try:
page.restore_defaults()
except Exception as e:
- log.error('Failed restoring all defaults for page %r: %s', page, e)
+ log.error("Failed restoring all defaults for page %r: %s", page, e)
self.highlight_enabled_profile_options(load_settings=False)
self.suspend_signals = False
@@ -449,7 +449,7 @@ def _show_dialog(self, msg, function):
class AttachedProfilesDialog(PicardDialog):
NAME = 'attachedprofiles'
- TITLE = N_('Attached Profiles')
+ TITLE = N_("Attached Profiles")
def __init__(self, parent=None, option_group=None, override_profiles=None, override_settings=None):
super().__init__(parent=parent)
@@ -479,8 +479,8 @@ def populate_table(self):
model.setHorizontalHeaderLabels(header_names)
group = UserProfileGroups.SETTINGS_GROUPS[self.option_group]
- group_title = group["title"]
- group_options = group["settings"]
+ group_title = group['title']
+ group_options = group['settings']
window_title = _("Profiles Attached to Options in %s Section") % group_title
self.setWindowTitle(window_title)
@@ -491,8 +491,8 @@ def populate_table(self):
row = [option_item]
attached = []
for profile in self.profiles:
- if name in self.settings[profile["id"]]:
- attached.append("{0}{1}".format(profile["title"], _(" [Enabled]") if profile["enabled"] else "",))
+ if name in self.settings[profile['id']]:
+ attached.append("{0}{1}".format(profile['title'], _(" [Enabled]") if profile['enabled'] else "",))
attached_profiles = "\n".join(attached) if attached else _("None")
profile_item = QtGui.QStandardItem(attached_profiles)
profile_item.setEditable(False)
diff --git a/picard/ui/options/fingerprinting.py b/picard/ui/options/fingerprinting.py
index 719974c327..c84b727d89 100644
--- a/picard/ui/options/fingerprinting.py
+++ b/picard/ui/options/fingerprinting.py
@@ -59,20 +59,20 @@ def validate(self, input, pos):
class FingerprintingOptionsPage(OptionsPage):
- NAME = "fingerprinting"
+ NAME = 'fingerprinting'
TITLE = N_("Fingerprinting")
PARENT = None
SORT_ORDER = 45
ACTIVE = True
- HELP_URL = '/config/options_fingerprinting.html'
+ HELP_URL = "/config/options_fingerprinting.html"
options = [
- BoolOption("setting", "ignore_existing_acoustid_fingerprints", False),
- BoolOption("setting", "save_acoustid_fingerprints", False),
- TextOption("setting", "fingerprinting_system", "acoustid"),
- TextOption("setting", "acoustid_fpcalc", ""),
- TextOption("setting", "acoustid_apikey", ""),
- IntOption("setting", "fpcalc_threads", DEFAULT_FPCALC_THREADS),
+ BoolOption('setting', 'ignore_existing_acoustid_fingerprints', False),
+ BoolOption('setting', 'save_acoustid_fingerprints', False),
+ TextOption('setting', 'fingerprinting_system', 'acoustid'),
+ TextOption('setting', 'acoustid_fpcalc', ''),
+ TextOption('setting', 'acoustid_apikey', ''),
+ IntOption('setting', 'fpcalc_threads', DEFAULT_FPCALC_THREADS),
]
def __init__(self, parent=None):
@@ -90,29 +90,29 @@ def __init__(self, parent=None):
def load(self):
config = get_config()
- if config.setting["fingerprinting_system"] == "acoustid":
+ if config.setting['fingerprinting_system'] == 'acoustid':
self.ui.use_acoustid.setChecked(True)
else:
self.ui.disable_fingerprinting.setChecked(True)
self.ui.acoustid_fpcalc.setPlaceholderText(find_fpcalc())
- self.ui.acoustid_fpcalc.setText(config.setting["acoustid_fpcalc"])
- self.ui.acoustid_apikey.setText(config.setting["acoustid_apikey"])
- self.ui.ignore_existing_acoustid_fingerprints.setChecked(config.setting["ignore_existing_acoustid_fingerprints"])
- self.ui.save_acoustid_fingerprints.setChecked(config.setting["save_acoustid_fingerprints"])
- self.ui.fpcalc_threads.setValue(config.setting["fpcalc_threads"])
+ self.ui.acoustid_fpcalc.setText(config.setting['acoustid_fpcalc'])
+ self.ui.acoustid_apikey.setText(config.setting['acoustid_apikey'])
+ self.ui.ignore_existing_acoustid_fingerprints.setChecked(config.setting['ignore_existing_acoustid_fingerprints'])
+ self.ui.save_acoustid_fingerprints.setChecked(config.setting['save_acoustid_fingerprints'])
+ self.ui.fpcalc_threads.setValue(config.setting['fpcalc_threads'])
self.update_groupboxes()
def save(self):
config = get_config()
if self.ui.use_acoustid.isChecked():
- config.setting["fingerprinting_system"] = "acoustid"
+ config.setting['fingerprinting_system'] = 'acoustid'
else:
- config.setting["fingerprinting_system"] = ""
- config.setting["acoustid_fpcalc"] = self.ui.acoustid_fpcalc.text()
- config.setting["acoustid_apikey"] = self.ui.acoustid_apikey.text()
- config.setting["ignore_existing_acoustid_fingerprints"] = self.ui.ignore_existing_acoustid_fingerprints.isChecked()
- config.setting["save_acoustid_fingerprints"] = self.ui.save_acoustid_fingerprints.isChecked()
- config.setting["fpcalc_threads"] = self.ui.fpcalc_threads.value()
+ config.setting['fingerprinting_system'] = ''
+ config.setting['acoustid_fpcalc'] = self.ui.acoustid_fpcalc.text()
+ config.setting['acoustid_apikey'] = self.ui.acoustid_apikey.text()
+ config.setting['ignore_existing_acoustid_fingerprints'] = self.ui.ignore_existing_acoustid_fingerprints.isChecked()
+ config.setting['save_acoustid_fingerprints'] = self.ui.save_acoustid_fingerprints.isChecked()
+ config.setting['fpcalc_threads'] = self.ui.fpcalc_threads.value()
def update_groupboxes(self):
if self.ui.use_acoustid.isChecked():
diff --git a/picard/ui/options/general.py b/picard/ui/options/general.py
index eeb64ba427..f358ce6b32 100644
--- a/picard/ui/options/general.py
+++ b/picard/ui/options/general.py
@@ -52,30 +52,30 @@
class GeneralOptionsPage(OptionsPage):
- NAME = "general"
+ NAME = 'general'
TITLE = N_("General")
PARENT = None
SORT_ORDER = 1
ACTIVE = True
- HELP_URL = '/config/options_general.html'
+ HELP_URL = "/config/options_general.html"
options = [
- TextOption("setting", "server_host", MUSICBRAINZ_SERVERS[0]),
- IntOption("setting", "server_port", 443),
- BoolOption("setting", "use_server_for_submission", False),
- BoolOption("setting", "analyze_new_files", False),
- BoolOption("setting", "cluster_new_files", False),
- BoolOption("setting", "ignore_file_mbids", False),
- TextOption("persist", "oauth_refresh_token", ""),
- TextOption("persist", "oauth_refresh_token_scopes", ""),
- TextOption("persist", "oauth_access_token", ""),
- IntOption("persist", "oauth_access_token_expires", 0),
- TextOption("persist", "oauth_username", ""),
- BoolOption("setting", "check_for_updates", True),
- IntOption("setting", "update_check_days", 7),
- IntOption("setting", "update_level", DEFAULT_PROGRAM_UPDATE_LEVEL),
- IntOption("persist", "last_update_check", 0),
- BoolOption("setting", "check_for_plugin_updates", False),
+ TextOption('setting', 'server_host', MUSICBRAINZ_SERVERS[0]),
+ IntOption('setting', 'server_port', 443),
+ BoolOption('setting', 'use_server_for_submission', False),
+ BoolOption('setting', 'analyze_new_files', False),
+ BoolOption('setting', 'cluster_new_files', False),
+ BoolOption('setting', 'ignore_file_mbids', False),
+ TextOption('persist', 'oauth_refresh_token', ''),
+ TextOption('persist', 'oauth_refresh_token_scopes', ''),
+ TextOption('persist', 'oauth_access_token', ''),
+ IntOption('persist', 'oauth_access_token_expires', 0),
+ TextOption('persist', 'oauth_username', ''),
+ BoolOption('setting', 'check_for_updates', True),
+ IntOption('setting', 'update_check_days', 7),
+ IntOption('setting', 'update_level', DEFAULT_PROGRAM_UPDATE_LEVEL),
+ IntOption('persist', 'last_update_check', 0),
+ BoolOption('setting', 'check_for_plugin_updates', False),
]
def __init__(self, parent=None):
@@ -94,17 +94,17 @@ def __init__(self, parent=None):
def load(self):
config = get_config()
- self.ui.server_host.setEditText(config.setting["server_host"])
- self.ui.server_port.setValue(config.setting["server_port"])
- self.ui.use_server_for_submission.setChecked(config.setting["use_server_for_submission"])
+ self.ui.server_host.setEditText(config.setting['server_host'])
+ self.ui.server_port.setValue(config.setting['server_port'])
+ self.ui.use_server_for_submission.setChecked(config.setting['use_server_for_submission'])
self.update_server_host()
- self.ui.analyze_new_files.setChecked(config.setting["analyze_new_files"])
- self.ui.cluster_new_files.setChecked(config.setting["cluster_new_files"])
- self.ui.ignore_file_mbids.setChecked(config.setting["ignore_file_mbids"])
- self.ui.check_for_plugin_updates.setChecked(config.setting["check_for_plugin_updates"])
- self.ui.check_for_updates.setChecked(config.setting["check_for_updates"])
- self.set_update_level(config.setting["update_level"])
- self.ui.update_check_days.setValue(config.setting["update_check_days"])
+ self.ui.analyze_new_files.setChecked(config.setting['analyze_new_files'])
+ self.ui.cluster_new_files.setChecked(config.setting['cluster_new_files'])
+ self.ui.ignore_file_mbids.setChecked(config.setting['ignore_file_mbids'])
+ self.ui.check_for_plugin_updates.setChecked(config.setting['check_for_plugin_updates'])
+ self.ui.check_for_updates.setChecked(config.setting['check_for_updates'])
+ self.set_update_level(config.setting['update_level'])
+ self.ui.update_check_days.setValue(config.setting['update_check_days'])
if not self.tagger.autoupdate_enabled:
self.ui.program_update_check_group.hide()
@@ -123,16 +123,16 @@ def set_update_level(self, value):
def save(self):
config = get_config()
- config.setting["server_host"] = self.ui.server_host.currentText().strip()
- config.setting["server_port"] = self.ui.server_port.value()
- config.setting["use_server_for_submission"] = self.ui.use_server_for_submission.isChecked()
- config.setting["analyze_new_files"] = self.ui.analyze_new_files.isChecked()
- config.setting["cluster_new_files"] = self.ui.cluster_new_files.isChecked()
- config.setting["ignore_file_mbids"] = self.ui.ignore_file_mbids.isChecked()
- config.setting["check_for_plugin_updates"] = self.ui.check_for_plugin_updates.isChecked()
- config.setting["check_for_updates"] = self.ui.check_for_updates.isChecked()
- config.setting["update_level"] = self.ui.update_level.currentData(QtCore.Qt.ItemDataRole.UserRole)
- config.setting["update_check_days"] = self.ui.update_check_days.value()
+ config.setting['server_host'] = self.ui.server_host.currentText().strip()
+ config.setting['server_port'] = self.ui.server_port.value()
+ config.setting['use_server_for_submission'] = self.ui.use_server_for_submission.isChecked()
+ config.setting['analyze_new_files'] = self.ui.analyze_new_files.isChecked()
+ config.setting['cluster_new_files'] = self.ui.cluster_new_files.isChecked()
+ config.setting['ignore_file_mbids'] = self.ui.ignore_file_mbids.isChecked()
+ config.setting['check_for_plugin_updates'] = self.ui.check_for_plugin_updates.isChecked()
+ config.setting['check_for_updates'] = self.ui.check_for_updates.isChecked()
+ config.setting['update_level'] = self.ui.update_level.currentData(QtCore.Qt.ItemDataRole.UserRole)
+ config.setting['update_check_days'] = self.ui.update_check_days.value()
def update_server_host(self):
host = self.ui.server_host.currentText().strip()
@@ -146,14 +146,14 @@ def update_login_logout(self, error_msg=None):
return
if self.tagger.webservice.oauth_manager.is_logged_in():
config = get_config()
- self.ui.logged_in.setText(_("Logged in as %s.") % config.persist["oauth_username"])
+ self.ui.logged_in.setText(_("Logged in as %s.") % config.persist['oauth_username'])
self.ui.logged_in.show()
self.ui.login_error.hide()
self.ui.login.hide()
self.ui.logout.show()
elif error_msg:
self.ui.logged_in.hide()
- self.ui.login_error.setText(_('Login failed: %s') % error_msg)
+ self.ui.login_error.setText(_("Login failed: %s") % error_msg)
self.ui.login_error.show()
self.ui.login.show()
self.ui.logout.hide()
diff --git a/picard/ui/options/genres.py b/picard/ui/options/genres.py
index 2ca99ceeaa..629b8c3427 100644
--- a/picard/ui/options/genres.py
+++ b/picard/ui/options/genres.py
@@ -83,22 +83,22 @@
class GenresOptionsPage(OptionsPage):
- NAME = "genres"
+ NAME = 'genres'
TITLE = N_("Genres")
- PARENT = "metadata"
+ PARENT = 'metadata'
SORT_ORDER = 20
ACTIVE = True
- HELP_URL = '/config/options_genres.html'
+ HELP_URL = "/config/options_genres.html"
options = [
- BoolOption("setting", "use_genres", False),
- IntOption("setting", "max_genres", 5),
- IntOption("setting", "min_genre_usage", 90),
- TextOption("setting", "genres_filter", "-seen live\n-favorites\n-fixme\n-owned"),
- TextOption("setting", "join_genres", ""),
- BoolOption("setting", "only_my_genres", False),
- BoolOption("setting", "artists_genres", False),
- BoolOption("setting", "folksonomy_tags", False),
+ BoolOption('setting', 'use_genres', False),
+ IntOption('setting', 'max_genres', 5),
+ IntOption('setting', 'min_genre_usage', 90),
+ TextOption('setting', 'genres_filter', '-seen live\n-favorites\n-fixme\n-owned'),
+ TextOption('setting', 'join_genres', ''),
+ BoolOption('setting', 'only_my_genres', False),
+ BoolOption('setting', 'artists_genres', False),
+ BoolOption('setting', 'folksonomy_tags', False),
]
def __init__(self, parent=None):
@@ -124,7 +124,7 @@ def __init__(self, parent=None):
def load(self):
config = get_config()
- self.ui.use_genres.setChecked(config.setting["use_genres"])
+ self.ui.use_genres.setChecked(config.setting['use_genres'])
self.ui.max_genres.setValue(config.setting["max_genres"])
self.ui.min_genre_usage.setValue(config.setting["min_genre_usage"])
self.ui.join_genres.setEditText(config.setting["join_genres"])
@@ -135,14 +135,14 @@ def load(self):
def save(self):
config = get_config()
- config.setting["use_genres"] = self.ui.use_genres.isChecked()
- config.setting["max_genres"] = self.ui.max_genres.value()
- config.setting["min_genre_usage"] = self.ui.min_genre_usage.value()
- config.setting["join_genres"] = self.ui.join_genres.currentText()
- config.setting["genres_filter"] = self.ui.genres_filter.toPlainText()
- config.setting["only_my_genres"] = self.ui.only_my_genres.isChecked()
- config.setting["artists_genres"] = self.ui.artists_genres.isChecked()
- config.setting["folksonomy_tags"] = self.ui.folksonomy_tags.isChecked()
+ config.setting['use_genres'] = self.ui.use_genres.isChecked()
+ config.setting['max_genres'] = self.ui.max_genres.value()
+ config.setting['min_genre_usage'] = self.ui.min_genre_usage.value()
+ config.setting['join_genres'] = self.ui.join_genres.currentText()
+ config.setting['genres_filter'] = self.ui.genres_filter.toPlainText()
+ config.setting['only_my_genres'] = self.ui.only_my_genres.isChecked()
+ config.setting['artists_genres'] = self.ui.artists_genres.isChecked()
+ config.setting['folksonomy_tags'] = self.ui.folksonomy_tags.isChecked()
def update_test_genres_filter(self):
test_text = self.ui.test_genres_filter.toPlainText()
diff --git a/picard/ui/options/interface.py b/picard/ui/options/interface.py
index 3527b9dc64..1ddb50bab5 100644
--- a/picard/ui/options/interface.py
+++ b/picard/ui/options/interface.py
@@ -63,47 +63,47 @@
class InterfaceOptionsPage(OptionsPage):
- NAME = "interface"
+ NAME = 'interface'
TITLE = N_("User Interface")
PARENT = None
SORT_ORDER = 80
ACTIVE = True
- HELP_URL = '/config/options_interface.html'
+ HELP_URL = "/config/options_interface.html"
options = [
- BoolOption("setting", "toolbar_show_labels", True),
- BoolOption("setting", "toolbar_multiselect", False),
- BoolOption("setting", "show_menu_icons", True if not IS_MACOS else False), # On macOS it is not common that the global menu shows icons
- BoolOption("setting", "builtin_search", True),
- BoolOption("setting", "use_adv_search_syntax", False),
- BoolOption("setting", "show_new_user_dialog", True),
- BoolOption("setting", "quit_confirmation", True),
- BoolOption("setting", "file_save_warning", True),
- TextOption("setting", "ui_language", ""),
- TextOption("setting", "ui_theme", str(UiTheme.DEFAULT)),
- BoolOption("setting", "filebrowser_horizontal_autoscroll", True),
- BoolOption("setting", "starting_directory", False),
- TextOption("setting", "starting_directory_path", _default_starting_dir),
- TextOption("setting", "load_image_behavior", "append"),
+ BoolOption('setting', 'toolbar_show_labels', True),
+ BoolOption('setting', 'toolbar_multiselect', False),
+ BoolOption('setting', 'show_menu_icons', True if not IS_MACOS else False), # On macOS it is not common that the global menu shows icons
+ BoolOption('setting', 'builtin_search', True),
+ BoolOption('setting', 'use_adv_search_syntax', False),
+ BoolOption('setting', 'show_new_user_dialog', True),
+ BoolOption('setting', 'quit_confirmation', True),
+ BoolOption('setting', 'file_save_warning', True),
+ TextOption('setting', 'ui_language', ''),
+ TextOption('setting', 'ui_theme', str(UiTheme.DEFAULT)),
+ BoolOption('setting', 'filebrowser_horizontal_autoscroll', True),
+ BoolOption('setting', 'starting_directory', False),
+ TextOption('setting', 'starting_directory_path', _default_starting_dir),
+ TextOption('setting', 'load_image_behavior', 'append'),
]
# Those are labels for theme display
_UI_THEME_LABELS = {
UiTheme.DEFAULT: {
- 'label': N_('Default'),
- 'desc': N_('The default color scheme based on the operating system display settings'),
+ 'label': N_("Default"),
+ 'desc': N_("The default color scheme based on the operating system display settings"),
},
UiTheme.DARK: {
- 'label': N_('Dark'),
- 'desc': N_('A dark display theme'),
+ 'label': N_("Dark"),
+ 'desc': N_("A dark display theme"),
},
UiTheme.LIGHT: {
- 'label': N_('Light'),
- 'desc': N_('A light display theme'),
+ 'label': N_("Light"),
+ 'desc': N_("A light display theme"),
},
UiTheme.SYSTEM: {
- 'label': N_('System'),
- 'desc': N_('The Qt5 theme configured in the desktop environment'),
+ 'label': N_("System"),
+ 'desc': N_("The Qt5 theme configured in the desktop environment"),
},
}
@@ -121,7 +121,7 @@ def __init__(self, parent=None):
self.ui.ui_theme.setItemData(idx, _(desc), QtCore.Qt.ItemDataRole.ToolTipRole)
self.ui.ui_theme.setCurrentIndex(self.ui.ui_theme.findData(UiTheme.DEFAULT))
- self.ui.ui_language.addItem(_('System default'), '')
+ self.ui.ui_language.addItem(_("System default"), '')
language_list = [(lang[0], lang[1], gettext_constants(lang[2])) for lang in UI_LANGUAGES]
def fcmp(x):
@@ -145,48 +145,48 @@ def fcmp(x):
def load(self):
config = get_config()
- self.ui.toolbar_show_labels.setChecked(config.setting["toolbar_show_labels"])
- self.ui.toolbar_multiselect.setChecked(config.setting["toolbar_multiselect"])
- self.ui.show_menu_icons.setChecked(config.setting["show_menu_icons"])
- self.ui.builtin_search.setChecked(config.setting["builtin_search"])
- self.ui.use_adv_search_syntax.setChecked(config.setting["use_adv_search_syntax"])
- self.ui.new_user_dialog.setChecked(config.setting["show_new_user_dialog"])
- self.ui.quit_confirmation.setChecked(config.setting["quit_confirmation"])
- self.ui.file_save_warning.setChecked(config.setting["file_save_warning"])
- current_ui_language = config.setting["ui_language"]
+ self.ui.toolbar_show_labels.setChecked(config.setting['toolbar_show_labels'])
+ self.ui.toolbar_multiselect.setChecked(config.setting['toolbar_multiselect'])
+ self.ui.show_menu_icons.setChecked(config.setting['show_menu_icons'])
+ self.ui.builtin_search.setChecked(config.setting['builtin_search'])
+ self.ui.use_adv_search_syntax.setChecked(config.setting['use_adv_search_syntax'])
+ self.ui.new_user_dialog.setChecked(config.setting['show_new_user_dialog'])
+ self.ui.quit_confirmation.setChecked(config.setting['quit_confirmation'])
+ self.ui.file_save_warning.setChecked(config.setting['file_save_warning'])
+ current_ui_language = config.setting['ui_language']
self.ui.ui_language.setCurrentIndex(self.ui.ui_language.findData(current_ui_language))
- self.ui.filebrowser_horizontal_autoscroll.setChecked(config.setting["filebrowser_horizontal_autoscroll"])
- self.ui.starting_directory.setChecked(config.setting["starting_directory"])
- self.ui.starting_directory_path.setText(config.setting["starting_directory_path"])
- current_theme = UiTheme(config.setting["ui_theme"])
+ self.ui.filebrowser_horizontal_autoscroll.setChecked(config.setting['filebrowser_horizontal_autoscroll'])
+ self.ui.starting_directory.setChecked(config.setting['starting_directory'])
+ self.ui.starting_directory_path.setText(config.setting['starting_directory_path'])
+ current_theme = UiTheme(config.setting['ui_theme'])
self.ui.ui_theme.setCurrentIndex(self.ui.ui_theme.findData(current_theme))
def save(self):
config = get_config()
- config.setting["toolbar_show_labels"] = self.ui.toolbar_show_labels.isChecked()
- config.setting["toolbar_multiselect"] = self.ui.toolbar_multiselect.isChecked()
- config.setting["show_menu_icons"] = self.ui.show_menu_icons.isChecked()
- self.tagger.enable_menu_icons(config.setting["show_menu_icons"])
- config.setting["builtin_search"] = self.ui.builtin_search.isChecked()
- config.setting["use_adv_search_syntax"] = self.ui.use_adv_search_syntax.isChecked()
- config.setting["show_new_user_dialog"] = self.ui.new_user_dialog.isChecked()
- config.setting["quit_confirmation"] = self.ui.quit_confirmation.isChecked()
- config.setting["file_save_warning"] = self.ui.file_save_warning.isChecked()
+ config.setting['toolbar_show_labels'] = self.ui.toolbar_show_labels.isChecked()
+ config.setting['toolbar_multiselect'] = self.ui.toolbar_multiselect.isChecked()
+ config.setting['show_menu_icons'] = self.ui.show_menu_icons.isChecked()
+ self.tagger.enable_menu_icons(config.setting['show_menu_icons'])
+ config.setting['builtin_search'] = self.ui.builtin_search.isChecked()
+ config.setting['use_adv_search_syntax'] = self.ui.use_adv_search_syntax.isChecked()
+ config.setting['show_new_user_dialog'] = self.ui.new_user_dialog.isChecked()
+ config.setting['quit_confirmation'] = self.ui.quit_confirmation.isChecked()
+ config.setting['file_save_warning'] = self.ui.file_save_warning.isChecked()
self.tagger.window.update_toolbar_style()
new_theme_setting = str(self.ui.ui_theme.itemData(self.ui.ui_theme.currentIndex()))
new_language = self.ui.ui_language.itemData(self.ui.ui_language.currentIndex())
restart_warning = None
- if new_theme_setting != config.setting["ui_theme"]:
- restart_warning_title = _('Theme changed')
- restart_warning = _('You have changed the application theme. You have to restart Picard in order for the change to take effect.')
+ if new_theme_setting != config.setting['ui_theme']:
+ restart_warning_title = _("Theme changed")
+ restart_warning = _("You have changed the application theme. You have to restart Picard in order for the change to take effect.")
if new_theme_setting == str(UiTheme.SYSTEM):
restart_warning += '\n\n' + _(
- 'Please note that using the system theme might cause the user interface to be not shown correctly. '
- 'If this is the case select the "Default" theme option to use Picard\'s default theme again.'
+ "Please note that using the system theme might cause the user interface to be not shown correctly. "
+ "If this is the case select the `Default` theme option to use Picard's default theme again."
)
- elif new_language != config.setting["ui_language"]:
- restart_warning_title = _('Language changed')
- restart_warning = _('You have changed the interface language. You have to restart Picard in order for the change to take effect.')
+ elif new_language != config.setting['ui_language']:
+ restart_warning_title = _("Language changed")
+ restart_warning = _("You have changed the interface language. You have to restart Picard in order for the change to take effect.")
if restart_warning:
dialog = QtWidgets.QMessageBox(
QtWidgets.QMessageBox.Icon.Information,
@@ -195,11 +195,11 @@ def save(self):
QtWidgets.QMessageBox.StandardButton.Ok,
self)
dialog.exec_()
- config.setting["ui_theme"] = new_theme_setting
- config.setting["ui_language"] = self.ui.ui_language.itemData(self.ui.ui_language.currentIndex())
- config.setting["filebrowser_horizontal_autoscroll"] = self.ui.filebrowser_horizontal_autoscroll.isChecked()
- config.setting["starting_directory"] = self.ui.starting_directory.isChecked()
- config.setting["starting_directory_path"] = os.path.normpath(self.ui.starting_directory_path.text())
+ config.setting['ui_theme'] = new_theme_setting
+ config.setting['ui_language'] = self.ui.ui_language.itemData(self.ui.ui_language.currentIndex())
+ config.setting['filebrowser_horizontal_autoscroll'] = self.ui.filebrowser_horizontal_autoscroll.isChecked()
+ config.setting['starting_directory'] = self.ui.starting_directory.isChecked()
+ config.setting['starting_directory_path'] = os.path.normpath(self.ui.starting_directory_path.text())
def starting_directory_browse(self):
item = self.ui.starting_directory_path
diff --git a/picard/ui/options/interface_colors.py b/picard/ui/options/interface_colors.py
index ebace8767a..b92859d553 100644
--- a/picard/ui/options/interface_colors.py
+++ b/picard/ui/options/interface_colors.py
@@ -54,7 +54,7 @@ def __init__(self, initial_color=None, parent=None):
self.setStyle(QtWidgets.QStyleFactory.create('macintosh'))
color = QtGui.QColor(initial_color)
if not color.isValid():
- color = QtGui.QColor("black")
+ color = QtGui.QColor('black')
self.color = color
self.clicked.connect(self.open_color_dialog)
self.update_color()
@@ -88,16 +88,16 @@ def delete_items_of_layout(layout):
class InterfaceColorsOptionsPage(OptionsPage):
- NAME = "interface_colors"
+ NAME = 'interface_colors'
TITLE = N_("Colors")
- PARENT = "interface"
+ PARENT = 'interface'
SORT_ORDER = 30
ACTIVE = True
- HELP_URL = '/config/options_interface_colors.html'
+ HELP_URL = "/config/options_interface_colors.html"
options = [
- Option("setting", "interface_colors", InterfaceColors(dark_theme=False).get_colors()),
- Option("setting", "interface_colors_dark", InterfaceColors(dark_theme=True).get_colors()),
+ Option('setting', 'interface_colors', InterfaceColors(dark_theme=False).get_colors()),
+ Option('setting', 'interface_colors_dark', InterfaceColors(dark_theme=True).get_colors()),
]
def __init__(self, parent=None):
@@ -143,8 +143,8 @@ def save(self):
if interface_colors.save_to_config():
dialog = QtWidgets.QMessageBox(
QtWidgets.QMessageBox.Icon.Information,
- _('Colors changed'),
- _('You have changed the interface colors. You may have to restart Picard in order for the changes to take effect.'),
+ _("Colors changed"),
+ _("You have changed the interface colors. You may have to restart Picard in order for the changes to take effect."),
QtWidgets.QMessageBox.StandardButton.Ok,
self)
dialog.exec_()
diff --git a/picard/ui/options/interface_toolbar.py b/picard/ui/options/interface_toolbar.py
index 43ef69fa7b..26849f17f3 100644
--- a/picard/ui/options/interface_toolbar.py
+++ b/picard/ui/options/interface_toolbar.py
@@ -56,52 +56,52 @@
class InterfaceToolbarOptionsPage(OptionsPage):
- NAME = "interface_toolbar"
+ NAME = 'interface_toolbar'
TITLE = N_("Action Toolbar")
PARENT = 'interface'
SORT_ORDER = 60
ACTIVE = True
- HELP_URL = '/config/options_interface_toolbar.html'
+ HELP_URL = "/config/options_interface_toolbar.html"
SEPARATOR = '—' * 5
TOOLBAR_BUTTONS = {
'add_directory_action': {
- 'label': N_('Add Folder'),
+ 'label': N_("Add Folder"),
'icon': 'folder'
},
'add_files_action': {
- 'label': N_('Add Files'),
+ 'label': N_("Add Files"),
'icon': 'document-open'
},
'cluster_action': {
- 'label': N_('Cluster'),
+ 'label': N_("Cluster"),
'icon': 'picard-cluster'
},
'autotag_action': {
- 'label': N_('Lookup'),
+ 'label': N_("Lookup"),
'icon': 'picard-auto-tag'
},
'analyze_action': {
- 'label': N_('Scan'),
+ 'label': N_("Scan"),
'icon': 'picard-analyze'
},
'browser_lookup_action': {
- 'label': N_('Lookup in Browser'),
+ 'label': N_("Lookup in Browser"),
'icon': 'lookup-musicbrainz'
},
'save_action': {
- 'label': N_('Save'),
+ 'label': N_("Save"),
'icon': 'document-save'
},
'view_info_action': {
- 'label': N_('Info'),
+ 'label': N_("Info"),
'icon': 'picard-edit-tags'
},
'remove_action': {
- 'label': N_('Remove'),
+ 'label': N_("Remove"),
'icon': 'list-remove'
},
'submit_acoustid_action': {
- 'label': N_('Submit AcoustIDs'),
+ 'label': N_("Submit AcoustIDs"),
'icon': 'acoustid-fingerprinter'
},
'generate_fingerprints_action': {
@@ -109,25 +109,25 @@ class InterfaceToolbarOptionsPage(OptionsPage):
'icon': 'fingerprint'
},
'play_file_action': {
- 'label': N_('Open in Player'),
+ 'label': N_("Open in Player"),
'icon': 'play-music'
},
'cd_lookup_action': {
- 'label': N_('Lookup CD…'),
+ 'label': N_("Lookup CD…"),
'icon': 'media-optical'
},
'tags_from_filenames_action': {
- 'label': N_('Parse File Names…'),
+ 'label': N_("Parse File Names…"),
'icon': 'picard-tags-from-filename'
},
'similar_items_search_action': {
- 'label': N_('Similar items'),
+ 'label': N_("Similar items"),
'icon': 'system-search'
},
}
ACTION_NAMES = set(TOOLBAR_BUTTONS.keys())
options = [
- ListOption("setting", "toolbar_layout", [
+ ListOption('setting', 'toolbar_layout', [
'add_directory_action',
'add_files_action',
'separator',
@@ -184,7 +184,7 @@ def _get_icon_from_name(self, name):
def _insert_item(self, action, index=None):
list_item = ToolbarListItem(action)
- list_item.setToolTip(_('Drag and Drop to re-order'))
+ list_item.setToolTip(_("Drag and Drop to re-order"))
if action in self.TOOLBAR_BUTTONS:
# TODO: Remove temporary workaround once https://github.com/python-babel/babel/issues/415 has been resolved.
babel_415_workaround = self.TOOLBAR_BUTTONS[action]['label']
diff --git a/picard/ui/options/interface_top_tags.py b/picard/ui/options/interface_top_tags.py
index 049b9002d4..32a24dd3e9 100644
--- a/picard/ui/options/interface_top_tags.py
+++ b/picard/ui/options/interface_top_tags.py
@@ -36,21 +36,21 @@
class InterfaceTopTagsOptionsPage(OptionsPage):
- NAME = "interface_top_tags"
+ NAME = 'interface_top_tags'
TITLE = N_("Top Tags")
- PARENT = "interface"
+ PARENT = 'interface'
SORT_ORDER = 30
ACTIVE = True
- HELP_URL = '/config/options_interface_top_tags.html'
+ HELP_URL = "/config/options_interface_top_tags.html"
options = [
- ListOption("setting", "metadatabox_top_tags", [
- "title",
- "artist",
- "album",
- "tracknumber",
- "~length",
- "date",
+ ListOption('setting', 'metadatabox_top_tags', [
+ 'title',
+ 'artist',
+ 'album',
+ 'tracknumber',
+ '~length',
+ 'date',
]),
]
@@ -61,14 +61,14 @@ def __init__(self, parent=None):
def load(self):
config = get_config()
- tags = config.setting["metadatabox_top_tags"]
+ tags = config.setting['metadatabox_top_tags']
self.ui.top_tags_list.update(tags)
def save(self):
config = get_config()
tags = list(self.ui.top_tags_list.tags)
- if tags != config.setting["metadatabox_top_tags"]:
- config.setting["metadatabox_top_tags"] = tags
+ if tags != config.setting['metadatabox_top_tags']:
+ config.setting['metadatabox_top_tags'] = tags
self.tagger.window.metadata_box.update()
def restore_defaults(self):
diff --git a/picard/ui/options/maintenance.py b/picard/ui/options/maintenance.py
index 150c480449..f960dd843a 100644
--- a/picard/ui/options/maintenance.py
+++ b/picard/ui/options/maintenance.py
@@ -60,12 +60,12 @@
class MaintenanceOptionsPage(OptionsPage):
- NAME = "maintenance"
+ NAME = 'maintenance'
TITLE = N_("Maintenance")
- PARENT = "advanced"
+ PARENT = 'advanced'
SORT_ORDER = 99
ACTIVE = True
- HELP_URL = '/config/options_maintenance.html'
+ HELP_URL = "/config/options_maintenance.html"
options = []
@@ -117,7 +117,7 @@ def load(self):
current_options = OPTIONS_NOT_IN_PAGES.union(key_options)
# All setting options included in the INI file.
- config.beginGroup("setting")
+ config.beginGroup('setting')
file_options = set(config.childKeys())
config.endGroup()
@@ -249,7 +249,7 @@ def load_backup(self):
filename, file_type = QtWidgets.QFileDialog.getOpenFileName(self, dialog_title, directory, dialog_file_types, options=options)
if not filename:
return
- log.warning('Loading configuration from %s', filename)
+ log.warning("Loading configuration from %s", filename)
if load_new_config(filename):
config = get_config()
upgrade_config(config)
@@ -292,7 +292,7 @@ def save(self):
to_remove = set(self.selected_options())
if to_remove and QtWidgets.QMessageBox.question(
self,
- _('Confirm Remove'),
+ _("Confirm Remove"),
_("Are you sure you want to remove the selected option settings?"),
) == QtWidgets.QMessageBox.StandardButton.Yes:
config = get_config()
diff --git a/picard/ui/options/matching.py b/picard/ui/options/matching.py
index 59cbd4a746..067de0ffad 100644
--- a/picard/ui/options/matching.py
+++ b/picard/ui/options/matching.py
@@ -36,17 +36,17 @@
class MatchingOptionsPage(OptionsPage):
- NAME = "matching"
+ NAME = 'matching'
TITLE = N_("Matching")
- PARENT = "advanced"
+ PARENT = 'advanced'
SORT_ORDER = 30
ACTIVE = True
- HELP_URL = '/config/options_matching.html'
+ HELP_URL = "/config/options_matching.html"
options = [
- FloatOption("setting", "file_lookup_threshold", 0.7),
- FloatOption("setting", "cluster_lookup_threshold", 0.7),
- FloatOption("setting", "track_matching_threshold", 0.4),
+ FloatOption('setting', 'file_lookup_threshold', 0.7),
+ FloatOption('setting', 'cluster_lookup_threshold', 0.7),
+ FloatOption('setting', 'track_matching_threshold', 0.4),
]
_release_type_sliders = {}
@@ -58,15 +58,15 @@ def __init__(self, parent=None):
def load(self):
config = get_config()
- self.ui.file_lookup_threshold.setValue(int(config.setting["file_lookup_threshold"] * 100))
- self.ui.cluster_lookup_threshold.setValue(int(config.setting["cluster_lookup_threshold"] * 100))
- self.ui.track_matching_threshold.setValue(int(config.setting["track_matching_threshold"] * 100))
+ self.ui.file_lookup_threshold.setValue(int(config.setting['file_lookup_threshold'] * 100))
+ self.ui.cluster_lookup_threshold.setValue(int(config.setting['cluster_lookup_threshold'] * 100))
+ self.ui.track_matching_threshold.setValue(int(config.setting['track_matching_threshold'] * 100))
def save(self):
config = get_config()
- config.setting["file_lookup_threshold"] = float(self.ui.file_lookup_threshold.value()) / 100.0
- config.setting["cluster_lookup_threshold"] = float(self.ui.cluster_lookup_threshold.value()) / 100.0
- config.setting["track_matching_threshold"] = float(self.ui.track_matching_threshold.value()) / 100.0
+ config.setting['file_lookup_threshold'] = float(self.ui.file_lookup_threshold.value()) / 100.0
+ config.setting['cluster_lookup_threshold'] = float(self.ui.cluster_lookup_threshold.value()) / 100.0
+ config.setting['track_matching_threshold'] = float(self.ui.track_matching_threshold.value()) / 100.0
register_options_page(MatchingOptionsPage)
diff --git a/picard/ui/options/metadata.py b/picard/ui/options/metadata.py
index 4fbd1d8abf..f6aa3c85e8 100644
--- a/picard/ui/options/metadata.py
+++ b/picard/ui/options/metadata.py
@@ -75,26 +75,26 @@ def iter_sorted_locales(locales):
class MetadataOptionsPage(OptionsPage):
- NAME = "metadata"
+ NAME = 'metadata'
TITLE = N_("Metadata")
PARENT = None
SORT_ORDER = 20
ACTIVE = True
- HELP_URL = '/config/options_metadata.html'
+ HELP_URL = "/config/options_metadata.html"
options = [
- TextOption("setting", "va_name", "Various Artists"),
- TextOption("setting", "nat_name", "[standalone recordings]"),
- ListOption("setting", "artist_locales", ["en"]),
- BoolOption("setting", "translate_artist_names", False),
- BoolOption("setting", "translate_artist_names_script_exception", False),
- ListOption("setting", "script_exceptions", []),
- BoolOption("setting", "release_ars", True),
- BoolOption("setting", "track_ars", False),
- BoolOption("setting", "convert_punctuation", False),
- BoolOption("setting", "standardize_artists", False),
- BoolOption("setting", "standardize_instruments", True),
- BoolOption("setting", "guess_tracknumber_and_title", True),
+ TextOption('setting', 'va_name', "Various Artists"),
+ TextOption('setting', 'nat_name', '[standalone recordings]'),
+ ListOption('setting', 'artist_locales', ['en']),
+ BoolOption('setting', 'translate_artist_names', False),
+ BoolOption('setting', 'translate_artist_names_script_exception', False),
+ ListOption('setting', 'script_exceptions', []),
+ BoolOption('setting', 'release_ars', True),
+ BoolOption('setting', 'track_ars', False),
+ BoolOption('setting', 'convert_punctuation', False),
+ BoolOption('setting', 'standardize_artists', False),
+ BoolOption('setting', 'standardize_instruments', True),
+ BoolOption('setting', 'guess_tracknumber_and_title', True),
]
def __init__(self, parent=None):
@@ -110,21 +110,21 @@ def __init__(self, parent=None):
def load(self):
config = get_config()
- self.ui.translate_artist_names.setChecked(config.setting["translate_artist_names"])
- self.current_locales = config.setting["artist_locales"]
+ self.ui.translate_artist_names.setChecked(config.setting['translate_artist_names'])
+ self.current_locales = config.setting['artist_locales']
self.make_locales_text()
- self.current_scripts = config.setting["script_exceptions"]
+ self.current_scripts = config.setting['script_exceptions']
self.make_scripts_text()
- self.ui.translate_artist_names_script_exception.setChecked(config.setting["translate_artist_names_script_exception"])
+ self.ui.translate_artist_names_script_exception.setChecked(config.setting['translate_artist_names_script_exception'])
- self.ui.convert_punctuation.setChecked(config.setting["convert_punctuation"])
- self.ui.release_ars.setChecked(config.setting["release_ars"])
- self.ui.track_ars.setChecked(config.setting["track_ars"])
- self.ui.va_name.setText(config.setting["va_name"])
- self.ui.nat_name.setText(config.setting["nat_name"])
- self.ui.standardize_artists.setChecked(config.setting["standardize_artists"])
- self.ui.standardize_instruments.setChecked(config.setting["standardize_instruments"])
- self.ui.guess_tracknumber_and_title.setChecked(config.setting["guess_tracknumber_and_title"])
+ self.ui.convert_punctuation.setChecked(config.setting['convert_punctuation'])
+ self.ui.release_ars.setChecked(config.setting['release_ars'])
+ self.ui.track_ars.setChecked(config.setting['track_ars'])
+ self.ui.va_name.setText(config.setting['va_name'])
+ self.ui.nat_name.setText(config.setting['nat_name'])
+ self.ui.standardize_artists.setChecked(config.setting['standardize_artists'])
+ self.ui.standardize_instruments.setChecked(config.setting['standardize_instruments'])
+ self.ui.guess_tracknumber_and_title.setChecked(config.setting['guess_tracknumber_and_title'])
self.set_enabled_states()
@@ -144,22 +144,22 @@ def translated_scripts():
def save(self):
config = get_config()
- config.setting["translate_artist_names"] = self.ui.translate_artist_names.isChecked()
- config.setting["artist_locales"] = self.current_locales
- config.setting["translate_artist_names_script_exception"] = self.ui.translate_artist_names_script_exception.isChecked()
- config.setting["script_exceptions"] = self.current_scripts
- config.setting["convert_punctuation"] = self.ui.convert_punctuation.isChecked()
- config.setting["release_ars"] = self.ui.release_ars.isChecked()
- config.setting["track_ars"] = self.ui.track_ars.isChecked()
- config.setting["va_name"] = self.ui.va_name.text()
+ config.setting['translate_artist_names'] = self.ui.translate_artist_names.isChecked()
+ config.setting['artist_locales'] = self.current_locales
+ config.setting['translate_artist_names_script_exception'] = self.ui.translate_artist_names_script_exception.isChecked()
+ config.setting['script_exceptions'] = self.current_scripts
+ config.setting['convert_punctuation'] = self.ui.convert_punctuation.isChecked()
+ config.setting['release_ars'] = self.ui.release_ars.isChecked()
+ config.setting['track_ars'] = self.ui.track_ars.isChecked()
+ config.setting['va_name'] = self.ui.va_name.text()
nat_name = self.ui.nat_name.text()
- if nat_name != config.setting["nat_name"]:
- config.setting["nat_name"] = nat_name
+ if nat_name != config.setting['nat_name']:
+ config.setting['nat_name'] = nat_name
if self.tagger.nats is not None:
self.tagger.nats.update()
- config.setting["standardize_artists"] = self.ui.standardize_artists.isChecked()
- config.setting["standardize_instruments"] = self.ui.standardize_instruments.isChecked()
- config.setting["guess_tracknumber_and_title"] = self.ui.guess_tracknumber_and_title.isChecked()
+ config.setting['standardize_artists'] = self.ui.standardize_artists.isChecked()
+ config.setting['standardize_instruments'] = self.ui.standardize_instruments.isChecked()
+ config.setting['guess_tracknumber_and_title'] = self.ui.guess_tracknumber_and_title.isChecked()
def set_va_name_default(self):
self.ui.va_name.setText(self.options[0].default)
diff --git a/picard/ui/options/network.py b/picard/ui/options/network.py
index a8a5eac6c4..46a3f8af16 100644
--- a/picard/ui/options/network.py
+++ b/picard/ui/options/network.py
@@ -38,24 +38,24 @@
class NetworkOptionsPage(OptionsPage):
- NAME = "network"
+ NAME = 'network'
TITLE = N_("Network")
- PARENT = "advanced"
+ PARENT = 'advanced'
SORT_ORDER = 10
ACTIVE = True
- HELP_URL = '/config/options_network.html'
+ HELP_URL = "/config/options_network.html"
options = [
- BoolOption("setting", "use_proxy", False),
- TextOption("setting", "proxy_type", "http"),
- TextOption("setting", "proxy_server_host", ""),
- IntOption("setting", "proxy_server_port", 80),
- TextOption("setting", "proxy_username", ""),
- TextOption("setting", "proxy_password", ""),
- BoolOption("setting", "browser_integration", True),
- IntOption("setting", "browser_integration_port", 8000),
- BoolOption("setting", "browser_integration_localhost_only", True),
- IntOption("setting", "network_transfer_timeout_seconds", 30),
+ BoolOption('setting', 'use_proxy', False),
+ TextOption('setting', 'proxy_type', 'http'),
+ TextOption('setting', 'proxy_server_host', ''),
+ IntOption('setting', 'proxy_server_port', 80),
+ TextOption('setting', 'proxy_username', ''),
+ TextOption('setting', 'proxy_password', ''),
+ BoolOption('setting', 'browser_integration', True),
+ IntOption('setting', 'browser_integration_port', 8000),
+ BoolOption('setting', 'browser_integration_localhost_only', True),
+ IntOption('setting', 'network_transfer_timeout_seconds', 30),
]
def __init__(self, parent=None):
@@ -65,39 +65,39 @@ def __init__(self, parent=None):
def load(self):
config = get_config()
- self.ui.web_proxy.setChecked(config.setting["use_proxy"])
- if config.setting["proxy_type"] == 'socks':
+ self.ui.web_proxy.setChecked(config.setting['use_proxy'])
+ if config.setting['proxy_type'] == 'socks':
self.ui.proxy_type_socks.setChecked(True)
else:
self.ui.proxy_type_http.setChecked(True)
- self.ui.server_host.setText(config.setting["proxy_server_host"])
- self.ui.server_port.setValue(config.setting["proxy_server_port"])
- self.ui.username.setText(config.setting["proxy_username"])
- self.ui.password.setText(config.setting["proxy_password"])
- self.ui.transfer_timeout.setValue(config.setting["network_transfer_timeout_seconds"])
- self.ui.browser_integration.setChecked(config.setting["browser_integration"])
- self.ui.browser_integration_port.setValue(config.setting["browser_integration_port"])
+ self.ui.server_host.setText(config.setting['proxy_server_host'])
+ self.ui.server_port.setValue(config.setting['proxy_server_port'])
+ self.ui.username.setText(config.setting['proxy_username'])
+ self.ui.password.setText(config.setting['proxy_password'])
+ self.ui.transfer_timeout.setValue(config.setting['network_transfer_timeout_seconds'])
+ self.ui.browser_integration.setChecked(config.setting['browser_integration'])
+ self.ui.browser_integration_port.setValue(config.setting['browser_integration_port'])
self.ui.browser_integration_localhost_only.setChecked(
- config.setting["browser_integration_localhost_only"])
+ config.setting['browser_integration_localhost_only'])
def save(self):
config = get_config()
- config.setting["use_proxy"] = self.ui.web_proxy.isChecked()
+ config.setting['use_proxy'] = self.ui.web_proxy.isChecked()
if self.ui.proxy_type_socks.isChecked():
- config.setting["proxy_type"] = 'socks'
+ config.setting['proxy_type'] = 'socks'
else:
- config.setting["proxy_type"] = 'http'
- config.setting["proxy_server_host"] = self.ui.server_host.text()
- config.setting["proxy_server_port"] = self.ui.server_port.value()
- config.setting["proxy_username"] = self.ui.username.text()
- config.setting["proxy_password"] = self.ui.password.text()
+ config.setting['proxy_type'] = 'http'
+ config.setting['proxy_server_host'] = self.ui.server_host.text()
+ config.setting['proxy_server_port'] = self.ui.server_port.value()
+ config.setting['proxy_username'] = self.ui.username.text()
+ config.setting['proxy_password'] = self.ui.password.text()
self.tagger.webservice.setup_proxy()
transfer_timeout = self.ui.transfer_timeout.value()
- config.setting["network_transfer_timeout_seconds"] = transfer_timeout
+ config.setting['network_transfer_timeout_seconds'] = transfer_timeout
self.tagger.webservice.set_transfer_timeout(transfer_timeout)
- config.setting["browser_integration"] = self.ui.browser_integration.isChecked()
- config.setting["browser_integration_port"] = self.ui.browser_integration_port.value()
- config.setting["browser_integration_localhost_only"] = \
+ config.setting['browser_integration'] = self.ui.browser_integration.isChecked()
+ config.setting['browser_integration_port'] = self.ui.browser_integration_port.value()
+ config.setting['browser_integration_localhost_only'] = \
self.ui.browser_integration_localhost_only.isChecked()
self.tagger.update_browser_integration()
diff --git a/picard/ui/options/plugins.py b/picard/ui/options/plugins.py
index a8428a49e9..5c1ed303ca 100644
--- a/picard/ui/options/plugins.py
+++ b/picard/ui/options/plugins.py
@@ -222,18 +222,18 @@ def enable(self, boolean, greyout=None):
class PluginsOptionsPage(OptionsPage):
- NAME = "plugins"
+ NAME = 'plugins'
TITLE = N_("Plugins")
PARENT = None
SORT_ORDER = 70
ACTIVE = True
- HELP_URL = '/config/options_plugins.html'
+ HELP_URL = "/config/options_plugins.html"
options = [
- ListOption("setting", "enabled_plugins", []),
- Option("persist", "plugins_list_state", QtCore.QByteArray()),
- Option("persist", "plugins_list_sort_section", 0),
- Option("persist", "plugins_list_sort_order", QtCore.Qt.SortOrder.AscendingOrder),
+ ListOption('setting', 'enabled_plugins', []),
+ Option('persist', 'plugins_list_state', QtCore.QByteArray()),
+ Option('persist', 'plugins_list_sort_section', 0),
+ Option('persist', 'plugins_list_sort_order', QtCore.Qt.SortOrder.AscendingOrder),
]
def __init__(self, parent=None):
@@ -299,9 +299,9 @@ def selected_item(self):
def save_state(self):
header = self.ui.plugins.header()
config = get_config()
- config.persist["plugins_list_state"] = header.saveState()
- config.persist["plugins_list_sort_section"] = header.sortIndicatorSection()
- config.persist["plugins_list_sort_order"] = header.sortIndicatorOrder()
+ config.persist['plugins_list_state'] = header.saveState()
+ config.persist['plugins_list_sort_section'] = header.sortIndicatorSection()
+ config.persist['plugins_list_sort_order'] = header.sortIndicatorOrder()
def set_current_item(self, item, scroll=False):
if scroll:
@@ -312,16 +312,16 @@ def set_current_item(self, item, scroll=False):
def restore_state(self):
header = self.ui.plugins.header()
config = get_config()
- header.restoreState(config.persist["plugins_list_state"])
- idx = config.persist["plugins_list_sort_section"]
- order = config.persist["plugins_list_sort_order"]
+ header.restoreState(config.persist['plugins_list_state'])
+ idx = config.persist['plugins_list_sort_section']
+ order = config.persist['plugins_list_sort_order']
header.setSortIndicator(idx, order)
self.ui.plugins.sortByColumn(idx, order)
@staticmethod
def is_plugin_enabled(plugin):
config = get_config()
- return bool(plugin.module_name in config.setting["enabled_plugins"])
+ return bool(plugin.module_name in config.setting['enabled_plugins'])
def available_plugins_name_version(self):
return {p.module_name: p.version for p in self.manager.available_plugins}
@@ -610,7 +610,7 @@ def v2int(elem):
def save(self):
config = get_config()
- config.setting["enabled_plugins"] = self.enabled_plugins()
+ config.setting['enabled_plugins'] = self.enabled_plugins()
self.save_state()
def refresh_details(self, item):
@@ -687,7 +687,7 @@ def download_plugin(self, item, update=False):
parse_response_type=None,
priority=True,
important=True,
- unencoded_queryargs={"id": plugin.module_name, "version": plugin.version.to_string(short=True)},
+ unencoded_queryargs={'id': plugin.module_name, 'version': plugin.version.to_string(short=True)},
)
def download_handler(self, update, response, reply, error, plugin):
@@ -716,7 +716,7 @@ def open_plugin_dir():
open_local_path(USER_PLUGIN_DIR)
def mimeTypes(self):
- return ["text/uri-list"]
+ return ['text/uri-list']
def dragEnterEvent(self, event):
event.setDropAction(QtCore.Qt.DropAction.CopyAction)
diff --git a/picard/ui/options/profiles.py b/picard/ui/options/profiles.py
index 20b9602a51..01c345bbec 100644
--- a/picard/ui/options/profiles.py
+++ b/picard/ui/options/profiles.py
@@ -52,23 +52,23 @@
class ProfilesOptionsPage(OptionsPage):
- NAME = "profiles"
+ NAME = 'profiles'
TITLE = N_("Option Profiles")
PARENT = None
SORT_ORDER = 10
ACTIVE = True
- HELP_URL = '/config/options_profiles.html'
+ HELP_URL = "/config/options_profiles.html"
PROFILES_KEY = SettingConfigSection.PROFILES_KEY
SETTINGS_KEY = SettingConfigSection.SETTINGS_KEY
- POSITION_KEY = "last_selected_profile_pos"
- EXPANDED_KEY = "profile_settings_tree_expanded_list"
+ POSITION_KEY = 'last_selected_profile_pos'
+ EXPANDED_KEY = 'profile_settings_tree_expanded_list'
TREEWIDGETITEM_COLUMN = 0
options = [
- IntOption("persist", POSITION_KEY, 0),
- ListOption("persist", EXPANDED_KEY, [])
+ IntOption('persist', POSITION_KEY, 0),
+ ListOption('persist', EXPANDED_KEY, [])
]
signal_refresh = QtCore.pyqtSignal()
@@ -112,17 +112,17 @@ def eventFilter(self, object, event):
def make_buttons(self):
"""Make buttons and add them to the button bars.
"""
- self.new_profile_button = QtWidgets.QPushButton(_('New'))
+ self.new_profile_button = QtWidgets.QPushButton(_("New"))
self.new_profile_button.setToolTip(_("Create a new profile"))
self.new_profile_button.clicked.connect(self.new_profile)
self.ui.profile_list_buttonbox.addButton(self.new_profile_button, QtWidgets.QDialogButtonBox.ButtonRole.ActionRole)
- self.copy_profile_button = QtWidgets.QPushButton(_('Copy'))
+ self.copy_profile_button = QtWidgets.QPushButton(_("Copy"))
self.copy_profile_button.setToolTip(_("Copy to a new profile"))
self.copy_profile_button.clicked.connect(self.copy_profile)
self.ui.profile_list_buttonbox.addButton(self.copy_profile_button, QtWidgets.QDialogButtonBox.ButtonRole.ActionRole)
- self.delete_profile_button = QtWidgets.QPushButton(_('Delete'))
+ self.delete_profile_button = QtWidgets.QPushButton(_("Delete"))
self.delete_profile_button.setToolTip(_("Delete the profile"))
self.delete_profile_button.clicked.connect(self.delete_profile)
self.ui.profile_list_buttonbox.addButton(self.delete_profile_button, QtWidgets.QDialogButtonBox.ButtonRole.ActionRole)
@@ -220,8 +220,8 @@ def make_setting_tree(self, settings=None):
return
self.building_tree = True
for group in UserProfileGroups.SETTINGS_GROUPS.values():
- title = group["title"]
- group_settings = group["settings"]
+ title = group['title']
+ group_settings = group['settings']
widget_item = QtWidgets.QTreeWidgetItem([title])
widget_item.setFlags(QtCore.Qt.ItemFlag.ItemIsEnabled | QtCore.Qt.ItemFlag.ItemIsUserCheckable | QtCore.Qt.ItemFlag.ItemIsAutoTristate)
widget_item.setCheckState(self.TREEWIDGETITEM_COLUMN, QtCore.Qt.CheckState.Unchecked)
@@ -243,9 +243,9 @@ def make_setting_tree(self, settings=None):
self.building_tree = False
def _get_naming_script(self, config, value):
- if value in config.setting["file_renaming_scripts"]:
- return config.setting["file_renaming_scripts"][value]["title"]
- presets = {x["id"]: x["title"] for x in get_file_naming_script_presets()}
+ if value in config.setting['file_renaming_scripts']:
+ return config.setting['file_renaming_scripts'][value]['title']
+ presets = {x['id']: x['title'] for x in get_file_naming_script_presets()}
if value in presets:
return presets[value]
return _("Unknown script")
@@ -282,11 +282,11 @@ def make_setting_value_text(self, key, value):
config = get_config()
if value is None:
return NONE_TEXT
- if key == "selected_file_naming_script_id":
+ if key == 'selected_file_naming_script_id':
return self._get_naming_script(config, value)
- if key == "list_of_scripts":
+ if key == 'list_of_scripts':
return self._get_scripts_list(config, key, ITEMS_TEMPLATE, NONE_TEXT)
- if key == "ca_providers":
+ if key == 'ca_providers':
return self._get_ca_providers_list(config, key, ITEMS_TEMPLATE, NONE_TEXT)
if isinstance(value, str):
return '"%s"' % value
diff --git a/picard/ui/options/ratings.py b/picard/ui/options/ratings.py
index e83921316d..bd5d6e84f8 100644
--- a/picard/ui/options/ratings.py
+++ b/picard/ui/options/ratings.py
@@ -37,18 +37,18 @@
class RatingsOptionsPage(OptionsPage):
- NAME = "ratings"
+ NAME = 'ratings'
TITLE = N_("Ratings")
- PARENT = "metadata"
+ PARENT = 'metadata'
SORT_ORDER = 20
ACTIVE = True
- HELP_URL = '/config/options_ratings.html'
+ HELP_URL = "/config/options_ratings.html"
options = [
- BoolOption("setting", "enable_ratings", False),
- TextOption("setting", "rating_user_email", "users@musicbrainz.org"),
- BoolOption("setting", "submit_ratings", True),
- IntOption("setting", "rating_steps", 6),
+ BoolOption('setting', 'enable_ratings', False),
+ TextOption('setting', 'rating_user_email', 'users@musicbrainz.org'),
+ BoolOption('setting', 'submit_ratings', True),
+ IntOption('setting', 'rating_steps', 6),
]
def __init__(self, parent=None):
@@ -58,15 +58,15 @@ def __init__(self, parent=None):
def load(self):
config = get_config()
- self.ui.enable_ratings.setChecked(config.setting["enable_ratings"])
- self.ui.rating_user_email.setText(config.setting["rating_user_email"])
- self.ui.submit_ratings.setChecked(config.setting["submit_ratings"])
+ self.ui.enable_ratings.setChecked(config.setting['enable_ratings'])
+ self.ui.rating_user_email.setText(config.setting['rating_user_email'])
+ self.ui.submit_ratings.setChecked(config.setting['submit_ratings'])
def save(self):
config = get_config()
- config.setting["enable_ratings"] = self.ui.enable_ratings.isChecked()
- config.setting["rating_user_email"] = self.ui.rating_user_email.text()
- config.setting["submit_ratings"] = self.ui.submit_ratings.isChecked()
+ config.setting['enable_ratings'] = self.ui.enable_ratings.isChecked()
+ config.setting['rating_user_email'] = self.ui.rating_user_email.text()
+ config.setting['submit_ratings'] = self.ui.submit_ratings.isChecked()
register_options_page(RatingsOptionsPage)
diff --git a/picard/ui/options/releases.py b/picard/ui/options/releases.py
index dc83f56777..c0be036523 100644
--- a/picard/ui/options/releases.py
+++ b/picard/ui/options/releases.py
@@ -154,17 +154,17 @@ def __next__(self):
class ReleasesOptionsPage(OptionsPage):
- NAME = "releases"
+ NAME = 'releases'
TITLE = N_("Preferred Releases")
- PARENT = "metadata"
+ PARENT = 'metadata'
SORT_ORDER = 10
ACTIVE = True
- HELP_URL = '/config/options_releases.html'
+ HELP_URL = "/config/options_releases.html"
options = [
- ListOption("setting", "release_type_scores", _release_type_scores),
- ListOption("setting", "preferred_release_countries", []),
- ListOption("setting", "preferred_release_formats", []),
+ ListOption('setting', 'release_type_scores', _release_type_scores),
+ ListOption('setting', 'preferred_release_countries', []),
+ ListOption('setting', 'preferred_release_formats', []),
]
def __init__(self, parent=None):
@@ -230,14 +230,14 @@ def restore_defaults(self):
def load(self):
config = get_config()
- scores = dict(config.setting["release_type_scores"])
+ scores = dict(config.setting['release_type_scores'])
for (release_type, release_type_slider) in self._release_type_sliders.items():
release_type_slider.setValue(scores.get(release_type,
_DEFAULT_SCORE))
- self._load_list_items("preferred_release_countries", RELEASE_COUNTRIES,
+ self._load_list_items('preferred_release_countries', RELEASE_COUNTRIES,
self.ui.country_list, self.ui.preferred_country_list)
- self._load_list_items("preferred_release_formats", RELEASE_FORMATS,
+ self._load_list_items('preferred_release_formats', RELEASE_FORMATS,
self.ui.format_list, self.ui.preferred_format_list)
def save(self):
@@ -245,10 +245,10 @@ def save(self):
scores = []
for (release_type, release_type_slider) in self._release_type_sliders.items():
scores.append((release_type, release_type_slider.value()))
- config.setting["release_type_scores"] = scores
+ config.setting['release_type_scores'] = scores
- self._save_list_items("preferred_release_countries", self.ui.preferred_country_list)
- self._save_list_items("preferred_release_formats", self.ui.preferred_format_list)
+ self._save_list_items('preferred_release_countries', self.ui.preferred_country_list)
+ self._save_list_items('preferred_release_formats', self.ui.preferred_format_list)
def reset_preferred_types(self):
for release_type_slider in self._release_type_sliders.values():
@@ -275,11 +275,11 @@ def _move_selected_items(self, list1, list2):
list1.takeItem(list1.row(item))
def _load_list_items(self, setting, source, list1, list2):
- if setting == "preferred_release_countries":
+ if setting == 'preferred_release_countries':
source_list = [(c[0], gettext_countries(c[1])) for c in
source.items()]
- elif setting == "preferred_release_formats":
- source_list = [(c[0], pgettext_attributes("medium_format", c[1])) for c
+ elif setting == 'preferred_release_formats':
+ source_list = [(c[0], pgettext_attributes('medium_format', c[1])) for c
in source.items()]
else:
source_list = [(c[0], _(c[1])) for c in source.items()]
diff --git a/picard/ui/options/renaming.py b/picard/ui/options/renaming.py
index fbbcd71109..d42155fa7c 100644
--- a/picard/ui/options/renaming.py
+++ b/picard/ui/options/renaming.py
@@ -69,20 +69,20 @@
class RenamingOptionsPage(OptionsPage):
- NAME = "filerenaming"
+ NAME = 'filerenaming'
TITLE = N_("File Naming")
PARENT = None
SORT_ORDER = 40
ACTIVE = True
- HELP_URL = '/config/options_filerenaming.html'
+ HELP_URL = "/config/options_filerenaming.html"
options = [
- BoolOption("setting", "rename_files", False),
- BoolOption("setting", "move_files", False),
- TextOption("setting", "move_files_to", _default_music_dir),
- BoolOption("setting", "move_additional_files", False),
- TextOption("setting", "move_additional_files_pattern", "*.jpg *.png"),
- BoolOption("setting", "delete_empty_dirs", True),
+ BoolOption('setting', 'rename_files', False),
+ BoolOption('setting', 'move_files', False),
+ TextOption('setting', 'move_files_to', _default_music_dir),
+ BoolOption('setting', 'move_additional_files', False),
+ TextOption('setting', 'move_additional_files_pattern', "*.jpg *.png"),
+ BoolOption('setting', 'delete_empty_dirs', True),
]
def __init__(self, parent=None):
@@ -231,15 +231,15 @@ def load(self):
compat_page.options_changed.connect(self.on_compat_options_changed)
config = get_config()
- self.ui.rename_files.setChecked(config.setting["rename_files"])
- self.ui.move_files.setChecked(config.setting["move_files"])
- self.ui.move_files_to.setText(config.setting["move_files_to"])
+ self.ui.rename_files.setChecked(config.setting['rename_files'])
+ self.ui.move_files.setChecked(config.setting['move_files'])
+ self.ui.move_files_to.setText(config.setting['move_files_to'])
self.ui.move_files_to.setCursorPosition(0)
- self.ui.move_additional_files.setChecked(config.setting["move_additional_files"])
- self.ui.move_additional_files_pattern.setText(config.setting["move_additional_files_pattern"])
- self.ui.delete_empty_dirs.setChecked(config.setting["delete_empty_dirs"])
- self.naming_scripts = config.setting["file_renaming_scripts"]
- self.selected_naming_script_id = config.setting["selected_file_naming_script_id"]
+ self.ui.move_additional_files.setChecked(config.setting['move_additional_files'])
+ self.ui.move_additional_files_pattern.setText(config.setting['move_additional_files_pattern'])
+ self.ui.delete_empty_dirs.setChecked(config.setting['delete_empty_dirs'])
+ self.naming_scripts = config.setting['file_renaming_scripts']
+ self.selected_naming_script_id = config.setting['selected_file_naming_script_id']
if self.script_editor_dialog:
self.script_editor_dialog.load()
else:
@@ -267,15 +267,15 @@ def check_format(self):
def save(self):
config = get_config()
- config.setting["rename_files"] = self.ui.rename_files.isChecked()
- config.setting["move_files"] = self.ui.move_files.isChecked()
- config.setting["move_files_to"] = os.path.normpath(self.ui.move_files_to.text())
- config.setting["move_additional_files"] = self.ui.move_additional_files.isChecked()
- config.setting["move_additional_files_pattern"] = self.ui.move_additional_files_pattern.text()
- config.setting["delete_empty_dirs"] = self.ui.delete_empty_dirs.isChecked()
- config.setting["selected_file_naming_script_id"] = self.selected_naming_script_id
- self.tagger.window.enable_renaming_action.setChecked(config.setting["rename_files"])
- self.tagger.window.enable_moving_action.setChecked(config.setting["move_files"])
+ config.setting['rename_files'] = self.ui.rename_files.isChecked()
+ config.setting['move_files'] = self.ui.move_files.isChecked()
+ config.setting['move_files_to'] = os.path.normpath(self.ui.move_files_to.text())
+ config.setting['move_additional_files'] = self.ui.move_additional_files.isChecked()
+ config.setting['move_additional_files_pattern'] = self.ui.move_additional_files_pattern.text()
+ config.setting['delete_empty_dirs'] = self.ui.delete_empty_dirs.isChecked()
+ config.setting['selected_file_naming_script_id'] = self.selected_naming_script_id
+ self.tagger.window.enable_renaming_action.setChecked(config.setting['rename_files'])
+ self.tagger.window.enable_moving_action.setChecked(config.setting['move_files'])
self.tagger.window.make_script_selector_menu()
def display_error(self, error):
diff --git a/picard/ui/options/renaming_compat.py b/picard/ui/options/renaming_compat.py
index 675959a59f..98c9ec17da 100644
--- a/picard/ui/options/renaming_compat.py
+++ b/picard/ui/options/renaming_compat.py
@@ -64,19 +64,19 @@
class RenamingCompatOptionsPage(OptionsPage):
- NAME = "filerenaming_compat"
+ NAME = 'filerenaming_compat'
TITLE = N_("Compatibility")
- PARENT = "filerenaming"
+ PARENT = 'filerenaming'
ACTIVE = True
- HELP_URL = '/config/options_filerenaming_compat.html'
+ HELP_URL = "/config/options_filerenaming_compat.html"
options = [
- BoolOption("setting", "windows_compatibility", True),
- BoolOption("setting", "windows_long_paths", system_supports_long_paths() if IS_WIN else False),
- BoolOption("setting", "ascii_filenames", False),
- BoolOption("setting", "replace_spaces_with_underscores", False),
- TextOption("setting", "replace_dir_separator", DEFAULT_REPLACEMENT),
- Option("setting", "win_compat_replacements", {
+ BoolOption('setting', 'windows_compatibility', True),
+ BoolOption('setting', 'windows_long_paths', system_supports_long_paths() if IS_WIN else False),
+ BoolOption('setting', 'ascii_filenames', False),
+ BoolOption('setting', 'replace_spaces_with_underscores', False),
+ TextOption('setting', 'replace_dir_separator', DEFAULT_REPLACEMENT),
+ Option('setting', 'win_compat_replacements', {
'*': DEFAULT_REPLACEMENT,
':': DEFAULT_REPLACEMENT,
'<': DEFAULT_REPLACEMENT,
@@ -92,7 +92,7 @@ class RenamingCompatOptionsPage(OptionsPage):
def __init__(self, parent=None):
super().__init__(parent)
config = get_config()
- self.win_compat_replacements = config.setting["win_compat_replacements"]
+ self.win_compat_replacements = config.setting['win_compat_replacements']
self.ui = Ui_RenamingCompatOptionsPage()
self.ui.setupUi(self)
self.ui.ascii_filenames.toggled.connect(self.on_options_changed)
@@ -104,7 +104,7 @@ def __init__(self, parent=None):
def load(self):
config = get_config()
- self.win_compat_replacements = config.setting["win_compat_replacements"]
+ self.win_compat_replacements = config.setting['win_compat_replacements']
try:
self.ui.windows_long_paths.toggled.disconnect(self.toggle_windows_long_paths)
except TypeError:
@@ -113,11 +113,11 @@ def load(self):
self.ui.windows_compatibility.setChecked(True)
self.ui.windows_compatibility.setEnabled(False)
else:
- self.ui.windows_compatibility.setChecked(config.setting["windows_compatibility"])
- self.ui.windows_long_paths.setChecked(config.setting["windows_long_paths"])
- self.ui.ascii_filenames.setChecked(config.setting["ascii_filenames"])
- self.ui.replace_spaces_with_underscores.setChecked(config.setting["replace_spaces_with_underscores"])
- self.ui.replace_dir_separator.setText(config.setting["replace_dir_separator"])
+ self.ui.windows_compatibility.setChecked(config.setting['windows_compatibility'])
+ self.ui.windows_long_paths.setChecked(config.setting['windows_long_paths'])
+ self.ui.ascii_filenames.setChecked(config.setting['ascii_filenames'])
+ self.ui.replace_spaces_with_underscores.setChecked(config.setting['replace_spaces_with_underscores'])
+ self.ui.replace_dir_separator.setText(config.setting['replace_dir_separator'])
self.ui.windows_long_paths.toggled.connect(self.toggle_windows_long_paths)
def save(self):
@@ -130,11 +130,11 @@ def toggle_windows_long_paths(self, state):
if state and not system_supports_long_paths():
dialog = QtWidgets.QMessageBox(
QtWidgets.QMessageBox.Icon.Information,
- _('Windows long path support'),
+ _("Windows long path support"),
_(
- 'Enabling long paths on Windows might cause files being saved with path names '
- 'exceeding the 259 character limit traditionally imposed by the Windows API. '
- 'Some software might not be able to properly access those files.'
+ "Enabling long paths on Windows might cause files being saved with path names "
+ "exceeding the 259 character limit traditionally imposed by the Windows API. "
+ "Some software might not be able to properly access those files."
),
QtWidgets.QMessageBox.StandardButton.Ok,
self)
diff --git a/picard/ui/options/scripting.py b/picard/ui/options/scripting.py
index 1a56f63b20..1b0e1900e7 100644
--- a/picard/ui/options/scripting.py
+++ b/picard/ui/options/scripting.py
@@ -96,17 +96,17 @@ def closeEvent(self, event):
class ScriptingOptionsPage(OptionsPage):
- NAME = "scripting"
+ NAME = 'scripting'
TITLE = N_("Scripting")
PARENT = None
SORT_ORDER = 75
ACTIVE = True
- HELP_URL = '/config/options_scripting.html'
+ HELP_URL = "/config/options_scripting.html"
options = [
- BoolOption("setting", "enable_tagger_scripts", False),
- ListOption("setting", "list_of_scripts", []),
- IntOption("persist", "last_selected_script_pos", 0),
+ BoolOption('setting', 'enable_tagger_scripts', False),
+ ListOption('setting', 'list_of_scripts', []),
+ IntOption('persist', 'last_selected_script_pos', 0),
]
default_script_directory = os.path.normpath(QtCore.QStandardPaths.writableLocation(QtCore.QStandardPaths.StandardLocation.DocumentsLocation))
@@ -173,8 +173,8 @@ def import_script(self):
self.output_file_error(error)
return
if script_item:
- title = _("%s (imported)") % script_item["title"]
- list_item = ScriptListWidgetItem(title, False, script_item["script"])
+ title = _("%s (imported)") % script_item['title']
+ list_item = ScriptListWidgetItem(title, False, script_item['script'])
self.ui.script_list.addItem(list_item)
self.ui.script_list.setCurrentRow(self.ui.script_list.count() - 1)
@@ -250,14 +250,14 @@ def restore_defaults(self):
def load(self):
config = get_config()
- self.ui.enable_tagger_scripts.setChecked(config.setting["enable_tagger_scripts"])
+ self.ui.enable_tagger_scripts.setChecked(config.setting['enable_tagger_scripts'])
self.ui.script_list.clear()
- for pos, name, enabled, text in config.setting["list_of_scripts"]:
+ for pos, name, enabled, text in config.setting['list_of_scripts']:
list_item = ScriptListWidgetItem(name, enabled, text)
self.ui.script_list.addItem(list_item)
# Select the last selected script item
- last_selected_script_pos = config.persist["last_selected_script_pos"]
+ last_selected_script_pos = config.persist['last_selected_script_pos']
last_selected_script = self.ui.script_list.item(last_selected_script_pos)
if last_selected_script:
self.ui.script_list.setCurrentItem(last_selected_script)
@@ -269,9 +269,9 @@ def _all_scripts(self):
def save(self):
config = get_config()
- config.setting["enable_tagger_scripts"] = self.ui.enable_tagger_scripts.isChecked()
- config.setting["list_of_scripts"] = list(self._all_scripts())
- config.persist["last_selected_script_pos"] = self.ui.script_list.currentRow()
+ config.setting['enable_tagger_scripts'] = self.ui.enable_tagger_scripts.isChecked()
+ config.setting['list_of_scripts'] = list(self._all_scripts())
+ config.persist['last_selected_script_pos'] = self.ui.script_list.currentRow()
def display_error(self, error):
# Ignore scripting errors, those are handled inline
diff --git a/picard/ui/options/tags.py b/picard/ui/options/tags.py
index d94c7df878..f3ceafccf0 100644
--- a/picard/ui/options/tags.py
+++ b/picard/ui/options/tags.py
@@ -43,22 +43,22 @@
class TagsOptionsPage(OptionsPage):
- NAME = "tags"
+ NAME = 'tags'
TITLE = N_("Tags")
PARENT = None
SORT_ORDER = 30
ACTIVE = True
- HELP_URL = '/config/options_tags.html'
+ HELP_URL = "/config/options_tags.html"
options = [
- BoolOption("setting", "dont_write_tags", False),
- BoolOption("setting", "preserve_timestamps", False),
- BoolOption("setting", "clear_existing_tags", False),
- BoolOption("setting", "preserve_images", False),
- BoolOption("setting", "remove_id3_from_flac", False),
- BoolOption("setting", "remove_ape_from_mp3", False),
- BoolOption("setting", "fix_missing_seekpoints_flac", False),
- ListOption("setting", "preserved_tags", []),
+ BoolOption('setting', 'dont_write_tags', False),
+ BoolOption('setting', 'preserve_timestamps', False),
+ BoolOption('setting', 'clear_existing_tags', False),
+ BoolOption('setting', 'preserve_images', False),
+ BoolOption('setting', 'remove_id3_from_flac', False),
+ BoolOption('setting', 'remove_ape_from_mp3', False),
+ BoolOption('setting', 'fix_missing_seekpoints_flac', False),
+ ListOption('setting', 'preserved_tags', []),
]
def __init__(self, parent=None):
@@ -68,30 +68,30 @@ def __init__(self, parent=None):
def load(self):
config = get_config()
- self.ui.write_tags.setChecked(not config.setting["dont_write_tags"])
- self.ui.preserve_timestamps.setChecked(config.setting["preserve_timestamps"])
- self.ui.clear_existing_tags.setChecked(config.setting["clear_existing_tags"])
- self.ui.preserve_images.setChecked(config.setting["preserve_images"])
- self.ui.remove_ape_from_mp3.setChecked(config.setting["remove_ape_from_mp3"])
- self.ui.remove_id3_from_flac.setChecked(config.setting["remove_id3_from_flac"])
- self.ui.fix_missing_seekpoints_flac.setChecked(config.setting["fix_missing_seekpoints_flac"])
- self.ui.preserved_tags.update(config.setting["preserved_tags"])
+ self.ui.write_tags.setChecked(not config.setting['dont_write_tags'])
+ self.ui.preserve_timestamps.setChecked(config.setting['preserve_timestamps'])
+ self.ui.clear_existing_tags.setChecked(config.setting['clear_existing_tags'])
+ self.ui.preserve_images.setChecked(config.setting['preserve_images'])
+ self.ui.remove_ape_from_mp3.setChecked(config.setting['remove_ape_from_mp3'])
+ self.ui.remove_id3_from_flac.setChecked(config.setting['remove_id3_from_flac'])
+ self.ui.fix_missing_seekpoints_flac.setChecked(config.setting['fix_missing_seekpoints_flac'])
+ self.ui.preserved_tags.update(config.setting['preserved_tags'])
self.ui.preserved_tags.set_user_sortable(False)
def save(self):
config = get_config()
- config.setting["dont_write_tags"] = not self.ui.write_tags.isChecked()
- config.setting["preserve_timestamps"] = self.ui.preserve_timestamps.isChecked()
+ config.setting['dont_write_tags'] = not self.ui.write_tags.isChecked()
+ config.setting['preserve_timestamps'] = self.ui.preserve_timestamps.isChecked()
clear_existing_tags = self.ui.clear_existing_tags.isChecked()
- if clear_existing_tags != config.setting["clear_existing_tags"]:
- config.setting["clear_existing_tags"] = clear_existing_tags
+ if clear_existing_tags != config.setting['clear_existing_tags']:
+ config.setting['clear_existing_tags'] = clear_existing_tags
self.tagger.window.metadata_box.update()
- config.setting["preserve_images"] = self.ui.preserve_images.isChecked()
- config.setting["remove_ape_from_mp3"] = self.ui.remove_ape_from_mp3.isChecked()
- config.setting["remove_id3_from_flac"] = self.ui.remove_id3_from_flac.isChecked()
- config.setting["fix_missing_seekpoints_flac"] = self.ui.fix_missing_seekpoints_flac.isChecked()
- config.setting["preserved_tags"] = list(self.ui.preserved_tags.tags)
- self.tagger.window.enable_tag_saving_action.setChecked(not config.setting["dont_write_tags"])
+ config.setting['preserve_images'] = self.ui.preserve_images.isChecked()
+ config.setting['remove_ape_from_mp3'] = self.ui.remove_ape_from_mp3.isChecked()
+ config.setting['remove_id3_from_flac'] = self.ui.remove_id3_from_flac.isChecked()
+ config.setting['fix_missing_seekpoints_flac'] = self.ui.fix_missing_seekpoints_flac.isChecked()
+ config.setting['preserved_tags'] = list(self.ui.preserved_tags.tags)
+ self.tagger.window.enable_tag_saving_action.setChecked(not config.setting['dont_write_tags'])
register_options_page(TagsOptionsPage)
diff --git a/picard/ui/options/tags_compatibility_aac.py b/picard/ui/options/tags_compatibility_aac.py
index b50bc2aedb..ee58e4f0c8 100644
--- a/picard/ui/options/tags_compatibility_aac.py
+++ b/picard/ui/options/tags_compatibility_aac.py
@@ -37,16 +37,16 @@
class TagsCompatibilityAACOptionsPage(OptionsPage):
- NAME = "tags_compatibility_aac"
+ NAME = 'tags_compatibility_aac'
TITLE = N_("AAC")
- PARENT = "tags"
+ PARENT = 'tags'
SORT_ORDER = 40
ACTIVE = True
- HELP_URL = '/config/options_tags_compatibility_aac.html'
+ HELP_URL = "/config/options_tags_compatibility_aac.html"
options = [
- BoolOption("setting", "aac_save_ape", True),
- BoolOption("setting", "remove_ape_from_aac", False),
+ BoolOption('setting', 'aac_save_ape', True),
+ BoolOption('setting', 'remove_ape_from_aac', False),
]
def __init__(self, parent=None):
@@ -57,17 +57,17 @@ def __init__(self, parent=None):
def load(self):
config = get_config()
- if config.setting["aac_save_ape"]:
+ if config.setting['aac_save_ape']:
self.ui.aac_save_ape.setChecked(True)
else:
self.ui.aac_no_tags.setChecked(True)
- self.ui.remove_ape_from_aac.setChecked(config.setting["remove_ape_from_aac"])
- self.ui.remove_ape_from_aac.setEnabled(not config.setting["aac_save_ape"])
+ self.ui.remove_ape_from_aac.setChecked(config.setting['remove_ape_from_aac'])
+ self.ui.remove_ape_from_aac.setEnabled(not config.setting['aac_save_ape'])
def save(self):
config = get_config()
- config.setting["aac_save_ape"] = self.ui.aac_save_ape.isChecked()
- config.setting["remove_ape_from_aac"] = self.ui.remove_ape_from_aac.isChecked()
+ config.setting['aac_save_ape'] = self.ui.aac_save_ape.isChecked()
+ config.setting['remove_ape_from_aac'] = self.ui.remove_ape_from_aac.isChecked()
register_options_page(TagsCompatibilityAACOptionsPage)
diff --git a/picard/ui/options/tags_compatibility_ac3.py b/picard/ui/options/tags_compatibility_ac3.py
index ad2bb738c1..fb91b1cf20 100644
--- a/picard/ui/options/tags_compatibility_ac3.py
+++ b/picard/ui/options/tags_compatibility_ac3.py
@@ -37,16 +37,16 @@
class TagsCompatibilityAC3OptionsPage(OptionsPage):
- NAME = "tags_compatibility_ac3"
+ NAME = 'tags_compatibility_ac3'
TITLE = N_("AC3")
- PARENT = "tags"
+ PARENT = 'tags'
SORT_ORDER = 50
ACTIVE = True
- HELP_URL = '/config/options_tags_compatibility_ac3.html'
+ HELP_URL = "/config/options_tags_compatibility_ac3.html"
options = [
- BoolOption("setting", "ac3_save_ape", True),
- BoolOption("setting", "remove_ape_from_ac3", False),
+ BoolOption('setting', 'ac3_save_ape', True),
+ BoolOption('setting', 'remove_ape_from_ac3', False),
]
def __init__(self, parent=None):
@@ -57,17 +57,17 @@ def __init__(self, parent=None):
def load(self):
config = get_config()
- if config.setting["ac3_save_ape"]:
+ if config.setting['ac3_save_ape']:
self.ui.ac3_save_ape.setChecked(True)
else:
self.ui.ac3_no_tags.setChecked(True)
- self.ui.remove_ape_from_ac3.setChecked(config.setting["remove_ape_from_ac3"])
- self.ui.remove_ape_from_ac3.setEnabled(not config.setting["ac3_save_ape"])
+ self.ui.remove_ape_from_ac3.setChecked(config.setting['remove_ape_from_ac3'])
+ self.ui.remove_ape_from_ac3.setEnabled(not config.setting['ac3_save_ape'])
def save(self):
config = get_config()
- config.setting["ac3_save_ape"] = self.ui.ac3_save_ape.isChecked()
- config.setting["remove_ape_from_ac3"] = self.ui.remove_ape_from_ac3.isChecked()
+ config.setting['ac3_save_ape'] = self.ui.ac3_save_ape.isChecked()
+ config.setting['remove_ape_from_ac3'] = self.ui.remove_ape_from_ac3.isChecked()
register_options_page(TagsCompatibilityAC3OptionsPage)
diff --git a/picard/ui/options/tags_compatibility_id3.py b/picard/ui/options/tags_compatibility_id3.py
index 03785ba49f..ead7a08aa2 100644
--- a/picard/ui/options/tags_compatibility_id3.py
+++ b/picard/ui/options/tags_compatibility_id3.py
@@ -40,19 +40,19 @@
class TagsCompatibilityID3OptionsPage(OptionsPage):
- NAME = "tags_compatibility_id3"
+ NAME = 'tags_compatibility_id3'
TITLE = N_("ID3")
- PARENT = "tags"
+ PARENT = 'tags'
SORT_ORDER = 30
ACTIVE = True
- HELP_URL = '/config/options_tags_compatibility_id3.html'
+ HELP_URL = "/config/options_tags_compatibility_id3.html"
options = [
- BoolOption("setting", "write_id3v1", True),
- BoolOption("setting", "write_id3v23", False),
- TextOption("setting", "id3v2_encoding", "utf-8"),
- TextOption("setting", "id3v23_join_with", "/"),
- BoolOption("setting", "itunes_compatible_grouping", False),
+ BoolOption('setting', 'write_id3v1', True),
+ BoolOption('setting', 'write_id3v23', False),
+ TextOption('setting', 'id3v2_encoding', 'utf-8'),
+ TextOption('setting', 'id3v23_join_with', '/'),
+ BoolOption('setting', 'itunes_compatible_grouping', False),
]
def __init__(self, parent=None):
@@ -64,33 +64,33 @@ def __init__(self, parent=None):
def load(self):
config = get_config()
- self.ui.write_id3v1.setChecked(config.setting["write_id3v1"])
- if config.setting["write_id3v23"]:
+ self.ui.write_id3v1.setChecked(config.setting['write_id3v1'])
+ if config.setting['write_id3v23']:
self.ui.write_id3v23.setChecked(True)
else:
self.ui.write_id3v24.setChecked(True)
- if config.setting["id3v2_encoding"] == "iso-8859-1":
+ if config.setting['id3v2_encoding'] == 'iso-8859-1':
self.ui.enc_iso88591.setChecked(True)
- elif config.setting["id3v2_encoding"] == "utf-16":
+ elif config.setting['id3v2_encoding'] == 'utf-16':
self.ui.enc_utf16.setChecked(True)
else:
self.ui.enc_utf8.setChecked(True)
- self.ui.id3v23_join_with.setEditText(config.setting["id3v23_join_with"])
- self.ui.itunes_compatible_grouping.setChecked(config.setting["itunes_compatible_grouping"])
+ self.ui.id3v23_join_with.setEditText(config.setting['id3v23_join_with'])
+ self.ui.itunes_compatible_grouping.setChecked(config.setting['itunes_compatible_grouping'])
self.update_encodings()
def save(self):
config = get_config()
- config.setting["write_id3v1"] = self.ui.write_id3v1.isChecked()
- config.setting["write_id3v23"] = self.ui.write_id3v23.isChecked()
- config.setting["id3v23_join_with"] = self.ui.id3v23_join_with.currentText()
+ config.setting['write_id3v1'] = self.ui.write_id3v1.isChecked()
+ config.setting['write_id3v23'] = self.ui.write_id3v23.isChecked()
+ config.setting['id3v23_join_with'] = self.ui.id3v23_join_with.currentText()
if self.ui.enc_iso88591.isChecked():
- config.setting["id3v2_encoding"] = "iso-8859-1"
+ config.setting['id3v2_encoding'] = 'iso-8859-1'
elif self.ui.enc_utf16.isChecked():
- config.setting["id3v2_encoding"] = "utf-16"
+ config.setting['id3v2_encoding'] = 'utf-16'
else:
- config.setting["id3v2_encoding"] = "utf-8"
- config.setting["itunes_compatible_grouping"] = self.ui.itunes_compatible_grouping.isChecked()
+ config.setting['id3v2_encoding'] = 'utf-8'
+ config.setting['itunes_compatible_grouping'] = self.ui.itunes_compatible_grouping.isChecked()
def update_encodings(self, force_utf8=False):
if self.ui.write_id3v23.isChecked():
diff --git a/picard/ui/options/tags_compatibility_wave.py b/picard/ui/options/tags_compatibility_wave.py
index 3062295e6a..b513a1c7e8 100644
--- a/picard/ui/options/tags_compatibility_wave.py
+++ b/picard/ui/options/tags_compatibility_wave.py
@@ -39,17 +39,17 @@
class TagsCompatibilityWaveOptionsPage(OptionsPage):
- NAME = "tags_compatibility_wave"
+ NAME = 'tags_compatibility_wave'
TITLE = N_("WAVE")
- PARENT = "tags"
+ PARENT = 'tags'
SORT_ORDER = 60
ACTIVE = True
- HELP_URL = '/config/options_tags_compatibility_wave.html'
+ HELP_URL = "/config/options_tags_compatibility_wave.html"
options = [
- BoolOption("setting", "write_wave_riff_info", True),
- BoolOption("setting", "remove_wave_riff_info", False),
- TextOption("setting", "wave_riff_info_encoding", "windows-1252"),
+ BoolOption('setting', 'write_wave_riff_info', True),
+ BoolOption('setting', 'remove_wave_riff_info', False),
+ TextOption('setting', 'wave_riff_info_encoding', 'windows-1252'),
]
def __init__(self, parent=None):
@@ -59,21 +59,21 @@ def __init__(self, parent=None):
def load(self):
config = get_config()
- self.ui.write_wave_riff_info.setChecked(config.setting["write_wave_riff_info"])
- self.ui.remove_wave_riff_info.setChecked(config.setting["remove_wave_riff_info"])
- if config.setting["wave_riff_info_encoding"] == "utf-8":
+ self.ui.write_wave_riff_info.setChecked(config.setting['write_wave_riff_info'])
+ self.ui.remove_wave_riff_info.setChecked(config.setting['remove_wave_riff_info'])
+ if config.setting['wave_riff_info_encoding'] == 'utf-8':
self.ui.wave_riff_info_enc_utf8.setChecked(True)
else:
self.ui.wave_riff_info_enc_cp1252.setChecked(True)
def save(self):
config = get_config()
- config.setting["write_wave_riff_info"] = self.ui.write_wave_riff_info.isChecked()
- config.setting["remove_wave_riff_info"] = self.ui.remove_wave_riff_info.isChecked()
+ config.setting['write_wave_riff_info'] = self.ui.write_wave_riff_info.isChecked()
+ config.setting['remove_wave_riff_info'] = self.ui.remove_wave_riff_info.isChecked()
if self.ui.wave_riff_info_enc_utf8.isChecked():
- config.setting["wave_riff_info_encoding"] = "utf-8"
+ config.setting['wave_riff_info_encoding'] = 'utf-8'
else:
- config.setting["wave_riff_info_encoding"] = "windows-1252"
+ config.setting['wave_riff_info_encoding'] = 'windows-1252'
if WAVFile.supports_tag('artist'):
diff --git a/picard/ui/passworddialog.py b/picard/ui/passworddialog.py
index 43b32afc48..23f0c1f0f6 100644
--- a/picard/ui/passworddialog.py
+++ b/picard/ui/passworddialog.py
@@ -62,15 +62,15 @@ def __init__(self, authenticator, proxy, parent=None):
self.ui.setupUi(self)
config = get_config()
self.ui.info_text.setText(_("The proxy %s requires you to login. Please enter your username and password.")
- % config.setting["proxy_server_host"])
- self.ui.username.setText(config.setting["proxy_username"])
- self.ui.password.setText(config.setting["proxy_password"])
+ % config.setting['proxy_server_host'])
+ self.ui.username.setText(config.setting['proxy_username'])
+ self.ui.password.setText(config.setting['proxy_password'])
self.ui.buttonbox.accepted.connect(self.set_proxy_password)
def set_proxy_password(self):
config = get_config()
- config.setting["proxy_username"] = self.ui.username.text()
- config.setting["proxy_password"] = self.ui.password.text()
+ config.setting['proxy_username'] = self.ui.username.text()
+ config.setting['proxy_password'] = self.ui.password.text()
self._authenticator.setUser(self.ui.username.text())
self._authenticator.setPassword(self.ui.password.text())
self.accept()
diff --git a/picard/ui/playertoolbar.py b/picard/ui/playertoolbar.py
index 76d26c4b83..6686833c87 100644
--- a/picard/ui/playertoolbar.py
+++ b/picard/ui/playertoolbar.py
@@ -88,14 +88,14 @@ def __init__(self, parent):
self._toolbar = None
self._selected_objects = []
if qt_multimedia_available:
- log.debug('Internal player: QtMultimedia available, initializing QMediaPlayer')
+ log.debug("Internal player: QtMultimedia available, initializing QMediaPlayer")
player = QtMultimedia.QMediaPlayer(parent)
player.setAudioRole(QtMultimedia.QAudio.Role.MusicRole)
self.state_changed = player.stateChanged
self._logarithmic_volume = get_logarithmic_volume(player.volume())
availability = player.availability()
if availability == QtMultimedia.QMultimedia.AvailabilityStatus.Available:
- log.debug('Internal player: available, QMediaPlayer set up')
+ log.debug("Internal player: available, QMediaPlayer set up")
self._player = player
self._player.error.connect(self._on_error)
elif availability == QtMultimedia.QMultimedia.AvailabilityStatus.ServiceMissing:
@@ -187,7 +187,7 @@ def _on_error(self, error):
class PlayerToolbar(QtWidgets.QToolBar):
def __init__(self, parent, player):
super().__init__(_("Player"), parent)
- self.setObjectName("player_toolbar")
+ self.setObjectName('player_toolbar')
self.setAllowedAreas(QtCore.Qt.ToolBarArea.TopToolBarArea
| QtCore.Qt.ToolBarArea.BottomToolBarArea
| QtCore.Qt.ToolBarArea.NoToolBarArea)
@@ -218,14 +218,14 @@ def __init__(self, parent, player):
self.addWidget(self.progress_widget)
config = get_config()
- volume = config.persist["mediaplayer_volume"]
+ volume = config.persist['mediaplayer_volume']
self.player.set_volume(volume)
self.volume_button = VolumeControlButton(self, volume)
self.volume_button.volume_changed.connect(self.player.set_volume)
self.volume_button.setToolButtonStyle(self.toolButtonStyle())
self.addWidget(self.volume_button)
- playback_rate = config.persist["mediaplayer_playback_rate"]
+ playback_rate = config.persist['mediaplayer_playback_rate']
self.player.set_playback_rate(playback_rate)
self.playback_rate_button = PlaybackRateButton(self, playback_rate)
self.playback_rate_button.playback_rate_changed.connect(self.player.set_playback_rate)
@@ -273,7 +273,7 @@ def __init__(self, parent, player):
self.player = player
self._position_update = False
- tool_font = QtWidgets.QApplication.font("QToolButton")
+ tool_font = QtWidgets.QApplication.font('QToolButton')
self.progress_slider = ClickableSlider(self)
self.progress_slider.setOrientation(QtCore.Qt.Orientation.Horizontal)
@@ -340,20 +340,20 @@ class PlaybackRateButton(QtWidgets.QToolButton):
def __init__(self, parent, playback_rate):
super().__init__(parent)
self.popover_position = 'bottom'
- self.rate_fmt = N_('%1.1f ×')
+ self.rate_fmt = N_("%1.1f ×")
button_margin = self.style().pixelMetric(QtWidgets.QStyle.PixelMetric.PM_ButtonMargin)
min_width = get_text_width(self.font(), _(self.rate_fmt) % 8.8)
self.setMinimumWidth(min_width + (2 * button_margin) + 2)
self.set_playback_rate(playback_rate)
self.clicked.connect(self.show_popover)
- tooltip = _('Change playback speed')
+ tooltip = _("Change playback speed")
self.setToolTip(tooltip)
self.setStatusTip(tooltip)
def show_popover(self):
slider_value = self.playback_rate * self.multiplier
popover = SliderPopover(
- self, self.popover_position, _('Playback speed'), slider_value)
+ self, self.popover_position, _("Playback speed"), slider_value)
# In 0.1 steps from 0.5 to 1.5
popover.slider.setMinimum(5)
popover.slider.setMaximum(15)
@@ -396,19 +396,19 @@ def __init__(self, parent, volume):
super().__init__(parent)
self.popover_position = 'bottom'
self.step = 3
- self.volume_fmt = N_('%d%%')
+ self.volume_fmt = N_("%d%%")
self.set_volume(volume)
button_margin = self.style().pixelMetric(QtWidgets.QStyle.PixelMetric.PM_ButtonMargin)
min_width = get_text_width(self.font(), _(self.volume_fmt) % 888)
self.setMinimumWidth(min_width + (2 * button_margin) + 2)
self.clicked.connect(self.show_popover)
- tooltip = _('Change audio volume')
+ tooltip = _("Change audio volume")
self.setToolTip(tooltip)
self.setStatusTip(tooltip)
def show_popover(self):
popover = SliderPopover(
- self, self.popover_position, _('Audio volume'), self.volume)
+ self, self.popover_position, _("Audio volume"), self.volume)
popover.slider.setMinimum(0)
popover.slider.setMaximum(100)
popover.slider.setPageStep(self.step)
diff --git a/picard/ui/ratingwidget.py b/picard/ui/ratingwidget.py
index 4fd87e0440..5de3621cdf 100644
--- a/picard/ui/ratingwidget.py
+++ b/picard/ui/ratingwidget.py
@@ -39,9 +39,9 @@ def __init__(self, parent, track):
super().__init__(parent)
self._track = track
config = get_config()
- self._maximum = config.setting["rating_steps"] - 1
+ self._maximum = config.setting['rating_steps'] - 1
try:
- self._rating = int(track.metadata["~rating"] or 0)
+ self._rating = int(track.metadata['~rating'] or 0)
except ValueError:
self._rating = 0
self._highlight = 0
@@ -105,12 +105,12 @@ def _submitted(self, document, http, error):
def _update_track(self):
track = self._track
rating = str(self._rating)
- track.metadata["~rating"] = rating
+ track.metadata['~rating'] = rating
for file in track.files:
- file.metadata["~rating"] = rating
+ file.metadata['~rating'] = rating
config = get_config()
- if config.setting["submit_ratings"]:
- ratings = {("recording", track.id): self._rating}
+ if config.setting['submit_ratings']:
+ ratings = {('recording', track.id): self._rating}
try:
self.tagger.mb_api.submit_ratings(ratings, self._submitted)
except ValueError: # This should never happen as self._rating is always an integer
diff --git a/picard/ui/scripteditor.py b/picard/ui/scripteditor.py
index ed63318924..0e3faa92f8 100644
--- a/picard/ui/scripteditor.py
+++ b/picard/ui/scripteditor.py
@@ -137,7 +137,7 @@ def update_examples(self, override=None, script_text=None):
if script_text and isinstance(script_text, str):
self.script_text = script_text
- if self.settings["move_files"] or self.settings["rename_files"]:
+ if self.settings['move_files'] or self.settings['rename_files']:
if not self._sampled_example_files:
self.update_sample_example_files()
self.example_list = [self._example_to_filename(example) for example in self._sampled_example_files]
@@ -159,14 +159,14 @@ def _example_to_filename(self, file):
c_metadata.copy(file.metadata)
try:
# Only apply scripts if the original file metadata has not been changed.
- if self.settings["enable_tagger_scripts"] and not c_metadata.diff(file.orig_metadata):
- for s_pos, s_name, s_enabled, s_text in self.settings["list_of_scripts"]:
+ if self.settings['enable_tagger_scripts'] and not c_metadata.diff(file.orig_metadata):
+ for s_pos, s_name, s_enabled, s_text in self.settings['list_of_scripts']:
if s_enabled and s_text:
parser = ScriptParser()
parser.eval(s_text, c_metadata)
filename_before = file.filename
filename_after = file.make_filename(filename_before, c_metadata, self.settings, self.script_text)
- if not self.settings["move_files"]:
+ if not self.settings['move_files']:
return os.path.basename(filename_before), os.path.basename(filename_after)
return filename_before, filename_after
except (ScriptError, TypeError, WinPathTooLong):
@@ -316,7 +316,7 @@ def confirmation_dialog(parent, message):
"""
dialog = QtWidgets.QMessageBox(
QtWidgets.QMessageBox.Icon.Warning,
- _('Confirm'),
+ _("Confirm"),
message,
QtWidgets.QMessageBox.StandardButton.Ok | QtWidgets.QMessageBox.StandardButton.Cancel,
parent
@@ -395,15 +395,15 @@ class ScriptEditorDialog(PicardDialog, SingletonDialog):
PROFILES_KEY = SettingConfigSection.PROFILES_KEY
SETTINGS_KEY = SettingConfigSection.SETTINGS_KEY
- SELECTED_SCRIPT_KEY = "selected_file_naming_script_id"
- SCRIPTS_LIST_KEY = "file_renaming_scripts"
+ SELECTED_SCRIPT_KEY = 'selected_file_naming_script_id'
+ SCRIPTS_LIST_KEY = 'file_renaming_scripts'
- help_url = PICARD_URLS["doc_naming_script_edit"]
+ help_url = PICARD_URLS['doc_naming_script_edit']
options = [
BoolOption('persist', 'script_editor_show_documentation', False),
- Option("setting", SCRIPTS_LIST_KEY, {}),
- TextOption("setting", SELECTED_SCRIPT_KEY, ""),
+ Option('setting', SCRIPTS_LIST_KEY, {}),
+ TextOption('setting', SELECTED_SCRIPT_KEY, ''),
]
signal_save = QtCore.pyqtSignal()
@@ -456,7 +456,7 @@ def __init__(self, parent=None, examples=None):
self.installEventFilter(self)
# Dialog buttons
- self.reset_button = QtWidgets.QPushButton(_('Reset'))
+ self.reset_button = QtWidgets.QPushButton(_("Reset"))
self.reset_button.setToolTip(self.reset_action.toolTip())
self.reset_button.clicked.connect(self.reload_from_config)
self.ui.buttonbox.addButton(self.reset_button, QtWidgets.QDialogButtonBox.ButtonRole.ActionRole)
@@ -530,7 +530,7 @@ def make_menu(self):
main_menu = QtWidgets.QMenuBar()
# File menu settings
- file_menu = main_menu.addMenu(_('&File'))
+ file_menu = main_menu.addMenu(_("&File"))
file_menu.setToolTipsVisible(True)
self.import_action = QtWidgets.QAction(_("&Import a script file"), self)
@@ -563,7 +563,7 @@ def make_menu(self):
file_menu.addAction(self.close_action)
# Script menu settings
- script_menu = main_menu.addMenu(_('&Script'))
+ script_menu = main_menu.addMenu(_("&Script"))
script_menu.setToolTipsVisible(True)
self.details_action = QtWidgets.QAction(_("View/Edit Script &Metadata"), self)
@@ -590,7 +590,7 @@ def make_menu(self):
script_menu.addAction(self.delete_action)
# Display menu settings
- display_menu = main_menu.addMenu(_('&View'))
+ display_menu = main_menu.addMenu(_("&View"))
display_menu.setToolTipsVisible(True)
self.examples_action = QtWidgets.QAction(_("&Reload random example files"), self)
@@ -611,7 +611,7 @@ def make_menu(self):
display_menu.addAction(self.docs_action)
# Help menu settings
- help_menu = main_menu.addMenu(_('&Help'))
+ help_menu = main_menu.addMenu(_("&Help"))
help_menu.setToolTipsVisible(True)
self.help_action = QtWidgets.QAction(_("&Help…"), self)
@@ -638,7 +638,7 @@ def _add_menu_item(title, script):
self.add_action.addAction(script_action)
# Add blank script template
- _add_menu_item(_('Empty / blank script'), f"$noop( {_('New Script')} )")
+ _add_menu_item(_("Empty / blank script"), f"$noop( {_('New Script')} )")
# Add preset script templates
for script_item in get_file_naming_script_presets():
@@ -802,12 +802,12 @@ def scripts_in_profiles(self):
profiles = config.profiles[self.PROFILES_KEY]
profile_settings = config.profiles[self.SETTINGS_KEY]
for profile in profiles:
- settings = profile_settings[profile["id"]]
+ settings = profile_settings[profile['id']]
if self.SELECTED_SCRIPT_KEY in settings:
profiles_list.append(
self.Profile(
- profile["id"],
- profile["title"],
+ profile['id'],
+ profile['title'],
settings[self.SELECTED_SCRIPT_KEY]
)
)
@@ -818,7 +818,7 @@ def update_script_text(self):
"""
selected = self.ui.preset_naming_scripts.currentIndex()
script_item = self.ui.preset_naming_scripts.itemData(selected)
- script_item["script"] = self.get_script()
+ script_item['script'] = self.get_script()
self.update_combo_box_item(selected, script_item)
def check_duplicate_script_title(self, new_title=None):
@@ -849,7 +849,7 @@ def update_script_title(self):
script_item = self.ui.preset_naming_scripts.itemData(selected)
if title:
if self.check_duplicate_script_title(new_title=title):
- script_item["title"] = title
+ script_item['title'] = title
self.update_combo_box_item(selected, script_item)
self.save_script()
self.signal_selection_changed.emit()
@@ -858,7 +858,7 @@ def update_script_title(self):
self.ui.script_title.setFocus()
else:
self.display_error(OptionsCheckError(_("Error"), _("The script title must not be empty.")))
- self.ui.script_title.setText(script_item["title"])
+ self.ui.script_title.setText(script_item['title'])
self.ui.script_title.setFocus()
def populate_script_selector(self):
@@ -872,7 +872,7 @@ def toggle_documentation(self):
"""
checked = self.docs_action.isChecked()
config = get_config()
- config.persist["script_editor_show_documentation"] = checked
+ config.persist['script_editor_show_documentation'] = checked
self.ui.documentation_frame.setVisible(checked)
def view_script_details(self):
@@ -916,7 +916,7 @@ def _insert_item(self, script_item):
Args:
script_item (dict): File naming script to insert as produced by FileNamingScript().to_dict()
"""
- self.selected_script_id = script_item["id"]
+ self.selected_script_id = script_item['id']
self.naming_scripts[self.selected_script_id] = script_item
idx = populate_script_selection_combo_box(
self.naming_scripts,
@@ -958,11 +958,11 @@ def make_it_so(self):
"""Save the scripts and settings to configuration and exit.
"""
script_item = self.get_selected_item()
- self.selected_script_id = script_item["id"]
+ self.selected_script_id = script_item['id']
self.naming_scripts = self.get_scripts_dict()
config = get_config()
config.setting[self.SCRIPTS_LIST_KEY] = self.naming_scripts
- config.setting[self.SELECTED_SCRIPT_KEY] = script_item["id"]
+ config.setting[self.SELECTED_SCRIPT_KEY] = script_item['id']
self.close()
def get_scripts_dict(self):
@@ -974,7 +974,7 @@ def get_scripts_dict(self):
naming_scripts = {}
for idx in range(self.ui.preset_naming_scripts.count()):
script_item = self.ui.preset_naming_scripts.itemData(idx)
- naming_scripts[script_item["id"]] = script_item
+ naming_scripts[script_item['id']] = script_item
return naming_scripts
def get_selected_item(self, idx=None):
@@ -999,7 +999,7 @@ def set_selected_script_id(self, id):
idx = 0
for i in range(self.ui.preset_naming_scripts.count()):
script_item = self.ui.preset_naming_scripts.itemData(i)
- if script_item["id"] == id:
+ if script_item['id'] == id:
idx = i
break
self.set_selected_script_index(idx)
@@ -1119,7 +1119,7 @@ def delete_script(self):
).exec_()
return
- if confirmation_dialog(self, _('Are you sure that you want to delete the script?')):
+ if confirmation_dialog(self, _("Are you sure that you want to delete the script?")):
widget = self.ui.preset_naming_scripts
idx = widget.currentIndex()
widget.blockSignals(True)
@@ -1159,8 +1159,8 @@ def save_script(self):
if title:
script_item = self.ui.preset_naming_scripts.itemData(selected)
if self.check_duplicate_script_title(new_title=title):
- script_item["title"] = title
- script_item["script"] = self.get_script()
+ script_item['title'] = title
+ script_item['script'] = self.get_script()
self.update_combo_box_item(selected, script_item)
else:
self.display_error(OptionsCheckError(_("Error"), _("The script title must not be empty.")))
@@ -1224,7 +1224,7 @@ def import_script(self):
continue
box = QtWidgets.QMessageBox()
box.setIcon(QtWidgets.QMessageBox.Icon.Question)
- box.setWindowTitle(_('Confirm'))
+ box.setWindowTitle(_("Confirm"))
box.setText(
_(
"A script named \"{script_name}\" already exists.\n"
@@ -1279,7 +1279,7 @@ def check_format(self):
parser.eval(script_text)
except Exception as e:
raise ScriptCheckError("", str(e))
- if config.setting["rename_files"]:
+ if config.setting['rename_files']:
if not self.get_script():
raise ScriptCheckError("", _("The file naming format must not be empty."))
@@ -1318,7 +1318,7 @@ class ScriptDetailsEditor(PicardDialog):
"""View / edit the metadata details for a script.
"""
NAME = 'scriptdetails'
- TITLE = N_('Script Details')
+ TITLE = N_("Script Details")
signal_save = QtCore.pyqtSignal()
@@ -1401,12 +1401,12 @@ def save_changes(self):
last_updated = self.ui.script_last_updated
if not last_updated.isModified() or not last_updated.text().strip():
self.set_last_updated()
- self.script_item["title"] = self.ui.script_title.text().strip()
- self.script_item["author"] = self.ui.script_author.text().strip()
- self.script_item["version"] = self.ui.script_version.text().strip()
- self.script_item["license"] = self.ui.script_license.text().strip()
- self.script_item["description"] = self.ui.script_description.toPlainText().strip()
- self.script_item["last_updated"] = self.ui.script_last_updated.text().strip()
+ self.script_item['title'] = self.ui.script_title.text().strip()
+ self.script_item['author'] = self.ui.script_author.text().strip()
+ self.script_item['version'] = self.ui.script_version.text().strip()
+ self.script_item['license'] = self.ui.script_license.text().strip()
+ self.script_item['description'] = self.ui.script_description.toPlainText().strip()
+ self.script_item['last_updated'] = self.ui.script_last_updated.text().strip()
self.signal_save.emit()
self.skip_change_check = True
self.close_window()
diff --git a/picard/ui/searchdialog/__init__.py b/picard/ui/searchdialog/__init__.py
index 23bd979635..cc69f65e65 100644
--- a/picard/ui/searchdialog/__init__.py
+++ b/picard/ui/searchdialog/__init__.py
@@ -51,7 +51,7 @@ def __init__(self, parent, force_advanced_search=None):
if force_advanced_search is None:
config = get_config()
self.force_advanced_search = False
- self.use_advanced_search = config.setting["use_adv_search_syntax"]
+ self.use_advanced_search = config.setting['use_adv_search_syntax']
else:
self.force_advanced_search = True
self.use_advanced_search = force_advanced_search
@@ -118,7 +118,7 @@ def update_advanced_syntax_setting(self):
self.use_advanced_search = self.use_adv_search_syntax.isChecked()
if not self.force_advanced_search:
config = get_config()
- config.setting["use_adv_search_syntax"] = self.use_advanced_search
+ config.setting['use_adv_search_syntax'] = self.use_advanced_search
def enable_search(self):
if self.query:
@@ -139,7 +139,7 @@ def set_query(self, query):
query = property(get_query, set_query)
-Retry = namedtuple("Retry", ["function", "query"])
+Retry = namedtuple('Retry', ['function', 'query'])
class SearchDialog(TableBasedDialog):
@@ -162,22 +162,22 @@ def use_advanced_search(self):
return self.force_advanced_search
else:
config = get_config()
- return config.setting["use_adv_search_syntax"]
+ return config.setting['use_adv_search_syntax']
def get_value_for_row_id(self, row, value):
return row
def setupUi(self):
self.verticalLayout = QtWidgets.QVBoxLayout(self)
- self.verticalLayout.setObjectName("vertical_layout")
+ self.verticalLayout.setObjectName('vertical_layout')
if self.show_search:
self.search_box = SearchBox(self, force_advanced_search=self.force_advanced_search)
- self.search_box.setObjectName("search_box")
+ self.search_box.setObjectName('search_box')
self.verticalLayout.addWidget(self.search_box)
self.center_widget = QtWidgets.QWidget(self)
- self.center_widget.setObjectName("center_widget")
+ self.center_widget.setObjectName('center_widget')
self.center_layout = QtWidgets.QVBoxLayout(self.center_widget)
- self.center_layout.setObjectName("center_layout")
+ self.center_layout.setObjectName('center_layout')
self.center_layout.setContentsMargins(1, 1, 1, 1)
self.center_widget.setLayout(self.center_layout)
self.verticalLayout.addWidget(self.center_widget)
@@ -205,7 +205,7 @@ def setupUi(self):
def show_progress(self):
progress_widget = QtWidgets.QWidget(self)
- progress_widget.setObjectName("progress_widget")
+ progress_widget.setObjectName('progress_widget')
layout = QtWidgets.QVBoxLayout(progress_widget)
text_label = QtWidgets.QLabel(_('Loading…'), progress_widget)
text_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignHCenter | QtCore.Qt.AlignmentFlag.AlignBottom)
@@ -228,7 +228,7 @@ def show_error(self, error, show_retry_button=False):
show_retry_button -- Whether to display retry button or not
"""
error_widget = QtWidgets.QWidget(self)
- error_widget.setObjectName("error_widget")
+ error_widget.setObjectName('error_widget')
layout = QtWidgets.QVBoxLayout(error_widget)
error_label = QtWidgets.QLabel(error, error_widget)
error_label.setWordWrap(True)
diff --git a/picard/ui/searchdialog/album.py b/picard/ui/searchdialog/album.py
index 8b15dc6597..83a85b19c2 100644
--- a/picard/ui/searchdialog/album.py
+++ b/picard/ui/searchdialog/album.py
@@ -133,17 +133,17 @@ def invalidate(self):
class AlbumSearchDialog(SearchDialog):
- dialog_header_state = "albumsearchdialog_header_state"
+ dialog_header_state = 'albumsearchdialog_header_state'
options = [
- Option("persist", dialog_header_state, QtCore.QByteArray())
+ Option('persist', dialog_header_state, QtCore.QByteArray())
]
def __init__(self, parent, force_advanced_search=None, existing_album=None):
super().__init__(
parent,
accept_button_title=_("Load into Picard"),
- search_type="album",
+ search_type='album',
force_advanced_search=force_advanced_search)
self.cluster = None
self.existing_album = existing_album
@@ -206,7 +206,7 @@ def show_similar_albums(self, cluster):
if self.use_advanced_search:
query_str = build_lucene_query(query)
else:
- query_str = query["release"]
+ query_str = query['release']
self.search(query_str)
def retry(self):
@@ -245,7 +245,7 @@ def fetch_coverart(self, cell):
if not cell.is_visible():
return
cell.fetched = True
- mbid = cell.release["musicbrainz_albumid"]
+ mbid = cell.release['musicbrainz_albumid']
cell.fetch_task = self.tagger.webservice.get_url(
url=f'{CAA_URL}/release/{mbid}',
handler=partial(self._caa_json_downloaded, cell),
@@ -264,14 +264,14 @@ def _caa_json_downloaded(self, cover_cell, data, http, error):
front = None
try:
- for image in data["images"]:
- if image["front"]:
+ for image in data['images']:
+ if image['front']:
front = image
break
if front:
cover_cell.fetch_task = self.tagger.webservice.download_url(
- url=front["thumbnails"]["small"],
+ url=front['thumbnails']['small'],
handler=partial(self._cover_downloaded, cover_cell)
)
else:
@@ -320,13 +320,13 @@ def parse_releases(self, releases):
release['score'] = node['score']
rg_node = node['release-group']
release_group_to_metadata(rg_node, release)
- if "media" in node:
+ if 'media' in node:
media = node['media']
- release["format"] = media_formats_from_node(media)
- release["tracks"] = node['track-count']
+ release['format'] = media_formats_from_node(media)
+ release['tracks'] = node['track-count']
countries = countries_from_node(node)
if countries:
- release["country"] = countries_shortlist(countries)
+ release['country'] = countries_shortlist(countries)
self.search_results.append(release)
def display_results(self):
@@ -335,19 +335,19 @@ def display_results(self):
column = self.colpos('cover')
for row, release in enumerate(self.search_results):
self.table.insertRow(row)
- self.set_table_item(row, 'name', release, "album")
- self.set_table_item(row, 'artist', release, "albumartist")
- self.set_table_item(row, 'format', release, "format")
- self.set_table_item(row, 'tracks', release, "tracks")
- self.set_table_item(row, 'date', release, "date")
- self.set_table_item(row, 'country', release, "country")
- self.set_table_item(row, 'labels', release, "label")
- self.set_table_item(row, 'catnums', release, "catalognumber")
- self.set_table_item(row, 'barcode', release, "barcode")
- self.set_table_item(row, 'language', release, "~releaselanguage")
- self.set_table_item(row, 'type', release, "releasetype")
- self.set_table_item(row, 'status', release, "releasestatus")
- self.set_table_item(row, 'score', release, "score")
+ self.set_table_item(row, 'name', release, 'album')
+ self.set_table_item(row, 'artist', release, 'albumartist')
+ self.set_table_item(row, 'format', release, 'format')
+ self.set_table_item(row, 'tracks', release, 'tracks')
+ self.set_table_item(row, 'date', release, 'date')
+ self.set_table_item(row, 'country', release, 'country')
+ self.set_table_item(row, 'labels', release, 'label')
+ self.set_table_item(row, 'catnums', release, 'catalognumber')
+ self.set_table_item(row, 'barcode', release, 'barcode')
+ self.set_table_item(row, 'language', release, '~releaselanguage')
+ self.set_table_item(row, 'type', release, 'releasetype')
+ self.set_table_item(row, 'status', release, 'releasestatus')
+ self.set_table_item(row, 'score', release, 'score')
self.cover_cells.append(CoverCell(self.table, release, row, column,
on_show=self.fetch_coverart))
if self.existing_album and release['musicbrainz_albumid'] == self.existing_album.id:
@@ -360,12 +360,12 @@ def accept_event(self, rows):
def load_selection(self, row):
release = self.search_results[row]
- release_mbid = release["musicbrainz_albumid"]
+ release_mbid = release['musicbrainz_albumid']
if self.existing_album:
self.existing_album.switch_release_version(release_mbid)
else:
self.tagger.get_release_group_by_id(
- release["musicbrainz_releasegroupid"]).loaded_albums.add(
+ release['musicbrainz_releasegroupid']).loaded_albums.add(
release_mbid)
album = self.tagger.load_album(release_mbid)
if self.cluster:
diff --git a/picard/ui/searchdialog/artist.py b/picard/ui/searchdialog/artist.py
index e8b6ab1d11..4787cf379e 100644
--- a/picard/ui/searchdialog/artist.py
+++ b/picard/ui/searchdialog/artist.py
@@ -38,17 +38,17 @@
class ArtistSearchDialog(SearchDialog):
- dialog_header_state = "artistsearchdialog_header_state"
+ dialog_header_state = 'artistsearchdialog_header_state'
options = [
- Option("persist", dialog_header_state, QtCore.QByteArray())
+ Option('persist', dialog_header_state, QtCore.QByteArray())
]
def __init__(self, parent):
super().__init__(
parent,
accept_button_title=_("Show in browser"),
- search_type="artist")
+ search_type='artist')
self.setWindowTitle(_("Artist Search Dialog"))
self.columns = [
('name', _("Name")),
@@ -102,15 +102,15 @@ def display_results(self):
self.prepare_table()
for row, artist in enumerate(self.search_results):
self.table.insertRow(row)
- self.set_table_item(row, 'name', artist, "name")
- self.set_table_item(row, 'type', artist, "type")
- self.set_table_item(row, 'gender', artist, "gender")
- self.set_table_item(row, 'area', artist, "area")
- self.set_table_item(row, 'begindate', artist, "begindate")
- self.set_table_item(row, 'beginarea', artist, "beginarea")
- self.set_table_item(row, 'enddate', artist, "enddate")
- self.set_table_item(row, 'endarea', artist, "endarea")
- self.set_table_item(row, 'score', artist, "score")
+ self.set_table_item(row, 'name', artist, 'name')
+ self.set_table_item(row, 'type', artist, 'type')
+ self.set_table_item(row, 'gender', artist, 'gender')
+ self.set_table_item(row, 'area', artist, 'area')
+ self.set_table_item(row, 'begindate', artist, 'begindate')
+ self.set_table_item(row, 'beginarea', artist, 'beginarea')
+ self.set_table_item(row, 'enddate', artist, 'enddate')
+ self.set_table_item(row, 'endarea', artist, 'endarea')
+ self.set_table_item(row, 'score', artist, 'score')
self.show_table(sort_column='score')
def accept_event(self, rows):
@@ -118,4 +118,4 @@ def accept_event(self, rows):
self.load_in_browser(row)
def load_in_browser(self, row):
- self.tagger.search(self.search_results[row]["musicbrainz_artistid"], "artist")
+ self.tagger.search(self.search_results[row]['musicbrainz_artistid'], 'artist')
diff --git a/picard/ui/searchdialog/track.py b/picard/ui/searchdialog/track.py
index f61d97a332..0489496d3f 100644
--- a/picard/ui/searchdialog/track.py
+++ b/picard/ui/searchdialog/track.py
@@ -51,17 +51,17 @@
class TrackSearchDialog(SearchDialog):
- dialog_header_state = "tracksearchdialog_header_state"
+ dialog_header_state = 'tracksearchdialog_header_state'
options = [
- Option("persist", dialog_header_state, QtCore.QByteArray())
+ Option('persist', dialog_header_state, QtCore.QByteArray())
]
def __init__(self, parent, force_advanced_search=None):
super().__init__(
parent,
accept_button_title=_("Load into Picard"),
- search_type="track",
+ search_type='track',
force_advanced_search=force_advanced_search)
self.file_ = None
self.setWindowTitle(_("Track Search Results"))
@@ -108,7 +108,7 @@ def show_similar_tracks(self, file_):
if self.use_advanced_search:
query_str = build_lucene_query(query)
else:
- query_str = query["track"]
+ query_str = query['track']
self.search(query_str)
def retry(self):
@@ -142,19 +142,19 @@ def display_results(self):
for row, obj in enumerate(self.search_results):
track = obj[0]
self.table.insertRow(row)
- self.set_table_item(row, 'name', track, "title")
- self.set_table_item(row, 'length', track, "~length", sortkey=track.length)
- self.set_table_item(row, 'artist', track, "artist")
- self.set_table_item(row, 'release', track, "album")
- self.set_table_item(row, 'date', track, "date")
- self.set_table_item(row, 'country', track, "country")
- self.set_table_item(row, 'type', track, "releasetype")
- self.set_table_item(row, 'score', track, "score")
+ self.set_table_item(row, 'name', track, 'title')
+ self.set_table_item(row, 'length', track, '~length', sortkey=track.length)
+ self.set_table_item(row, 'artist', track, 'artist')
+ self.set_table_item(row, 'release', track, 'album')
+ self.set_table_item(row, 'date', track, 'date')
+ self.set_table_item(row, 'country', track, 'country')
+ self.set_table_item(row, 'type', track, 'releasetype')
+ self.set_table_item(row, 'score', track, 'score')
self.show_table(sort_column='score')
def parse_tracks(self, tracks):
for node in tracks:
- if "releases" in node:
+ if 'releases' in node:
for rel_node in node['releases']:
track = Metadata()
recording_to_metadata(node, track)
@@ -164,7 +164,7 @@ def parse_tracks(self, tracks):
release_group_to_metadata(rg_node, track)
countries = countries_from_node(rel_node)
if countries:
- track["country"] = countries_shortlist(countries)
+ track['country'] = countries_shortlist(countries)
self.search_results.append((track, node))
else:
# This handles the case when no release is associated with a track
@@ -186,30 +186,30 @@ def load_selection(self, row):
"""
track, node = self.search_results[row]
- if track.get("musicbrainz_albumid"):
+ if track.get('musicbrainz_albumid'):
# The track is not an NAT
- self.tagger.get_release_group_by_id(track["musicbrainz_releasegroupid"]).loaded_albums.add(
- track["musicbrainz_albumid"])
+ self.tagger.get_release_group_by_id(track['musicbrainz_releasegroupid']).loaded_albums.add(
+ track['musicbrainz_albumid'])
if self.file_:
# Search is performed for a file.
# Have to move that file from its existing album to the new one.
if isinstance(self.file_.parent, Track):
album = self.file_.parent.album
- self.tagger.move_file_to_track(self.file_, track["musicbrainz_albumid"], track["musicbrainz_recordingid"])
+ self.tagger.move_file_to_track(self.file_, track['musicbrainz_albumid'], track['musicbrainz_recordingid'])
if album.get_num_total_files() == 0:
# Remove album if it has no more files associated
self.tagger.remove_album(album)
else:
- self.tagger.move_file_to_track(self.file_, track["musicbrainz_albumid"], track["musicbrainz_recordingid"])
+ self.tagger.move_file_to_track(self.file_, track['musicbrainz_albumid'], track['musicbrainz_recordingid'])
else:
# No files associated. Just a normal search.
- self.tagger.load_album(track["musicbrainz_albumid"])
+ self.tagger.load_album(track['musicbrainz_albumid'])
else:
if self.file_ and getattr(self.file_.parent, 'album', None):
album = self.file_.parent.album
- self.tagger.move_file_to_nat(self.file_, track["musicbrainz_recordingid"], node)
+ self.tagger.move_file_to_nat(self.file_, track['musicbrainz_recordingid'], node)
if album.get_num_total_files() == 0:
self.tagger.remove_album(album)
else:
- self.tagger.load_nat(track["musicbrainz_recordingid"], node)
- self.tagger.move_file_to_nat(self.file_, track["musicbrainz_recordingid"], node)
+ self.tagger.load_nat(track['musicbrainz_recordingid'], node)
+ self.tagger.move_file_to_nat(self.file_, track['musicbrainz_recordingid'], node)
diff --git a/picard/ui/statusindicator.py b/picard/ui/statusindicator.py
index 847946c305..4ce84d10fc 100644
--- a/picard/ui/statusindicator.py
+++ b/picard/ui/statusindicator.py
@@ -129,8 +129,8 @@ def __init__(self, bus, app_id):
@property
def current_progress(self):
return {
- "progress": self._progress,
- "progress-visible": self._visible,
+ 'progress': self._progress,
+ 'progress-visible': self._visible,
}
@property
diff --git a/picard/ui/tagsfromfilenames.py b/picard/ui/tagsfromfilenames.py
index 570f33bd4b..3e3caedb3f 100644
--- a/picard/ui/tagsfromfilenames.py
+++ b/picard/ui/tagsfromfilenames.py
@@ -101,7 +101,7 @@ class TagsFromFileNamesDialog(PicardDialog):
help_url = 'doc_tags_from_filenames'
options = [
- TextOption("persist", "tags_from_filenames_format", ""),
+ TextOption('persist', 'tags_from_filenames_format', ''),
]
def __init__(self, files, parent=None):
@@ -118,7 +118,7 @@ def __init__(self, files, parent=None):
"%artist% - %album%/%tracknumber% - %title%",
]
config = get_config()
- tff_format = config.persist["tags_from_filenames_format"]
+ tff_format = config.persist['tags_from_filenames_format']
if tff_format not in items:
selected_index = 0
if tff_format:
@@ -163,5 +163,5 @@ def accept(self):
file.metadata.update(metadata)
file.update()
config = get_config()
- config.persist["tags_from_filenames_format"] = self.ui.format.currentText()
+ config.persist['tags_from_filenames_format'] = self.ui.format.currentText()
super().accept()
diff --git a/picard/ui/theme.py b/picard/ui/theme.py
index c445dafd8a..8714d80cab 100644
--- a/picard/ui/theme.py
+++ b/picard/ui/theme.py
@@ -178,7 +178,7 @@ def is_dark_theme(self):
r"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize") as key:
dark_theme = winreg.QueryValueEx(key, "AppsUseLightTheme")[0] == 0
except OSError:
- log.warning('Failed reading AppsUseLightTheme from registry')
+ log.warning("Failed reading AppsUseLightTheme from registry")
return dark_theme
@property
@@ -190,7 +190,7 @@ def accent_color(self):
accent_color_hex = '#{:06x}'.format(accent_color_dword & 0xffffff)
accent_color = QtGui.QColor(accent_color_hex)
except OSError:
- log.warning('Failed reading ColorizationColor from registry')
+ log.warning("Failed reading ColorizationColor from registry")
return accent_color
def update_palette(self, palette, dark_theme, accent_color):
diff --git a/picard/ui/util.py b/picard/ui/util.py
index 8a164656ec..9db80f7616 100644
--- a/picard/ui/util.py
+++ b/picard/ui/util.py
@@ -46,10 +46,10 @@ class StandardButton(QtWidgets.QPushButton):
CLOSE = 4
__types = {
- OK: (N_('&Ok'), 'SP_DialogOkButton'),
- CANCEL: (N_('&Cancel'), 'SP_DialogCancelButton'),
- HELP: (N_('&Help'), 'SP_DialogHelpButton'),
- CLOSE: (N_('Clos&e'), 'SP_DialogCloseButton'),
+ OK: (N_("&Ok"), 'SP_DialogOkButton'),
+ CANCEL: (N_("&Cancel"), 'SP_DialogCancelButton'),
+ HELP: (N_("&Help"), 'SP_DialogHelpButton'),
+ CLOSE: (N_("Clos&e"), 'SP_DialogCloseButton'),
}
def __init__(self, btntype):
@@ -65,10 +65,10 @@ def __init__(self, btntype):
def find_starting_directory():
config = get_config()
- if config.setting["starting_directory"]:
- path = config.setting["starting_directory_path"]
+ if config.setting['starting_directory']:
+ path = config.setting['starting_directory_path']
else:
- path = config.persist["current_directory"] or QtCore.QDir.homePath()
+ path = config.persist['current_directory'] or QtCore.QDir.homePath()
return find_existing_path(path)
diff --git a/picard/ui/widgets/scriptdocumentation.py b/picard/ui/widgets/scriptdocumentation.py
index 2a3756dc55..7897cb62a8 100644
--- a/picard/ui/widgets/scriptdocumentation.py
+++ b/picard/ui/widgets/scriptdocumentation.py
@@ -110,17 +110,17 @@ def process_html(html, function):
self.verticalLayout = QtWidgets.QVBoxLayout(self)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
- self.verticalLayout.setObjectName("docs_verticalLayout")
+ self.verticalLayout.setObjectName('docs_verticalLayout')
self.textBrowser = QtWidgets.QTextBrowser(self)
self.textBrowser.setEnabled(True)
self.textBrowser.setMinimumSize(QtCore.QSize(0, 0))
- self.textBrowser.setObjectName("docs_textBrowser")
+ self.textBrowser.setObjectName('docs_textBrowser')
self.textBrowser.setHtml(html)
self.textBrowser.show()
self.verticalLayout.addWidget(self.textBrowser)
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setContentsMargins(-1, 0, -1, -1)
- self.horizontalLayout.setObjectName("docs_horizontalLayout")
+ self.horizontalLayout.setObjectName('docs_horizontalLayout')
self.scripting_doc_link = QtWidgets.QLabel(self)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Preferred)
sizePolicy.setHorizontalStretch(0)
@@ -132,7 +132,7 @@ def process_html(html, function):
self.scripting_doc_link.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.scripting_doc_link.setWordWrap(True)
self.scripting_doc_link.setOpenExternalLinks(True)
- self.scripting_doc_link.setObjectName("docs_scripting_doc_link")
+ self.scripting_doc_link.setObjectName('docs_scripting_doc_link')
self.scripting_doc_link.setText(link)
self.scripting_doc_link.show()
self.horizontalLayout.addWidget(self.scripting_doc_link)
diff --git a/picard/util/__init__.py b/picard/util/__init__.py
index a83d8b9d93..5f211c6fba 100644
--- a/picard/util/__init__.py
+++ b/picard/util/__init__.py
@@ -245,7 +245,7 @@ def system_supports_long_paths():
system_supports_long_paths._supported = supported
return supported
except OSError:
- log.info('Failed reading LongPathsEnabled from registry')
+ log.info("Failed reading LongPathsEnabled from registry")
return False
@@ -257,7 +257,7 @@ def normpath(path):
# realpath can fail if path does not exist or is not accessible
# or on Windows if drives are mounted without mount manager
# (see https://tickets.metabrainz.org/browse/PICARD-2425).
- log.warning('Failed getting realpath for "%s": %s', path, why)
+ log.warning("Failed getting realpath for `%s`: %s", path, why)
# If the path is longer than 259 characters on Windows, prepend the \\?\
# prefix. This enables access to long paths using the Windows API. See
# https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation
@@ -400,7 +400,7 @@ def translate_from_sortname(name, sortname):
"""'Translate' the artist name by reversing the sortname."""
for c in name:
ctg = unicodedata.category(c)
- if ctg[0] == "L" and unicodedata.name(c).find("LATIN") == -1:
+ if ctg[0] == "L" and unicodedata.name(c).find('LATIN') == -1:
for separator in (" & ", "; ", " and ", " vs. ", " with ", " y "):
if separator in sortname:
parts = sortname.split(separator)
@@ -749,11 +749,11 @@ def build_qurl(host, port=80, path=None, queryargs=None):
url.setHost(host)
if port == 443 or host in MUSICBRAINZ_SERVERS:
- url.setScheme("https")
+ url.setScheme('https')
elif port == 80:
- url.setScheme("http")
+ url.setScheme('http')
else:
- url.setScheme("http")
+ url.setScheme('http')
url.setPort(port)
if path is not None:
diff --git a/picard/util/bytes2human.py b/picard/util/bytes2human.py
index 5794a5aa8f..a26a117fee 100644
--- a/picard/util/bytes2human.py
+++ b/picard/util/bytes2human.py
@@ -34,17 +34,17 @@
# used to force gettextization
_BYTES_STRINGS_I18N = (
- N_('%(value)s B'),
- N_('%(value)s kB'),
- N_('%(value)s KiB'),
- N_('%(value)s MB'),
- N_('%(value)s MiB'),
- N_('%(value)s GB'),
- N_('%(value)s GiB'),
- N_('%(value)s TB'),
- N_('%(value)s TiB'),
- N_('%(value)s PB'),
- N_('%(value)s PiB'),
+ N_("%(value)s B"),
+ N_("%(value)s kB"),
+ N_("%(value)s KiB"),
+ N_("%(value)s MB"),
+ N_("%(value)s MiB"),
+ N_("%(value)s GB"),
+ N_("%(value)s GiB"),
+ N_("%(value)s TB"),
+ N_("%(value)s TiB"),
+ N_("%(value)s PB"),
+ N_("%(value)s PiB"),
)
@@ -116,9 +116,9 @@ def calc_unit(number, multiple=1000):
elif multiple == 1024:
k, b = 'K', 'iB'
else:
- raise ValueError('multiple parameter has to be 1000 or 1024')
+ raise ValueError("multiple parameter has to be 1000 or 1024")
- suffixes = ["B"] + [i + b for i in k + "MGTP"]
+ suffixes = ['B'] + [i + b for i in k + 'MGTP']
for suffix in suffixes:
if n < multiple or suffix == suffixes[-1]:
return (sign * n, suffix)
diff --git a/picard/util/cdrom.py b/picard/util/cdrom.py
index 8d8c31d0f2..d43b11046c 100644
--- a/picard/util/cdrom.py
+++ b/picard/util/cdrom.py
@@ -63,7 +63,7 @@ def _generic_iter_drives():
config = get_config()
yield from (
device.strip() for device
- in config.setting["cd_lookup_device"].split(",")
+ in config.setting['cd_lookup_device'].split(',')
if device and not device.isspace()
)
@@ -97,7 +97,7 @@ def _iter_drives():
mask = GetLogicalDrives()
for i in range(26):
if mask >> i & 1:
- drive = chr(i + ord("A")) + ":"
+ drive = chr(i + ord('A')) + ':'
if GetDriveType(drive) == DRIVE_TYPE_CDROM:
yield drive
diff --git a/picard/util/checkupdate.py b/picard/util/checkupdate.py
index f2ac320cff..78593e1fa0 100644
--- a/picard/util/checkupdate.py
+++ b/picard/util/checkupdate.py
@@ -128,7 +128,7 @@ def _display_results(self):
try:
test_version = Version(*version_tuple)
except (TypeError, VersionError):
- log.error('Invalid version %r for update level %s.', version_tuple, update_level)
+ log.error("Invalid version %r for update level %s.", version_tuple, update_level)
continue
if self._update_level >= test_key and test_version > high_version:
key = PROGRAM_UPDATE_LEVELS[test_key]['name']
@@ -153,7 +153,7 @@ def _display_results(self):
if self._update_level in PROGRAM_UPDATE_LEVELS:
update_level = PROGRAM_UPDATE_LEVELS[self._update_level]['title']
else:
- update_level = N_('unknown')
+ update_level = N_("unknown")
QMessageBox.information(
self._parent,
_("Picard Update"),
diff --git a/picard/util/emptydir.py b/picard/util/emptydir.py
index 48e1aa37bf..5edb4d86c8 100644
--- a/picard/util/emptydir.py
+++ b/picard/util/emptydir.py
@@ -84,8 +84,8 @@ def rm_empty_dir(path):
or considered a special directory.
"""
if os.path.realpath(path) in PROTECTED_DIRECTORIES:
- raise SkipRemoveDir('%s is a protected directory' % path)
+ raise SkipRemoveDir("%s is a protected directory" % path)
elif not is_empty_dir(path):
- raise SkipRemoveDir('%s is not empty' % path)
+ raise SkipRemoveDir("%s is not empty" % path)
else:
shutil.rmtree(path)
diff --git a/picard/util/filenaming.py b/picard/util/filenaming.py
index 11e4c28b4e..6f5ae72fa4 100644
--- a/picard/util/filenaming.py
+++ b/picard/util/filenaming.py
@@ -60,7 +60,7 @@
import pywintypes
import win32api
except ImportError as e:
- log.warning('pywin32 not available: %s', e)
+ log.warning("pywin32 not available: %s", e)
def _get_utf16_length(text):
diff --git a/picard/util/imageinfo.py b/picard/util/imageinfo.py
index 4795e74f5f..2fc20814fc 100644
--- a/picard/util/imageinfo.py
+++ b/picard/util/imageinfo.py
@@ -53,7 +53,7 @@ def __init__(self, data):
self.data = data
self.datalen = len(self.data)
if self.datalen < 16:
- raise NotEnoughData('Not enough data')
+ raise NotEnoughData("Not enough data")
def read(self):
self._read()
@@ -176,7 +176,7 @@ def _read(self):
index = data.find(b'\x9d\x01\x2a')
if index != -1:
if self.datalen < index + 7:
- raise NotEnoughData('Not enough data for WebP VP8')
+ raise NotEnoughData("Not enough data for WebP VP8")
self.w, self.h = struct.unpack(' str:
self.__create_pipe()
if message is not None:
- message = message.decode("utf-8")
+ message = message.decode('utf-8')
if exit_code == 0:
return message # type: ignore
else:
diff --git a/picard/util/remotecommands.py b/picard/util/remotecommands.py
index b61ac47f0d..4c9112b0ae 100644
--- a/picard/util/remotecommands.py
+++ b/picard/util/remotecommands.py
@@ -36,93 +36,93 @@ def __init__(self, method_name, help_text=None, help_args=None):
REMOTE_COMMANDS = {
- "CLEAR_LOGS": RemoteCommand(
- "handle_command_clear_logs",
+ 'CLEAR_LOGS': RemoteCommand(
+ 'handle_command_clear_logs',
help_text="Clear the Picard logs",
),
- "CLUSTER": RemoteCommand(
- "handle_command_cluster",
+ 'CLUSTER': RemoteCommand(
+ 'handle_command_cluster',
help_text="Cluster all files in the cluster pane.",
),
- "FINGERPRINT": RemoteCommand(
- "handle_command_fingerprint",
+ 'FINGERPRINT': RemoteCommand(
+ 'handle_command_fingerprint',
help_text="Calculate acoustic fingerprints for all (matched) files in the album pane.",
),
- "FROM_FILE": RemoteCommand(
- "handle_command_from_file",
+ 'FROM_FILE': RemoteCommand(
+ 'handle_command_from_file',
help_text="Load commands from a file.",
help_args="[Path to a file containing commands]",
),
- "LOAD": RemoteCommand(
- "handle_command_load",
+ 'LOAD': RemoteCommand(
+ 'handle_command_load',
help_text="Load one or more files/MBIDs/URLs to Picard.",
help_args="[supported MBID/URL or path to a file]",
),
- "LOOKUP": RemoteCommand(
- "handle_command_lookup",
+ 'LOOKUP': RemoteCommand(
+ 'handle_command_lookup',
help_text="Lookup files in the clustering pane. Defaults to all files.",
help_args="[clustered|unclustered|all]"
),
- "LOOKUP_CD": RemoteCommand(
- "handle_command_lookup_cd",
+ 'LOOKUP_CD': RemoteCommand(
+ 'handle_command_lookup_cd',
help_text="Read CD from the selected drive and lookup on MusicBrainz. "
"Without argument, it defaults to the first (alphabetically) available disc drive.",
help_args="[device/log file]",
),
- "PAUSE": RemoteCommand(
- "handle_command_pause",
+ 'PAUSE': RemoteCommand(
+ 'handle_command_pause',
help_text="Pause executable command processing.",
help_args="[number of seconds to pause]",
),
- "QUIT": RemoteCommand(
- "handle_command_quit",
+ 'QUIT': RemoteCommand(
+ 'handle_command_quit',
help_text="Exit the running instance of Picard. "
"Use the argument 'FORCE' to bypass Picard's unsaved files check.",
help_args="[FORCE]",
),
- "REMOVE": RemoteCommand(
- "handle_command_remove",
+ 'REMOVE': RemoteCommand(
+ 'handle_command_remove',
help_text="Remove the file from Picard. Do nothing if no arguments provided.",
help_args="[absolute path to one or more files]",
),
- "REMOVE_ALL": RemoteCommand(
- "handle_command_remove_all",
+ 'REMOVE_ALL': RemoteCommand(
+ 'handle_command_remove_all',
help_text="Remove all files from Picard.",
),
- "REMOVE_EMPTY": RemoteCommand(
- "handle_command_remove_empty",
+ 'REMOVE_EMPTY': RemoteCommand(
+ 'handle_command_remove_empty',
help_text="Remove all empty clusters and albums.",
),
- "REMOVE_SAVED": RemoteCommand(
- "handle_command_remove_saved",
+ 'REMOVE_SAVED': RemoteCommand(
+ 'handle_command_remove_saved',
help_text="Remove all saved files from the album pane.",
),
- "REMOVE_UNCLUSTERED": RemoteCommand(
- "handle_command_remove_unclustered",
+ 'REMOVE_UNCLUSTERED': RemoteCommand(
+ 'handle_command_remove_unclustered',
help_text="Remove all unclustered files from the cluster pane.",
),
- "SAVE_MATCHED": RemoteCommand(
- "handle_command_save_matched",
+ 'SAVE_MATCHED': RemoteCommand(
+ 'handle_command_save_matched',
help_text="Save all matched files from the album pane."
),
- "SAVE_MODIFIED": RemoteCommand(
- "handle_command_save_modified",
+ 'SAVE_MODIFIED': RemoteCommand(
+ 'handle_command_save_modified',
help_text="Save all modified files from the album pane.",
),
- "SCAN": RemoteCommand(
- "handle_command_scan",
+ 'SCAN': RemoteCommand(
+ 'handle_command_scan',
help_text="Scan all files in the cluster pane.",
),
- "SHOW": RemoteCommand(
- "handle_command_show",
+ 'SHOW': RemoteCommand(
+ 'handle_command_show',
help_text="Make the running instance the currently active window.",
),
- "SUBMIT_FINGERPRINTS": RemoteCommand(
- "handle_command_submit_fingerprints",
+ 'SUBMIT_FINGERPRINTS': RemoteCommand(
+ 'handle_command_submit_fingerprints',
help_text="Submit outstanding acoustic fingerprints for all (matched) files in the album pane.",
),
- "WRITE_LOGS": RemoteCommand(
- "handle_command_write_logs",
+ 'WRITE_LOGS': RemoteCommand(
+ 'handle_command_write_logs',
help_text="Write Picard logs to a given path.",
help_args="[absolute path to one file]",
),
diff --git a/picard/util/script_detector_weighted.py b/picard/util/script_detector_weighted.py
index ee6118dfe5..13711418bb 100644
--- a/picard/util/script_detector_weighted.py
+++ b/picard/util/script_detector_weighted.py
@@ -40,16 +40,16 @@ class ScriptSelectionOrder(IntEnum):
# characters to convey the same information as other characters sets. The factor is generally
# based on the relative number of characters in the alphabet compared with the LATIN alphabet.
SCRIPT_WEIGHTING_FACTORS = {
- "LATIN": 1.0,
- "CYRILLIC": 1.02,
- "GREEK": 0.92,
- "ARABIC": 1.08,
- "HEBREW": 0.85,
- "CJK": 2.5,
- "HANGUL": 0.92,
- "HIRAGANA": 1.77,
- "KATAKANA": 1.77,
- "THAI": 1.69,
+ 'LATIN': 1.0,
+ 'CYRILLIC': 1.02,
+ 'GREEK': 0.92,
+ 'ARABIC': 1.08,
+ 'HEBREW': 0.85,
+ 'CJK': 2.5,
+ 'HANGUL': 0.92,
+ 'HIRAGANA': 1.77,
+ 'KATAKANA': 1.77,
+ 'THAI': 1.69,
}
diff --git a/picard/util/scripttofilename.py b/picard/util/scripttofilename.py
index 50a51a3091..f05194d5da 100644
--- a/picard/util/scripttofilename.py
+++ b/picard/util/scripttofilename.py
@@ -56,25 +56,25 @@ def script_to_filename_with_metadata(naming_format, metadata, file=None, setting
config = get_config()
settings = config.setting
# make sure every metadata can safely be used in a path name
- win_compat = IS_WIN or settings["windows_compatibility"]
+ win_compat = IS_WIN or settings['windows_compatibility']
new_metadata = Metadata()
- replace_dir_separator = settings["replace_dir_separator"]
+ replace_dir_separator = settings['replace_dir_separator']
for name in metadata:
new_metadata[name] = [
sanitize_filename(str(v), repl=replace_dir_separator, win_compat=win_compat)
for v in metadata.getall(name)
]
- naming_format = naming_format.replace("\t", "").replace("\n", "")
+ naming_format = naming_format.replace('\t', '').replace('\n', '')
filename = ScriptParser().eval(naming_format, new_metadata, file)
- if settings["ascii_filenames"]:
+ if settings['ascii_filenames']:
filename = replace_non_ascii(filename, pathsave=True, win_compat=win_compat)
# replace incompatible characters
if win_compat:
- filename = replace_win32_incompat(filename, replacements=settings["win_compat_replacements"])
- if settings["replace_spaces_with_underscores"]:
+ filename = replace_win32_incompat(filename, replacements=settings['win_compat_replacements'])
+ if settings['replace_spaces_with_underscores']:
filename = _re_replace_underscores.sub('_', filename.strip())
# remove null characters
- filename = filename.replace("\x00", "")
+ filename = filename.replace('\x00', '')
return (filename, new_metadata)
diff --git a/picard/util/versions.py b/picard/util/versions.py
index a00a03b95e..9ff50df2c9 100644
--- a/picard/util/versions.py
+++ b/picard/util/versions.py
@@ -39,25 +39,25 @@
_versions = OrderedDict([
- ("version", PICARD_FANCY_VERSION_STR),
- ("python-version", python_version()),
- ("pyqt-version", pyqt_version),
- ("qt-version", qVersion()),
- ("mutagen-version", mutagen_version),
- ("discid-version", discid_version),
- ("astrcmp", astrcmp_implementation),
- ("ssl-version", QSslSocket.sslLibraryVersionString())
+ ('version', PICARD_FANCY_VERSION_STR),
+ ('python-version', python_version()),
+ ('pyqt-version', pyqt_version),
+ ('qt-version', qVersion()),
+ ('mutagen-version', mutagen_version),
+ ('discid-version', discid_version),
+ ('astrcmp', astrcmp_implementation),
+ ('ssl-version', QSslSocket.sslLibraryVersionString())
])
_names = {
- "version": "Picard",
- "python-version": "Python",
- "pyqt-version": "PyQt",
- "qt-version": "Qt",
- "mutagen-version": "Mutagen",
- "discid-version": "Discid",
- "astrcmp": "astrcmp",
- "ssl-version": "SSL",
+ 'version': "Picard",
+ 'python-version': "Python",
+ 'pyqt-version': "PyQt",
+ 'qt-version': "Qt",
+ 'mutagen-version': "Mutagen",
+ 'discid-version': "Discid",
+ 'astrcmp': "astrcmp",
+ 'ssl-version': "SSL",
}
diff --git a/picard/webservice/__init__.py b/picard/webservice/__init__.py
index e6942d2ff6..2488d2d0cc 100644
--- a/picard/webservice/__init__.py
+++ b/picard/webservice/__init__.py
@@ -210,7 +210,7 @@ def __init__(
if self.data:
if not self.request_mimetype:
- self.request_mimetype = self.response_mimetype or "application/x-www-form-urlencoded"
+ self.request_mimetype = self.response_mimetype or 'application/x-www-form-urlencoded'
self.setHeader(QNetworkRequest.KnownHeaders.ContentTypeHeader, self.request_mimetype)
@property
@@ -218,8 +218,8 @@ def has_auth(self):
return self.mblogin and self.access_token
def _update_authorization_header(self):
- auth = "Bearer " + self.access_token if self.has_auth else ""
- self.setRawHeader(b"Authorization", auth.encode('utf-8'))
+ auth = 'Bearer ' + self.access_token if self.has_auth else ''
+ self.setRawHeader(b'Authorization', auth.encode('utf-8'))
@property
def host(self):
@@ -342,10 +342,10 @@ def __init__(self, parent=None):
self.set_transfer_timeout(config.setting['network_transfer_timeout_seconds'])
self.manager.finished.connect(self._process_reply)
self._request_methods = {
- "GET": self.manager.get,
- "POST": self.manager.post,
- "PUT": self.manager.put,
- "DELETE": self.manager.deleteResource
+ 'GET': self.manager.get,
+ 'POST': self.manager.post,
+ 'PUT': self.manager.put,
+ 'DELETE': self.manager.deleteResource
}
self._init_queues()
self._init_timers()
@@ -414,17 +414,17 @@ def set_cache(self, cache_size_in_bytes=None):
def setup_proxy(self):
proxy = QtNetwork.QNetworkProxy()
config = get_config()
- if config.setting["use_proxy"]:
- if config.setting["proxy_type"] == 'socks':
+ if config.setting['use_proxy']:
+ if config.setting['proxy_type'] == 'socks':
proxy.setType(QtNetwork.QNetworkProxy.ProxyType.Socks5Proxy)
else:
proxy.setType(QtNetwork.QNetworkProxy.ProxyType.HttpProxy)
- proxy.setHostName(config.setting["proxy_server_host"])
- proxy.setPort(config.setting["proxy_server_port"])
- if config.setting["proxy_username"]:
- proxy.setUser(config.setting["proxy_username"])
- if config.setting["proxy_password"]:
- proxy.setPassword(config.setting["proxy_password"])
+ proxy.setHostName(config.setting['proxy_server_host'])
+ proxy.setPort(config.setting['proxy_server_port'])
+ if config.setting['proxy_username']:
+ proxy.setUser(config.setting['proxy_username'])
+ if config.setting['proxy_password']:
+ proxy.setPassword(config.setting['proxy_password'])
self.manager.setProxy(proxy)
def set_transfer_timeout(self, timeout):
diff --git a/picard/webservice/api_helpers.py b/picard/webservice/api_helpers.py
index 8911f72b66..9a7e83352d 100644
--- a/picard/webservice/api_helpers.py
+++ b/picard/webservice/api_helpers.py
@@ -143,24 +143,24 @@ def get_track_by_id(self, trackid, handler, inc=None, **kwargs):
def lookup_discid(self, discid, handler, priority=True, important=True, refresh=False):
inc = ('artist-credits', 'labels')
- return self._get_by_id('discid', discid, handler, inc, queryargs={"cdstubs": "no"},
+ return self._get_by_id('discid', discid, handler, inc, queryargs={'cdstubs': 'no'},
priority=priority, important=important, refresh=refresh)
def _find(self, entitytype, handler, **kwargs):
filters = {}
- limit = kwargs.pop("limit")
+ limit = kwargs.pop('limit')
if limit:
filters['limit'] = limit
- is_search = kwargs.pop("search", False)
+ is_search = kwargs.pop('search', False)
if is_search:
config = get_config()
- use_advanced_search = kwargs.pop("advanced_search", config.setting["use_adv_search_syntax"])
+ use_advanced_search = kwargs.pop('advanced_search', config.setting['use_adv_search_syntax'])
if use_advanced_search:
- query = kwargs["query"]
+ query = kwargs['query']
else:
- query = escape_lucene_query(kwargs["query"]).strip().lower()
+ query = escape_lucene_query(kwargs['query']).strip().lower()
filters['dismax'] = 'true'
else:
query = build_lucene_query(kwargs)
@@ -195,14 +195,14 @@ def _browse(self, entitytype, handler, inc=None, queryargs=None, mblogin=False):
if queryargs is None:
queryargs = {}
if inc:
- queryargs["inc"] = self._make_inc_arg(inc)
+ queryargs['inc'] = self._make_inc_arg(inc)
return self.get(f"/{entitytype}", handler, unencoded_queryargs=queryargs,
priority=True, important=True, mblogin=mblogin,
refresh=False)
def browse_releases(self, handler, **kwargs):
- inc = ("media", "labels")
- return self._browse("release", handler, inc, queryargs=kwargs)
+ inc = ('media', 'labels')
+ return self._browse('release', handler, inc, queryargs=kwargs)
def browse_recordings(self, handler, inc, **kwargs):
return self._browse('recording', handler, inc, queryargs=kwargs)
@@ -216,20 +216,20 @@ def _xml_ratings(ratings):
return _wrap_xml_metadata('%s' % recordings)
def submit_ratings(self, ratings, handler):
- params = {"client": CLIENT_STRING}
+ params = {'client': CLIENT_STRING}
data = self._xml_ratings(ratings)
return self.post("/rating", data, handler, priority=True,
- unencoded_queryargs=params, parse_response_type="xml",
- request_mimetype="application/xml; charset=utf-8")
+ unencoded_queryargs=params, parse_response_type='xml',
+ request_mimetype='application/xml; charset=utf-8')
def get_collection(self, collection_id, handler, limit=100, offset=0):
if collection_id is not None:
- inc = ("releases", "artist-credits", "media")
+ inc = ('releases', 'artist-credits', 'media')
path = f"/collection/{collection_id}/releases"
queryargs = {
- "inc": self._make_inc_arg(inc),
- "limit": limit,
- "offset": offset,
+ 'inc': self._make_inc_arg(inc),
+ 'limit': limit,
+ 'offset': offset,
}
else:
path = '/collection'
@@ -243,12 +243,12 @@ def get_collection_list(self, handler):
@staticmethod
def _collection_request(collection_id, releases, batchsize=400):
for i in range(0, len(releases), batchsize):
- ids = ";".join(releases[i:i+batchsize])
+ ids = ';'.join(releases[i:i+batchsize])
yield f"/collection/{collection_id}/releases/{ids}"
@staticmethod
def _get_client_queryarg():
- return {"client": CLIENT_STRING}
+ return {'client': CLIENT_STRING}
def put_to_collection(self, collection_id, releases, handler):
for path in self._collection_request(collection_id, releases):
@@ -279,13 +279,13 @@ def query_acoustid(self, handler, **args):
body = self._encode_acoustid_args(args)
return self.post(
"/lookup", body, handler, priority=False, important=False,
- mblogin=False, request_mimetype="application/x-www-form-urlencoded"
+ mblogin=False, request_mimetype='application/x-www-form-urlencoded'
)
@staticmethod
def _submissions_to_args(submissions):
config = get_config()
- args = {'user': config.setting["acoustid_apikey"]}
+ args = {'user': config.setting['acoustid_apikey']}
for i, submission in enumerate(submissions):
for key, value in submission.args.items():
if value:
@@ -297,5 +297,5 @@ def submit_acoustid_fingerprints(self, submissions, handler):
body = self._encode_acoustid_args(args)
return self.post(
"/submit", body, handler, priority=True, important=False,
- mblogin=False, request_mimetype="application/x-www-form-urlencoded"
+ mblogin=False, request_mimetype='application/x-www-form-urlencoded'
)