--- a/Plugins/UiExtensionPlugins/PipInterface/Pip.py Sat Feb 16 10:27:50 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1141 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> -# - -""" -Package implementing the pip GUI logic. -""" - -from __future__ import unicode_literals -try: - str = unicode # __IGNORE_EXCEPTION__ -except NameError: - pass - -import os -import sys - -from PyQt5.QtCore import pyqtSlot, QObject, QProcess -from PyQt5.QtWidgets import QMenu, QInputDialog, QDialog - -from E5Gui import E5MessageBox -from E5Gui.E5Action import E5Action -from E5Gui.E5Application import e5App - -from .PipDialog import PipDialog -from . import DefaultIndexUrlXml - -import Preferences -import Globals - - -class Pip(QObject): - """ - Class implementing the pip GUI logic. - """ - def __init__(self, plugin, parent=None): - """ - Constructor - - @param plugin reference to the plugin object - @type PipInterfacePlugin - @param parent parent - @type QObject - """ - super(Pip, self).__init__(parent) - - self.__plugin = plugin - self.__ui = parent - - self.__virtualenvManager = e5App().getObject("VirtualEnvManager") - self.__project = e5App().getObject("Project") - - self.__menus = {} # dictionary with references to menus - - self.__plugin.currentEnvironmentChanged.connect( - self.__handleTearOffMenu) - - def initActions(self): - """ - Public method to define the actions. - """ - self.actions = [] - - self.selectEnvironmentAct = E5Action( - self.tr('Virtual Environment for pip'), - self.tr('&Virtual Environment for pip'), - 0, 0, - self, 'pip_select_environment') - self.selectEnvironmentAct.setStatusTip(self.tr( - 'Selects the virtual environment to be used for pip')) - self.selectEnvironmentAct.setWhatsThis(self.tr( - """<b>Virtual Environment for pip</b>""" - """<p>This selects the virtual environment to be used for pip.""" - """</p>""" - )) - self.selectEnvironmentAct.triggered.connect(self.__selectPipVirtualenv) - self.actions.append(self.selectEnvironmentAct) - - ############################################## - ## Actions for listing packages - ############################################## - - self.listPackagesAct = E5Action( - self.tr('List Installed Packages'), - self.tr('&List Installed Packages...'), - 0, 0, - self, 'pip_list_packages') - self.listPackagesAct.setStatusTip(self.tr( - 'List all installed packages with versions')) - self.listPackagesAct.setWhatsThis(self.tr( - """<b>List Installed Packages</b>""" - """<p>This lists all the installed packages together""" - """ with their versions.</p>""" - )) - self.listPackagesAct.triggered.connect(self.__listPackages) - self.actions.append(self.listPackagesAct) - - self.listUptodatePackagesAct = E5Action( - self.tr('List Up-to-date Packages'), - self.tr('List Up-to-&date Packages...'), - 0, 0, - self, 'pip_list_uptodate_packages') - self.listUptodatePackagesAct.setStatusTip(self.tr( - 'List all installed, up-to-date packages with versions')) - self.listUptodatePackagesAct.setWhatsThis(self.tr( - """<b>List Up-to-date Packages</b>""" - """<p>This lists all the installed, up-to-date packages together""" - """ with their versions.</p>""" - )) - self.listUptodatePackagesAct.triggered.connect( - self.__listUptodatePackages) - self.actions.append(self.listUptodatePackagesAct) - - self.listOutdatedPackagesAct = E5Action( - self.tr('List Outdated Packages'), - self.tr('List &Outdated Packages...'), - 0, 0, - self, 'pip_list_outdated_packages') - self.listOutdatedPackagesAct.setStatusTip(self.tr( - 'List all installed, outdated packages with versions')) - self.listOutdatedPackagesAct.setWhatsThis(self.tr( - """<b>List Up-to-date Packages</b>""" - """<p>This lists all the installed, outdated packages together""" - """ with their current and latest versions.</p>""" - )) - self.listOutdatedPackagesAct.triggered.connect( - self.__listOutdatedPackages) - self.actions.append(self.listOutdatedPackagesAct) - - ############################################## - ## Actions for installing packages - ############################################## - - self.installPackagesAct = E5Action( - self.tr('Install Packages'), - self.tr('&Install Packages'), - 0, 0, - self, 'pip_install_packages') - self.installPackagesAct.setStatusTip(self.tr( - 'Install packages according to user input')) - self.installPackagesAct.setWhatsThis(self.tr( - """<b>Install Packages</b>""" - """<p>This installs packages according to user input.</p>""" - )) - self.installPackagesAct.triggered.connect(self.__installPackages) - self.actions.append(self.installPackagesAct) - - self.installLocalPackageAct = E5Action( - self.tr('Install Local Package'), - self.tr('Install Local Package'), - 0, 0, - self, 'pip_install_local_package') - self.installLocalPackageAct.setStatusTip(self.tr( - 'Install a package from local storage')) - self.installLocalPackageAct.setWhatsThis(self.tr( - """<b>Install Local Package</b>""" - """<p>This installs a package available on local storage.</p>""" - )) - self.installLocalPackageAct.triggered.connect( - self.__installLocalPackage) - self.actions.append(self.installLocalPackageAct) - - self.installRequirementsAct = E5Action( - self.tr('Install Requirements'), - self.tr('Install Requirements'), - 0, 0, - self, 'pip_install_requirements') - self.installRequirementsAct.setStatusTip(self.tr( - 'Install packages according to a requirements file')) - self.installRequirementsAct.setWhatsThis(self.tr( - """<b>Install Requirements</b>""" - """<p>This installs packages according to a requirements""" - """ file.</p>""" - )) - self.installRequirementsAct.triggered.connect( - self.__installRequirements) - self.actions.append(self.installRequirementsAct) - - self.installPipAct = E5Action( - self.tr('Install Pip'), - self.tr('Install Pip'), - 0, 0, - self, 'pip_install_pip') - self.installPipAct.setStatusTip(self.tr( - 'Install the pip package itself')) - self.installPipAct.setWhatsThis(self.tr( - """<b>Install Pip</b>""" - """<p>This installs the pip package itself.</p>""" - )) - self.installPipAct.triggered.connect(self.__installPip) - self.actions.append(self.installPipAct) - - self.repairPipAct = E5Action( - self.tr('Repair Pip'), - self.tr('Repair Pip'), - 0, 0, - self, 'pip_repair_pip') - self.repairPipAct.setStatusTip(self.tr( - 'Repair the pip package')) - self.repairPipAct.setWhatsThis(self.tr( - """<b>Repair Pip</b>""" - """<p>This repairs the pip package by re-installing it.</p>""" - )) - self.repairPipAct.triggered.connect(self.__repairPip) - self.actions.append(self.repairPipAct) - - self.upgradePipAct = E5Action( - self.tr('Upgrade Pip'), - self.tr('Upgrade &Pip'), - 0, 0, - self, 'pip_upgrade_pip') - self.upgradePipAct.setStatusTip(self.tr( - 'Upgrade the pip package itself')) - self.upgradePipAct.setWhatsThis(self.tr( - """<b>Upgrade Pip</b>""" - """<p>This upgrades the pip package itself.</p>""" - )) - self.upgradePipAct.triggered.connect(self.upgradePip) - self.actions.append(self.upgradePipAct) - - self.upgradePackagesAct = E5Action( - self.tr('Upgrade Packages'), - self.tr('&Upgrade Packages'), - 0, 0, - self, 'pip_upgrade_packages') - self.upgradePackagesAct.setStatusTip(self.tr( - 'Upgrade packages according to user input')) - self.upgradePackagesAct.setWhatsThis(self.tr( - """<b>Upgrade Packages</b>""" - """<p>This upgrades packages according to user input.</p>""" - )) - self.upgradePackagesAct.triggered.connect(self.__upgradePackages) - self.actions.append(self.upgradePackagesAct) - - ############################################## - ## Actions for uninstalling packages - ############################################## - - self.uninstallPackagesAct = E5Action( - self.tr('Uninstall Packages'), - self.tr('Uninstall Packages'), - 0, 0, - self, 'pip_uninstall_packages') - self.uninstallPackagesAct.setStatusTip(self.tr( - 'Uninstall packages according to user input')) - self.uninstallPackagesAct.setWhatsThis(self.tr( - """<b>Uninstall Packages</b>""" - """<p>This uninstalls packages according to user input.</p>""" - )) - self.uninstallPackagesAct.triggered.connect(self.__uninstallPackages) - self.actions.append(self.uninstallPackagesAct) - - self.uninstallRequirementsAct = E5Action( - self.tr('Uninstall Requirements'), - self.tr('Uninstall Requirements'), - 0, 0, - self, 'pip_uninstall_requirements') - self.uninstallRequirementsAct.setStatusTip(self.tr( - 'Uninstall packages according to a requirements file')) - self.uninstallRequirementsAct.setWhatsThis(self.tr( - """<b>Uninstall Requirements</b>""" - """<p>This uninstalls packages according to a requirements""" - """ file.</p>""" - )) - self.uninstallRequirementsAct.triggered.connect( - self.__uninstallRequirements) - self.actions.append(self.uninstallRequirementsAct) - - ############################################## - ## Actions for generating requirements files - ############################################## - - self.generateRequirementsAct = E5Action( - self.tr('Generate Requirements'), - self.tr('&Generate Requirements...'), - 0, 0, - self, 'pip_generate_requirements') - self.generateRequirementsAct.setStatusTip(self.tr( - 'Generate the contents of a requirements file')) - self.generateRequirementsAct.setWhatsThis(self.tr( - """<b>Generate Requirements</b>""" - """<p>This generates the contents of a requirements file.</p>""" - )) - self.generateRequirementsAct.triggered.connect( - self.__generateRequirements) - self.actions.append(self.generateRequirementsAct) - - ############################################## - ## Actions for generating requirements files - ############################################## - - self.searchPyPIAct = E5Action( - self.tr('Search PyPI'), - self.tr('&Search PyPI...'), - 0, 0, - self, 'pip_search_pypi') - self.searchPyPIAct.setStatusTip(self.tr( - 'Open a dialog to search the Python Package Index')) - self.searchPyPIAct.setWhatsThis(self.tr( - """<b>Search PyPI</b>""" - """<p>This opens a dialog to search the Python Package""" - """ Index.</p>""" - )) - self.searchPyPIAct.triggered.connect(self.__searchPyPI) - self.actions.append(self.searchPyPIAct) - - ############################################## - ## Actions for editing configuration files - ############################################## - - self.editUserConfigAct = E5Action( - self.tr('Edit User Configuration'), - self.tr('Edit User Configuration...'), - 0, 0, - self, 'pip_edit_user_config') - self.editUserConfigAct.setStatusTip(self.tr( - 'Open the per user configuration file in an editor')) - self.editUserConfigAct.setWhatsThis(self.tr( - """<b>Edit User Configuration</b>""" - """<p>This opens the per user configuration file in an editor.""" - """</p>""" - )) - self.editUserConfigAct.triggered.connect(self.__editUserConfiguration) - self.actions.append(self.editUserConfigAct) - - self.editVirtualenvConfigAct = E5Action( - self.tr('Edit Current Virtualenv Configuration'), - self.tr('Edit Current Virtualenv Configuration...'), - 0, 0, - self, 'pip_edit_virtualenv_config') - self.editVirtualenvConfigAct.setStatusTip(self.tr( - 'Open the current virtualenv configuration file in an editor')) - self.editVirtualenvConfigAct.setWhatsThis(self.tr( - """<b>Edit Current Virtualenv Configuration</b>""" - """<p>This opens the current virtualenv configuration file in""" - """ an editor. </p>""" - )) - self.editVirtualenvConfigAct.triggered.connect( - self.__editVirtualenvConfiguration) - self.actions.append(self.editVirtualenvConfigAct) - - self.pipConfigAct = E5Action( - self.tr('Configure'), - self.tr('Configure...'), - 0, 0, self, 'pip_configure') - self.pipConfigAct.setStatusTip(self.tr( - 'Show the configuration dialog with the Python Package Management' - ' page selected' - )) - self.pipConfigAct.setWhatsThis(self.tr( - """<b>Configure</b>""" - """<p>Show the configuration dialog with the Python Package""" - """ Management page selected.</p>""" - )) - self.pipConfigAct.triggered.connect(self.__pipConfigure) - self.actions.append(self.pipConfigAct) - - def initMenu(self): - """ - Public slot to initialize the menu. - - @return the menu generated - @rtype QMenu - """ - self.__menus = {} # clear menus references - - menu = QMenu(self.tr('P&ython Package Management'), self.__ui) - menu.setTearOffEnabled(True) - - menu.addAction(self.selectEnvironmentAct) - menu.addSeparator() - menu.addAction(self.listPackagesAct) - menu.addAction(self.listUptodatePackagesAct) - menu.addAction(self.listOutdatedPackagesAct) - menu.addSeparator() - menu.addAction(self.installPipAct) - menu.addSeparator() - menu.addAction(self.installPackagesAct) - menu.addAction(self.installLocalPackageAct) - menu.addAction(self.installRequirementsAct) - menu.addSeparator() - menu.addAction(self.upgradePipAct) - menu.addAction(self.upgradePackagesAct) - menu.addSeparator() - menu.addAction(self.uninstallPackagesAct) - menu.addAction(self.uninstallRequirementsAct) - menu.addSeparator() - menu.addAction(self.generateRequirementsAct) - menu.addSeparator() - menu.addAction(self.searchPyPIAct) - menu.addSeparator() - menu.addAction(self.repairPipAct) - menu.addSeparator() - menu.addAction(self.editUserConfigAct) - menu.addAction(self.editVirtualenvConfigAct) - menu.addSeparator() - menu.addAction(self.pipConfigAct) - - self.__menus["main"] = menu - - menu.aboutToShow.connect(self.__aboutToShowMenu) - - return menu - - def __aboutToShowMenu(self): - """ - Private slot to set the action enabled status. - """ - enable = bool(self.__plugin.getPreferences("CurrentEnvironment")) - for act in self.actions: - if act not in [self.selectEnvironmentAct, - self.installPipAct, - self.editUserConfigAct, - self.editVirtualenvConfigAct, - self.pipConfigAct]: - act.setEnabled(enable) - - def getMenu(self, name): - """ - Public method to get a reference to the requested menu. - - @param name name of the menu - @type str - @return reference to the menu or None, if no - menu with the given name exists - @rtype QMenu or None - """ - if name in self.__menus: - return self.__menus[name] - else: - return None - - def getMenuNames(self): - """ - Public method to get the names of all menus. - - @return menu names - @rtype list of str - """ - return list(self.__menus.keys()) - - def __handleTearOffMenu(self, venvName): - """ - Private slot to handle a change of the selected virtual environment. - - @param venvName logical name of the virtual environment - @type str - """ - if self.__menus["main"].isTearOffMenuVisible(): - # determine, if torn off menu needs to be refreshed - enabled = self.listPackagesAct.isEnabled() - if ((bool(venvName) and not enabled) or - (not bool(venvName) and enabled)): - self.__menus["main"].hideTearOffMenu() - - ########################################################################## - ## Methods below implement some utility functions - ########################################################################## - - def runProcess(self, args, interpreter): - """ - Public method to execute the current pip with the given arguments. - - The selected pip executable is called with the given arguments and - waited for its end. - - @param args list of command line arguments - @type list of str - @param interpreter path of the Python interpreter to be used - @type str - @return tuple containing a flag indicating success and the output - of the process - @rtype tuple of (bool, str) - """ - ioEncoding = Preferences.getSystem("IOEncoding") - - process = QProcess() - process.start(interpreter, args) - procStarted = process.waitForStarted() - if procStarted: - finished = process.waitForFinished(30000) - if finished: - if process.exitCode() == 0: - output = str(process.readAllStandardOutput(), ioEncoding, - 'replace') - return True, output - else: - return (False, - self.tr("python exited with an error ({0}).") - .format(process.exitCode())) - else: - process.terminate() - process.waitForFinished(2000) - process.kill() - process.waitForFinished(3000) - return False, self.tr("python did not finish within" - " 30 seconds.") - - return False, self.tr("python could not be started.") - - def __getUserConfig(self): - """ - Private method to get the name of the user configuration file. - - @return path of the user configuration file - @rtype str - """ - # Unix: ~/.config/pip/pip.conf - # OS X: ~/Library/Application Support/pip/pip.conf - # Windows: %APPDATA%\pip\pip.ini - # Environment: $PIP_CONFIG_FILE - - try: - return os.environ["PIP_CONFIG_FILE"] - except KeyError: - pass - - if Globals.isWindowsPlatform(): - config = os.path.join(os.environ["APPDATA"], "pip", "pip.ini") - elif Globals.isMacPlatform(): - config = os.path.expanduser( - "~/Library/Application Support/pip/pip.conf") - else: - config = os.path.expanduser("~/.config/pip/pip.conf") - - return config - - def __getVirtualenvConfig(self): - """ - Private method to get the name of the virtualenv configuration file. - - @return path of the virtualenv configuration file - @rtype str - """ - # Unix, OS X: $VIRTUAL_ENV/pip.conf - # Windows: %VIRTUAL_ENV%\pip.ini - - if Globals.isWindowsPlatform(): - pip = "pip.ini" - else: - pip = "pip.conf" - try: - venvDirectory = os.environ["VIRTUAL_ENV"] - except KeyError: - venvName = self.__plugin.getPreferences("CurrentEnvironment") - if not venvName: - self.__selectPipVirtualenv() - venvName = self.__plugin.getPreferences("CurrentEnvironment") - if self.__virtualenvManager.isGlobalEnvironment(venvName): - venvDirectory = self.__getUserConfig() - else: - venvDirectory = \ - self.__virtualenvManager.getVirtualenvDirectory(venvName) - - return os.path.join(venvDirectory, pip) - - def getDefaultEnvironmentString(self): - """ - Public method to get the string for the default environment. - - @return string for the default environment - @rtype str - """ - return self.tr("<standard>") - - def getProjectEnvironmentString(self): - """ - Public method to get the string for the project environment. - - @return string for the project environment - @rtype str - """ - if self.__project.isOpen(): - return self.tr("<project>") - else: - return "" - - def getVirtualenvInterpreter(self, venvName): - """ - Public method to get the interpreter for a virtual environment. - - @param venvName logical name for the virtual environment - @type str - @return interpreter path - @rtype str - """ - if venvName == self.getDefaultEnvironmentString(): - venvName = self.__plugin.getPreferences("CurrentEnvironment") - elif venvName == self.getProjectEnvironmentString(): - venvName = self.__project.getDebugProperty("VIRTUALENV") - if not venvName: - # fall back to standard if not defined - venvName = self.__plugin.getPreferences("CurrentEnvironment") - - interpreter = self.__virtualenvManager.getVirtualenvInterpreter( - venvName) - if not interpreter: - E5MessageBox.critical( - None, - self.tr("Interpreter for Virtual Environment"), - self.tr("""No interpreter configured for the selected""" - """ virtual environment.""")) - - return interpreter - - def getVirtualenvNames(self): - """ - Public method to get a sorted list of virtual environment names. - - @return sorted list of virtual environment names - @rtype list of str - """ - return sorted(self.__virtualenvManager.getVirtualenvNames()) - - ########################################################################## - ## Methods below implement the individual menu entries - ########################################################################## - - def __selectPipVirtualenv(self): - """ - Private method to select the virtual environment to be used. - """ - environments = self.getVirtualenvNames() - if environments: - currentEnvironment = self.__plugin.getPreferences( - "CurrentEnvironment") - try: - index = environments.index(currentEnvironment) - except ValueError: - index = 0 - environment, ok = QInputDialog.getItem( - None, - self.tr("Virtual Environment for pip"), - self.tr("Select the virtual environment to be used:"), - environments, index, False) - - if ok and environment: - self.__plugin.setPreferences("CurrentEnvironment", - environment) - else: - E5MessageBox.warning( - None, - self.tr("Virtual Environment for pip"), - self.tr("""No virtual environments have been configured yet.""" - """ Please use the Virtualenv Manager to do that.""")) - - def __listPackages(self): - """ - Private slot to list all installed packages. - """ - from .PipListDialog import PipListDialog - self.__listDialog = PipListDialog( - self, "list", self.__plugin.getPreferences("PipSearchIndex"), - self.tr("Installed Packages")) - self.__listDialog.show() - self.__listDialog.start() - - def __listUptodatePackages(self): - """ - Private slot to list all installed, up-to-date packages. - """ - from .PipListDialog import PipListDialog - self.__listUptodateDialog = PipListDialog( - self, "uptodate", self.__plugin.getPreferences("PipSearchIndex"), - self.tr("Up-to-date Packages")) - self.__listUptodateDialog.show() - self.__listUptodateDialog.start() - - def __listOutdatedPackages(self): - """ - Private slot to list all installed, up-to-date packages. - """ - from .PipListDialog import PipListDialog - self.__listOutdatedDialog = PipListDialog( - self, "outdated", self.__plugin.getPreferences("PipSearchIndex"), - self.tr("Outdated Packages")) - self.__listOutdatedDialog.show() - self.__listOutdatedDialog.start() - - def __editUserConfiguration(self): - """ - Private slot to edit the user configuration. - """ - self.__editConfiguration() - - def __editVirtualenvConfiguration(self): - """ - Private slot to edit the current virtualenv configuration. - """ - self.__editConfiguration(virtualenv=True) - - def __editConfiguration(self, virtualenv=False): - """ - Private method to edit a configuration. - - @param virtualenv flag indicating to edit the current virtualenv - configuration file - @type bool - """ - from QScintilla.MiniEditor import MiniEditor - if virtualenv: - cfgFile = self.__getVirtualenvConfig() - else: - cfgFile = self.__getUserConfig() - cfgDir = os.path.dirname(cfgFile) - if not cfgDir: - E5MessageBox.critical( - None, - self.tr("Edit Configuration"), - self.tr("""No valid configuration path determined.""" - """ Is a virtual environment selected? Aborting""")) - return - - try: - if not os.path.isdir(cfgDir): - os.makedirs(cfgDir) - except OSError: - E5MessageBox.critical( - None, - self.tr("Edit Configuration"), - self.tr("""No valid configuration path determined.""" - """ Is a virtual environment selected? Aborting""")) - return - - if not os.path.exists(cfgFile): - try: - f = open(cfgFile, "w") - f.write("[global]\n") - f.close() - except (IOError, OSError): - # ignore these - pass - - # check, if the destination is writeable - if not os.access(cfgFile, os.W_OK): - E5MessageBox.critical( - None, - self.tr("Edit Configuration"), - self.tr("""No valid configuartion path determined.""" - """ Is a virtual environment selected? Aborting""")) - return - - self.__editor = MiniEditor(cfgFile, "Properties") - self.__editor.show() - - def __installPip(self, userSite=False): - """ - Private slot to install pip. - - @param userSite flag indicating an install to the user install - directory - @type bool - """ - from .PipSelectionDialog import PipSelectionDialog - dlg = PipSelectionDialog(self) - if dlg.exec_() != QDialog.Accepted: - return - - venvName, userSite = dlg.getData() - interpreter = self.getVirtualenvInterpreter(venvName) - if not interpreter: - return - - dia = PipDialog(self.tr('Install PIP')) - if userSite: - commands = [(interpreter, ["-m", "ensurepip", "--user"])] - else: - commands = [(interpreter, ["-m", "ensurepip"])] - if self.__plugin.getPreferences("PipSearchIndex"): - indexUrl = \ - self.__plugin.getPreferences("PipSearchIndex") + "/simple" - args = ["-m", "pip", "install", "--index-url", indexUrl, - "--upgrade"] - else: - args = ["-m", "pip", "install", "--upgrade"] - if userSite: - args.append("--user") - args.append("pip") - commands.append((interpreter, args[:])) - - res = dia.startProcesses(commands) - if res: - dia.exec_() - - @pyqtSlot() - def upgradePip(self, venvName="", userSite=False): - """ - Public method to upgrade pip itself. - - @param venvName name of the virtual environment to be used - @type str - @param userSite flag indicating an install to the user install - directory - @type bool - @return flag indicating a successful execution - @rtype bool - """ - # Upgrading pip needs to be treated specially because - # it must be done using the python executable - - if not venvName: - from .PipSelectionDialog import PipSelectionDialog - dlg = PipSelectionDialog(self) - if dlg.exec_() != QDialog.Accepted: - return - - venvName, userSite = dlg.getData() - - interpreter = self.getVirtualenvInterpreter(venvName) - if not interpreter: - return - - if self.__plugin.getPreferences("PipSearchIndex"): - indexUrl = \ - self.__plugin.getPreferences("PipSearchIndex") + "/simple" - args = ["-m", "pip", "install", "--index-url", indexUrl, - "--upgrade"] - else: - args = ["-m", "pip", "install", "--upgrade"] - if userSite: - args.append("--user") - args.append("pip") - - dia = PipDialog(self.tr('Upgrade PIP')) - res = dia.startProcess(interpreter, args) - if res: - dia.exec_() - return res - - @pyqtSlot() - def __repairPip(self): - """ - Private method to repair the pip installation. - - @return flag indicating a successful execution - @rtype bool - """ - from .PipSelectionDialog import PipSelectionDialog - dlg = PipSelectionDialog(self) - if dlg.exec_() != QDialog.Accepted: - return False - - venvName, userSite = dlg.getData() - interpreter = self.getVirtualenvInterpreter(venvName) - if not interpreter: - return - - # python -m pip install --ignore-installed pip - if self.__plugin.getPreferences("PipSearchIndex"): - indexUrl = \ - self.__plugin.getPreferences("PipSearchIndex") + "/simple" - args = ["-m", "pip", "install", "--index-url", indexUrl, - "--ignore-installed"] - else: - args = ["-m", "pip", "install", "--ignore-installed"] - if userSite: - args.append("--user") - args.append("pip") - - dia = PipDialog(self.tr('Repair PIP')) - res = dia.startProcess(interpreter, args) - if res: - dia.exec_() - - def __checkUpgradePyQt(self, packages): - """ - Private method to check, if an upgrade of PyQt packages is attempted. - - @param packages list of packages to upgrade - @type list of str - @return flag indicating to abort the upgrade attempt - @rtype bool - """ - pyqtPackages = [p for p in packages - if p.lower() in ["pyqt5", "qscintilla", "sip"]] - - if bool(pyqtPackages): - abort = not E5MessageBox.yesNo( - None, - self.tr("Upgrade Packages"), - self.tr( - """You are trying to upgrade PyQt packages. This will""" - """ not work for the current instance of Python ({0}).""" - """ Do you want to continue?""").format(sys.executable), - icon=E5MessageBox.Critical) - else: - abort = False - - return abort - - def upgradePackages(self, packages, venvName="", userSite=False): - """ - Public method to upgrade the given list of packages. - - @param packages list of packages to upgrade - @type list of str - @param venvName name of the virtual environment to be used - @type str - @param userSite flag indicating an install to the user install - directory - @type bool - @return flag indicating a successful execution - @rtype bool - """ - if self.__checkUpgradePyQt(packages): - return False - - if not venvName: - venvName = self.__plugin.getPreferences("CurrentEnvironment") - interpreter = self.getVirtualenvInterpreter(venvName) - if not interpreter: - return - - if self.__plugin.getPreferences("PipSearchIndex"): - indexUrl = \ - self.__plugin.getPreferences("PipSearchIndex") + "/simple" - args = ["-m", "pip", "install", "--index-url", indexUrl, - "--upgrade"] - else: - args = ["-m", "pip", "install", "--upgrade"] - if userSite: - args.append("--user") - args += packages - dia = PipDialog(self.tr('Upgrade Packages')) - res = dia.startProcess(interpreter, args) - if res: - dia.exec_() - return res - - def __upgradePackages(self): - """ - Private slot to upgrade packages to be given by the user. - """ - from .PipPackagesInputDialog import PipPackagesInputDialog - dlg = PipPackagesInputDialog(self, self.tr("Upgrade Packages")) - if dlg.exec_() == QDialog.Accepted: - venvName, packages, user = dlg.getData() - if packages: - self.upgradePackages(packages, venvName=venvName, - userSite=user) - - def installPackages(self, packages, venvName="", userSite=False): - """ - Public method to install the given list of packages. - - @param packages list of packages to install - @type list of str - @param venvName name of the virtual environment to be used - @type str - @param userSite flag indicating an install to the user install - directory - @type bool - """ - if not venvName: - venvName = self.__plugin.getPreferences("CurrentEnvironment") - interpreter = self.getVirtualenvInterpreter(venvName) - if not interpreter: - return - - if self.__plugin.getPreferences("PipSearchIndex"): - indexUrl = \ - self.__plugin.getPreferences("PipSearchIndex") + "/simple" - args = ["-m", "pip", "install", "--index-url", indexUrl] - else: - args = ["-m", "pip", "install"] - if userSite: - args.append("--user") - args += packages - dia = PipDialog(self.tr('Install Packages')) - res = dia.startProcess(interpreter, args) - if res: - dia.exec_() - - def __installPackages(self): - """ - Private slot to install packages to be given by the user. - """ - from .PipPackagesInputDialog import PipPackagesInputDialog - dlg = PipPackagesInputDialog( - self, self.tr("Install Packages")) - if dlg.exec_() == QDialog.Accepted: - venvName, packages, user = dlg.getData() - if packages: - self.installPackages(packages, venvName=venvName, - userSite=user) - - def __installLocalPackage(self): - """ - Private slot to install a package available on local storage. - """ - from .PipFileSelectionDialog import PipFileSelectionDialog - dlg = PipFileSelectionDialog(self, "package") - if dlg.exec_() == QDialog.Accepted: - venvName, package, user = dlg.getData() - if package and os.path.exists(package): - self.installPackages([package], venvName=venvName, - userSite=user) - - def __installRequirements(self): - """ - Private slot to install packages as given in a requirements file. - """ - from .PipFileSelectionDialog import PipFileSelectionDialog - dlg = PipFileSelectionDialog(self, "requirements") - if dlg.exec_() == QDialog.Accepted: - venvName, requirements, user = dlg.getData() - if requirements and os.path.exists(requirements): - interpreter = self.getVirtualenvInterpreter(venvName) - if not interpreter: - return - if self.__plugin.getPreferences("PipSearchIndex"): - indexUrl = \ - self.__plugin.getPreferences("PipSearchIndex") + \ - "/simple" - args = ["-m", "pip", "install", "--index-url", indexUrl] - else: - args = ["-m", "pip", "install"] - if user: - args.append("--user") - args += ["--requirement", requirements] - dia = PipDialog(self.tr('Install Packages from Requirements')) - res = dia.startProcess(interpreter, args) - if res: - dia.exec_() - - def uninstallPackages(self, packages, venvName=""): - """ - Public method to uninstall the given list of packages. - - @param packages list of packages to uninstall - @type list of str - @param venvName name of the virtual environment to be used - @type str - @return flag indicating a successful execution - @rtype bool - """ - res = False - if packages: - from UI.DeleteFilesConfirmationDialog import \ - DeleteFilesConfirmationDialog - dlg = DeleteFilesConfirmationDialog( - self.parent(), - self.tr("Uninstall Packages"), - self.tr( - "Do you really want to uninstall these packages?"), - packages) - if dlg.exec_() == QDialog.Accepted: - if not venvName: - venvName = self.__plugin.getPreferences( - "CurrentEnvironment") - interpreter = self.getVirtualenvInterpreter(venvName) - if not interpreter: - return - args = ["-m", "pip", "uninstall", "--yes"] + packages - dia = PipDialog(self.tr('Uninstall Packages')) - res = dia.startProcess(interpreter, args) - if res: - dia.exec_() - return res - - def __uninstallPackages(self): - """ - Private slot to uninstall packages to be given by the user. - """ - from .PipPackagesInputDialog import PipPackagesInputDialog - dlg = PipPackagesInputDialog( - self, self.tr("Uninstall Packages"), install=False) - if dlg.exec_() == QDialog.Accepted: - venvName, packages, _user = dlg.getData() - if packages: - self.uninstallPackages(packages, venvName=venvName) - - def __uninstallRequirements(self): - """ - Private slot to uninstall packages as given in a requirements file. - """ - from .PipFileSelectionDialog import PipFileSelectionDialog - dlg = PipFileSelectionDialog(self, "requirements", - install=False) - if dlg.exec_() == QDialog.Accepted: - venvName, requirements, _user = dlg.getData() - if requirements and os.path.exists(requirements): - try: - f = open(requirements, "r") - reqs = f.read().splitlines() - f.close() - except (OSError, IOError): - return - - from UI.DeleteFilesConfirmationDialog import \ - DeleteFilesConfirmationDialog - dlg = DeleteFilesConfirmationDialog( - self.parent(), - self.tr("Uninstall Packages"), - self.tr( - "Do you really want to uninstall these packages?"), - reqs) - if dlg.exec_() == QDialog.Accepted: - if not venvName: - venvName = self.__plugin.getPreferences( - "CurrentEnvironment") - interpreter = self.getVirtualenvInterpreter(venvName) - if not interpreter: - return - args = ["-m", "pip", "uninstall", "--requirement", - requirements] - dia = PipDialog( - self.tr('Uninstall Packages from Requirements')) - res = dia.startProcess(interpreter, args) - if res: - dia.exec_() - - def __generateRequirements(self): - """ - Private slot to generate the contents for a requirements file. - """ - from .PipFreezeDialog import PipFreezeDialog - self.__freezeDialog = PipFreezeDialog(self) - self.__freezeDialog.show() - self.__freezeDialog.start() - - def __searchPyPI(self): - """ - Private slot to search the Python Package Index. - """ - from .PipSearchDialog import PipSearchDialog - - if self.__plugin.getPreferences("PipSearchIndex"): - indexUrl = self.__plugin.getPreferences("PipSearchIndex") + "/pypi" - else: - indexUrl = DefaultIndexUrlXml - - self.__searchDialog = PipSearchDialog(self, indexUrl) - self.__searchDialog.show() - - def __pipConfigure(self): - """ - Private slot to open the configuration page. - """ - e5App().getObject("UserInterface").showPreferences("pipPage")