From 277e943e5cd271358e5970637077afa965dc2eb3 Mon Sep 17 00:00:00 2001 From: Philipp Wolfer Date: Sun, 26 Jun 2022 14:39:06 +0200 Subject: [PATCH 01/10] PICARD-2506: Fixed calling fpcalc with long path filename On Windows always add the long path prefix \\?\ if the path exceeds this limit, independent of the OS configuration for long path supports. This fixes ffmpeg currently not being able to handle long paths. Added util method win_prefix_longpath() to help with that. --- picard/acoustid/__init__.py | 13 ++++++++++--- picard/util/__init__.py | 9 +++++++-- test/test_utils.py | 12 ++++++++++++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/picard/acoustid/__init__.py b/picard/acoustid/__init__.py index 757b3154f..e820bccaa 100644 --- a/picard/acoustid/__init__.py +++ b/picard/acoustid/__init__.py @@ -6,7 +6,7 @@ # Copyright (C) 2017-2018 Sambhav Kothari # Copyright (C) 2018 Vishal Choudhary # Copyright (C) 2018-2021 Laurent Monin -# Copyright (C) 2018-2021 Philipp Wolfer +# Copyright (C) 2018-2022 Philipp Wolfer # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -36,8 +36,12 @@ from picard import log from picard.acoustid.json_helpers import parse_recording from picard.config import get_config from picard.const import FPCALC_NAMES +from picard.const.sys import IS_WIN from picard.file import File -from picard.util import find_executable +from picard.util import ( + find_executable, + win_prefix_longpath, +) def get_score(node): @@ -248,7 +252,10 @@ class AcoustIDClient(QtCore.QObject): process.setProperty('picard_finished', False) process.finished.connect(partial(self._on_fpcalc_finished, task)) process.error.connect(partial(self._on_fpcalc_error, task)) - process.start(self._fpcalc, ["-json", "-length", "120", task.file.filename]) + file_path = task.file.filename + if IS_WIN: + file_path = win_prefix_longpath(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): diff --git a/picard/util/__init__.py b/picard/util/__init__.py index 735e97f2d..211a08bf0 100644 --- a/picard/util/__init__.py +++ b/picard/util/__init__.py @@ -228,8 +228,13 @@ def normpath(path): # 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 - if (IS_WIN and len(path) > WIN_MAX_FILEPATH_LEN and not system_supports_long_paths() - and not path.startswith(WIN_LONGPATH_PREFIX)): + if IS_WIN and not system_supports_long_paths(): + path = win_prefix_longpath(path) + return path + + +def win_prefix_longpath(path): + if len(path) > WIN_MAX_FILEPATH_LEN and not path.startswith(WIN_LONGPATH_PREFIX): path = WIN_LONGPATH_PREFIX + path return path diff --git a/test/test_utils.py b/test/test_utils.py index e23c2b39e..251ee037b 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -71,6 +71,7 @@ from picard.util import ( tracknum_from_filename, uniqify, wildcards_to_regex_pattern, + win_prefix_longpath, ) @@ -738,6 +739,17 @@ class NormpathTest(PicardTestCase): self.assertEqual('\\\\?\\' + path, normpath(path)) +class WinPrefixLongpathTest(PicardTestCase): + + def test_win_prefix_longpath_is_long(self): + path = 'C:\\foo\\' + (253 * 'a') + self.assertEqual('\\\\?\\' + path, win_prefix_longpath(path)) + + def test_win_prefix_longpath_is_short(self): + path = 'C:\\foo\\' + (252 * 'a') + self.assertEqual(path, win_prefix_longpath(path)) + + class SystemSupportsLongPathsTest(PicardTestCase): def setUp(self): From 84f1092ff71bf0f1fc9de74740728d2cbe35b0de Mon Sep 17 00:00:00 2001 From: Philipp Wolfer Date: Sun, 26 Jun 2022 14:11:43 +0200 Subject: [PATCH 02/10] PICARD-2507: Include pregap track in medium's totaltracks count --- picard/mbjson.py | 6 ++- test/data/ws_data/media_pregap.json | 83 +++++++++++++++++++++++++++++ test/test_mbjson.py | 12 +++++ 3 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 test/data/ws_data/media_pregap.json diff --git a/picard/mbjson.py b/picard/mbjson.py index a3612ba13..4285db9fb 100644 --- a/picard/mbjson.py +++ b/picard/mbjson.py @@ -75,7 +75,6 @@ _MEDIUM_TO_METADATA = { 'format': 'media', 'position': 'discnumber', 'title': 'discsubtitle', - 'track-count': 'totaltracks', } _RECORDING_TO_METADATA = { @@ -478,6 +477,11 @@ def medium_to_metadata(node, m): for key, value in _node_skip_empty_iter(node): if key in _MEDIUM_TO_METADATA: m[_MEDIUM_TO_METADATA[key]] = value + totaltracks = node.get('track-count', 0) + if node.get('pregap'): + totaltracks += 1 + if totaltracks: + m['totaltracks'] = totaltracks def artist_to_metadata(node, m): diff --git a/test/data/ws_data/media_pregap.json b/test/data/ws_data/media_pregap.json new file mode 100644 index 000000000..97c9a2a8e --- /dev/null +++ b/test/data/ws_data/media_pregap.json @@ -0,0 +1,83 @@ +{ + "track-count": 8, + "discs": [ + { + "sectors": 134481, + "offset-count": 8, + "id": "7v3LmtkMIT49mHs7LobaAwBNsck-", + "offsets": [ + 6824, + 18966, + 37134, + 52930, + 69024, + 80329, + 98814, + 117353 + ] + } + ], + "format-id": "8a08dc62-1aa2-34de-a904-fa467c53052c", + "position": 1, + "track-offset": 0, + "format": "Enhanced CD", + "title": "", + "pregap": { + "number": "0", + "position": 0, + "artist-credit": [ + { + "name": "Lemon Demon", + "joinphrase": "", + "artist": { + "type": "Person", + "sort-name": "Lemon Demon", + "disambiguation": "", + "id": "6b014cfd-4927-4187-a741-715998e6d785", + "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df", + "aliases": [ + { + "name": "Deporitaz", + "primary": null, + "type-id": null, + "locale": null, + "begin": null, + "ended": false, + "end": null, + "sort-name": "Deporitaz", + "type": null + } + ], + "name": "Lemon Demon" + } + } + ], + "recording": { + "video": false, + "id": "a6f68447-7810-4d1e-a5a2-d10ff0943aee", + "first-release-date": "2019", + "aliases": [], + "title": "Sexy DVD", + "length": 88000, + "disambiguation": "", + "artist-credit": [ + { + "artist": { + "id": "6b014cfd-4927-4187-a741-715998e6d785", + "type": "Person", + "sort-name": "Lemon Demon", + "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df", + "disambiguation": "", + "name": "Lemon Demon" + }, + "joinphrase": "", + "name": "Lemon Demon" + } + ] + }, + "length": 88000, + "title": "Sexy DVD", + "id": "74fa2a03-325a-4a6b-bcfd-12f95ba30d16" + }, + "tracks": [] +} \ No newline at end of file diff --git a/test/test_mbjson.py b/test/test_mbjson.py index dbe709966..243d7ef08 100644 --- a/test/test_mbjson.py +++ b/test/test_mbjson.py @@ -402,6 +402,18 @@ class MediaTest(MBJSONTest): self.assertEqual(m['totaltracks'], '10') +class MediaPregapTest(MBJSONTest): + + filename = 'media_pregap.json' + + def test_track(self): + m = Metadata() + medium_to_metadata(self.json_doc, m) + self.assertEqual(m['discnumber'], '1') + self.assertEqual(m['media'], 'Enhanced CD') + self.assertEqual(m['totaltracks'], '9') + + class NullMediaTest(MBJSONTest): filename = 'media_null.json' From 8c1af7eade55d49afdb6f4ab489ceb9180fa54c0 Mon Sep 17 00:00:00 2001 From: Bob Swift Date: Sun, 26 Jun 2022 11:37:12 -0600 Subject: [PATCH 03/10] Build example file names from a copy of the file metadata --- picard/ui/scripteditor.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/picard/ui/scripteditor.py b/picard/ui/scripteditor.py index 4503f606b..c0666b92d 100644 --- a/picard/ui/scripteditor.py +++ b/picard/ui/scripteditor.py @@ -2,7 +2,7 @@ # # Picard, the next-generation MusicBrainz tagger # -# Copyright (C) 2021 Bob Swift +# Copyright (C) 2021-2022 Bob Swift # Copyright (C) 2021 Laurent Monin # Copyright (C) 2021-2022 Philipp Wolfer # @@ -50,6 +50,7 @@ from picard.const import ( PICARD_URLS, ) from picard.file import File +from picard.metadata import Metadata from picard.script import ( ScriptError, ScriptParser, @@ -154,14 +155,17 @@ class ScriptEditorExamples(): Returns: tuple: Example before and after names for the specified file """ + # Operate on a copy of the file object metadata to avoid multiple changes to file metadata. See PICARD-2508. + c_metadata = Metadata() + c_metadata.copy(file.metadata) try: if self.settings["enable_tagger_scripts"]: 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, file.metadata) + parser.eval(s_text, c_metadata) filename_before = file.filename - filename_after = file.make_filename(filename_before, file.metadata, self.settings, self.script_text) + filename_after = file.make_filename(filename_before, c_metadata, self.settings, self.script_text) if not self.settings["move_files"]: return os.path.basename(filename_before), os.path.basename(filename_after) return filename_before, filename_after From 28b9187dab0a610b4fcd26840305b478d0d80c8b Mon Sep 17 00:00:00 2001 From: Bob Swift Date: Sun, 26 Jun 2022 14:40:29 -0600 Subject: [PATCH 04/10] Only execute scripts if original metadata has not changed --- picard/ui/scripteditor.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/picard/ui/scripteditor.py b/picard/ui/scripteditor.py index c0666b92d..81b1f051a 100644 --- a/picard/ui/scripteditor.py +++ b/picard/ui/scripteditor.py @@ -159,7 +159,8 @@ class ScriptEditorExamples(): c_metadata = Metadata() c_metadata.copy(file.metadata) try: - if self.settings["enable_tagger_scripts"]: + # 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 s_enabled and s_text: parser = ScriptParser() From 67db5950a29a90dfa40b769bd1072f35f8de6126 Mon Sep 17 00:00:00 2001 From: Philipp Wolfer Date: Mon, 27 Jun 2022 08:55:07 +0200 Subject: [PATCH 05/10] Update picard.pot --- po/picard.pot | 614 +++++++++++++++++++++++++------------------------- 1 file changed, 309 insertions(+), 305 deletions(-) diff --git a/po/picard.pot b/po/picard.pot index 209c64401..4811b8674 100644 --- a/po/picard.pot +++ b/po/picard.pot @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: picard 2.8.0.dev2\n" +"Project-Id-Version: picard 2.8.1\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2022-05-01 15:38+0200\n" +"POT-Creation-Date: 2022-06-27 08:54+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,40 +17,40 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.9.1\n" -#: picard/album.py:144 +#: picard/album.py:149 msgid "Unmatched Files" msgstr "" -#: picard/album.py:509 +#: picard/album.py:512 #, python-format msgid "Album %(id)s loaded: %(artist)s - %(album)s" msgstr "" -#: picard/album.py:551 +#: picard/album.py:554 #, python-format msgid "Loading album %(id)s ..." msgstr "" -#: picard/album.py:774 +#: picard/album.py:769 msgid "[loading album information]" msgstr "" -#: picard/album.py:776 +#: picard/album.py:771 #, python-format msgid "[could not load album %s]" msgstr "" -#: picard/cluster.py:260 +#: picard/cluster.py:259 #, python-format msgid "Cluster %(album)s identified!" msgstr "" -#: picard/cluster.py:263 +#: picard/cluster.py:262 #, python-format msgid "No matching releases for cluster %(album)s" msgstr "" -#: picard/cluster.py:282 +#: picard/cluster.py:281 #, python-format msgid "Looking up the metadata for cluster %(album)s..." msgstr "" @@ -110,7 +110,7 @@ msgid "Merge" msgstr "" #: picard/config_upgrade.py:104 picard/ui/metadatabox.py:426 -#: picard/ui/options/interface.py:111 picard/ui/ui_options_interface.py:180 +#: picard/ui/options/interface.py:113 picard/ui/ui_options_interface.py:180 msgid "Remove" msgstr "" @@ -118,22 +118,22 @@ msgstr "" msgid "Primary file naming script" msgstr "" -#: picard/file.py:827 +#: picard/file.py:826 #, python-format msgid "No matching tracks above the threshold for file '%(filename)s'" msgstr "" -#: picard/file.py:829 +#: picard/file.py:828 #, python-format msgid "File '%(filename)s' identified!" msgstr "" -#: picard/file.py:841 +#: picard/file.py:840 #, python-format msgid "No matching tracks for file '%(filename)s'" msgstr "" -#: picard/file.py:873 +#: picard/file.py:872 #, python-format msgid "Looking up the metadata for file %(filename)s ..." msgstr "" @@ -432,7 +432,7 @@ msgstr "" msgid "Tagger scripts" msgstr "" -#: picard/profile.py:138 picard/ui/options/interface.py:71 +#: picard/profile.py:138 picard/ui/options/interface.py:73 msgid "User Interface" msgstr "" @@ -461,7 +461,7 @@ msgstr "" msgid "Directory to begin browsing" msgstr "" -#: picard/profile.py:151 picard/ui/options/advanced.py:43 +#: picard/profile.py:151 picard/ui/options/advanced.py:44 msgid "Advanced" msgstr "" @@ -469,11 +469,11 @@ msgstr "" msgid "Ignore file paths matching a regular expression" msgstr "" -#: picard/profile.py:154 picard/ui/ui_options_advanced.py:119 +#: picard/profile.py:154 picard/ui/ui_options_advanced.py:145 msgid "Ignore hidden files" msgstr "" -#: picard/profile.py:155 picard/ui/ui_options_advanced.py:116 +#: picard/profile.py:155 picard/ui/ui_options_advanced.py:144 msgid "Include sub-folders when adding files from folder" msgstr "" @@ -481,27 +481,31 @@ msgstr "" msgid "Ignore track duration difference under x seconds" msgstr "" -#: picard/profile.py:161 +#: picard/profile.py:163 picard/ui/ui_options_advanced.py:142 +msgid "Maximum number of entities to return per MusicBrainz query" +msgstr "" + +#: picard/profile.py:166 msgid "Completeness check ignore: Video tracks" msgstr "" -#: picard/profile.py:162 +#: picard/profile.py:167 msgid "Completeness check ignore: Pregap tracks" msgstr "" -#: picard/profile.py:163 +#: picard/profile.py:168 msgid "Completeness check ignore: Data tracks" msgstr "" -#: picard/profile.py:164 +#: picard/profile.py:169 msgid "Completeness check ignore: Silent tracks" msgstr "" -#: picard/profile.py:165 +#: picard/profile.py:170 msgid "Tags to ignore for comparison" msgstr "" -#: picard/releasegroup.py:69 picard/ui/searchdialog/album.py:140 +#: picard/releasegroup.py:69 picard/ui/searchdialog/album.py:142 msgid "Tracks" msgstr "" @@ -510,11 +514,11 @@ msgid "Year" msgstr "" #: picard/releasegroup.py:71 picard/ui/cdlookup.py:72 -#: picard/ui/searchdialog/album.py:142 picard/ui/searchdialog/track.py:69 +#: picard/ui/searchdialog/album.py:144 picard/ui/searchdialog/track.py:71 msgid "Country" msgstr "" -#: picard/releasegroup.py:72 picard/ui/searchdialog/album.py:139 +#: picard/releasegroup.py:72 picard/ui/searchdialog/album.py:141 msgid "Format" msgstr "" @@ -542,16 +546,16 @@ msgstr "" msgid "Authorization code:" msgstr "" -#: picard/tagger.py:807 +#: picard/tagger.py:809 #, python-format msgid "Removing album %(id)s: %(artist)s - %(album)s" msgstr "" -#: picard/tagger.py:825 +#: picard/tagger.py:827 msgid "CD Lookup Error" msgstr "" -#: picard/tagger.py:826 +#: picard/tagger.py:828 #, python-format msgid "" "Error while reading CD:\n" @@ -559,12 +563,12 @@ msgid "" "%s" msgstr "" -#: picard/tagger.py:855 +#: picard/tagger.py:857 msgid "EAC / XLD / Whipper log files" msgstr "" -#: picard/script/serializer.py:352 picard/tagger.py:856 -#: picard/ui/coverartbox.py:617 picard/ui/mainwindow.py:1227 +#: picard/script/serializer.py:352 picard/tagger.py:858 +#: picard/ui/coverartbox.py:617 picard/ui/mainwindow.py:1234 #: picard/ui/options/maintenance.py:167 picard/ui/options/scripting.py:131 msgid "All files" msgstr "" @@ -578,22 +582,22 @@ msgstr "" msgid "[could not load recording %s]" msgstr "" -#: picard/acoustid/__init__.py:93 +#: picard/acoustid/__init__.py:97 #, python-format msgid "AcoustID lookup network error for '%(filename)s'!" msgstr "" -#: picard/acoustid/__init__.py:142 +#: picard/acoustid/__init__.py:146 #, python-format msgid "AcoustID lookup failed for '%(filename)s'!" msgstr "" -#: picard/acoustid/__init__.py:165 +#: picard/acoustid/__init__.py:169 #, python-format msgid "AcoustID lookup returned no result for file '%(filename)s'" msgstr "" -#: picard/acoustid/__init__.py:176 +#: picard/acoustid/__init__.py:180 #, python-format msgid "Looking up the fingerprint for file '%(filename)s' ..." msgstr "" @@ -3702,32 +3706,32 @@ msgid "Official website" msgstr "" #: picard/ui/cdlookup.py:72 picard/ui/itemviews.py:165 -#: picard/ui/mainwindow.py:1111 picard/util/tags.py:38 +#: picard/ui/mainwindow.py:1118 picard/util/tags.py:38 msgid "Album" msgstr "" #: picard/ui/cdlookup.py:72 picard/ui/itemviews.py:162 -#: picard/ui/mainwindow.py:1112 picard/ui/searchdialog/album.py:138 -#: picard/ui/searchdialog/track.py:66 picard/util/tags.py:41 +#: picard/ui/mainwindow.py:1119 picard/ui/searchdialog/album.py:140 +#: picard/ui/searchdialog/track.py:68 picard/util/tags.py:41 msgid "Artist" msgstr "" #: picard/ui/cdlookup.py:72 picard/ui/itemviews.py:174 -#: picard/ui/searchdialog/album.py:141 picard/ui/searchdialog/track.py:68 +#: picard/ui/searchdialog/album.py:143 picard/ui/searchdialog/track.py:70 #: picard/util/tags.py:54 msgid "Date" msgstr "" -#: picard/ui/cdlookup.py:73 picard/ui/searchdialog/album.py:143 +#: picard/ui/cdlookup.py:73 picard/ui/searchdialog/album.py:145 msgid "Labels" msgstr "" -#: picard/ui/cdlookup.py:73 picard/ui/searchdialog/album.py:144 +#: picard/ui/cdlookup.py:73 picard/ui/searchdialog/album.py:146 msgid "Catalog #s" msgstr "" #: picard/ui/cdlookup.py:73 picard/ui/itemviews.py:170 -#: picard/ui/searchdialog/album.py:145 picard/util/tags.py:45 +#: picard/ui/searchdialog/album.py:147 picard/util/tags.py:45 msgid "Barcode" msgstr "" @@ -3735,11 +3739,11 @@ msgstr "" msgid "Disambiguation" msgstr "" -#: picard/ui/collectionmenu.py:61 +#: picard/ui/collectionmenu.py:60 msgid "Refresh List" msgstr "" -#: picard/ui/collectionmenu.py:174 +#: picard/ui/collectionmenu.py:173 #, python-format msgid "%s (%i release)" msgid_plural "%s (%i releases)" @@ -3863,8 +3867,8 @@ msgid "Existing Cover" msgstr "" #: picard/ui/infodialog.py:104 picard/ui/infodialog.py:109 -#: picard/ui/searchdialog/album.py:147 picard/ui/searchdialog/artist.py:53 -#: picard/ui/searchdialog/track.py:70 +#: picard/ui/searchdialog/album.py:149 picard/ui/searchdialog/artist.py:55 +#: picard/ui/searchdialog/track.py:72 msgid "Type" msgstr "" @@ -3873,12 +3877,12 @@ msgid "New Cover" msgstr "" #: picard/ui/infodialog.py:109 picard/ui/itemviews.py:176 -#: picard/ui/searchdialog/album.py:149 +#: picard/ui/searchdialog/album.py:151 msgid "Cover" msgstr "" #: picard/ui/infodialog.py:153 picard/ui/infodialog.py:359 -#: picard/ui/options/interface.py:107 +#: picard/ui/options/interface.py:109 msgid "Info" msgstr "" @@ -3982,7 +3986,7 @@ msgstr "" msgid "Estimated Time" msgstr "" -#: picard/ui/infostatus.py:71 picard/ui/options/plugins.py:605 +#: picard/ui/infostatus.py:71 picard/ui/options/plugins.py:607 msgid "Files" msgstr "" @@ -4016,7 +4020,7 @@ msgstr[1] "" msgid "Title" msgstr "" -#: picard/ui/itemviews.py:161 picard/ui/searchdialog/track.py:65 +#: picard/ui/itemviews.py:161 picard/ui/searchdialog/track.py:67 #: picard/util/tags.py:70 msgid "Length" msgstr "" @@ -4261,538 +4265,538 @@ msgstr "" msgid "Activity History" msgstr "" -#: picard/ui/mainwindow.py:211 picard/ui/ui_aboutdialog.py:84 +#: picard/ui/mainwindow.py:212 picard/ui/ui_aboutdialog.py:84 msgid "MusicBrainz Picard" msgstr "" -#: picard/ui/mainwindow.py:338 +#: picard/ui/mainwindow.py:339 msgid "Unsaved Changes" msgstr "" -#: picard/ui/mainwindow.py:339 +#: picard/ui/mainwindow.py:340 msgid "Are you sure you want to quit Picard?" msgstr "" -#: picard/ui/mainwindow.py:340 +#: picard/ui/mainwindow.py:341 #, python-format msgid "There is %d unsaved file. Closing Picard will lose all unsaved changes." msgid_plural "There are %d unsaved files. Closing Picard will lose all unsaved changes." msgstr[0] "" msgstr[1] "" -#: picard/ui/mainwindow.py:347 +#: picard/ui/mainwindow.py:348 msgid "&Quit Picard" msgstr "" -#: picard/ui/mainwindow.py:383 +#: picard/ui/mainwindow.py:384 msgid "Ready" msgstr "" -#: picard/ui/mainwindow.py:388 +#: picard/ui/mainwindow.py:389 msgid "" "Picard listens on this port to integrate with your browser. When you " "\"Search\" or \"Open in Browser\" from Picard, clicking the \"Tagger\" " "button on the web page loads the release into Picard." msgstr "" -#: picard/ui/mainwindow.py:414 +#: picard/ui/mainwindow.py:415 #, python-format msgid " Listening on port %(port)d " msgstr "" -#: picard/ui/mainwindow.py:473 +#: picard/ui/mainwindow.py:474 msgid "AcoustID submission not configured" msgstr "" -#: picard/ui/mainwindow.py:474 +#: picard/ui/mainwindow.py:475 msgid "" "You need to configure your AcoustID API key before you can submit " "fingerprints." msgstr "" -#: picard/ui/mainwindow.py:477 +#: picard/ui/mainwindow.py:478 msgid "Open AcoustID options" msgstr "" -#: picard/ui/mainwindow.py:488 +#: picard/ui/mainwindow.py:489 msgid "&Options..." msgstr "" -#: picard/ui/mainwindow.py:495 +#: picard/ui/mainwindow.py:496 msgid "Open &file naming script editor..." msgstr "" -#: picard/ui/mainwindow.py:496 +#: picard/ui/mainwindow.py:497 msgid "Ctrl+Shift+S" msgstr "" -#: picard/ui/mainwindow.py:502 +#: picard/ui/mainwindow.py:503 msgid "&Cut" msgstr "" -#: picard/ui/mainwindow.py:510 picard/ui/metadatabox.py:443 +#: picard/ui/mainwindow.py:511 picard/ui/metadatabox.py:443 msgid "&Paste" msgstr "" -#: picard/ui/mainwindow.py:518 picard/ui/scripteditor.py:635 +#: picard/ui/mainwindow.py:519 picard/ui/scripteditor.py:640 msgid "&Help..." msgstr "" -#: picard/ui/mainwindow.py:525 +#: picard/ui/mainwindow.py:526 msgid "&About..." msgstr "" -#: picard/ui/mainwindow.py:532 +#: picard/ui/mainwindow.py:533 msgid "&Donate..." msgstr "" -#: picard/ui/mainwindow.py:538 +#: picard/ui/mainwindow.py:539 msgid "&Report a Bug..." msgstr "" -#: picard/ui/mainwindow.py:544 +#: picard/ui/mainwindow.py:545 msgid "&Support Forum..." msgstr "" -#: picard/ui/mainwindow.py:550 +#: picard/ui/mainwindow.py:551 msgid "&Add Files..." msgstr "" -#: picard/ui/mainwindow.py:551 +#: picard/ui/mainwindow.py:552 msgid "Add files to the tagger" msgstr "" -#: picard/ui/mainwindow.py:559 +#: picard/ui/mainwindow.py:560 msgid "Add Fold&er..." msgstr "" -#: picard/ui/mainwindow.py:560 +#: picard/ui/mainwindow.py:561 msgid "Add a folder to the tagger" msgstr "" -#: picard/ui/mainwindow.py:562 +#: picard/ui/mainwindow.py:563 msgid "Ctrl+E" msgstr "" -#: picard/ui/mainwindow.py:569 +#: picard/ui/mainwindow.py:570 msgid "Close Window" msgstr "" -#: picard/ui/mainwindow.py:570 +#: picard/ui/mainwindow.py:571 msgid "Ctrl+W" msgstr "" -#: picard/ui/mainwindow.py:578 +#: picard/ui/mainwindow.py:579 msgid "&Save" msgstr "" -#: picard/ui/mainwindow.py:579 +#: picard/ui/mainwindow.py:580 msgid "Save selected files" msgstr "" -#: picard/ui/mainwindow.py:588 +#: picard/ui/mainwindow.py:589 msgid "S&ubmit AcoustIDs" msgstr "" -#: picard/ui/mainwindow.py:589 +#: picard/ui/mainwindow.py:590 msgid "Submit acoustic fingerprints" msgstr "" -#: picard/ui/mainwindow.py:596 +#: picard/ui/mainwindow.py:597 msgid "E&xit" msgstr "" -#: picard/ui/mainwindow.py:599 +#: picard/ui/mainwindow.py:600 msgid "Ctrl+Q" msgstr "" -#: picard/ui/mainwindow.py:605 +#: picard/ui/mainwindow.py:606 msgid "&Remove" msgstr "" -#: picard/ui/mainwindow.py:606 +#: picard/ui/mainwindow.py:607 msgid "Remove selected files/albums" msgstr "" -#: picard/ui/mainwindow.py:613 picard/ui/metadatabox.py:400 +#: picard/ui/mainwindow.py:614 picard/ui/metadatabox.py:400 msgid "Lookup in &Browser" msgstr "" -#: picard/ui/mainwindow.py:614 +#: picard/ui/mainwindow.py:615 msgid "Lookup selected item on MusicBrainz website" msgstr "" -#: picard/ui/mainwindow.py:617 +#: picard/ui/mainwindow.py:618 msgid "Ctrl+Shift+L" msgstr "" -#: picard/ui/mainwindow.py:624 +#: picard/ui/mainwindow.py:625 msgid "Submit cluster as release..." msgstr "" -#: picard/ui/mainwindow.py:625 +#: picard/ui/mainwindow.py:626 msgid "Submit cluster as a new release to MusicBrainz" msgstr "" -#: picard/ui/mainwindow.py:635 +#: picard/ui/mainwindow.py:636 msgid "Submit file as standalone recording..." msgstr "" -#: picard/ui/mainwindow.py:636 +#: picard/ui/mainwindow.py:637 msgid "Submit file as a new recording to MusicBrainz" msgstr "" -#: picard/ui/mainwindow.py:646 +#: picard/ui/mainwindow.py:647 msgid "Submit file as release..." msgstr "" -#: picard/ui/mainwindow.py:647 +#: picard/ui/mainwindow.py:648 msgid "Submit file as a new release to MusicBrainz" msgstr "" -#: picard/ui/mainwindow.py:656 +#: picard/ui/mainwindow.py:657 msgid "Search for similar albums..." msgstr "" -#: picard/ui/mainwindow.py:657 +#: picard/ui/mainwindow.py:658 msgid "View similar releases and optionally choose a different release" msgstr "" -#: picard/ui/mainwindow.py:663 +#: picard/ui/mainwindow.py:664 msgid "Search for similar tracks..." msgstr "" -#: picard/ui/mainwindow.py:664 +#: picard/ui/mainwindow.py:665 msgid "View similar tracks and optionally choose a different release" msgstr "" -#: picard/ui/mainwindow.py:666 +#: picard/ui/mainwindow.py:667 msgid "Ctrl+T" msgstr "" -#: picard/ui/mainwindow.py:672 +#: picard/ui/mainwindow.py:673 msgid "Show &other album versions..." msgstr "" -#: picard/ui/mainwindow.py:673 +#: picard/ui/mainwindow.py:674 msgid "Ctrl+Shift+O" msgstr "" -#: picard/ui/mainwindow.py:680 +#: picard/ui/mainwindow.py:681 msgid "File &Browser" msgstr "" -#: picard/ui/mainwindow.py:684 +#: picard/ui/mainwindow.py:685 msgid "Ctrl+B" msgstr "" -#: picard/ui/mainwindow.py:691 +#: picard/ui/mainwindow.py:692 msgid "&Metadata" msgstr "" -#: picard/ui/mainwindow.py:695 +#: picard/ui/mainwindow.py:696 msgid "Ctrl+Shift+M" msgstr "" -#: picard/ui/mainwindow.py:702 +#: picard/ui/mainwindow.py:703 msgid "&Cover Art" msgstr "" -#: picard/ui/mainwindow.py:713 +#: picard/ui/mainwindow.py:714 msgid "&Actions" msgstr "" -#: picard/ui/mainwindow.py:722 picard/ui/mainwindow.py:1102 +#: picard/ui/mainwindow.py:723 picard/ui/mainwindow.py:1109 #: picard/ui/searchdialog/__init__.py:48 msgid "Search" msgstr "" -#: picard/ui/mainwindow.py:729 picard/ui/mainwindow.py:737 +#: picard/ui/mainwindow.py:730 picard/ui/mainwindow.py:737 msgid "Lookup &CD..." msgstr "" -#: picard/ui/mainwindow.py:730 +#: picard/ui/mainwindow.py:731 msgid "Lookup the details of the CD in your drive" msgstr "" -#: picard/ui/mainwindow.py:732 picard/ui/mainwindow.py:919 +#: picard/ui/mainwindow.py:733 msgid "Ctrl+K" msgstr "" -#: picard/ui/mainwindow.py:746 +#: picard/ui/mainwindow.py:747 msgid "&Scan" msgstr "" -#: picard/ui/mainwindow.py:747 +#: picard/ui/mainwindow.py:748 msgid "" "Use AcoustID audio fingerprint to identify the files by the actual music," " even if they have no metadata" msgstr "" -#: picard/ui/mainwindow.py:749 +#: picard/ui/mainwindow.py:750 msgid "Identify the file using its AcoustID audio fingerprint" msgstr "" -#: picard/ui/mainwindow.py:751 +#: picard/ui/mainwindow.py:752 msgid "Ctrl+Y" msgstr "" -#: picard/ui/mainwindow.py:757 +#: picard/ui/mainwindow.py:758 msgid "&Generate AcoustID Fingerprints" msgstr "" -#: picard/ui/mainwindow.py:758 picard/ui/options/interface.py:119 +#: picard/ui/mainwindow.py:759 picard/ui/options/interface.py:121 msgid "Generate Fingerprints" msgstr "" -#: picard/ui/mainwindow.py:759 +#: picard/ui/mainwindow.py:760 msgid "" "Generate the AcoustID audio fingerprints for the selected files without " "doing a lookup" msgstr "" -#: picard/ui/mainwindow.py:761 +#: picard/ui/mainwindow.py:762 msgid "Generate the AcoustID audio fingerprints for the selected files" msgstr "" -#: picard/ui/mainwindow.py:762 +#: picard/ui/mainwindow.py:763 msgid "Ctrl+Shift+Y" msgstr "" -#: picard/ui/mainwindow.py:768 +#: picard/ui/mainwindow.py:769 msgid "Cl&uster" msgstr "" -#: picard/ui/mainwindow.py:769 +#: picard/ui/mainwindow.py:770 msgid "Cluster files into album clusters" msgstr "" -#: picard/ui/mainwindow.py:772 +#: picard/ui/mainwindow.py:773 msgid "Ctrl+U" msgstr "" -#: picard/ui/mainwindow.py:778 +#: picard/ui/mainwindow.py:779 msgid "&Lookup" msgstr "" -#: picard/ui/mainwindow.py:779 +#: picard/ui/mainwindow.py:780 msgid "Lookup selected items in MusicBrainz" msgstr "" -#: picard/ui/mainwindow.py:784 +#: picard/ui/mainwindow.py:785 msgid "Ctrl+L" msgstr "" -#: picard/ui/mainwindow.py:790 +#: picard/ui/mainwindow.py:791 msgid "&Info..." msgstr "" -#: picard/ui/mainwindow.py:793 +#: picard/ui/mainwindow.py:794 msgid "Ctrl+I" msgstr "" -#: picard/ui/mainwindow.py:799 +#: picard/ui/mainwindow.py:800 msgid "&Refresh" msgstr "" -#: picard/ui/mainwindow.py:800 +#: picard/ui/mainwindow.py:801 msgid "Ctrl+R" msgstr "" -#: picard/ui/mainwindow.py:807 +#: picard/ui/mainwindow.py:808 msgid "&Rename Files" msgstr "" -#: picard/ui/mainwindow.py:816 +#: picard/ui/mainwindow.py:817 msgid "&Move Files" msgstr "" -#: picard/ui/mainwindow.py:825 +#: picard/ui/mainwindow.py:826 msgid "Save &Tags" msgstr "" -#: picard/ui/mainwindow.py:833 +#: picard/ui/mainwindow.py:834 msgid "Tags From &File Names..." msgstr "" -#: picard/ui/mainwindow.py:834 picard/ui/options/interface.py:131 +#: picard/ui/mainwindow.py:835 picard/ui/options/interface.py:133 msgid "Parse File Names..." msgstr "" -#: picard/ui/mainwindow.py:835 +#: picard/ui/mainwindow.py:836 msgid "Set tags based on the file names" msgstr "" -#: picard/ui/mainwindow.py:836 picard/ui/widgets/scripttextedit.py:338 +#: picard/ui/mainwindow.py:837 picard/ui/widgets/scripttextedit.py:338 msgid "Ctrl+Shift+T" msgstr "" -#: picard/ui/mainwindow.py:844 +#: picard/ui/mainwindow.py:845 msgid "&Open My Collections in Browser" msgstr "" -#: picard/ui/mainwindow.py:851 +#: picard/ui/mainwindow.py:852 msgid "View &Error/Debug Log" msgstr "" -#: picard/ui/mainwindow.py:853 +#: picard/ui/mainwindow.py:854 msgid "Ctrl+G" msgstr "" -#: picard/ui/mainwindow.py:859 +#: picard/ui/mainwindow.py:860 msgid "View Activity &History" msgstr "" -#: picard/ui/mainwindow.py:862 +#: picard/ui/mainwindow.py:863 msgid "Ctrl+Shift+H" msgstr "" -#: picard/ui/mainwindow.py:862 picard/ui/scripteditor.py:626 +#: picard/ui/mainwindow.py:863 picard/ui/scripteditor.py:631 msgid "Ctrl+H" msgstr "" -#: picard/ui/mainwindow.py:868 +#: picard/ui/mainwindow.py:869 msgid "Open in &Player" msgstr "" -#: picard/ui/mainwindow.py:869 +#: picard/ui/mainwindow.py:870 msgid "Play the file in your default media player" msgstr "" -#: picard/ui/mainwindow.py:876 +#: picard/ui/mainwindow.py:877 msgid "Open Containing &Folder" msgstr "" -#: picard/ui/mainwindow.py:877 +#: picard/ui/mainwindow.py:878 msgid "Open the containing folder in your file explorer" msgstr "" -#: picard/ui/mainwindow.py:885 +#: picard/ui/mainwindow.py:886 msgid "&Check for Update…" msgstr "" -#: picard/ui/mainwindow.py:926 +#: picard/ui/mainwindow.py:925 msgid "From EAC / XLD / Whipper &log file..." msgstr "" -#: picard/ui/mainwindow.py:969 picard/ui/scripteditor.py:550 +#: picard/ui/mainwindow.py:976 picard/ui/scripteditor.py:555 msgid "&File" msgstr "" -#: picard/ui/mainwindow.py:982 +#: picard/ui/mainwindow.py:989 msgid "&Edit" msgstr "" -#: picard/ui/mainwindow.py:988 picard/ui/scripteditor.py:611 +#: picard/ui/mainwindow.py:995 picard/ui/scripteditor.py:616 msgid "&View" msgstr "" -#: picard/ui/mainwindow.py:997 +#: picard/ui/mainwindow.py:1004 msgid "&Options" msgstr "" -#: picard/ui/mainwindow.py:1003 +#: picard/ui/mainwindow.py:1010 msgid "&Select file naming script" msgstr "" -#: picard/ui/mainwindow.py:1011 +#: picard/ui/mainwindow.py:1018 msgid "&Enable/disable profiles" msgstr "" -#: picard/ui/mainwindow.py:1018 +#: picard/ui/mainwindow.py:1025 msgid "&Tools" msgstr "" -#: picard/ui/mainwindow.py:1032 picard/ui/scripteditor.py:632 +#: picard/ui/mainwindow.py:1039 picard/ui/scripteditor.py:637 #: picard/ui/util.py:51 msgid "&Help" msgstr "" -#: picard/ui/mainwindow.py:1066 picard/ui/ui_options_plugins.py:134 +#: picard/ui/mainwindow.py:1073 picard/ui/ui_options_plugins.py:134 msgid "Actions" msgstr "" -#: picard/ui/mainwindow.py:1113 +#: picard/ui/mainwindow.py:1120 msgid "Track" msgstr "" -#: picard/ui/mainwindow.py:1130 +#: picard/ui/mainwindow.py:1137 msgid "&Advanced search" msgstr "" -#: picard/ui/mainwindow.py:1131 +#: picard/ui/mainwindow.py:1138 msgid "&Builtin search" msgstr "" -#: picard/ui/mainwindow.py:1226 +#: picard/ui/mainwindow.py:1233 msgid "All supported formats" msgstr "" -#: picard/ui/mainwindow.py:1255 +#: picard/ui/mainwindow.py:1262 #, python-format msgid "Adding multiple directories from '%(directory)s' ..." msgstr "" -#: picard/ui/mainwindow.py:1260 +#: picard/ui/mainwindow.py:1267 #, python-format msgid "Adding directory: '%(directory)s' ..." msgstr "" -#: picard/ui/mainwindow.py:1366 +#: picard/ui/mainwindow.py:1373 msgid "Configuration Required" msgstr "" -#: picard/ui/mainwindow.py:1367 +#: picard/ui/mainwindow.py:1374 msgid "" "Audio fingerprinting is not yet configured. Would you like to configure " "it now?" msgstr "" -#: picard/ui/mainwindow.py:1461 +#: picard/ui/mainwindow.py:1468 msgid "Browser integration not enabled" msgstr "" -#: picard/ui/mainwindow.py:1462 +#: picard/ui/mainwindow.py:1469 msgid "" "Submitting releases to MusicBrainz requires the browser integration to be" " enabled. Do you want to enable the browser integration now?" msgstr "" -#: picard/ui/mainwindow.py:1570 +#: picard/ui/mainwindow.py:1577 #, python-format msgid "%(filename)s (error: %(error)s)" msgstr "" -#: picard/ui/mainwindow.py:1576 +#: picard/ui/mainwindow.py:1583 #, python-format msgid "%(filename)s" msgstr "" -#: picard/ui/mainwindow.py:1585 +#: picard/ui/mainwindow.py:1592 #, python-format msgid "%(filename)s (%(similarity)d%%) (error: %(error)s)" msgstr "" -#: picard/ui/mainwindow.py:1592 +#: picard/ui/mainwindow.py:1599 #, python-format msgid "%(filename)s (%(similarity)d%%)" msgstr "" -#: picard/ui/mainwindow.py:1655 +#: picard/ui/mainwindow.py:1662 msgid "Authentication Required" msgstr "" -#: picard/ui/mainwindow.py:1656 +#: picard/ui/mainwindow.py:1663 msgid "" "Picard needs authorization to access your personal data on the " "MusicBrainz server. Would you like to log in now?" msgstr "" -#: picard/ui/mainwindow.py:1671 +#: picard/ui/mainwindow.py:1678 msgid "Authentication failed" msgstr "" -#: picard/ui/mainwindow.py:1672 picard/ui/options/general.py:146 +#: picard/ui/mainwindow.py:1679 picard/ui/options/general.py:146 #, python-format msgid "Login failed: %s" msgstr "" @@ -4954,11 +4958,11 @@ msgstr "" msgid "Audio volume" msgstr "" -#: picard/ui/scripteditor.py:145 +#: picard/ui/scripteditor.py:146 msgid "Renaming options are disabled" msgstr "" -#: picard/ui/scripteditor.py:214 +#: picard/ui/scripteditor.py:219 #, python-format msgid "" "If you select files from the Cluster pane or Album pane prior to opening " @@ -4967,139 +4971,139 @@ msgid "" "then some default examples will be provided." msgstr "" -#: picard/ui/scripteditor.py:226 +#: picard/ui/scripteditor.py:231 #, python-format msgid "" "Reload up to %u items chosen at random from files selected in the main " "window" msgstr "" -#: picard/ui/scripteditor.py:315 picard/ui/scripteditor.py:1212 +#: picard/ui/scripteditor.py:320 picard/ui/scripteditor.py:1217 msgid "Confirm" msgstr "" -#: picard/ui/scripteditor.py:356 +#: picard/ui/scripteditor.py:361 #, python-format msgid "User: %s" msgstr "" -#: picard/ui/scripteditor.py:391 +#: picard/ui/scripteditor.py:396 msgid "title" msgstr "" -#: picard/ui/scripteditor.py:410 +#: picard/ui/scripteditor.py:415 msgid "File naming script editor" msgstr "" -#: picard/ui/scripteditor.py:476 +#: picard/ui/scripteditor.py:481 msgid "Reset" msgstr "" -#: picard/ui/options/dialog.py:131 picard/ui/scripteditor.py:481 +#: picard/ui/options/dialog.py:131 picard/ui/scripteditor.py:486 msgid "Make It So!" msgstr "" -#: picard/ui/scripteditor.py:553 +#: picard/ui/scripteditor.py:558 msgid "&Import a script file" msgstr "" -#: picard/ui/scripteditor.py:554 +#: picard/ui/scripteditor.py:559 msgid "Import a file as a new script" msgstr "" -#: picard/ui/scripteditor.py:559 +#: picard/ui/scripteditor.py:564 msgid "&Export a script file" msgstr "" -#: picard/ui/scripteditor.py:560 +#: picard/ui/scripteditor.py:565 msgid "Export the script to a file" msgstr "" -#: picard/ui/scripteditor.py:565 +#: picard/ui/scripteditor.py:570 msgid "&Reset all scripts" msgstr "" -#: picard/ui/scripteditor.py:566 +#: picard/ui/scripteditor.py:571 msgid "Reset all scripts to the saved values" msgstr "" -#: picard/ui/scripteditor.py:571 +#: picard/ui/scripteditor.py:576 msgid "&Save and exit" msgstr "" -#: picard/ui/scripteditor.py:572 +#: picard/ui/scripteditor.py:577 msgid "Save changes to the script settings and exit" msgstr "" -#: picard/ui/scripteditor.py:577 +#: picard/ui/scripteditor.py:582 msgid "E&xit without saving" msgstr "" -#: picard/ui/scripteditor.py:578 +#: picard/ui/scripteditor.py:583 msgid "Close the script editor without saving changes" msgstr "" -#: picard/ui/scripteditor.py:583 +#: picard/ui/scripteditor.py:588 msgid "&Script" msgstr "" -#: picard/ui/scripteditor.py:586 +#: picard/ui/scripteditor.py:591 msgid "View/Edit Script &Metadata" msgstr "" -#: picard/ui/scripteditor.py:587 +#: picard/ui/scripteditor.py:592 msgid "Display the details for the script" msgstr "" -#: picard/ui/scripteditor.py:589 +#: picard/ui/scripteditor.py:594 msgid "Ctrl+M" msgstr "" -#: picard/ui/scripteditor.py:592 +#: picard/ui/scripteditor.py:597 msgid "Add a &new script" msgstr "" -#: picard/ui/scripteditor.py:593 +#: picard/ui/scripteditor.py:598 msgid "Create a new file naming script" msgstr "" -#: picard/ui/scripteditor.py:598 +#: picard/ui/scripteditor.py:603 msgid "&Copy the current script" msgstr "" -#: picard/ui/scripteditor.py:599 +#: picard/ui/scripteditor.py:604 msgid "Save a copy of the script as a new script" msgstr "" -#: picard/ui/scripteditor.py:604 +#: picard/ui/scripteditor.py:609 msgid "&Delete the current script" msgstr "" -#: picard/ui/scripteditor.py:605 +#: picard/ui/scripteditor.py:610 msgid "Delete the script" msgstr "" -#: picard/ui/scripteditor.py:614 +#: picard/ui/scripteditor.py:619 msgid "&Reload random example files" msgstr "" -#: picard/ui/scripteditor.py:623 +#: picard/ui/scripteditor.py:628 msgid "&Show documentation" msgstr "" -#: picard/ui/scripteditor.py:624 +#: picard/ui/scripteditor.py:629 msgid "View the scripting documentation in a sidebar" msgstr "" -#: picard/ui/scripteditor.py:640 +#: picard/ui/scripteditor.py:645 msgid "&Scripting documentation..." msgstr "" -#: picard/ui/scripteditor.py:641 +#: picard/ui/scripteditor.py:646 msgid "Open the scripting documentation in your browser" msgstr "" -#: picard/ui/scripteditor.py:740 +#: picard/ui/scripteditor.py:745 msgid "" "At least one unsaved script has been attached to an option profile.\n" "\n" @@ -5114,21 +5118,21 @@ msgid "" "Are you sure that you want to continue?" msgstr "" -#: picard/ui/options/renaming.py:285 picard/ui/scripteditor.py:842 -#: picard/ui/scripteditor.py:1151 picard/ui/scripteditor.py:1391 +#: picard/ui/options/renaming.py:285 picard/ui/scripteditor.py:847 +#: picard/ui/scripteditor.py:1156 picard/ui/scripteditor.py:1396 msgid "Error" msgstr "" -#: picard/ui/scripteditor.py:842 picard/ui/scripteditor.py:1151 -#: picard/ui/scripteditor.py:1392 +#: picard/ui/scripteditor.py:847 picard/ui/scripteditor.py:1156 +#: picard/ui/scripteditor.py:1397 msgid "The script title must not be empty." msgstr "" -#: picard/ui/scripteditor.py:1098 +#: picard/ui/scripteditor.py:1103 msgid "Error Deleting Script" msgstr "" -#: picard/ui/scripteditor.py:1099 +#: picard/ui/scripteditor.py:1104 #, python-format msgid "" "The script could not be deleted because it is used in one of the user " @@ -5137,38 +5141,38 @@ msgid "" "Profile: %s" msgstr "" -#: picard/ui/scripteditor.py:1108 +#: picard/ui/scripteditor.py:1113 msgid "Are you sure that you want to delete the script?" msgstr "" -#: picard/ui/options/scripting.py:161 picard/ui/scripteditor.py:1193 +#: picard/ui/options/scripting.py:161 picard/ui/scripteditor.py:1198 msgid "File Error" msgstr "" -#: picard/ui/scripteditor.py:1214 +#: picard/ui/scripteditor.py:1219 msgid "" "A script named \"{script_name}\" already exists.\n" "\n" "Do you want to overwrite it, add as a copy or cancel?" msgstr "" -#: picard/ui/scripteditor.py:1221 +#: picard/ui/scripteditor.py:1226 msgid "Overwrite" msgstr "" -#: picard/ui/options/profiles.py:118 picard/ui/scripteditor.py:1223 +#: picard/ui/options/profiles.py:118 picard/ui/scripteditor.py:1228 msgid "Copy" msgstr "" -#: picard/ui/options/renaming.py:295 picard/ui/scripteditor.py:1269 +#: picard/ui/options/renaming.py:295 picard/ui/scripteditor.py:1274 msgid "The file naming format must not be empty." msgstr "" -#: picard/ui/scripteditor.py:1306 +#: picard/ui/scripteditor.py:1311 msgid "Script Details" msgstr "" -#: picard/ui/scripteditor.py:1371 +#: picard/ui/scripteditor.py:1376 msgid "" "There are unsaved changes to the current metadata.\n" "\n" @@ -5320,39 +5324,39 @@ msgstr "" msgid "Options" msgstr "" -#: picard/ui/ui_options_advanced.py:115 +#: picard/ui/ui_options_advanced.py:140 msgid "Advanced options" msgstr "" -#: picard/ui/ui_options_advanced.py:117 -msgid "Ignore track duration difference under this number of seconds" -msgstr "" - -#: picard/ui/ui_options_advanced.py:118 +#: picard/ui/ui_options_advanced.py:141 msgid "Ignore file paths matching the following regular expression:" msgstr "" -#: picard/ui/ui_options_advanced.py:120 +#: picard/ui/ui_options_advanced.py:143 +msgid "Ignore track duration difference under this number of seconds" +msgstr "" + +#: picard/ui/ui_options_advanced.py:146 msgid "Ignore the following tracks when determining whether a release is complete" msgstr "" -#: picard/ui/ui_options_advanced.py:121 +#: picard/ui/ui_options_advanced.py:147 msgid "Video tracks" msgstr "" -#: picard/ui/ui_options_advanced.py:122 +#: picard/ui/ui_options_advanced.py:148 msgid "Pregap tracks" msgstr "" -#: picard/ui/ui_options_advanced.py:123 +#: picard/ui/ui_options_advanced.py:149 msgid "Data tracks" msgstr "" -#: picard/ui/ui_options_advanced.py:124 +#: picard/ui/ui_options_advanced.py:150 msgid "Silent tracks" msgstr "" -#: picard/ui/ui_options_advanced.py:125 +#: picard/ui/ui_options_advanced.py:151 msgid "Tags to ignore for comparison:" msgstr "" @@ -5664,7 +5668,7 @@ msgstr "" msgid "Standalone recordings:" msgstr "" -#: picard/ui/options/interface.py:172 picard/ui/ui_options_metadata.py:143 +#: picard/ui/options/interface.py:174 picard/ui/ui_options_metadata.py:143 #: picard/ui/ui_options_metadata.py:144 #: picard/ui/ui_provider_options_local.py:54 msgid "Default" @@ -5706,12 +5710,12 @@ msgstr "" msgid "Listen only on localhost" msgstr "" -#: picard/ui/options/plugins.py:218 picard/ui/ui_options_plugins.py:131 +#: picard/ui/options/plugins.py:220 picard/ui/ui_options_plugins.py:131 msgid "Plugins" msgstr "" -#: picard/ui/options/plugins.py:602 picard/ui/searchdialog/album.py:137 -#: picard/ui/searchdialog/artist.py:52 picard/ui/searchdialog/track.py:64 +#: picard/ui/options/plugins.py:604 picard/ui/searchdialog/album.py:139 +#: picard/ui/searchdialog/artist.py:54 picard/ui/searchdialog/track.py:66 #: picard/ui/ui_options_plugins.py:132 msgid "Name" msgstr "" @@ -6288,106 +6292,106 @@ msgstr "" msgid "Error line %d: %s" msgstr "" -#: picard/ui/options/interface.py:79 +#: picard/ui/options/interface.py:81 msgid "Add Folder" msgstr "" -#: picard/ui/options/interface.py:83 +#: picard/ui/options/interface.py:85 msgid "Add Files" msgstr "" -#: picard/ui/options/interface.py:87 +#: picard/ui/options/interface.py:89 msgid "Cluster" msgstr "" -#: picard/ui/options/interface.py:91 +#: picard/ui/options/interface.py:93 msgid "Lookup" msgstr "" -#: picard/ui/options/interface.py:95 +#: picard/ui/options/interface.py:97 msgid "Scan" msgstr "" -#: picard/ui/options/interface.py:99 +#: picard/ui/options/interface.py:101 msgid "Lookup in Browser" msgstr "" -#: picard/ui/options/interface.py:103 +#: picard/ui/options/interface.py:105 msgid "Save" msgstr "" -#: picard/ui/options/interface.py:115 +#: picard/ui/options/interface.py:117 msgid "Submit AcoustIDs" msgstr "" -#: picard/ui/options/interface.py:123 +#: picard/ui/options/interface.py:125 msgid "Open in Player" msgstr "" -#: picard/ui/options/interface.py:127 +#: picard/ui/options/interface.py:129 msgid "Lookup CD..." msgstr "" -#: picard/ui/options/interface.py:173 +#: picard/ui/options/interface.py:175 msgid "The default color scheme based on the operating system display settings" msgstr "" -#: picard/ui/options/interface.py:176 +#: picard/ui/options/interface.py:178 msgid "Dark" msgstr "" -#: picard/ui/options/interface.py:177 +#: picard/ui/options/interface.py:179 msgid "A dark display theme" msgstr "" -#: picard/ui/options/interface.py:180 +#: picard/ui/options/interface.py:182 msgid "Light" msgstr "" -#: picard/ui/options/interface.py:181 +#: picard/ui/options/interface.py:183 msgid "A light display theme" msgstr "" -#: picard/ui/options/interface.py:184 +#: picard/ui/options/interface.py:186 msgid "System" msgstr "" -#: picard/ui/options/interface.py:185 +#: picard/ui/options/interface.py:187 msgid "The Qt5 theme configured in the desktop environment" msgstr "" -#: picard/ui/options/interface.py:203 +#: picard/ui/options/interface.py:205 msgid "System default" msgstr "" -#: picard/ui/options/interface.py:264 +#: picard/ui/options/interface.py:266 msgid "Theme changed" msgstr "" -#: picard/ui/options/interface.py:265 +#: picard/ui/options/interface.py:267 msgid "" "You have changed the application theme. You have to restart Picard in " "order for the change to take effect." msgstr "" -#: picard/ui/options/interface.py:267 +#: picard/ui/options/interface.py:269 msgid "" "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." msgstr "" -#: picard/ui/options/interface.py:272 +#: picard/ui/options/interface.py:274 msgid "Language changed" msgstr "" -#: picard/ui/options/interface.py:273 +#: picard/ui/options/interface.py:275 msgid "" "You have changed the interface language. You have to restart Picard in " "order for the change to take effect." msgstr "" -#: picard/ui/options/interface.py:305 +#: picard/ui/options/interface.py:307 msgid "Drag and Drop to re-order" msgstr "" @@ -6524,38 +6528,38 @@ msgstr "" msgid "Network" msgstr "" -#: picard/ui/options/plugins.py:137 +#: picard/ui/options/plugins.py:139 msgid "Download and install plugin" msgstr "" -#: picard/ui/options/plugins.py:145 +#: picard/ui/options/plugins.py:147 #, python-format msgid "Download and upgrade plugin to version %s" msgstr "" -#: picard/ui/options/plugins.py:151 +#: picard/ui/options/plugins.py:153 msgid "Enabled" msgstr "" -#: picard/ui/options/plugins.py:155 +#: picard/ui/options/plugins.py:157 msgid "Disabled" msgstr "" -#: picard/ui/options/plugins.py:165 +#: picard/ui/options/plugins.py:167 msgid "Uninstall plugin" msgstr "" -#: picard/ui/options/plugins.py:401 +#: picard/ui/options/plugins.py:403 msgid "Reloading list of available plugins..." msgstr "" -#: picard/ui/options/plugins.py:409 picard/ui/options/plugins.py:418 -#: picard/ui/options/plugins.py:439 +#: picard/ui/options/plugins.py:411 picard/ui/options/plugins.py:420 +#: picard/ui/options/plugins.py:441 #, python-format msgid "Plugin '%s'" msgstr "" -#: picard/ui/options/plugins.py:410 +#: picard/ui/options/plugins.py:412 #, python-format msgid "" "An error occurred while loading the plugin '%s':\n" @@ -6563,48 +6567,48 @@ msgid "" "%s" msgstr "" -#: picard/ui/options/plugins.py:419 +#: picard/ui/options/plugins.py:421 #, python-format msgid "The plugin '%s' is not compatible with this version of Picard." msgstr "" -#: picard/ui/options/plugins.py:440 +#: picard/ui/options/plugins.py:442 #, python-format msgid "The plugin '%s' will be upgraded to version %s on next run of Picard." msgstr "" -#: picard/ui/options/plugins.py:461 +#: picard/ui/options/plugins.py:463 #, python-format msgid "Uninstall plugin '%s'?" msgstr "" -#: picard/ui/options/plugins.py:462 +#: picard/ui/options/plugins.py:464 #, python-format msgid "Do you really want to uninstall the plugin '%s' ?" msgstr "" -#: picard/ui/options/plugins.py:594 +#: picard/ui/options/plugins.py:596 msgid "Restart Picard to upgrade to new version" msgstr "" -#: picard/ui/options/plugins.py:596 +#: picard/ui/options/plugins.py:598 msgid "New version available" msgstr "" -#: picard/ui/options/plugins.py:603 +#: picard/ui/options/plugins.py:605 msgid "Authors" msgstr "" -#: picard/ui/options/plugins.py:604 picard/util/tags.py:71 +#: picard/ui/options/plugins.py:606 picard/util/tags.py:71 msgid "License" msgstr "" -#: picard/ui/options/plugins.py:645 +#: picard/ui/options/plugins.py:664 #, python-format msgid "The plugin '%s' could not be downloaded." msgstr "" -#: picard/ui/options/plugins.py:646 +#: picard/ui/options/plugins.py:665 msgid "Please try again later." msgstr "" @@ -6766,68 +6770,68 @@ msgstr "" msgid "No results found. Please try a different search query." msgstr "" -#: picard/ui/searchdialog/album.py:130 picard/ui/searchdialog/track.py:58 +#: picard/ui/searchdialog/album.py:132 picard/ui/searchdialog/track.py:60 msgid "Load into Picard" msgstr "" -#: picard/ui/searchdialog/album.py:135 +#: picard/ui/searchdialog/album.py:137 msgid "Album Search Results" msgstr "" -#: picard/ui/searchdialog/album.py:146 picard/util/tags.py:69 +#: picard/ui/searchdialog/album.py:148 picard/util/tags.py:69 msgid "Language" msgstr "" -#: picard/ui/searchdialog/album.py:148 +#: picard/ui/searchdialog/album.py:150 msgid "Status" msgstr "" -#: picard/ui/searchdialog/album.py:150 picard/ui/searchdialog/artist.py:60 -#: picard/ui/searchdialog/track.py:71 +#: picard/ui/searchdialog/album.py:152 picard/ui/searchdialog/artist.py:62 +#: picard/ui/searchdialog/track.py:73 msgid "Score" msgstr "" -#: picard/ui/searchdialog/artist.py:48 +#: picard/ui/searchdialog/artist.py:50 msgid "Show in browser" msgstr "" -#: picard/ui/searchdialog/artist.py:50 +#: picard/ui/searchdialog/artist.py:52 msgid "Artist Search Dialog" msgstr "" -#: picard/ui/searchdialog/artist.py:54 +#: picard/ui/searchdialog/artist.py:56 msgid "Gender" msgstr "" -#: picard/ui/searchdialog/artist.py:55 +#: picard/ui/searchdialog/artist.py:57 msgid "Area" msgstr "" -#: picard/ui/searchdialog/artist.py:56 +#: picard/ui/searchdialog/artist.py:58 msgid "Begin" msgstr "" -#: picard/ui/searchdialog/artist.py:57 +#: picard/ui/searchdialog/artist.py:59 msgid "Begin Area" msgstr "" -#: picard/ui/searchdialog/artist.py:58 +#: picard/ui/searchdialog/artist.py:60 msgid "End" msgstr "" -#: picard/ui/searchdialog/artist.py:59 +#: picard/ui/searchdialog/artist.py:61 msgid "End Area" msgstr "" -#: picard/ui/searchdialog/track.py:62 +#: picard/ui/searchdialog/track.py:64 msgid "Track Search Results" msgstr "" -#: picard/ui/searchdialog/track.py:67 +#: picard/ui/searchdialog/track.py:69 msgid "Release" msgstr "" -#: picard/ui/searchdialog/track.py:169 +#: picard/ui/searchdialog/track.py:172 msgid "Standalone Recording" msgstr "" @@ -6885,7 +6889,7 @@ msgid "" "unlock the table in the table header's context menu." msgstr "" -#: picard/util/__init__.py:320 +#: picard/util/__init__.py:326 msgid "No Title" msgstr "" From 965f675243831dd5abb907a7e7d6eb5ca0e07f9b Mon Sep 17 00:00:00 2001 From: Kamil Date: Tue, 28 Jun 2022 23:30:19 +0000 Subject: [PATCH 06/10] added timeout to *verify sdist package* Should have a bit more time preallocated than just run-tests but it also can get stuck (runs tests too), so timeout 40min should be okay. --- .github/workflows/run-tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 40502624d..07c563244 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -120,6 +120,7 @@ jobs: run: picard --long-version --no-crash-dialog - name: Verify sdist package if: runner.os != 'Windows' + timeout-minutes: 40 run: | pip install pytest scripts/package/run-sdist-test.sh From 20869e31b1cd54aa737d2d18836a081f1523552c Mon Sep 17 00:00:00 2001 From: Kamil Date: Tue, 28 Jun 2022 23:34:48 +0000 Subject: [PATCH 07/10] timeouts added --- .github/workflows/pypi-release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/pypi-release.yml b/.github/workflows/pypi-release.yml index 601680eb5..ba11977ac 100644 --- a/.github/workflows/pypi-release.yml +++ b/.github/workflows/pypi-release.yml @@ -20,6 +20,7 @@ jobs: python -m pip install --upgrade pip pip install --upgrade -r requirements.txt - name: Run tests + timeout-minutes: 30 run: | python setup.py test - name: Build Python source distribution @@ -97,6 +98,7 @@ jobs: python -m pip install --upgrade pip wheel pip install --upgrade -r requirements.txt - name: Run tests + timeout-minutes: 30 run: | python setup.py test - name: Build Python binary distribution From 4896e30dbe0c4d9d7cbf4d066e96e027ba89be30 Mon Sep 17 00:00:00 2001 From: Kamil Date: Tue, 28 Jun 2022 23:36:52 +0000 Subject: [PATCH 08/10] timeout added --- .github/workflows/package.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index fd4fb0b69..f1889b5bf 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -79,6 +79,7 @@ jobs: pip3 install -r requirements-build.txt pip3 install -r requirements-macos-${MACOSX_DEPLOYMENT_TARGET}.txt - name: Run tests + timeout-minutes: 30 run: | python3 setup.py test - name: Prepare code signing certificate @@ -153,6 +154,7 @@ jobs: pip install -r requirements-build.txt pip install -r requirements-win.txt - name: Run tests + timeout-minutes: 30 run: python setup.py test - name: Prepare code signing certificate if: matrix.type != 'store-app' From f3d3b2647da426095c63be2e1e6736c74fa7f764 Mon Sep 17 00:00:00 2001 From: Kamil Date: Wed, 29 Jun 2022 14:19:17 +0000 Subject: [PATCH 09/10] unified timeouts --- .github/workflows/run-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 07c563244..3b26ba041 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -120,7 +120,7 @@ jobs: run: picard --long-version --no-crash-dialog - name: Verify sdist package if: runner.os != 'Windows' - timeout-minutes: 40 + timeout-minutes: 30 run: | pip install pytest scripts/package/run-sdist-test.sh From a204b5223f9c1a7fd276030c3e95f9fc2f78dc3a Mon Sep 17 00:00:00 2001 From: Kamil Date: Mon, 4 Jul 2022 08:01:33 +0200 Subject: [PATCH 10/10] unparsed_args removed from `tagger.py` (#2127) unparsed_args removed from `tagger.py` The variable wasn't used anywhere (wasn't even stored as `Tagger`'s attribute) --- picard/tagger.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/picard/tagger.py b/picard/tagger.py index a9e017590..7b47b6d85 100644 --- a/picard/tagger.py +++ b/picard/tagger.py @@ -186,7 +186,7 @@ class Tagger(QtWidgets.QApplication): _debug = False _no_restore = False - def __init__(self, picard_args, unparsed_args, localedir, autoupdate): + def __init__(self, picard_args, localedir, autoupdate): super().__init__(sys.argv) self.__class__.__instance = self @@ -1047,8 +1047,8 @@ def process_picard_args(): parser.add_argument("-V", "--long-version", action='store_true', help="display long version information and exit") parser.add_argument('FILE', nargs='*') - picard_args, unparsed_args = parser.parse_known_args() - return picard_args, unparsed_args + + return parser.parse_known_args()[0] class OverrideStyle(QtWidgets.QProxyStyle): @@ -1085,7 +1085,7 @@ def main(localedir=None, autoupdate=True): signal.signal(signal.SIGINT, signal.SIG_DFL) - picard_args, unparsed_args = process_picard_args() + picard_args = process_picard_args() if picard_args.version: return version() if picard_args.long_version: @@ -1098,7 +1098,7 @@ def main(localedir=None, autoupdate=True): except ImportError: pass - tagger = Tagger(picard_args, unparsed_args, localedir, autoupdate) + tagger = Tagger(picard_args, localedir, autoupdate) # Initialize Qt default translations translator = QtCore.QTranslator()