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' 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 diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 40502624d..3b26ba041 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: 30 run: | pip install pytest scripts/package/run-sdist-test.sh 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/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/picard/tagger.py b/picard/tagger.py index d8f67eaef..d734ee535 100644 --- a/picard/tagger.py +++ b/picard/tagger.py @@ -188,7 +188,8 @@ class Tagger(QtWidgets.QApplication): _debug = False _no_restore = False - def __init__(self, picard_args, unparsed_args, localedir, autoupdate, pipe_handler=None): + + def __init__(self, picard_args, localedir, autoupdate, pipe_handler=None): super().__init__(sys.argv) self.__class__.__instance = self @@ -1066,8 +1067,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): @@ -1106,7 +1107,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: @@ -1142,7 +1143,7 @@ def main(localedir=None, autoupdate=True): except ImportError: pass - tagger = Tagger(picard_args, unparsed_args, localedir, autoupdate, pipe_handler=pipe_handler) + tagger = Tagger(picard_args, localedir, autoupdate, pipe_handler=pipe_handler) # Initialize Qt default translations translator = QtCore.QTranslator() diff --git a/picard/ui/scripteditor.py b/picard/ui/scripteditor.py index 4503f606b..81b1f051a 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,18 @@ 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"]: + # 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() - 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 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/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 "" 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' 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):