Sun, 15 Sep 2024 11:57:39 +0200
Changed the long running "outdated" actions to use an asynchronous process with timeout.
--- a/PKGLIST Sat Sep 07 19:29:57 2024 +0200 +++ b/PKGLIST Sun Sep 15 11:57:39 2024 +0200 @@ -14,6 +14,7 @@ PipxInterface/PipxInterpretersDialog.ui PipxInterface/PipxPackagesInputDialog.py PipxInterface/PipxPackagesInputDialog.ui +PipxInterface/PipxProcess.py PipxInterface/PipxReinstallDialog.py PipxInterface/PipxReinstallDialog.ui PipxInterface/PipxSpecInputDialog.py
--- a/PipxInterface/Documentation/Source/Plugin_Pipx_Interface.PipxInterface.Pipx.html Sat Sep 07 19:29:57 2024 +0200 +++ b/PipxInterface/Documentation/Source/Plugin_Pipx_Interface.PipxInterface.Pipx.html Sun Sep 15 11:57:39 2024 +0200 @@ -20,7 +20,7 @@ <table> <tr> <td><a href="#Pipx">Pipx</a></td> -<td>Class implementing the pip GUI logic.</td> +<td>Class implementing the pipx interface.</td> </tr> </table> @@ -34,9 +34,18 @@ <a NAME="Pipx" ID="Pipx"></a> <h2>Pipx</h2> <p> - Class implementing the pip GUI logic. + Class implementing the pipx interface. </p> +<h3>Signals</h3> +<dl> + +<dt>outdatedPackage(package:str, latestVer:str, oudatedDeps:bool)</dt> +<dd> +emitted with + the result of a check for outdated status of a package +</dd> +</dl> <h3>Derived from</h3> QObject <h3>Class Attributes</h3> @@ -56,6 +65,18 @@ <td>Constructor</td> </tr> <tr> +<td><a href="#Pipx.__asyncProcessError">__asyncProcessError</a></td> +<td>Private method to handle a process error signal.</td> +</tr> +<tr> +<td><a href="#Pipx.__asyncProcessFinished">__asyncProcessFinished</a></td> +<td>Private method to handle the process finished signal.</td> +</tr> +<tr> +<td><a href="#Pipx.__checkPackageOutdatedCb">__checkPackageOutdatedCb</a></td> +<td>Private method handling the pipx process output of a check for an outdated package.</td> +</tr> +<tr> <td><a href="#Pipx.__getPackageDependencies">__getPackageDependencies</a></td> <td>Private method to get a list of dependencies of a given package.</td> </tr> @@ -68,6 +89,14 @@ <td>Private method to allow the JSON decoding of Path objects of a spec metadata file as created by 'pipx list --json'.</td> </tr> <tr> +<td><a href="#Pipx.__runPipxAsyncProcess">__runPipxAsyncProcess</a></td> +<td>Private method to execute pipx with the given arguments asynchronously.</td> +</tr> +<tr> +<td><a href="#Pipx.__runPipxProcess">__runPipxProcess</a></td> +<td>Private method to execute pipx with the given arguments.</td> +</tr> +<tr> <td><a href="#Pipx.checkPackageOutdated">checkPackageOutdated</a></td> <td>Public method to check, if a given package is outdated.</td> </tr> @@ -92,6 +121,10 @@ <td>Public method to get the list of outdated package dependencies.</td> </tr> <tr> +<td><a href="#Pipx.getPackageVersion">getPackageVersion</a></td> +<td>Public method to get the version of a package.</td> +</tr> +<tr> <td><a href="#Pipx.getPipxInterpretersList">getPipxInterpretersList</a></td> <td>Public method returning a list all standalone interpreters.</td> </tr> @@ -136,10 +169,6 @@ <td>Public method to reinstall the given package with given options.</td> </tr> <tr> -<td><a href="#Pipx.runPipxProcess">runPipxProcess</a></td> -<td>Public method to execute pipx with the given arguments.</td> -</tr> -<tr> <td><a href="#Pipx.uninstallAllPackages">uninstallAllPackages</a></td> <td>Public method to uninstall all pipx managed packages.</td> </tr> @@ -189,6 +218,74 @@ reference to the user interface object </dd> </dl> +<a NAME="Pipx.__asyncProcessError" ID="Pipx.__asyncProcessError"></a> +<h4>Pipx.__asyncProcessError</h4> +<b>__asyncProcessError</b>(<i>process, error</i>) +<p> + Private method to handle a process error signal. +</p> + +<dl> + +<dt><i>process</i> (QProcess)</dt> +<dd> +reference to the process +</dd> +<dt><i>error</i> (QProcess.ProcessError)</dt> +<dd> +error that occurred +</dd> +</dl> +<a NAME="Pipx.__asyncProcessFinished" ID="Pipx.__asyncProcessFinished"></a> +<h4>Pipx.__asyncProcessFinished</h4> +<b>__asyncProcessFinished</b>(<i>callback, process, _exitCode, exitStatus</i>) +<p> + Private method to handle the process finished signal. +</p> + +<dl> + +<dt><i>callback</i> (function)</dt> +<dd> +reference to the function to be called a success flag and the + process output or error message +</dd> +<dt><i>process</i> (QProcess)</dt> +<dd> +reference to the process +</dd> +<dt><i>_exitCode</i> (int)</dt> +<dd> +exit code of the process +</dd> +<dt><i>exitStatus</i> (QProcess.ExitStatus)</dt> +<dd> +exit status of the process +</dd> +</dl> +<a NAME="Pipx.__checkPackageOutdatedCb" ID="Pipx.__checkPackageOutdatedCb"></a> +<h4>Pipx.__checkPackageOutdatedCb</h4> +<b>__checkPackageOutdatedCb</b>(<i>package, ok, output</i>) +<p> + Private method handling the pipx process output of a check for an outdated + package. +</p> + +<dl> + +<dt><i>package</i> (str)</dt> +<dd> +name of the package +</dd> +<dt><i>ok</i> (bool)</dt> +<dd> +flag indicating the process ended successfully +</dd> +<dt><i>output</i> (str)</dt> +<dd> +output of the pipx process or an error message +</dd> +</dl> <a NAME="Pipx.__getPackageDependencies" ID="Pipx.__getPackageDependencies"></a> <h4>Pipx.__getPackageDependencies</h4> <b>__getPackageDependencies</b>(<i>package, uptodate=False, outdated=False</i>) @@ -269,6 +366,68 @@ dict or pathlib.Path </dd> </dl> +<a NAME="Pipx.__runPipxAsyncProcess" ID="Pipx.__runPipxAsyncProcess"></a> +<h4>Pipx.__runPipxAsyncProcess</h4> +<b>__runPipxAsyncProcess</b>(<i>args, callback=None, timeout=30000</i>) +<p> + Private method to execute pipx with the given arguments asynchronously. +</p> + +<dl> + +<dt><i>args</i> (list of str)</dt> +<dd> +list of command line arguments for pipx +</dd> +<dt><i>callback</i> (function (optional))</dt> +<dd> +reference to the function to be called a success flag and the + process output or error message (defaults to None) +</dd> +<dt><i>timeout</i> (int (optional))</dt> +<dd> +timeout for the process in milliseconds (defaults to 30000) +</dd> +</dl> +<dl> +<dt>Return:</dt> +<dd> +reference to the generated process object +</dd> +</dl> +<dl> +<dt>Return Type:</dt> +<dd> +QProcess +</dd> +</dl> +<a NAME="Pipx.__runPipxProcess" ID="Pipx.__runPipxProcess"></a> +<h4>Pipx.__runPipxProcess</h4> +<b>__runPipxProcess</b>(<i>args</i>) +<p> + Private method to execute pipx with the given arguments. +</p> + +<dl> + +<dt><i>args</i> (list of str)</dt> +<dd> +list of command line arguments for pipx +</dd> +</dl> +<dl> +<dt>Return:</dt> +<dd> +tuple containing a flag indicating success and the output + of the process +</dd> +</dl> +<dl> +<dt>Return Type:</dt> +<dd> +tuple of (bool, str) +</dd> +</dl> <a NAME="Pipx.checkPackageOutdated" ID="Pipx.checkPackageOutdated"></a> <h4>Pipx.checkPackageOutdated</h4> <b>checkPackageOutdated</b>(<i>package</i>) @@ -283,19 +442,6 @@ name of the package </dd> </dl> -<dl> -<dt>Return:</dt> -<dd> -tuple containing the latest version in case the package is outdated - or None otherwise and a flag indicating any outdated dependencies -</dd> -</dl> -<dl> -<dt>Return Type:</dt> -<dd> -tuple of (str or None, bool) -</dd> -</dl> <a NAME="Pipx.createSpecMetadataFile" ID="Pipx.createSpecMetadataFile"></a> <h4>Pipx.createSpecMetadataFile</h4> <b>createSpecMetadataFile</b>(<i>specFile</i>) @@ -403,6 +549,32 @@ list of tuple of (str, str, str) </dd> </dl> +<a NAME="Pipx.getPackageVersion" ID="Pipx.getPackageVersion"></a> +<h4>Pipx.getPackageVersion</h4> +<b>getPackageVersion</b>(<i>package</i>) +<p> + Public method to get the version of a package. +</p> + +<dl> + +<dt><i>package</i> (str)</dt> +<dd> +package name +</dd> +</dl> +<dl> +<dt>Return:</dt> +<dd> +package version +</dd> +</dl> +<dl> +<dt>Return Type:</dt> +<dd> +str +</dd> +</dl> <a NAME="Pipx.getPipxInterpretersList" ID="Pipx.getPipxInterpretersList"></a> <h4>Pipx.getPipxInterpretersList</h4> <b>getPipxInterpretersList</b>(<i></i>) @@ -658,33 +830,6 @@ on the system (defaults to False) </dd> </dl> -<a NAME="Pipx.runPipxProcess" ID="Pipx.runPipxProcess"></a> -<h4>Pipx.runPipxProcess</h4> -<b>runPipxProcess</b>(<i>args</i>) -<p> - Public method to execute pipx with the given arguments. -</p> - -<dl> - -<dt><i>args</i> (list of str)</dt> -<dd> -list of command line arguments for pipx -</dd> -</dl> -<dl> -<dt>Return:</dt> -<dd> -tuple containing a flag indicating success and the output - of the process -</dd> -</dl> -<dl> -<dt>Return Type:</dt> -<dd> -tuple of (bool, str) -</dd> -</dl> <a NAME="Pipx.uninstallAllPackages" ID="Pipx.uninstallAllPackages"></a> <h4>Pipx.uninstallAllPackages</h4> <b>uninstallAllPackages</b>(<i></i>)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PipxInterface/Documentation/Source/Plugin_Pipx_Interface.PipxInterface.PipxProcess.html Sun Sep 15 11:57:39 2024 +0200 @@ -0,0 +1,194 @@ +<!DOCTYPE html> +<html><head> +<title>Plugin_Pipx_Interface.PipxInterface.PipxProcess</title> +<meta charset="UTF-8"> +<link rel="stylesheet" href="styles.css"> +</head> +<body> +<a NAME="top" ID="top"></a> +<h1>Plugin_Pipx_Interface.PipxInterface.PipxProcess</h1> +<p> +Module implementing a QProcess derive class with a timeout and convenience signals. +</p> + +<h3>Global Attributes</h3> +<table> +<tr><td>None</td></tr> +</table> + +<h3>Classes</h3> +<table> +<tr> +<td><a href="#PipxProcess">PipxProcess</a></td> +<td>Class implementing a QProcess derive class with a timeout and convenience signals succeeded and failed.</td> +</tr> +</table> + +<h3>Functions</h3> +<table> +<tr><td>None</td></tr> +</table> + +<hr /> +<hr /> +<a NAME="PipxProcess" ID="PipxProcess"></a> +<h2>PipxProcess</h2> +<p> + Class implementing a QProcess derive class with a timeout and convenience signals + succeeded and failed. +</p> + +<h3>Signals</h3> +<dl> + +<dt>failed()</dt> +<dd> +emitted to indicate a process failure +</dd> +<dt>succeeded()</dt> +<dd> +emitted to indicate that the process finished successfully +</dd> +<dt>timeout()</dt> +<dd> +emitted to indicate the expiry of the configured timeout value +</dd> +</dl> +<h3>Derived from</h3> +QProcess +<h3>Class Attributes</h3> +<table> +<tr><td>None</td></tr> +</table> + +<h3>Class Methods</h3> +<table> +<tr><td>None</td></tr> +</table> + +<h3>Methods</h3> +<table> +<tr> +<td><a href="#PipxProcess.__init__">PipxProcess</a></td> +<td>Constructor</td> +</tr> +<tr> +<td><a href="#PipxProcess.__finished">__finished</a></td> +<td>Private slot handling the end of the process.</td> +</tr> +<tr> +<td><a href="#PipxProcess.__started">__started</a></td> +<td>Private slot handling the process start.</td> +</tr> +<tr> +<td><a href="#PipxProcess.__timeout">__timeout</a></td> +<td>Private slot to handle the timer interval exoiration.</td> +</tr> +<tr> +<td><a href="#PipxProcess.timedOut">timedOut</a></td> +<td>Public method to test, if the process timed out.</td> +</tr> +<tr> +<td><a href="#PipxProcess.timeoutInterval">timeoutInterval</a></td> +<td>Public method to get the process timeout interval.</td> +</tr> +</table> + +<h3>Static Methods</h3> +<table> +<tr><td>None</td></tr> +</table> + + +<a NAME="PipxProcess.__init__" ID="PipxProcess.__init__"></a> +<h4>PipxProcess (Constructor)</h4> +<b>PipxProcess</b>(<i>timeout=30000, parent=None</i>) +<p> + Constructor +</p> + +<dl> + +<dt><i>timeout</i> (int (optional))</dt> +<dd> +timeout value in milliseconds. If the process does not finish + within this interval, it is killed (defaults to 30000) +</dd> +<dt><i>parent</i> (QObject (optional))</dt> +<dd> +reference to the parent object (defaults to None) +</dd> +</dl> +<a NAME="PipxProcess.__finished" ID="PipxProcess.__finished"></a> +<h4>PipxProcess.__finished</h4> +<b>__finished</b>(<i>exitCode, exitStatus</i>) +<p> + Private slot handling the end of the process. +</p> + +<dl> + +<dt><i>exitCode</i> (int)</dt> +<dd> +exit code of the process (0 = success) +</dd> +<dt><i>exitStatus</i> (QProcess.ExitStatus)</dt> +<dd> +exit status of the process +</dd> +</dl> +<a NAME="PipxProcess.__started" ID="PipxProcess.__started"></a> +<h4>PipxProcess.__started</h4> +<b>__started</b>(<i></i>) +<p> + Private slot handling the process start. +</p> + +<a NAME="PipxProcess.__timeout" ID="PipxProcess.__timeout"></a> +<h4>PipxProcess.__timeout</h4> +<b>__timeout</b>(<i></i>) +<p> + Private slot to handle the timer interval exoiration. +</p> + +<a NAME="PipxProcess.timedOut" ID="PipxProcess.timedOut"></a> +<h4>PipxProcess.timedOut</h4> +<b>timedOut</b>(<i></i>) +<p> + Public method to test, if the process timed out. +</p> + +<dl> +<dt>Return:</dt> +<dd> +flag indicating a timeout +</dd> +</dl> +<dl> +<dt>Return Type:</dt> +<dd> +bool +</dd> +</dl> +<a NAME="PipxProcess.timeoutInterval" ID="PipxProcess.timeoutInterval"></a> +<h4>PipxProcess.timeoutInterval</h4> +<b>timeoutInterval</b>(<i></i>) +<p> + Public method to get the process timeout interval. +</p> + +<dl> +<dt>Return:</dt> +<dd> +process timeout interval in milliseconds +</dd> +</dl> +<dl> +<dt>Return Type:</dt> +<dd> +int +</dd> +</dl> +<div align="right"><a href="#top">Up</a></div> +<hr /> +</body></html>
--- a/PipxInterface/Documentation/Source/Plugin_Pipx_Interface.PipxInterface.PipxWidget.html Sat Sep 07 19:29:57 2024 +0200 +++ b/PipxInterface/Documentation/Source/Plugin_Pipx_Interface.PipxInterface.PipxWidget.html Sun Sep 15 11:57:39 2024 +0200 @@ -20,7 +20,7 @@ <table> <tr> <td><a href="#PipxWidget">PipxWidget</a></td> -<td>Class documentation goes here.</td> +<td>Class implementing the pipx management widget.</td> </tr> </table> @@ -34,7 +34,7 @@ <a NAME="PipxWidget" ID="PipxWidget"></a> <h2>PipxWidget</h2> <p> - Class documentation goes here. + Class implementing the pipx management widget. </p> <h3>Derived from</h3> @@ -74,6 +74,10 @@ <td>Private method to check, if a package item is outdated or has outdated dependencies.</td> </tr> <tr> +<td><a href="#PipxWidget.__checkPackageVersion">__checkPackageVersion</a></td> +<td>Private method to check the version of a package.</td> +</tr> +<tr> <td><a href="#PipxWidget.__createSpecMetadataFile">__createSpecMetadataFile</a></td> <td>Private slot to create a spec metadata file needed by 'pipx install-all'.</td> </tr> @@ -94,6 +98,10 @@ <td>Private method to determine, which app of the given list of apps is running.</td> </tr> <tr> +<td><a href="#PipxWidget.__handleOutdatedPackage">__handleOutdatedPackage</a></td> +<td>Private slot to handle the pipx client reporting an outdated package or a package with outdated dependencies.</td> +</tr> +<tr> <td><a href="#PipxWidget.__hasOutdatedItems">__hasOutdatedItems</a></td> <td>Private method to check, if the list of packages contains any entries which is outdated or has outdated dependencies.</td> </tr> @@ -269,16 +277,18 @@ reference to the package item </dd> </dl> +<a NAME="PipxWidget.__checkPackageVersion" ID="PipxWidget.__checkPackageVersion"></a> +<h4>PipxWidget.__checkPackageVersion</h4> +<b>__checkPackageVersion</b>(<i>itm</i>) +<p> + Private method to check the version of a package. +</p> + <dl> -<dt>Return:</dt> + +<dt><i>itm</i> (QTreeWidgetItem)</dt> <dd> -flag indicating the outdated status -</dd> -</dl> -<dl> -<dt>Return Type:</dt> -<dd> -bool +reference to the package item </dd> </dl> <a NAME="PipxWidget.__createSpecMetadataFile" ID="PipxWidget.__createSpecMetadataFile"></a> @@ -367,6 +377,29 @@ set of str </dd> </dl> +<a NAME="PipxWidget.__handleOutdatedPackage" ID="PipxWidget.__handleOutdatedPackage"></a> +<h4>PipxWidget.__handleOutdatedPackage</h4> +<b>__handleOutdatedPackage</b>(<i>package, latestVersion, outdatedDependencies</i>) +<p> + Private slot to handle the pipx client reporting an outdated package or a + package with outdated dependencies. +</p> + +<dl> + +<dt><i>package</i> (str)</dt> +<dd> +name of the package +</dd> +<dt><i>latestVersion</i> (str)</dt> +<dd> +latest available version in case outdated +</dd> +<dt><i>outdatedDependencies</i> (bool)</dt> +<dd> +flag indicating outdated dependencies +</dd> +</dl> <a NAME="PipxWidget.__hasOutdatedItems" ID="PipxWidget.__hasOutdatedItems"></a> <h4>PipxWidget.__hasOutdatedItems</h4> <b>__hasOutdatedItems</b>(<i></i>)
--- a/PipxInterface/Documentation/Source/index-Plugin_Pipx_Interface.PipxInterface.html Sat Sep 07 19:29:57 2024 +0200 +++ b/PipxInterface/Documentation/Source/index-Plugin_Pipx_Interface.PipxInterface.html Sun Sep 15 11:57:39 2024 +0200 @@ -48,6 +48,10 @@ <td>Module implementing a dialog to enter package specifications.</td> </tr> <tr> +<td><a href="Plugin_Pipx_Interface.PipxInterface.PipxProcess.html">PipxProcess</a></td> +<td>Module implementing a QProcess derive class with a timeout and convenience signals.</td> +</tr> +<tr> <td><a href="Plugin_Pipx_Interface.PipxInterface.PipxReinstallDialog.html">PipxReinstallDialog</a></td> <td>Module implementing a dialog to enter the desired Python interpreter version.</td> </tr>
--- a/PipxInterface/Pipx.py Sat Sep 07 19:29:57 2024 +0200 +++ b/PipxInterface/Pipx.py Sun Sep 15 11:57:39 2024 +0200 @@ -8,25 +8,36 @@ """ import contextlib +import functools import json import os import pathlib import sysconfig -from PyQt6.QtCore import QObject, QProcess +from PyQt6.QtCore import QObject, QProcess, pyqtSignal from eric7 import Preferences from eric7.EricWidgets import EricMessageBox from eric7.SystemUtilities import OSUtilities +try: + from eric7.EricCore.EricProcess import EricProcess +except ImportError: + from .PipxProcess import PipxProcess as EricProcess + from .PipxExecDialog import PipxExecDialog class Pipx(QObject): """ - Class implementing the pip GUI logic. + Class implementing the pipx interface. + + @signal outdatedPackage(package:str, latestVer:str, oudatedDeps:bool) emitted with + the result of a check for outdated status of a package """ + outdatedPackage = pyqtSignal(str, str, bool) + def __init__(self, parent=None): """ Constructor @@ -38,6 +49,8 @@ self.__ui = parent + self.__pipxProcesses = [] + ############################################################################ ## Utility methods ############################################################################ @@ -49,7 +62,7 @@ @return string containing the pipx version number @rtype str """ - ok, output = self.runPipxProcess(["--version"]) + ok, output = self.__runPipxProcess(["--version"]) if ok: return output.strip() else: @@ -114,9 +127,9 @@ return pipx - def runPipxProcess(self, args): + def __runPipxProcess(self, args): """ - Public method to execute pipx with the given arguments. + Private method to execute pipx with the given arguments. @param args list of command line arguments for pipx @type list of str @@ -167,6 +180,106 @@ return pathlib.Path(jsonDict["__Path__"]) return jsonDict + def __runPipxAsyncProcess(self, args, callback=None, timeout=30000): + """ + Private method to execute pipx with the given arguments asynchronously. + + @param args list of command line arguments for pipx + @type list of str + @param callback reference to the function to be called a success flag and the + process output or error message (defaults to None) + @type function (optional) + @param timeout timeout for the process in milliseconds (defaults to 30000) + @type int (optional) + @return reference to the generated process object + @rtype QProcess + """ + process = EricProcess(timeout=timeout) + process.finished.connect( + functools.partial(self.__asyncProcessFinished, callback, process) + ) + process.errorOccurred.connect( + functools.partial(self.__asyncProcessError, process) + ) + self.__pipxProcesses.append(process) + process.start(self.__getPipxExecutable(), args) + return process + + def __asyncProcessError(self, process, error): + """ + Private method to handle a process error signal. + + @param process reference to the process + @type QProcess + @param error error that occurred + @type QProcess.ProcessError + """ + if error == QProcess.ProcessError.FailedToStart: + with contextlib.suppress(ValueError): + self.__pipxProcesses.remove(process) + EricMessageBox.critical( + None, self.tr("pipx Start Error"), self.tr("pipx could not be started.") + ) + else: + EricMessageBox.critical( + None, + self.tr("pipx Runtime Error"), + self.tr( + "<p>The pipx process reported an error.</p><p>Error: {0}</p>" + ).format(process.errorString()), + ) + + def __asyncProcessFinished(self, callback, process, _exitCode, exitStatus): + """ + Private method to handle the process finished signal. + + @param callback reference to the function to be called a success flag and the + process output or error message + @type function + @param process reference to the process + @type QProcess + @param _exitCode exit code of the process + @type int + @param exitStatus exit status of the process + @type QProcess.ExitStatus + """ + if process.timedOut(): + msg = self.tr("pipx did not finish within {0} seconds.").format( + process.timeoutInterval() // 1_000 + ) + if callback: + callback(False, msg) + else: + EricMessageBox.critical(None, self.tr("pipx Timeout Error"), msg) + + elif exitStatus == QProcess.ExitStatus.NormalExit: + ioEncoding = Preferences.getSystem("IOEncoding") + if process.exitCode() == 0: + output = str(process.readAllStandardOutput(), ioEncoding, "replace") + if callback: + callback(True, output) + else: + error = str(process.readAllStandardError(), ioEncoding, "replace") + msg = self.tr("<p>Message: {0}</p>").format(error) if error else "" + if callback: + callback( + False, + self.tr("<p>pipx exited with an error ({0}).</p>{1}").format( + process.exitCode(), msg + ), + ) + else: + EricMessageBox.critical( + None, + self.tr("pipx Execution Error"), + self.tr("<p>pipx exited with an error ({0}).</p>{1}").format( + process.exitCode(), msg + ), + ) + + with contextlib.suppress(ValueError): + self.__pipxProcesses.remove(process) + ############################################################################ ## pipx interpreter list function (modified from original to work here) ############################################################################ @@ -219,7 +332,7 @@ packages = [] - ok, output = self.runPipxProcess(["list", "--json"]) + ok, output = self.__runPipxProcess(["list", "--json"]) if ok and output: with contextlib.suppress(json.JSONDecodeError): data = json.loads(output, object_hook=self.__metadataDecoderHook) @@ -343,7 +456,7 @@ of failure @rtype tuple of (bool, str) """ - ok, output = self.runPipxProcess(["list", "--json"]) + ok, output = self.__runPipxProcess(["list", "--json"]) if ok: try: with open(specFile, "w") as f: @@ -522,15 +635,27 @@ @param package name of the package @type str - @return tuple containing the latest version in case the package is outdated - or None otherwise and a flag indicating any outdated dependencies - @rtype tuple of (str or None, bool) """ args = ["runpip", package, "list", "--outdated", "--format", "json"] if Preferences.getPip("PipSearchIndex"): indexUrl = Preferences.getPip("PipSearchIndex") + "/simple" args += ["--index-url", indexUrl] - ok, output = self.runPipxProcess(args) + self.__runPipxAsyncProcess( + args, callback=functools.partial(self.__checkPackageOutdatedCb, package) + ) + + def __checkPackageOutdatedCb(self, package, ok, output): + """ + Private method handling the pipx process output of a check for an outdated + package. + + @param package name of the package + @type str + @param ok flag indicating the process ended successfully + @type bool + @param output output of the pipx process or an error message + @type str + """ if not ok: EricMessageBox.information( None, @@ -540,15 +665,35 @@ "<p>Reason: {1}</p>" ).format(package, output), ) - return None, False + self.outdatedPackage.emit(package, "", False) + return outdatedList = json.loads(output) # check if the main package is in the list for outdatedPackage in outdatedList: if outdatedPackage["name"] == package: - return outdatedPackage["latest_version"], len(outdatedList) > 1 + self.outdatedPackage.emit( + package, outdatedPackage["latest_version"], len(outdatedList) > 1 + ) + return + + self.outdatedPackage.emit(package, "", bool(outdatedList)) + + def getPackageVersion(self, package): + """ + Public method to get the version of a package. - return None, bool(outdatedList) + @param package package name + @type str + @return package version + @rtype str + """ + packagesList = self.__getPackageDependencies(package=package) + for pack in packagesList: + if pack["name"] == package: + return pack["version"] + else: + return "" def __getPackageDependencies(self, package, uptodate=False, outdated=False): """ @@ -572,7 +717,7 @@ if Preferences.getPip("PipSearchIndex"): indexUrl = Preferences.getPip("PipSearchIndex") + "/simple" args += ["--index-url", indexUrl] - ok, output = self.runPipxProcess(args) + ok, output = self.__runPipxProcess(args) if not ok: EricMessageBox.information( None,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PipxInterface/PipxProcess.py Sun Sep 15 11:57:39 2024 +0200 @@ -0,0 +1,100 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2024 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a QProcess derive class with a timeout and convenience signals. +""" + +from PyQt6.QtCore import QProcess, QTimer, pyqtSignal, pyqtSlot + + +class PipxProcess(QProcess): + """ + Class implementing a QProcess derive class with a timeout and convenience signals + succeeded and failed. + + @signal failed() emitted to indicate a process failure + @signal succeeded() emitted to indicate that the process finished successfully + @signal timeout() emitted to indicate the expiry of the configured timeout value + """ + + failed = pyqtSignal() + succeeded = pyqtSignal() + timeout = pyqtSignal() + + def __init__(self, timeout=30000, parent=None): + """ + Constructor + + @param timeout timeout value in milliseconds. If the process does not finish + within this interval, it is killed (defaults to 30000) + @type int (optional) + @param parent reference to the parent object (defaults to None) + @type QObject (optional) + """ + super().__init__(parent=parent) + + self.started.connect(self.__started) + self.finished.connect(self.__finished) + + self.__timeoutTimer = QTimer(self) + self.__timeoutTimer.setInterval(timeout) + self.__timeoutTimer.timeout.connect(self.__timeout) + + self.__timedOut = False + + def timedOut(self): + """ + Public method to test, if the process timed out. + + @return flag indicating a timeout + @rtype bool + """ + return self.__timedOut + + def timeoutInterval(self): + """ + Public method to get the process timeout interval. + + @return process timeout interval in milliseconds + @rtype int + """ + return self.__timeoutTimer.interval() + + @pyqtSlot() + def __timeout(self): + """ + Private slot to handle the timer interval exoiration. + """ + self.__timeoutTimer.stop() + self.__timedOut = True + self.kill() + + self.timeout.emit() + + @pyqtSlot() + def __started(self): + """ + Private slot handling the process start. + """ + self.__timedOut = False + self.__timeoutTimer.start() + + @pyqtSlot(int, QProcess.ExitStatus) + def __finished(self, exitCode, exitStatus): + """ + Private slot handling the end of the process. + + @param exitCode exit code of the process (0 = success) + @type int + @param exitStatus exit status of the process + @type QProcess.ExitStatus + """ + self.__timeoutTimer.stop() + + if exitStatus == QProcess.ExitStatus.CrashExit or exitCode != 0: + self.failed.emit() + else: + self.succeeded.emit()
--- a/PipxInterface/PipxWidget.py Sat Sep 07 19:29:57 2024 +0200 +++ b/PipxInterface/PipxWidget.py Sun Sep 15 11:57:39 2024 +0200 @@ -29,7 +29,7 @@ class PipxWidget(QWidget, Ui_PipxWidget): """ - Class documentation goes here. + Class implementing the pipx management widget. """ PackageColumn = 0 @@ -58,6 +58,7 @@ self.__plugin = plugin self.__pipx = Pipx(self) + self.__pipx.outdatedPackage.connect(self.__handleOutdatedPackage) if fromEric: self.layout().setContentsMargins(0, 3, 0, 0) @@ -380,40 +381,45 @@ @param itm reference to the package item @type QTreeWidgetItem - @return flag indicating the outdated status - @rtype bool """ package = itm.text(PipxWidget.PackageColumn) - latestVersion, outdatedDependencies = self.__pipx.checkPackageOutdated(package) - if latestVersion is not None: + self.__pipx.checkPackageOutdated(package) + + @pyqtSlot(str, str, bool) + def __handleOutdatedPackage(self, package, latestVersion, outdatedDependencies): + """ + Private slot to handle the pipx client reporting an outdated package or a + package with outdated dependencies. + + @param package name of the package + @type str + @param latestVersion latest available version in case outdated + @type str + @param outdatedDependencies flag indicating outdated dependencies + @type bool + """ + itm = self.__getItemForPackage(package=package) + if latestVersion: self.__markPackageOutdated(itm, latestVersion, outdatedDependencies) - isOutdated = True elif ( self.__plugin.getPreferences("IncludeOutdatedDependencies") and outdatedDependencies ): self.__markPackageDependenciesOutdated(itm) - isOutdated = True else: self.__markPackageClean(itm) - isOutdated = False - return isOutdated + + self.__resizePackagesColumns() + self.__plugin.setOutdatedIndicator(self.__hasOutdatedItems()) @pyqtSlot() def __checkOutdatedPackages(self): """ Private slot to check, if there are any outdated packages. """ - outdatedItems = [] - - with EricOverrideCursor(): - for row in range(self.packagesList.topLevelItemCount()): - itm = self.packagesList.topLevelItem(row) - if self.__checkPackageOutdated(itm): - outdatedItems.append(itm) - - self.__resizePackagesColumns() - self.__plugin.setOutdatedIndicator(bool(outdatedItems)) + for row in range(self.packagesList.topLevelItemCount()): + itm = self.packagesList.topLevelItem(row) + self.__checkPackageOutdated(itm) @pyqtSlot() def __upgradePackage(self): @@ -435,6 +441,7 @@ else: package = packageItem.text(PipxWidget.PackageColumn) self.__pipx.upgradePackage(package) + self.__checkPackageVersion(packageItem) self.__checkPackageOutdated(packageItem) self.__resizePackagesColumns() @@ -528,8 +535,9 @@ """ Private slot to show a dialog with the dependencies of the selected package. """ - package = self.__selectedPackages()[0] - dependencies = self.__pipx.getAllPackageDependencies(package=package) + with EricOverrideCursor(): + package = self.__selectedPackages()[0] + dependencies = self.__pipx.getAllPackageDependencies(package=package) dlg = PipxDependenciesDialog( package=package, @@ -544,8 +552,9 @@ Private slot to show a dialog with the outdated dependencies of the selected package. """ - package = self.__selectedPackages()[0] - dependencies = self.__pipx.getOutdatedPackageDependencies(package=package) + with EricOverrideCursor(): + package = self.__selectedPackages()[0] + dependencies = self.__pipx.getOutdatedPackageDependencies(package=package) dlg = PipxDependenciesDialog( package=package, @@ -560,8 +569,9 @@ Private slot to show a dialog with the up-to-date dependencies of the selected package. """ - package = self.__selectedPackages()[0] - dependencies = self.__pipx.getUptodatePackageDependencies(package=package) + with EricOverrideCursor(): + package = self.__selectedPackages()[0] + dependencies = self.__pipx.getUptodatePackageDependencies(package=package) dlg = PipxDependenciesDialog( package=package, @@ -665,6 +675,18 @@ item.setIcon(PipxWidget.VersionColumn, QIcon()) item.setToolTip(PipxWidget.VersionColumn, self.tr("everything up-to-date")) + def __checkPackageVersion(self, itm): + """ + Private method to check the version of a package. + + @param itm reference to the package item + @type QTreeWidgetItem + """ + package = itm.text(PipxWidget.PackageColumn) + version = self.__pipx.getPackageVersion(package) + itm.setText(PipxWidget.VersionColumn, version) + itm.setData(0, PipxWidget.VersionRole, version) + def __populatePackages(self): """ Private method to populate the packages list. @@ -709,12 +731,13 @@ if itm.isExpanded(): expandedPackages.append(itm.text(PipxWidget.PackageColumn)) latestVersion = itm.data(0, PipxWidget.LatestVersionRole) - outdatedDependencies = itm.data(0, PipxWidget.OutdatedDependenciesRole) - if latestVersion or outdatedDependencies: - outdatedPackages[itm.text(PipxWidget.PackageColumn)] = ( - latestVersion, - outdatedDependencies, - ) + if not self.__plugin.getPreferences("AutoCheckOutdated"): + outdatedDependencies = itm.data(0, PipxWidget.OutdatedDependenciesRole) + if latestVersion or outdatedDependencies: + outdatedPackages[itm.text(PipxWidget.PackageColumn)] = ( + latestVersion, + outdatedDependencies, + ) self.__populatePackages()
--- a/PipxInterface/i18n/pipx_de.ts Sat Sep 07 19:29:57 2024 +0200 +++ b/PipxInterface/i18n/pipx_de.ts Sun Sep 15 11:57:39 2024 +0200 @@ -4,107 +4,141 @@ <context> <name>Pipx</name> <message> - <location filename="../Pipx.py" line="140" /> + <location filename="../Pipx.py" line="263" /> + <location filename="../Pipx.py" line="153" /> <source><p>Message: {0}</p></source> <translation><p>Meldung: {0}</p></translation> </message> <message> - <location filename="../Pipx.py" line="143" /> + <location filename="../Pipx.py" line="275" /> + <location filename="../Pipx.py" line="267" /> + <location filename="../Pipx.py" line="156" /> <source><p>pipx exited with an error ({0}).</p>{1}</source> <translation><p>pipx wurde mit einem Fehler beendet ({0}).</p>{1}</translation> </message> <message> - <location filename="../Pipx.py" line="152" /> + <location filename="../Pipx.py" line="165" /> <source>pipx did not finish within 30 seconds.</source> <translation>pipx endete nicht innerhalb 30 Sekunden.</translation> </message> <message> - <location filename="../Pipx.py" line="154" /> + <location filename="../Pipx.py" line="221" /> + <location filename="../Pipx.py" line="167" /> <source>pipx could not be started.</source> <translation>pipx konnte nicht gestarted werden.</translation> </message> <message> - <location filename="../Pipx.py" line="286" /> + <location filename="../Pipx.py" line="221" /> + <source>pipx Start Error</source> + <translation>pipx Startfehler</translation> + </message> + <message> + <location filename="../Pipx.py" line="226" /> + <source>pipx Runtime Error</source> + <translation>pipx Laufzeitfehler</translation> + </message> + <message> + <location filename="../Pipx.py" line="227" /> + <source><p>The pipx process reported an error.</p><p>Error: {0}</p></source> + <translation><p>Der pipx Prozess meldete einen Fehler.</p><p>Fehler: {0}</p></translation> + </message> + <message> + <location filename="../Pipx.py" line="247" /> + <source>pipx did not finish within {0} seconds.</source> + <translation>pipx endete nicht innerhalb {0} Sekunden.</translation> + </message> + <message> + <location filename="../Pipx.py" line="253" /> + <source>pipx Timeout Error</source> + <translation>pipx Zeitüberschreitungsfehler</translation> + </message> + <message> + <location filename="../Pipx.py" line="274" /> + <source>pipx Execution Error</source> + <translation>pipx Ausführungsfehler</translation> + </message> + <message> + <location filename="../Pipx.py" line="399" /> <source>Install Packages</source> <translation>Pakete installieren</translation> </message> <message> - <location filename="../Pipx.py" line="331" /> + <location filename="../Pipx.py" line="444" /> <source>Install All Packages</source> <translation>Alle Pakete installieren</translation> </message> <message> - <location filename="../Pipx.py" line="381" /> + <location filename="../Pipx.py" line="494" /> <source>Re-Install Package</source> <translation>Paket neu installieren</translation> </message> <message> - <location filename="../Pipx.py" line="412" /> + <location filename="../Pipx.py" line="525" /> <source>Re-Install All Packages</source> <translation>Alle Pakete neu installieren</translation> </message> <message> - <location filename="../Pipx.py" line="425" /> + <location filename="../Pipx.py" line="538" /> <source>Uninstall Package</source> <translation>Paket deinstallieren</translation> </message> <message> - <location filename="../Pipx.py" line="435" /> + <location filename="../Pipx.py" line="548" /> <source>Uninstall All Packages</source> <translation>Alle Pakete deinstallieren</translation> </message> <message> - <location filename="../Pipx.py" line="452" /> + <location filename="../Pipx.py" line="565" /> <source>Upgrade Package</source> <translation>Paket aktualisieren</translation> </message> <message> - <location filename="../Pipx.py" line="462" /> + <location filename="../Pipx.py" line="575" /> <source>Upgrade All Packages</source> <translation>Alle Pakete aktualisieren</translation> </message> <message> - <location filename="../Pipx.py" line="472" /> + <location filename="../Pipx.py" line="585" /> <source>Upgrade Shared Libraries</source> <translation>Gemeinsame Bibliotheken aktualisieren</translation> </message> <message> - <location filename="../Pipx.py" line="486" /> + <location filename="../Pipx.py" line="599" /> <source>Upgrade Interpreters</source> <translation>Interpreter aktualisieren</translation> </message> <message> - <location filename="../Pipx.py" line="499" /> + <location filename="../Pipx.py" line="612" /> <source>Prune Unused Interpreters</source> <translation>Ungenutzte Interpreter entfernen</translation> </message> <message> - <location filename="../Pipx.py" line="510" /> + <location filename="../Pipx.py" line="623" /> <source>Ensure PATH Modifications</source> <translation>PATH-Änderungen sicherstellen</translation> </message> <message> - <location filename="../Pipx.py" line="537" /> + <location filename="../Pipx.py" line="662" /> <source>Check Outdated Package</source> <translation>Prüfe veraltete Pakete</translation> </message> <message> - <location filename="../Pipx.py" line="538" /> + <location filename="../Pipx.py" line="663" /> <source><p>The status of package <b>{0}</b> could not be determined.</p><p>Reason: {1}</p></source> <translation><p>Der Status des Paketes <b>{0}</b> konnte nicht bestimmt werden.</p><p>Ursache: {1}</p></translation> </message> <message> - <location filename="../Pipx.py" line="579" /> + <location filename="../Pipx.py" line="724" /> <source>Get Package Dependencies</source> <translation>Paketabhängigkeiten abrufen</translation> </message> <message> - <location filename="../Pipx.py" line="580" /> + <location filename="../Pipx.py" line="725" /> <source><p>The status of dependencies of package <b>{0}</b> could not be determined.</p><p>Reason: {1}</p></source> <translation><p>Der Status der Abhängigkeiten des Pakets <b>{0}</b> konnte nicht ermittelt werden.</p><p>Ursache: {1}</p></translation> </message> <message> - <location filename="../Pipx.py" line="650" /> + <location filename="../Pipx.py" line="795" /> <source>Upgrade Dependencies</source> <translation>Abhängigkeiten aktualisieren</translation> </message> @@ -512,229 +546,229 @@ <context> <name>PipxWidget</name> <message> - <location filename="../PipxWidget.py" line="112" /> + <location filename="../PipxWidget.py" line="113" /> <source>Install</source> <translation>Installieren</translation> </message> <message> - <location filename="../PipxWidget.py" line="245" /> - <location filename="../PipxWidget.py" line="114" /> + <location filename="../PipxWidget.py" line="246" /> + <location filename="../PipxWidget.py" line="115" /> <source>Install Packages</source> <translation>Pakete installieren</translation> </message> <message> - <location filename="../PipxWidget.py" line="264" /> - <location filename="../PipxWidget.py" line="117" /> + <location filename="../PipxWidget.py" line="265" /> + <location filename="../PipxWidget.py" line="118" /> <source>Install All Packages</source> <translation>Alle Pakete installieren</translation> </message> <message> - <location filename="../PipxWidget.py" line="121" /> + <location filename="../PipxWidget.py" line="122" /> <source>Re-Install Selected Package</source> <translation>Ausgewähltes Paket neu installieren</translation> </message> <message> - <location filename="../PipxWidget.py" line="362" /> - <location filename="../PipxWidget.py" line="124" /> + <location filename="../PipxWidget.py" line="363" /> + <location filename="../PipxWidget.py" line="125" /> <source>Re-Install All Packages</source> <translation>Alle Pakete neu installieren</translation> </message> <message> - <location filename="../PipxWidget.py" line="320" /> - <location filename="../PipxWidget.py" line="311" /> - <location filename="../PipxWidget.py" line="299" /> - <location filename="../PipxWidget.py" line="283" /> - <location filename="../PipxWidget.py" line="128" /> + <location filename="../PipxWidget.py" line="321" /> + <location filename="../PipxWidget.py" line="312" /> + <location filename="../PipxWidget.py" line="300" /> + <location filename="../PipxWidget.py" line="284" /> + <location filename="../PipxWidget.py" line="129" /> <source>Create Spec Metadata File</source> <translation>Erzeuge Spec-Metadaten-Datei</translation> </message> <message> - <location filename="../PipxWidget.py" line="135" /> + <location filename="../PipxWidget.py" line="136" /> <source>Upgrade</source> <translation>Aktualisieren</translation> </message> <message> - <location filename="../PipxWidget.py" line="137" /> + <location filename="../PipxWidget.py" line="138" /> <source>Check Outdated Packages</source> <translation>Prüfe veraltete Pakete</translation> </message> <message> - <location filename="../PipxWidget.py" line="428" /> - <location filename="../PipxWidget.py" line="141" /> + <location filename="../PipxWidget.py" line="434" /> + <location filename="../PipxWidget.py" line="142" /> <source>Upgrade Selected Package</source> <translation>Ausgewähltes Paket aktualisieren</translation> </message> <message> - <location filename="../PipxWidget.py" line="452" /> - <location filename="../PipxWidget.py" line="144" /> + <location filename="../PipxWidget.py" line="459" /> + <location filename="../PipxWidget.py" line="145" /> <source>Upgrade All Packages</source> <translation>Alle Pakete aktualisieren</translation> </message> <message> - <location filename="../PipxWidget.py" line="148" /> + <location filename="../PipxWidget.py" line="149" /> <source>Upgrade Shared Libraries</source> <translation>Gemeinsame Bibliotheken aktualisieren</translation> </message> <message> - <location filename="../PipxWidget.py" line="155" /> + <location filename="../PipxWidget.py" line="156" /> <source>Uninstall</source> <translation>Deinstallieren</translation> </message> <message> - <location filename="../PipxWidget.py" line="157" /> + <location filename="../PipxWidget.py" line="158" /> <source>Uninstall Selected Package</source> <translation>Ausgewähltes Paket deinstallieren</translation> </message> <message> - <location filename="../PipxWidget.py" line="494" /> - <location filename="../PipxWidget.py" line="160" /> + <location filename="../PipxWidget.py" line="501" /> + <location filename="../PipxWidget.py" line="161" /> <source>Uninstall All Packages</source> <translation>Alle Pakete deinstallieren</translation> </message> <message> - <location filename="../PipxWidget.py" line="167" /> + <location filename="../PipxWidget.py" line="168" /> <source>Dependencies</source> <translation>Abhängigkeiten</translation> </message> <message> - <location filename="../PipxWidget.py" line="169" /> + <location filename="../PipxWidget.py" line="170" /> <source>Show All Dependencies</source> <translation>Zeige Alle Abhängigkeiten</translation> </message> <message> - <location filename="../PipxWidget.py" line="172" /> + <location filename="../PipxWidget.py" line="173" /> <source>Show Outdated Dependencies</source> <translation>Zeige Veraltete Abhängigkeiten</translation> </message> <message> - <location filename="../PipxWidget.py" line="175" /> + <location filename="../PipxWidget.py" line="176" /> <source>Show Up-to-date Dependencies</source> <translation>Zeige Aktuelle Abhängigkeiten</translation> </message> <message> - <location filename="../PipxWidget.py" line="179" /> + <location filename="../PipxWidget.py" line="180" /> <source>Upgrade Dependencies</source> <translation>Abhängigkeiten aktualisieren</translation> </message> <message> - <location filename="../PipxWidget.py" line="198" /> + <location filename="../PipxWidget.py" line="199" /> <source>Standalone Interpreters</source> <translation>Eigenständige Interpreter</translation> </message> <message> - <location filename="../PipxWidget.py" line="202" /> + <location filename="../PipxWidget.py" line="203" /> <source>Ensure PATH Modifications</source> <translation>PATH-Änderungen sicherstellen</translation> </message> <message> - <location filename="../PipxWidget.py" line="205" /> + <location filename="../PipxWidget.py" line="206" /> <source>Configure...</source> <translation>Einstellungen...</translation> </message> <message> - <location filename="../PipxWidget.py" line="285" /> + <location filename="../PipxWidget.py" line="286" /> <source>JSON Files (*.json);;All Files (*)</source> <translation>JSON Dateien (*.json);;Alle Dateien (*)</translation> </message> <message> - <location filename="../PipxWidget.py" line="286" /> + <location filename="../PipxWidget.py" line="287" /> <source>JSON Files (*.json)</source> <translation>JSON-Dateien (*.json)</translation> </message> <message> - <location filename="../PipxWidget.py" line="300" /> + <location filename="../PipxWidget.py" line="301" /> <source><p>The file <b>{0}</b> exists already. Overwrite it?</p></source> <translation><p>Die Datei <b>{0}</b> existiert bereits. Überschreiben?</p></translation> </message> <message> - <location filename="../PipxWidget.py" line="312" /> + <location filename="../PipxWidget.py" line="313" /> <source><p>The spec metadata file <b>{0}</b> was created successfully.</p></source> <translation><p>Die Spec-Metadaten-Datei <b>{0}</b> wurde erfolgreich erzeugt.</p></translation> </message> <message> - <location filename="../PipxWidget.py" line="321" /> + <location filename="../PipxWidget.py" line="322" /> <source><p>The spec metadata file <b>{0}</b> could not be created.</p><p>Reason: {1}</p></source> <translation><p>Die Spec-Metadaten-Datei <b>{0}</b> konnte nicht erzeugt werden.</p><p>Ursache: {1}</p></translation> </message> <message> - <location filename="../PipxWidget.py" line="337" /> + <location filename="../PipxWidget.py" line="338" /> <source>Re-Install Package</source> <translation>Paket neu installieren</translation> </message> <message> - <location filename="../PipxWidget.py" line="338" /> + <location filename="../PipxWidget.py" line="339" /> <source><p>Shall the package <b>{0}</b> really be reinstalled?</p></source> <translation><p>Soll das Paket <b>{0}</b> wirklich neu installiert werden?</p></translation> </message> <message> - <location filename="../PipxWidget.py" line="363" /> + <location filename="../PipxWidget.py" line="364" /> <source>Do you really want to reinstall all packages?</source> <translation>Sollen wirklich alle Pakete neu installiert werden?</translation> </message> <message> - <location filename="../PipxWidget.py" line="429" /> + <location filename="../PipxWidget.py" line="435" /> <source><p>The selected package cannot be upgraded because some of its apps are running.</p><ul><li>{0}</li></ul><p>Stop these apps and try again.</p></source> <translation><p>Das ausgewählte Paket kann nicht aktualisiert werden, da einige seiner Anwendungen ausgeführt werden.</p><ul><li>{0}</li></ul><p>Beende diese Anwendungen und versuche es erneut.</p></translation> </message> <message> - <location filename="../PipxWidget.py" line="453" /> + <location filename="../PipxWidget.py" line="460" /> <source><p>The packages cannot be upgraded because some of their apps are running.</p><ul><li>{0}</li></ul><p>Stop these apps and try again.</p></source> <translation><p>Die Pakete können nicht aktualisiert werden, da einige ihrer Anwendungen ausgeführt werden.</p><ul><li>{0}</li></ul><p>Beende diese Anwendungen und versuche es erneut.</p></translation> </message> <message> - <location filename="../PipxWidget.py" line="478" /> + <location filename="../PipxWidget.py" line="485" /> <source>Uninstall Package</source> <translation>Paket deinstallieren</translation> </message> <message> - <location filename="../PipxWidget.py" line="479" /> + <location filename="../PipxWidget.py" line="486" /> <source><p>Shall the package <b>{0}</b> really be uninstalled?</p></source> <translation><p>Soll das Paket <b>{0}</b> wirklich deinstalliert werden?</p></translation> </message> <message> - <location filename="../PipxWidget.py" line="495" /> + <location filename="../PipxWidget.py" line="502" /> <source><p>Do you really want to uninstall <b>ALL</b> packages?</p></source> <translation><p>Sollen wirklich <b>ALLE</b> Pakete deinstalliert werden?</p></translation> </message> <message> - <location filename="../PipxWidget.py" line="596" /> + <location filename="../PipxWidget.py" line="606" /> <source><b>pipx Version {0}</b></source> <translation><b>pipx Version {0}</b></translation> </message> <message> - <location filename="../PipxWidget.py" line="626" /> + <location filename="../PipxWidget.py" line="636" /> <source>{0} ({1})</source> <comment>current version, latest version</comment> <translation>{0} ({1})</translation> </message> <message> - <location filename="../PipxWidget.py" line="634" /> + <location filename="../PipxWidget.py" line="644" /> <source>package and some dependencies outdated</source> <translation>Paket und einige Abhängigkeiten veraltet</translation> </message> <message> - <location filename="../PipxWidget.py" line="637" /> + <location filename="../PipxWidget.py" line="647" /> <source>package outdated</source> <translation>Paket veraltet</translation> </message> <message> - <location filename="../PipxWidget.py" line="652" /> + <location filename="../PipxWidget.py" line="661" /> <source>some dependencies outdated</source> <translation>einige Abhängigkeiten veraltet</translation> </message> <message> - <location filename="../PipxWidget.py" line="667" /> + <location filename="../PipxWidget.py" line="676" /> <source>everything up-to-date</source> <translation>alles aktuell</translation> </message> <message> - <location filename="../PipxWidget.py" line="682" /> + <location filename="../PipxWidget.py" line="703" /> <source>{0}{1}</source> <comment>Python version, standalone indicator</comment> <translation>{0}{1}</translation> </message> <message> - <location filename="../PipxWidget.py" line="684" /> + <location filename="../PipxWidget.py" line="705" /> <source> (standalone)</source> <translation> (eigenständig)</translation> </message>
--- a/PipxInterface/i18n/pipx_empty.ts Sat Sep 07 19:29:57 2024 +0200 +++ b/PipxInterface/i18n/pipx_empty.ts Sun Sep 15 11:57:39 2024 +0200 @@ -4,107 +4,141 @@ <context> <name>Pipx</name> <message> - <location filename="../Pipx.py" line="140" /> + <location filename="../Pipx.py" line="263" /> + <location filename="../Pipx.py" line="153" /> <source><p>Message: {0}</p></source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="143" /> + <location filename="../Pipx.py" line="275" /> + <location filename="../Pipx.py" line="267" /> + <location filename="../Pipx.py" line="156" /> <source><p>pipx exited with an error ({0}).</p>{1}</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="152" /> + <location filename="../Pipx.py" line="165" /> <source>pipx did not finish within 30 seconds.</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="154" /> + <location filename="../Pipx.py" line="221" /> + <location filename="../Pipx.py" line="167" /> <source>pipx could not be started.</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="286" /> + <location filename="../Pipx.py" line="221" /> + <source>pipx Start Error</source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../Pipx.py" line="226" /> + <source>pipx Runtime Error</source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../Pipx.py" line="227" /> + <source><p>The pipx process reported an error.</p><p>Error: {0}</p></source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../Pipx.py" line="247" /> + <source>pipx did not finish within {0} seconds.</source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../Pipx.py" line="253" /> + <source>pipx Timeout Error</source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../Pipx.py" line="274" /> + <source>pipx Execution Error</source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../Pipx.py" line="399" /> <source>Install Packages</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="331" /> + <location filename="../Pipx.py" line="444" /> <source>Install All Packages</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="381" /> + <location filename="../Pipx.py" line="494" /> <source>Re-Install Package</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="412" /> + <location filename="../Pipx.py" line="525" /> <source>Re-Install All Packages</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="425" /> + <location filename="../Pipx.py" line="538" /> <source>Uninstall Package</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="435" /> + <location filename="../Pipx.py" line="548" /> <source>Uninstall All Packages</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="452" /> + <location filename="../Pipx.py" line="565" /> <source>Upgrade Package</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="462" /> + <location filename="../Pipx.py" line="575" /> <source>Upgrade All Packages</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="472" /> + <location filename="../Pipx.py" line="585" /> <source>Upgrade Shared Libraries</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="486" /> + <location filename="../Pipx.py" line="599" /> <source>Upgrade Interpreters</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="499" /> + <location filename="../Pipx.py" line="612" /> <source>Prune Unused Interpreters</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="510" /> + <location filename="../Pipx.py" line="623" /> <source>Ensure PATH Modifications</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="537" /> + <location filename="../Pipx.py" line="662" /> <source>Check Outdated Package</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="538" /> + <location filename="../Pipx.py" line="663" /> <source><p>The status of package <b>{0}</b> could not be determined.</p><p>Reason: {1}</p></source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="579" /> + <location filename="../Pipx.py" line="724" /> <source>Get Package Dependencies</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="580" /> + <location filename="../Pipx.py" line="725" /> <source><p>The status of dependencies of package <b>{0}</b> could not be determined.</p><p>Reason: {1}</p></source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="650" /> + <location filename="../Pipx.py" line="795" /> <source>Upgrade Dependencies</source> <translation type="unfinished" /> </message> @@ -512,229 +546,229 @@ <context> <name>PipxWidget</name> <message> - <location filename="../PipxWidget.py" line="112" /> + <location filename="../PipxWidget.py" line="113" /> <source>Install</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="245" /> - <location filename="../PipxWidget.py" line="114" /> + <location filename="../PipxWidget.py" line="246" /> + <location filename="../PipxWidget.py" line="115" /> <source>Install Packages</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="264" /> - <location filename="../PipxWidget.py" line="117" /> + <location filename="../PipxWidget.py" line="265" /> + <location filename="../PipxWidget.py" line="118" /> <source>Install All Packages</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="121" /> + <location filename="../PipxWidget.py" line="122" /> <source>Re-Install Selected Package</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="362" /> - <location filename="../PipxWidget.py" line="124" /> + <location filename="../PipxWidget.py" line="363" /> + <location filename="../PipxWidget.py" line="125" /> <source>Re-Install All Packages</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="320" /> - <location filename="../PipxWidget.py" line="311" /> - <location filename="../PipxWidget.py" line="299" /> - <location filename="../PipxWidget.py" line="283" /> - <location filename="../PipxWidget.py" line="128" /> + <location filename="../PipxWidget.py" line="321" /> + <location filename="../PipxWidget.py" line="312" /> + <location filename="../PipxWidget.py" line="300" /> + <location filename="../PipxWidget.py" line="284" /> + <location filename="../PipxWidget.py" line="129" /> <source>Create Spec Metadata File</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="135" /> + <location filename="../PipxWidget.py" line="136" /> <source>Upgrade</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="137" /> + <location filename="../PipxWidget.py" line="138" /> <source>Check Outdated Packages</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="428" /> - <location filename="../PipxWidget.py" line="141" /> + <location filename="../PipxWidget.py" line="434" /> + <location filename="../PipxWidget.py" line="142" /> <source>Upgrade Selected Package</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="452" /> - <location filename="../PipxWidget.py" line="144" /> + <location filename="../PipxWidget.py" line="459" /> + <location filename="../PipxWidget.py" line="145" /> <source>Upgrade All Packages</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="148" /> + <location filename="../PipxWidget.py" line="149" /> <source>Upgrade Shared Libraries</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="155" /> + <location filename="../PipxWidget.py" line="156" /> <source>Uninstall</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="157" /> + <location filename="../PipxWidget.py" line="158" /> <source>Uninstall Selected Package</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="494" /> - <location filename="../PipxWidget.py" line="160" /> + <location filename="../PipxWidget.py" line="501" /> + <location filename="../PipxWidget.py" line="161" /> <source>Uninstall All Packages</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="167" /> + <location filename="../PipxWidget.py" line="168" /> <source>Dependencies</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="169" /> + <location filename="../PipxWidget.py" line="170" /> <source>Show All Dependencies</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="172" /> + <location filename="../PipxWidget.py" line="173" /> <source>Show Outdated Dependencies</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="175" /> + <location filename="../PipxWidget.py" line="176" /> <source>Show Up-to-date Dependencies</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="179" /> + <location filename="../PipxWidget.py" line="180" /> <source>Upgrade Dependencies</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="198" /> + <location filename="../PipxWidget.py" line="199" /> <source>Standalone Interpreters</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="202" /> + <location filename="../PipxWidget.py" line="203" /> <source>Ensure PATH Modifications</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="205" /> + <location filename="../PipxWidget.py" line="206" /> <source>Configure...</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="285" /> - <source>JSON Files (*.json);;All Files (*)</source> - <translation type="unfinished" /> - </message> - <message> <location filename="../PipxWidget.py" line="286" /> + <source>JSON Files (*.json);;All Files (*)</source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../PipxWidget.py" line="287" /> <source>JSON Files (*.json)</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="300" /> + <location filename="../PipxWidget.py" line="301" /> <source><p>The file <b>{0}</b> exists already. Overwrite it?</p></source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="312" /> + <location filename="../PipxWidget.py" line="313" /> <source><p>The spec metadata file <b>{0}</b> was created successfully.</p></source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="321" /> + <location filename="../PipxWidget.py" line="322" /> <source><p>The spec metadata file <b>{0}</b> could not be created.</p><p>Reason: {1}</p></source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="337" /> - <source>Re-Install Package</source> - <translation type="unfinished" /> - </message> - <message> <location filename="../PipxWidget.py" line="338" /> + <source>Re-Install Package</source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../PipxWidget.py" line="339" /> <source><p>Shall the package <b>{0}</b> really be reinstalled?</p></source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="363" /> + <location filename="../PipxWidget.py" line="364" /> <source>Do you really want to reinstall all packages?</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="429" /> + <location filename="../PipxWidget.py" line="435" /> <source><p>The selected package cannot be upgraded because some of its apps are running.</p><ul><li>{0}</li></ul><p>Stop these apps and try again.</p></source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="453" /> + <location filename="../PipxWidget.py" line="460" /> <source><p>The packages cannot be upgraded because some of their apps are running.</p><ul><li>{0}</li></ul><p>Stop these apps and try again.</p></source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="478" /> + <location filename="../PipxWidget.py" line="485" /> <source>Uninstall Package</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="479" /> + <location filename="../PipxWidget.py" line="486" /> <source><p>Shall the package <b>{0}</b> really be uninstalled?</p></source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="495" /> + <location filename="../PipxWidget.py" line="502" /> <source><p>Do you really want to uninstall <b>ALL</b> packages?</p></source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="596" /> + <location filename="../PipxWidget.py" line="606" /> <source><b>pipx Version {0}</b></source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="626" /> + <location filename="../PipxWidget.py" line="636" /> <source>{0} ({1})</source> <comment>current version, latest version</comment> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="634" /> + <location filename="../PipxWidget.py" line="644" /> <source>package and some dependencies outdated</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="637" /> + <location filename="../PipxWidget.py" line="647" /> <source>package outdated</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="652" /> + <location filename="../PipxWidget.py" line="661" /> <source>some dependencies outdated</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="667" /> + <location filename="../PipxWidget.py" line="676" /> <source>everything up-to-date</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="682" /> + <location filename="../PipxWidget.py" line="703" /> <source>{0}{1}</source> <comment>Python version, standalone indicator</comment> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="684" /> + <location filename="../PipxWidget.py" line="705" /> <source> (standalone)</source> <translation type="unfinished" /> </message>
--- a/PipxInterface/i18n/pipx_en.ts Sat Sep 07 19:29:57 2024 +0200 +++ b/PipxInterface/i18n/pipx_en.ts Sun Sep 15 11:57:39 2024 +0200 @@ -4,107 +4,141 @@ <context> <name>Pipx</name> <message> - <location filename="../Pipx.py" line="140" /> + <location filename="../Pipx.py" line="263" /> + <location filename="../Pipx.py" line="153" /> <source><p>Message: {0}</p></source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="143" /> + <location filename="../Pipx.py" line="275" /> + <location filename="../Pipx.py" line="267" /> + <location filename="../Pipx.py" line="156" /> <source><p>pipx exited with an error ({0}).</p>{1}</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="152" /> + <location filename="../Pipx.py" line="165" /> <source>pipx did not finish within 30 seconds.</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="154" /> + <location filename="../Pipx.py" line="221" /> + <location filename="../Pipx.py" line="167" /> <source>pipx could not be started.</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="286" /> + <location filename="../Pipx.py" line="221" /> + <source>pipx Start Error</source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../Pipx.py" line="226" /> + <source>pipx Runtime Error</source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../Pipx.py" line="227" /> + <source><p>The pipx process reported an error.</p><p>Error: {0}</p></source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../Pipx.py" line="247" /> + <source>pipx did not finish within {0} seconds.</source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../Pipx.py" line="253" /> + <source>pipx Timeout Error</source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../Pipx.py" line="274" /> + <source>pipx Execution Error</source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../Pipx.py" line="399" /> <source>Install Packages</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="331" /> + <location filename="../Pipx.py" line="444" /> <source>Install All Packages</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="381" /> + <location filename="../Pipx.py" line="494" /> <source>Re-Install Package</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="412" /> + <location filename="../Pipx.py" line="525" /> <source>Re-Install All Packages</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="425" /> + <location filename="../Pipx.py" line="538" /> <source>Uninstall Package</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="435" /> + <location filename="../Pipx.py" line="548" /> <source>Uninstall All Packages</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="452" /> + <location filename="../Pipx.py" line="565" /> <source>Upgrade Package</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="462" /> + <location filename="../Pipx.py" line="575" /> <source>Upgrade All Packages</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="472" /> + <location filename="../Pipx.py" line="585" /> <source>Upgrade Shared Libraries</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="486" /> + <location filename="../Pipx.py" line="599" /> <source>Upgrade Interpreters</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="499" /> + <location filename="../Pipx.py" line="612" /> <source>Prune Unused Interpreters</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="510" /> + <location filename="../Pipx.py" line="623" /> <source>Ensure PATH Modifications</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="537" /> + <location filename="../Pipx.py" line="662" /> <source>Check Outdated Package</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="538" /> + <location filename="../Pipx.py" line="663" /> <source><p>The status of package <b>{0}</b> could not be determined.</p><p>Reason: {1}</p></source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="579" /> + <location filename="../Pipx.py" line="724" /> <source>Get Package Dependencies</source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="580" /> + <location filename="../Pipx.py" line="725" /> <source><p>The status of dependencies of package <b>{0}</b> could not be determined.</p><p>Reason: {1}</p></source> <translation type="unfinished" /> </message> <message> - <location filename="../Pipx.py" line="650" /> + <location filename="../Pipx.py" line="795" /> <source>Upgrade Dependencies</source> <translation type="unfinished" /> </message> @@ -512,229 +546,229 @@ <context> <name>PipxWidget</name> <message> - <location filename="../PipxWidget.py" line="112" /> + <location filename="../PipxWidget.py" line="113" /> <source>Install</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="245" /> - <location filename="../PipxWidget.py" line="114" /> + <location filename="../PipxWidget.py" line="246" /> + <location filename="../PipxWidget.py" line="115" /> <source>Install Packages</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="264" /> - <location filename="../PipxWidget.py" line="117" /> + <location filename="../PipxWidget.py" line="265" /> + <location filename="../PipxWidget.py" line="118" /> <source>Install All Packages</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="121" /> + <location filename="../PipxWidget.py" line="122" /> <source>Re-Install Selected Package</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="362" /> - <location filename="../PipxWidget.py" line="124" /> + <location filename="../PipxWidget.py" line="363" /> + <location filename="../PipxWidget.py" line="125" /> <source>Re-Install All Packages</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="320" /> - <location filename="../PipxWidget.py" line="311" /> - <location filename="../PipxWidget.py" line="299" /> - <location filename="../PipxWidget.py" line="283" /> - <location filename="../PipxWidget.py" line="128" /> + <location filename="../PipxWidget.py" line="321" /> + <location filename="../PipxWidget.py" line="312" /> + <location filename="../PipxWidget.py" line="300" /> + <location filename="../PipxWidget.py" line="284" /> + <location filename="../PipxWidget.py" line="129" /> <source>Create Spec Metadata File</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="135" /> + <location filename="../PipxWidget.py" line="136" /> <source>Upgrade</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="137" /> + <location filename="../PipxWidget.py" line="138" /> <source>Check Outdated Packages</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="428" /> - <location filename="../PipxWidget.py" line="141" /> + <location filename="../PipxWidget.py" line="434" /> + <location filename="../PipxWidget.py" line="142" /> <source>Upgrade Selected Package</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="452" /> - <location filename="../PipxWidget.py" line="144" /> + <location filename="../PipxWidget.py" line="459" /> + <location filename="../PipxWidget.py" line="145" /> <source>Upgrade All Packages</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="148" /> + <location filename="../PipxWidget.py" line="149" /> <source>Upgrade Shared Libraries</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="155" /> + <location filename="../PipxWidget.py" line="156" /> <source>Uninstall</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="157" /> + <location filename="../PipxWidget.py" line="158" /> <source>Uninstall Selected Package</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="494" /> - <location filename="../PipxWidget.py" line="160" /> + <location filename="../PipxWidget.py" line="501" /> + <location filename="../PipxWidget.py" line="161" /> <source>Uninstall All Packages</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="167" /> + <location filename="../PipxWidget.py" line="168" /> <source>Dependencies</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="169" /> + <location filename="../PipxWidget.py" line="170" /> <source>Show All Dependencies</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="172" /> + <location filename="../PipxWidget.py" line="173" /> <source>Show Outdated Dependencies</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="175" /> + <location filename="../PipxWidget.py" line="176" /> <source>Show Up-to-date Dependencies</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="179" /> + <location filename="../PipxWidget.py" line="180" /> <source>Upgrade Dependencies</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="198" /> + <location filename="../PipxWidget.py" line="199" /> <source>Standalone Interpreters</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="202" /> + <location filename="../PipxWidget.py" line="203" /> <source>Ensure PATH Modifications</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="205" /> + <location filename="../PipxWidget.py" line="206" /> <source>Configure...</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="285" /> - <source>JSON Files (*.json);;All Files (*)</source> - <translation type="unfinished" /> - </message> - <message> <location filename="../PipxWidget.py" line="286" /> + <source>JSON Files (*.json);;All Files (*)</source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../PipxWidget.py" line="287" /> <source>JSON Files (*.json)</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="300" /> + <location filename="../PipxWidget.py" line="301" /> <source><p>The file <b>{0}</b> exists already. Overwrite it?</p></source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="312" /> + <location filename="../PipxWidget.py" line="313" /> <source><p>The spec metadata file <b>{0}</b> was created successfully.</p></source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="321" /> + <location filename="../PipxWidget.py" line="322" /> <source><p>The spec metadata file <b>{0}</b> could not be created.</p><p>Reason: {1}</p></source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="337" /> - <source>Re-Install Package</source> - <translation type="unfinished" /> - </message> - <message> <location filename="../PipxWidget.py" line="338" /> + <source>Re-Install Package</source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../PipxWidget.py" line="339" /> <source><p>Shall the package <b>{0}</b> really be reinstalled?</p></source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="363" /> + <location filename="../PipxWidget.py" line="364" /> <source>Do you really want to reinstall all packages?</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="429" /> + <location filename="../PipxWidget.py" line="435" /> <source><p>The selected package cannot be upgraded because some of its apps are running.</p><ul><li>{0}</li></ul><p>Stop these apps and try again.</p></source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="453" /> + <location filename="../PipxWidget.py" line="460" /> <source><p>The packages cannot be upgraded because some of their apps are running.</p><ul><li>{0}</li></ul><p>Stop these apps and try again.</p></source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="478" /> + <location filename="../PipxWidget.py" line="485" /> <source>Uninstall Package</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="479" /> + <location filename="../PipxWidget.py" line="486" /> <source><p>Shall the package <b>{0}</b> really be uninstalled?</p></source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="495" /> + <location filename="../PipxWidget.py" line="502" /> <source><p>Do you really want to uninstall <b>ALL</b> packages?</p></source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="596" /> + <location filename="../PipxWidget.py" line="606" /> <source><b>pipx Version {0}</b></source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="626" /> + <location filename="../PipxWidget.py" line="636" /> <source>{0} ({1})</source> <comment>current version, latest version</comment> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="634" /> + <location filename="../PipxWidget.py" line="644" /> <source>package and some dependencies outdated</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="637" /> + <location filename="../PipxWidget.py" line="647" /> <source>package outdated</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="652" /> + <location filename="../PipxWidget.py" line="661" /> <source>some dependencies outdated</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="667" /> + <location filename="../PipxWidget.py" line="676" /> <source>everything up-to-date</source> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="682" /> + <location filename="../PipxWidget.py" line="703" /> <source>{0}{1}</source> <comment>Python version, standalone indicator</comment> <translation type="unfinished" /> </message> <message> - <location filename="../PipxWidget.py" line="684" /> + <location filename="../PipxWidget.py" line="705" /> <source> (standalone)</source> <translation type="unfinished" /> </message>
--- a/PipxInterface/i18n/pipx_es.ts Sat Sep 07 19:29:57 2024 +0200 +++ b/PipxInterface/i18n/pipx_es.ts Sun Sep 15 11:57:39 2024 +0200 @@ -4,107 +4,141 @@ <context> <name>Pipx</name> <message> - <location filename="../Pipx.py" line="140" /> + <location filename="../Pipx.py" line="263" /> + <location filename="../Pipx.py" line="153" /> <source><p>Message: {0}</p></source> <translation><p>Mensaje: {0}</p></translation> </message> <message> - <location filename="../Pipx.py" line="143" /> + <location filename="../Pipx.py" line="275" /> + <location filename="../Pipx.py" line="267" /> + <location filename="../Pipx.py" line="156" /> <source><p>pipx exited with an error ({0}).</p>{1}</source> <translation><p>pipx ha terminado con un error ({0}).</p>{1}</translation> </message> <message> - <location filename="../Pipx.py" line="152" /> + <location filename="../Pipx.py" line="165" /> <source>pipx did not finish within 30 seconds.</source> <translation>pipx no ha terminado antes de 30 segundos.</translation> </message> <message> - <location filename="../Pipx.py" line="154" /> + <location filename="../Pipx.py" line="221" /> + <location filename="../Pipx.py" line="167" /> <source>pipx could not be started.</source> <translation>pipx no se ha podido iniciar.</translation> </message> <message> - <location filename="../Pipx.py" line="286" /> + <location filename="../Pipx.py" line="221" /> + <source>pipx Start Error</source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../Pipx.py" line="226" /> + <source>pipx Runtime Error</source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../Pipx.py" line="227" /> + <source><p>The pipx process reported an error.</p><p>Error: {0}</p></source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../Pipx.py" line="247" /> + <source>pipx did not finish within {0} seconds.</source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../Pipx.py" line="253" /> + <source>pipx Timeout Error</source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../Pipx.py" line="274" /> + <source>pipx Execution Error</source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../Pipx.py" line="399" /> <source>Install Packages</source> <translation>Instalar Packages</translation> </message> <message> - <location filename="../Pipx.py" line="331" /> + <location filename="../Pipx.py" line="444" /> <source>Install All Packages</source> <translation>Instalar Todos los Packages</translation> </message> <message> - <location filename="../Pipx.py" line="381" /> + <location filename="../Pipx.py" line="494" /> <source>Re-Install Package</source> <translation>Reinstalar Package</translation> </message> <message> - <location filename="../Pipx.py" line="412" /> + <location filename="../Pipx.py" line="525" /> <source>Re-Install All Packages</source> <translation>Reinstalar Todos los Packages</translation> </message> <message> - <location filename="../Pipx.py" line="425" /> + <location filename="../Pipx.py" line="538" /> <source>Uninstall Package</source> <translation>Desinstalar Package</translation> </message> <message> - <location filename="../Pipx.py" line="435" /> + <location filename="../Pipx.py" line="548" /> <source>Uninstall All Packages</source> <translation>Desinstalar Todos los Packages</translation> </message> <message> - <location filename="../Pipx.py" line="452" /> + <location filename="../Pipx.py" line="565" /> <source>Upgrade Package</source> <translation>Actualizar Package</translation> </message> <message> - <location filename="../Pipx.py" line="462" /> + <location filename="../Pipx.py" line="575" /> <source>Upgrade All Packages</source> <translation>Actualizar Todos los Packages</translation> </message> <message> - <location filename="../Pipx.py" line="472" /> + <location filename="../Pipx.py" line="585" /> <source>Upgrade Shared Libraries</source> <translation>Actualizar Bibliotecas Compartidas</translation> </message> <message> - <location filename="../Pipx.py" line="486" /> + <location filename="../Pipx.py" line="599" /> <source>Upgrade Interpreters</source> <translation>Actualizar Intérpretes</translation> </message> <message> - <location filename="../Pipx.py" line="499" /> + <location filename="../Pipx.py" line="612" /> <source>Prune Unused Interpreters</source> <translation>Limpiar Intérpretes no Utililizados</translation> </message> <message> - <location filename="../Pipx.py" line="510" /> + <location filename="../Pipx.py" line="623" /> <source>Ensure PATH Modifications</source> <translation>Asegurar modificaciones de PATH</translation> </message> <message> - <location filename="../Pipx.py" line="537" /> + <location filename="../Pipx.py" line="662" /> <source>Check Outdated Package</source> <translation>Comprobar Package Desactualizado</translation> </message> <message> - <location filename="../Pipx.py" line="538" /> + <location filename="../Pipx.py" line="663" /> <source><p>The status of package <b>{0}</b> could not be determined.</p><p>Reason: {1}</p></source> <translation><p>El status del package <b>{0}</b> no se ha podido determinar.</p><p>Razón: {1}</p></translation> </message> <message> - <location filename="../Pipx.py" line="579" /> + <location filename="../Pipx.py" line="724" /> <source>Get Package Dependencies</source> <translation>Obtener Dependencias del PAckage</translation> </message> <message> - <location filename="../Pipx.py" line="580" /> + <location filename="../Pipx.py" line="725" /> <source><p>The status of dependencies of package <b>{0}</b> could not be determined.</p><p>Reason: {1}</p></source> <translation><p>El estado de las dependencias del package <b>{0}</b> no se han podido determinar.</p><p>Razón: {1}</p></translation> </message> <message> - <location filename="../Pipx.py" line="650" /> + <location filename="../Pipx.py" line="795" /> <source>Upgrade Dependencies</source> <translation>Actualizar Dependencias</translation> </message> @@ -512,229 +546,229 @@ <context> <name>PipxWidget</name> <message> - <location filename="../PipxWidget.py" line="112" /> + <location filename="../PipxWidget.py" line="113" /> <source>Install</source> <translation>Instalar</translation> </message> <message> - <location filename="../PipxWidget.py" line="245" /> - <location filename="../PipxWidget.py" line="114" /> + <location filename="../PipxWidget.py" line="246" /> + <location filename="../PipxWidget.py" line="115" /> <source>Install Packages</source> <translation>Instalar Packages</translation> </message> <message> - <location filename="../PipxWidget.py" line="264" /> - <location filename="../PipxWidget.py" line="117" /> + <location filename="../PipxWidget.py" line="265" /> + <location filename="../PipxWidget.py" line="118" /> <source>Install All Packages</source> <translation>Instalar Todos los Packages</translation> </message> <message> - <location filename="../PipxWidget.py" line="121" /> + <location filename="../PipxWidget.py" line="122" /> <source>Re-Install Selected Package</source> <translation>Reinstalar Package Seleccionado</translation> </message> <message> - <location filename="../PipxWidget.py" line="362" /> - <location filename="../PipxWidget.py" line="124" /> + <location filename="../PipxWidget.py" line="363" /> + <location filename="../PipxWidget.py" line="125" /> <source>Re-Install All Packages</source> <translation>Reinstalar Todos los Packages</translation> </message> <message> - <location filename="../PipxWidget.py" line="320" /> - <location filename="../PipxWidget.py" line="311" /> - <location filename="../PipxWidget.py" line="299" /> - <location filename="../PipxWidget.py" line="283" /> - <location filename="../PipxWidget.py" line="128" /> + <location filename="../PipxWidget.py" line="321" /> + <location filename="../PipxWidget.py" line="312" /> + <location filename="../PipxWidget.py" line="300" /> + <location filename="../PipxWidget.py" line="284" /> + <location filename="../PipxWidget.py" line="129" /> <source>Create Spec Metadata File</source> <translation>Crear Archivo de Metadatos de Spec</translation> </message> <message> - <location filename="../PipxWidget.py" line="135" /> + <location filename="../PipxWidget.py" line="136" /> <source>Upgrade</source> <translation>Actualizar</translation> </message> <message> - <location filename="../PipxWidget.py" line="137" /> + <location filename="../PipxWidget.py" line="138" /> <source>Check Outdated Packages</source> <translation>Comprobar Packages Desactualizados</translation> </message> <message> - <location filename="../PipxWidget.py" line="428" /> - <location filename="../PipxWidget.py" line="141" /> + <location filename="../PipxWidget.py" line="434" /> + <location filename="../PipxWidget.py" line="142" /> <source>Upgrade Selected Package</source> <translation>Actualizar Package Seleccionado</translation> </message> <message> - <location filename="../PipxWidget.py" line="452" /> - <location filename="../PipxWidget.py" line="144" /> + <location filename="../PipxWidget.py" line="459" /> + <location filename="../PipxWidget.py" line="145" /> <source>Upgrade All Packages</source> <translation>Actualizar Todos los Packages</translation> </message> <message> - <location filename="../PipxWidget.py" line="148" /> + <location filename="../PipxWidget.py" line="149" /> <source>Upgrade Shared Libraries</source> <translation>Actualizar Bibliotecas Compartidas</translation> </message> <message> - <location filename="../PipxWidget.py" line="155" /> + <location filename="../PipxWidget.py" line="156" /> <source>Uninstall</source> <translation>Desinstalar</translation> </message> <message> - <location filename="../PipxWidget.py" line="157" /> + <location filename="../PipxWidget.py" line="158" /> <source>Uninstall Selected Package</source> <translation>Desinstalar Package Seleccionado</translation> </message> <message> - <location filename="../PipxWidget.py" line="494" /> - <location filename="../PipxWidget.py" line="160" /> + <location filename="../PipxWidget.py" line="501" /> + <location filename="../PipxWidget.py" line="161" /> <source>Uninstall All Packages</source> <translation>Desinstalar Todos los Packages</translation> </message> <message> - <location filename="../PipxWidget.py" line="167" /> + <location filename="../PipxWidget.py" line="168" /> <source>Dependencies</source> <translation>Dependencias</translation> </message> <message> - <location filename="../PipxWidget.py" line="169" /> + <location filename="../PipxWidget.py" line="170" /> <source>Show All Dependencies</source> <translation>Mostrar Todas las Dependencias</translation> </message> <message> - <location filename="../PipxWidget.py" line="172" /> + <location filename="../PipxWidget.py" line="173" /> <source>Show Outdated Dependencies</source> <translation>Mostrar Dependencias Desactualizadas</translation> </message> <message> - <location filename="../PipxWidget.py" line="175" /> + <location filename="../PipxWidget.py" line="176" /> <source>Show Up-to-date Dependencies</source> <translation>Mostrar Dependencias Actualizadas</translation> </message> <message> - <location filename="../PipxWidget.py" line="179" /> + <location filename="../PipxWidget.py" line="180" /> <source>Upgrade Dependencies</source> <translation>Actualizar Dependencias</translation> </message> <message> - <location filename="../PipxWidget.py" line="198" /> + <location filename="../PipxWidget.py" line="199" /> <source>Standalone Interpreters</source> <translation>Intérpretes Independientes</translation> </message> <message> - <location filename="../PipxWidget.py" line="202" /> + <location filename="../PipxWidget.py" line="203" /> <source>Ensure PATH Modifications</source> <translation>Asegurar modificaciones de PATH</translation> </message> <message> - <location filename="../PipxWidget.py" line="205" /> + <location filename="../PipxWidget.py" line="206" /> <source>Configure...</source> <translation>Configurar...</translation> </message> <message> - <location filename="../PipxWidget.py" line="285" /> + <location filename="../PipxWidget.py" line="286" /> <source>JSON Files (*.json);;All Files (*)</source> <translation>Archivos JSON (*.json);;Todos los Archivos (*)</translation> </message> <message> - <location filename="../PipxWidget.py" line="286" /> + <location filename="../PipxWidget.py" line="287" /> <source>JSON Files (*.json)</source> <translation>Archivos JSON (*.json)</translation> </message> <message> - <location filename="../PipxWidget.py" line="300" /> + <location filename="../PipxWidget.py" line="301" /> <source><p>The file <b>{0}</b> exists already. Overwrite it?</p></source> <translation><p>El archivo <b>{0}</b> ya existe. ¿Desea sobreescribirlo?</p></translation> </message> <message> - <location filename="../PipxWidget.py" line="312" /> + <location filename="../PipxWidget.py" line="313" /> <source><p>The spec metadata file <b>{0}</b> was created successfully.</p></source> <translation><p>El archivo de metadatos de spec <b>{0}</b> se ha creado con éxito</p></translation> </message> <message> - <location filename="../PipxWidget.py" line="321" /> + <location filename="../PipxWidget.py" line="322" /> <source><p>The spec metadata file <b>{0}</b> could not be created.</p><p>Reason: {1}</p></source> <translation><p>El archivo de metadatos de spec <b>{0}</b> no se ha podido crear.</p><p>Razón: {1}</p></translation> </message> <message> - <location filename="../PipxWidget.py" line="337" /> + <location filename="../PipxWidget.py" line="338" /> <source>Re-Install Package</source> <translation>Reinstalar Package</translation> </message> <message> - <location filename="../PipxWidget.py" line="338" /> + <location filename="../PipxWidget.py" line="339" /> <source><p>Shall the package <b>{0}</b> really be reinstalled?</p></source> <translation><p>¿Debe ser el package <b>{0}</b> reinstalado seguro?</p></translation> </message> <message> - <location filename="../PipxWidget.py" line="363" /> + <location filename="../PipxWidget.py" line="364" /> <source>Do you really want to reinstall all packages?</source> <translation>¿Desea seguro reinstalar todos los packages?</translation> </message> <message> - <location filename="../PipxWidget.py" line="429" /> + <location filename="../PipxWidget.py" line="435" /> <source><p>The selected package cannot be upgraded because some of its apps are running.</p><ul><li>{0}</li></ul><p>Stop these apps and try again.</p></source> <translation><p>El package seleccionado no se puede actualizar porque algunas de sus apps están en ejecución.</p><ul><li>{0}</li></ul><p>Detener estasapps e intentar de nuevo.</p></translation> </message> <message> - <location filename="../PipxWidget.py" line="453" /> + <location filename="../PipxWidget.py" line="460" /> <source><p>The packages cannot be upgraded because some of their apps are running.</p><ul><li>{0}</li></ul><p>Stop these apps and try again.</p></source> <translation><p>Los packages no se pueden actualizar porque algunas de sus apps están en ejecución.</p><ul><li>{0}</li></ul><p>Detener estas apps e intentar de nuevo.</p></translation> </message> <message> - <location filename="../PipxWidget.py" line="478" /> + <location filename="../PipxWidget.py" line="485" /> <source>Uninstall Package</source> <translation>Desinstalar Package</translation> </message> <message> - <location filename="../PipxWidget.py" line="479" /> + <location filename="../PipxWidget.py" line="486" /> <source><p>Shall the package <b>{0}</b> really be uninstalled?</p></source> <translation><p>¿Debe ser el package <b>{0}</b> desinstalado seguro?</p></translation> </message> <message> - <location filename="../PipxWidget.py" line="495" /> + <location filename="../PipxWidget.py" line="502" /> <source><p>Do you really want to uninstall <b>ALL</b> packages?</p></source> <translation><p>¿Desea seguro desinstalar <b>TODOS</b> los packages?</p></translation> </message> <message> - <location filename="../PipxWidget.py" line="596" /> + <location filename="../PipxWidget.py" line="606" /> <source><b>pipx Version {0}</b></source> <translation><b>pipx Versión {0}</b></translation> </message> <message> - <location filename="../PipxWidget.py" line="626" /> + <location filename="../PipxWidget.py" line="636" /> <source>{0} ({1})</source> <comment>current version, latest version</comment> <translation>{0} ({1})</translation> </message> <message> - <location filename="../PipxWidget.py" line="634" /> + <location filename="../PipxWidget.py" line="644" /> <source>package and some dependencies outdated</source> <translation>package y algunas dependencias desactualizados</translation> </message> <message> - <location filename="../PipxWidget.py" line="637" /> + <location filename="../PipxWidget.py" line="647" /> <source>package outdated</source> <translation>package desactualizado</translation> </message> <message> - <location filename="../PipxWidget.py" line="651" /> + <location filename="../PipxWidget.py" line="661" /> <source>some dependencies outdated</source> <translation>algunas dependencias desactualizadas</translation> </message> <message> - <location filename="../PipxWidget.py" line="666" /> + <location filename="../PipxWidget.py" line="676" /> <source>everything up-to-date</source> <translation>todo actualizado</translation> </message> <message> - <location filename="../PipxWidget.py" line="681" /> + <location filename="../PipxWidget.py" line="703" /> <source>{0}{1}</source> <comment>Python version, standalone indicator</comment> <translation>{0}{1}</translation> </message> <message> - <location filename="../PipxWidget.py" line="683" /> + <location filename="../PipxWidget.py" line="705" /> <source> (standalone)</source> <translation> (independiente)</translation> </message>
--- a/PipxInterface/i18n/pipx_ru.ts Sat Sep 07 19:29:57 2024 +0200 +++ b/PipxInterface/i18n/pipx_ru.ts Sun Sep 15 11:57:39 2024 +0200 @@ -4,107 +4,141 @@ <context> <name>Pipx</name> <message> - <location filename="../Pipx.py" line="140" /> + <location filename="../Pipx.py" line="263" /> + <location filename="../Pipx.py" line="153" /> <source><p>Message: {0}</p></source> <translation><p>Сообщение: {0}</p></translation> </message> <message> - <location filename="../Pipx.py" line="143" /> + <location filename="../Pipx.py" line="275" /> + <location filename="../Pipx.py" line="267" /> + <location filename="../Pipx.py" line="156" /> <source><p>pipx exited with an error ({0}).</p>{1}</source> <translation><p>pipx завершился с ошибкой ({0}).</p>{1}</translation> </message> <message> - <location filename="../Pipx.py" line="152" /> + <location filename="../Pipx.py" line="165" /> <source>pipx did not finish within 30 seconds.</source> <translation>pipx не была завершена в течение 30 секунд.</translation> </message> <message> - <location filename="../Pipx.py" line="154" /> + <location filename="../Pipx.py" line="221" /> + <location filename="../Pipx.py" line="167" /> <source>pipx could not be started.</source> <translation>pipx не удалось запустить.</translation> </message> <message> - <location filename="../Pipx.py" line="286" /> + <location filename="../Pipx.py" line="221" /> + <source>pipx Start Error</source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../Pipx.py" line="226" /> + <source>pipx Runtime Error</source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../Pipx.py" line="227" /> + <source><p>The pipx process reported an error.</p><p>Error: {0}</p></source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../Pipx.py" line="247" /> + <source>pipx did not finish within {0} seconds.</source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../Pipx.py" line="253" /> + <source>pipx Timeout Error</source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../Pipx.py" line="274" /> + <source>pipx Execution Error</source> + <translation type="unfinished" /> + </message> + <message> + <location filename="../Pipx.py" line="399" /> <source>Install Packages</source> <translation>Установить пакеты</translation> </message> <message> - <location filename="../Pipx.py" line="331" /> + <location filename="../Pipx.py" line="444" /> <source>Install All Packages</source> <translation>Установить все пакеты</translation> </message> <message> - <location filename="../Pipx.py" line="381" /> + <location filename="../Pipx.py" line="494" /> <source>Re-Install Package</source> <translation>Переустановить пакет</translation> </message> <message> - <location filename="../Pipx.py" line="412" /> + <location filename="../Pipx.py" line="525" /> <source>Re-Install All Packages</source> <translation>Переустановить все пакеты</translation> </message> <message> - <location filename="../Pipx.py" line="425" /> + <location filename="../Pipx.py" line="538" /> <source>Uninstall Package</source> <translation>Деинсталировать пакет</translation> </message> <message> - <location filename="../Pipx.py" line="435" /> + <location filename="../Pipx.py" line="548" /> <source>Uninstall All Packages</source> <translation>Деинсталировать все пакеты</translation> </message> <message> - <location filename="../Pipx.py" line="452" /> + <location filename="../Pipx.py" line="565" /> <source>Upgrade Package</source> <translation>Обновить пакет</translation> </message> <message> - <location filename="../Pipx.py" line="462" /> + <location filename="../Pipx.py" line="575" /> <source>Upgrade All Packages</source> <translation>Обновить все пакеты</translation> </message> <message> - <location filename="../Pipx.py" line="472" /> + <location filename="../Pipx.py" line="585" /> <source>Upgrade Shared Libraries</source> <translation>Обновить общие библиотеки</translation> </message> <message> - <location filename="../Pipx.py" line="486" /> + <location filename="../Pipx.py" line="599" /> <source>Upgrade Interpreters</source> <translation>Обновить интерпретаторы</translation> </message> <message> - <location filename="../Pipx.py" line="499" /> + <location filename="../Pipx.py" line="612" /> <source>Prune Unused Interpreters</source> <translation>Удалить неиспользуемые интерпретаторы</translation> </message> <message> - <location filename="../Pipx.py" line="510" /> + <location filename="../Pipx.py" line="623" /> <source>Ensure PATH Modifications</source> <translation>Внести изменения в переменную PATH</translation> </message> <message> - <location filename="../Pipx.py" line="537" /> + <location filename="../Pipx.py" line="662" /> <source>Check Outdated Package</source> <translation>Проверить устаревшие пакеты</translation> </message> <message> - <location filename="../Pipx.py" line="538" /> + <location filename="../Pipx.py" line="663" /> <source><p>The status of package <b>{0}</b> could not be determined.</p><p>Reason: {1}</p></source> <translation><p>Не удалось определить статус пакета <b>{0}</b>.</p><p>Причина: {1}</p></translation> </message> <message> - <location filename="../Pipx.py" line="579" /> + <location filename="../Pipx.py" line="724" /> <source>Get Package Dependencies</source> <translation>Получение зависимостей пакетов</translation> </message> <message> - <location filename="../Pipx.py" line="580" /> + <location filename="../Pipx.py" line="725" /> <source><p>The status of dependencies of package <b>{0}</b> could not be determined.</p><p>Reason: {1}</p></source> <translation><p>Не удалось определить статус зависимостей пакета <b>{0}</b>.</p><p>Причина: {1}</p></translation> </message> <message> - <location filename="../Pipx.py" line="650" /> + <location filename="../Pipx.py" line="795" /> <source>Upgrade Dependencies</source> <translation>Обновление зависимостей</translation> </message> @@ -512,229 +546,229 @@ <context> <name>PipxWidget</name> <message> - <location filename="../PipxWidget.py" line="112" /> + <location filename="../PipxWidget.py" line="113" /> <source>Install</source> <translation>Установить</translation> </message> <message> - <location filename="../PipxWidget.py" line="245" /> - <location filename="../PipxWidget.py" line="114" /> + <location filename="../PipxWidget.py" line="246" /> + <location filename="../PipxWidget.py" line="115" /> <source>Install Packages</source> <translation>Установить пакеты</translation> </message> <message> - <location filename="../PipxWidget.py" line="264" /> - <location filename="../PipxWidget.py" line="117" /> + <location filename="../PipxWidget.py" line="265" /> + <location filename="../PipxWidget.py" line="118" /> <source>Install All Packages</source> <translation>Установить все пакеты</translation> </message> <message> - <location filename="../PipxWidget.py" line="121" /> + <location filename="../PipxWidget.py" line="122" /> <source>Re-Install Selected Package</source> <translation>Переустановить выбранный пакет</translation> </message> <message> - <location filename="../PipxWidget.py" line="362" /> - <location filename="../PipxWidget.py" line="124" /> + <location filename="../PipxWidget.py" line="363" /> + <location filename="../PipxWidget.py" line="125" /> <source>Re-Install All Packages</source> <translation>Переустановить все пакеты</translation> </message> <message> - <location filename="../PipxWidget.py" line="320" /> - <location filename="../PipxWidget.py" line="311" /> - <location filename="../PipxWidget.py" line="299" /> - <location filename="../PipxWidget.py" line="283" /> - <location filename="../PipxWidget.py" line="128" /> + <location filename="../PipxWidget.py" line="321" /> + <location filename="../PipxWidget.py" line="312" /> + <location filename="../PipxWidget.py" line="300" /> + <location filename="../PipxWidget.py" line="284" /> + <location filename="../PipxWidget.py" line="129" /> <source>Create Spec Metadata File</source> <translation>Создать файл спецификации метаданных</translation> </message> <message> - <location filename="../PipxWidget.py" line="135" /> + <location filename="../PipxWidget.py" line="136" /> <source>Upgrade</source> <translation>Обновить</translation> </message> <message> - <location filename="../PipxWidget.py" line="137" /> + <location filename="../PipxWidget.py" line="138" /> <source>Check Outdated Packages</source> <translation>Проверить устаревшие пакеты</translation> </message> <message> - <location filename="../PipxWidget.py" line="428" /> - <location filename="../PipxWidget.py" line="141" /> + <location filename="../PipxWidget.py" line="434" /> + <location filename="../PipxWidget.py" line="142" /> <source>Upgrade Selected Package</source> <translation>Обновить выбранный пакет</translation> </message> <message> - <location filename="../PipxWidget.py" line="452" /> - <location filename="../PipxWidget.py" line="144" /> + <location filename="../PipxWidget.py" line="459" /> + <location filename="../PipxWidget.py" line="145" /> <source>Upgrade All Packages</source> <translation>Обновить все пакеты</translation> </message> <message> - <location filename="../PipxWidget.py" line="148" /> + <location filename="../PipxWidget.py" line="149" /> <source>Upgrade Shared Libraries</source> <translation>Обновить общие библиотеки</translation> </message> <message> - <location filename="../PipxWidget.py" line="155" /> + <location filename="../PipxWidget.py" line="156" /> <source>Uninstall</source> <translation>Деинсталировать</translation> </message> <message> - <location filename="../PipxWidget.py" line="157" /> + <location filename="../PipxWidget.py" line="158" /> <source>Uninstall Selected Package</source> <translation>Деинсталировать выбранный пакет</translation> </message> <message> - <location filename="../PipxWidget.py" line="494" /> - <location filename="../PipxWidget.py" line="160" /> + <location filename="../PipxWidget.py" line="501" /> + <location filename="../PipxWidget.py" line="161" /> <source>Uninstall All Packages</source> <translation>Деинсталировать все пакеты</translation> </message> <message> - <location filename="../PipxWidget.py" line="167" /> + <location filename="../PipxWidget.py" line="168" /> <source>Dependencies</source> <translation>Зависимости</translation> </message> <message> - <location filename="../PipxWidget.py" line="169" /> + <location filename="../PipxWidget.py" line="170" /> <source>Show All Dependencies</source> <translation>Показать все зависимости</translation> </message> <message> - <location filename="../PipxWidget.py" line="172" /> + <location filename="../PipxWidget.py" line="173" /> <source>Show Outdated Dependencies</source> <translation>Показать устаревшие зависимости</translation> </message> <message> - <location filename="../PipxWidget.py" line="175" /> + <location filename="../PipxWidget.py" line="176" /> <source>Show Up-to-date Dependencies</source> <translation>Показать актуальные зависимости</translation> </message> <message> - <location filename="../PipxWidget.py" line="179" /> + <location filename="../PipxWidget.py" line="180" /> <source>Upgrade Dependencies</source> <translation>Обновить зависимости</translation> </message> <message> - <location filename="../PipxWidget.py" line="198" /> + <location filename="../PipxWidget.py" line="199" /> <source>Standalone Interpreters</source> <translation>Автономные интерпретаторы</translation> </message> <message> - <location filename="../PipxWidget.py" line="202" /> + <location filename="../PipxWidget.py" line="203" /> <source>Ensure PATH Modifications</source> <translation>Внести изменения в переменную PATH</translation> </message> <message> - <location filename="../PipxWidget.py" line="205" /> + <location filename="../PipxWidget.py" line="206" /> <source>Configure...</source> <translation>Настроить...</translation> </message> <message> - <location filename="../PipxWidget.py" line="285" /> + <location filename="../PipxWidget.py" line="286" /> <source>JSON Files (*.json);;All Files (*)</source> <translation>Файлы JSON (*.json);;Все файлы (*)</translation> </message> <message> - <location filename="../PipxWidget.py" line="286" /> + <location filename="../PipxWidget.py" line="287" /> <source>JSON Files (*.json)</source> <translation>Файлы JSON (*.json)</translation> </message> <message> - <location filename="../PipxWidget.py" line="300" /> + <location filename="../PipxWidget.py" line="301" /> <source><p>The file <b>{0}</b> exists already. Overwrite it?</p></source> <translation><p>Файл <b>{0}</b> уже существует. Перезаписать?</p></translation> </message> <message> - <location filename="../PipxWidget.py" line="312" /> + <location filename="../PipxWidget.py" line="313" /> <source><p>The spec metadata file <b>{0}</b> was created successfully.</p></source> <translation><p>Файл спецификации метаданных <b>{0}</b> был успешно создан.</p></translation> </message> <message> - <location filename="../PipxWidget.py" line="321" /> + <location filename="../PipxWidget.py" line="322" /> <source><p>The spec metadata file <b>{0}</b> could not be created.</p><p>Reason: {1}</p></source> <translation><p>Не удалось создать файл спецификации метаданных <b>{0}</b>.</p><p>Причина: {1}</p></translation> </message> <message> - <location filename="../PipxWidget.py" line="337" /> + <location filename="../PipxWidget.py" line="338" /> <source>Re-Install Package</source> <translation>Переустановить пакет</translation> </message> <message> - <location filename="../PipxWidget.py" line="338" /> + <location filename="../PipxWidget.py" line="339" /> <source><p>Shall the package <b>{0}</b> really be reinstalled?</p></source> <translation><p>Действительно ли пакет <b>{0}</b> должен быть переустановлен?</p></translation> </message> <message> - <location filename="../PipxWidget.py" line="363" /> + <location filename="../PipxWidget.py" line="364" /> <source>Do you really want to reinstall all packages?</source> <translation>Вы действительно хотите переустановить все пакеты?</translation> </message> <message> - <location filename="../PipxWidget.py" line="429" /> + <location filename="../PipxWidget.py" line="435" /> <source><p>The selected package cannot be upgraded because some of its apps are running.</p><ul><li>{0}</li></ul><p>Stop these apps and try again.</p></source> <translation><p>Выбранный пакет не может быть обновлен, поскольку некоторые из его приложений запущены.</p><ul><li>{0}</li></ul><p>Остановите эти приложения и повторите попытку.</p></translation> </message> <message> - <location filename="../PipxWidget.py" line="453" /> + <location filename="../PipxWidget.py" line="460" /> <source><p>The packages cannot be upgraded because some of their apps are running.</p><ul><li>{0}</li></ul><p>Stop these apps and try again.</p></source> <translation><p>Обновление пакетов невозможно, поскольку некоторые из их приложений запущены.</p><ul><li>{0}</li></ul><p>Остановите эти приложения и повторите попытку.</p></translation> </message> <message> - <location filename="../PipxWidget.py" line="478" /> + <location filename="../PipxWidget.py" line="485" /> <source>Uninstall Package</source> <translation>Деинсталировать пакет</translation> </message> <message> - <location filename="../PipxWidget.py" line="479" /> + <location filename="../PipxWidget.py" line="486" /> <source><p>Shall the package <b>{0}</b> really be uninstalled?</p></source> <translation><p>Действительно ли пакет <b>{0}</b> должен быть удален?</p></translation> </message> <message> - <location filename="../PipxWidget.py" line="495" /> + <location filename="../PipxWidget.py" line="502" /> <source><p>Do you really want to uninstall <b>ALL</b> packages?</p></source> <translation><p>Вы действительно хотите удалить </b>ВСЕ </b> пакеты?</p></translation> </message> <message> - <location filename="../PipxWidget.py" line="596" /> + <location filename="../PipxWidget.py" line="606" /> <source><b>pipx Version {0}</b></source> <translation><b>Версия pipx {0}</b></translation> </message> <message> - <location filename="../PipxWidget.py" line="626" /> + <location filename="../PipxWidget.py" line="636" /> <source>{0} ({1})</source> <comment>current version, latest version</comment> <translation>{0} ({1})</translation> </message> <message> - <location filename="../PipxWidget.py" line="634" /> + <location filename="../PipxWidget.py" line="644" /> <source>package and some dependencies outdated</source> <translation>пакет и некоторые зависимости устарели</translation> </message> <message> - <location filename="../PipxWidget.py" line="637" /> + <location filename="../PipxWidget.py" line="647" /> <source>package outdated</source> <translation>пакет устарел</translation> </message> <message> - <location filename="../PipxWidget.py" line="651" /> + <location filename="../PipxWidget.py" line="661" /> <source>some dependencies outdated</source> <translation>некоторые зависимости устарели</translation> </message> <message> - <location filename="../PipxWidget.py" line="666" /> + <location filename="../PipxWidget.py" line="676" /> <source>everything up-to-date</source> <translation>все обновлено</translation> </message> <message> - <location filename="../PipxWidget.py" line="681" /> + <location filename="../PipxWidget.py" line="703" /> <source>{0}{1}</source> <comment>Python version, standalone indicator</comment> <translation /> </message> <message> - <location filename="../PipxWidget.py" line="683" /> + <location filename="../PipxWidget.py" line="705" /> <source> (standalone)</source> <translation> (автономный)</translation> </message>
--- a/PluginPipxInterface.epj Sat Sep 07 19:29:57 2024 +0200 +++ b/PluginPipxInterface.epj Sun Sep 15 11:57:39 2024 +0200 @@ -306,6 +306,7 @@ "PipxInterface/PipxExecDialog.py", "PipxInterface/PipxInterpretersDialog.py", "PipxInterface/PipxPackagesInputDialog.py", + "PipxInterface/PipxProcess.py", "PipxInterface/PipxReinstallDialog.py", "PipxInterface/PipxSpecInputDialog.py", "PipxInterface/PipxWidget.py",
--- a/PluginPipxInterface.py Sat Sep 07 19:29:57 2024 +0200 +++ b/PluginPipxInterface.py Sun Sep 15 11:57:39 2024 +0200 @@ -36,7 +36,7 @@ "author": "Detlev Offenbach <detlev@die-offenbachs.de>", "autoactivate": True, "deactivateable": True, - "version": "10.3.9", + "version": "10.4.0", "className": "PluginPipxInterface", "packageName": "PipxInterface", "shortDescription": "Graphical interface to the 'pipx' command.",
--- a/changelog.md Sat Sep 07 19:29:57 2024 +0200 +++ b/changelog.md Sun Sep 15 11:57:39 2024 +0200 @@ -1,6 +1,12 @@ ChangeLog --------- +__Version 10.4.0__ + +- bug fixes +- Changed the long running "outdated" actions to use an asynchronous process with + timeout. + __Version 10.3.9__ - Updated Spanish translations.