Thu, 21 Feb 2019 19:55:35 +0100
PipInterface: continued with the pip interface widget.
PipInterface/Pip.py | file | annotate | diff | comparison | revisions | |
PipInterface/PipFileSelectionDialog.py | file | annotate | diff | comparison | revisions | |
PipInterface/PipFileSelectionDialog.ui | file | annotate | diff | comparison | revisions | |
PipInterface/PipPackagesInputDialog.py | file | annotate | diff | comparison | revisions | |
PipInterface/PipPackagesInputDialog.ui | file | annotate | diff | comparison | revisions | |
PipInterface/PipPackagesWidget.py | file | annotate | diff | comparison | revisions | |
PipInterface/PipSearchDialog.py | file | annotate | diff | comparison | revisions | |
PipInterface/PipSearchDialog.ui | file | annotate | diff | comparison | revisions | |
PipInterface/PipSelectionDialog.py | file | annotate | diff | comparison | revisions | |
PipInterface/PipSelectionDialog.ui | file | annotate | diff | comparison | revisions | |
eric6.e4p | file | annotate | diff | comparison | revisions |
--- a/PipInterface/Pip.py Wed Feb 20 19:44:13 2019 +0100 +++ b/PipInterface/Pip.py Thu Feb 21 19:55:35 2019 +0100 @@ -57,12 +57,12 @@ ## self.__plugin.currentEnvironmentChanged.connect( ## self.__handleTearOffMenu) - def initActions(self): - """ - Public method to define the actions. - """ - self.actions = [] - +## 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'), @@ -129,164 +129,164 @@ ## 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 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 ## ############################################## @@ -306,67 +306,67 @@ ## 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 - """ +## ############################################## +## ## 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() +## menu = QMenu() ## menu.setTearOffEnabled(True) ## menu.setIcon(UI.PixmapCache.getIcon("pypi.png")) ## @@ -376,47 +376,47 @@ ## 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.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.addSeparator() ## menu.addAction(self.uninstallPackagesAct) - menu.addAction(self.uninstallRequirementsAct) - menu.addSeparator() - menu.addAction(self.generateRequirementsAct) - menu.addSeparator() +## 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) - +## 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(Preferences.getPip("CurrentEnvironment")) - for act in self.actions: - if act not in [self.selectEnvironmentAct, - self.installPipAct, - self.editUserConfigAct, - self.editVirtualenvConfigAct, - self.pipConfigAct]: - act.setEnabled(enable) +## menu.aboutToShow.connect(self.__aboutToShowMenu) +## +## return menu +## +## def __aboutToShowMenu(self): +## """ +## Private slot to set the action enabled status. +## """ +## enable = bool(Preferences.getPip("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): ## """ @@ -538,6 +538,7 @@ # Unix, OS X: $VIRTUAL_ENV/pip.conf # Windows: %VIRTUAL_ENV%\pip.ini + # TODO: modify to use venvName if Globals.isWindowsPlatform(): pip = "pip.ini" else: @@ -688,88 +689,84 @@ ## 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): +## 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() +## if not cfgFile: +## return +## 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, venvName, userSite=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() - if not cfgFile: - return - 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 + Public method to install pip. - 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 venvName name of the environment to install pip into + @type str @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 @@ -794,64 +791,60 @@ 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 Preferences.getPip("PipSearchIndex"): +## indexUrl = Preferences.getPip("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 upgradePip(self, venvName="", userSite=False): + def repairPip(self, venvName): """ - Public method to upgrade pip itself. + Public method to repair the pip installation. - @param venvName name of the virtual environment to be used + @param venvName name of the environment to install pip into @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 Preferences.getPip("PipSearchIndex"): - indexUrl = Preferences.getPip("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 @@ -863,8 +856,6 @@ "--ignore-installed"] else: args = ["-m", "pip", "install", "--ignore-installed"] - if userSite: - args.append("--user") args.append("pip") dia = PipDialog(self.tr('Repair PIP')) @@ -978,31 +969,31 @@ 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 __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): """ @@ -1064,18 +1055,18 @@ 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 __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. @@ -1115,15 +1106,15 @@ 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 __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. @@ -1280,9 +1271,9 @@ )) return packages - - def __pipConfigure(self): - """ - Private slot to open the configuration page. - """ - e5App().getObject("UserInterface").showPreferences("pipPage") +## +## def __pipConfigure(self): +## """ +## Private slot to open the configuration page. +## """ +## e5App().getObject("UserInterface").showPreferences("pipPage")
--- a/PipInterface/PipFileSelectionDialog.py Wed Feb 20 19:44:13 2019 +0100 +++ b/PipInterface/PipFileSelectionDialog.py Thu Feb 21 19:55:35 2019 +0100 @@ -70,12 +70,6 @@ self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) - self.venvComboBox.addItem(pip.getDefaultEnvironmentString()) - projectVenv = pip.getProjectEnvironmentString() - if projectVenv: - self.venvComboBox.addItem(projectVenv) - self.venvComboBox.addItems(pip.getVirtualenvNames()) - self.userCheckBox.setVisible(install) msh = self.minimumSizeHint() @@ -98,13 +92,11 @@ """ Public method to get the entered data. - @return tuple with the environment name, the name of the - selected file and a flag indicating to install to the - user install directory - @rtype tuple of (str, str, bool) + @return tuple with the name of the selected file and a flag indicating + to install to the user install directory + @rtype tuple of (str, bool) """ return ( - self.venvComboBox.currentText(), self.filePicker.text(), self.userCheckBox.isChecked() )
--- a/PipInterface/PipFileSelectionDialog.ui Wed Feb 20 19:44:13 2019 +0100 +++ b/PipInterface/PipFileSelectionDialog.ui Thu Feb 21 19:55:35 2019 +0100 @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>600</width> - <height>170</height> + <height>114</height> </rect> </property> <property name="windowTitle"> @@ -18,20 +18,6 @@ </property> <layout class="QVBoxLayout" name="verticalLayout"> <item> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Virtual Environment:</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="venvComboBox"> - <property name="toolTip"> - <string>Select the virtual environment to be used</string> - </property> - </widget> - </item> - <item> <widget class="QLabel" name="fileLabel"> <property name="text"> <string>File Name:</string>
--- a/PipInterface/PipPackagesInputDialog.py Wed Feb 20 19:44:13 2019 +0100 +++ b/PipInterface/PipPackagesInputDialog.py Thu Feb 21 19:55:35 2019 +0100 @@ -39,12 +39,6 @@ self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) - self.venvComboBox.addItem(pip.getDefaultEnvironmentString()) - projectVenv = pip.getProjectEnvironmentString() - if projectVenv: - self.venvComboBox.addItem(projectVenv) - self.venvComboBox.addItems(pip.getVirtualenvNames()) - self.userCheckBox.setVisible(install) msh = self.minimumSizeHint() @@ -64,15 +58,13 @@ """ Public method to get the entered data. - @return tuple with the environment name, the list of package - specifications and a flag indicating to install to the user - install directory - @rtype tuple of (str, list of str, bool) + @return tuple with the list of package specifications and a flag + indicating to install to the user install directory + @rtype tuple of (list of str, bool) """ packages = [p.strip() for p in self.packagesEdit.text().split()] return ( - self.venvComboBox.currentText(), packages, self.userCheckBox.isChecked() )
--- a/PipInterface/PipPackagesInputDialog.ui Wed Feb 20 19:44:13 2019 +0100 +++ b/PipInterface/PipPackagesInputDialog.ui Thu Feb 21 19:55:35 2019 +0100 @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>600</width> - <height>186</height> + <height>130</height> </rect> </property> <property name="windowTitle"> @@ -18,20 +18,6 @@ </property> <layout class="QVBoxLayout" name="verticalLayout"> <item> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Virtual Environment:</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="venvComboBox"> - <property name="toolTip"> - <string>Select the virtual environment to be used</string> - </property> - </widget> - </item> - <item> <widget class="QLabel" name="label_2"> <property name="text"> <string>Package Specifications (separated by whitespace):</string>
--- a/PipInterface/PipPackagesWidget.py Wed Feb 20 19:44:13 2019 +0100 +++ b/PipInterface/PipPackagesWidget.py Thu Feb 21 19:55:35 2019 +0100 @@ -10,11 +10,12 @@ from __future__ import unicode_literals import textwrap +import os from PyQt5.QtCore import pyqtSlot, Qt, QEventLoop, QRegExp from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import QWidget, QToolButton, QApplication, QHeaderView, \ - QTreeWidgetItem + QTreeWidgetItem, QInputDialog, QMenu, QDialog from E5Gui.E5Application import e5App from E5Gui import E5MessageBox @@ -109,6 +110,11 @@ self.statusLabel.hide() self.searchWidget.hide() + + self.__detailsData = {} + self.__query = [] + + self.__packageDetailsDialog = None def __populateEnvironments(self): """ @@ -497,6 +503,13 @@ self.__updateSearchButton() @pyqtSlot() + def on_searchEdit_returnPressed(self): + """ + Private slot initiating a search via a press of the Return key. + """ + self.__search() + + @pyqtSlot() def on_searchButton_clicked(self): """ Private slot handling a press of the search button. @@ -685,6 +698,165 @@ return score + @pyqtSlot() + def on_installButton_clicked(self): + """ + Private slot to handle pressing the Install button.. + """ + self.__install() + + @pyqtSlot() + def on_installUserSiteButton_clicked(self): + """ + Private slot to handle pressing the Install to User-Site button.. + """ + self.__install(userSite=True) + + def __install(self, userSite=False): + """ + Private slot to install the selected packages. + + @param userSite flag indicating to install to the user directory + @type bool + """ + venvName = self.environmentsComboBox.currentText() + if venvName: + packages = [] + for itm in self.searchResultList.selectedItems(): + packages.append(itm.text(0).strip()) + if packages: + self.__pip.installPackages(packages, venvName=venvName, + userSite=userSite) + + @pyqtSlot() + def on_showDetailsButton_clicked(self): + """ + Private slot to handle pressing the Show Details button. + """ + self.__showDetails() + + @pyqtSlot(QTreeWidgetItem, int) + def on_searchResultList_itemActivated(self, item, column): + """ + Private slot reacting on an search result item activation. + + @param item reference to the activated item + @type QTreeWidgetItem + @param column activated column + @type int + """ + self.__showDetails(item) + + def __showDetails(self, item=None): + """ + Private slot to show details about the selected package. + + @param item reference to the search result item to show details for + @type QTreeWidgetItem + """ + self.showDetailsButton.setEnabled(False) + QApplication.setOverrideCursor(Qt.WaitCursor) + QApplication.processEvents(QEventLoop.ExcludeUserInputEvents) + + self.__detailsData = {} + + if not item: + item = self.searchResultList.selectedItems()[0] + + packageVersions = item.data(0, self.SearchVersionRole) + if len(packageVersions) == 1: + packageVersion = packageVersions[0] + elif len(packageVersions) == 0: + packageVersion = "" + else: + packageVersion, ok = QInputDialog.getItem( + self, + self.tr("Show Package Details"), + self.tr("Select the package version:"), + packageVersions, + 0, False) + if not ok: + return + + packageName = item.text(0) + self.__client.call( + "release_data", + (packageName, packageVersion), + lambda d: self.__getPackageDownloadsData(packageName, + packageVersion, + d), + lambda c, s: self.__detailsError(packageName, c, s) + ) + + def __getPackageDownloadsData(self, packageName, packageVersion, data): + """ + Private method to store the details data and get downloads + information. + + @param packageName name of the package + @type str + @param packageVersion version info + @type str + @param data result data with package details in the first + element + @type tuple + """ + if data and data[0]: + self.__detailsData = data[0] + self.__client.call( + "release_urls", + (packageName, packageVersion), + self.__displayPackageDetails, + lambda c, s: self.__detailsError(packageName, c, s) + ) + else: + QApplication.restoreOverrideCursor() + E5MessageBox.warning( + self, + self.tr("Search PyPI"), + self.tr("""<p>No package details info for <b>{0}</b>""" + """ available.</p>""").format(packageName)) + + def __displayPackageDetails(self, data): + """ + Private method to display the returned package details. + + @param data result data with downloads information in the first element + @type tuple + """ + from .PipPackageDetailsDialog import PipPackageDetailsDialog + + QApplication.restoreOverrideCursor() + self.showDetailsButton.setEnabled(True) + + if self.__packageDetailsDialog is not None: + self.__packageDetailsDialog.close() + + self.__packageDetailsDialog = \ + PipPackageDetailsDialog(self.__detailsData, data[0], self) + self.__packageDetailsDialog.show() + + def __detailsError(self, packageName, errorCode, errorString): + """ + Private method handling a details error. + + @param packageName name of the package + @type str + @param errorCode code of the error + @type int + @param errorString error message + @type str + """ + QApplication.restoreOverrideCursor() + self.showDetailsButton.setEnabled(True) + E5MessageBox.warning( + self, + self.tr("Search PyPI"), + self.tr("""<p>Package details info for <b>{0}</b> could not be""" + """ retrieved.</p><p>Reason: {1}</p>""") + .format(packageName, errorString) + ) + ####################################################################### ## Menu related methods below ####################################################################### @@ -694,8 +866,229 @@ Private method to create the super menu and attach it to the super menu button. """ - self.__pip.initActions() - - self.__pipMenu = self.__pip.initMenu() + self.__pipMenu = QMenu() + self.__installPipAct = self.__pipMenu.addAction( + self.tr("Install Pip"), + self.__installPip) + self.__installPipUserAct = self.__pipMenu.addAction( + self.tr("Install Pip to User-Site"), + self.__installPipUser) + self.__repairPipAct = self.__pipMenu.addAction( + self.tr("Repair Pip"), + self.__repairPip) + self.__pipMenu.addSeparator() + self.__installPackagesAct = self.__pipMenu.addAction( + self.tr("Install Packages"), + self.__installPackages) + self.__installLocalPackageAct = self.__pipMenu.addAction( + self.tr("Install Local Package"), + self.__installLocalPackage) + self.__pipMenu.addSeparator() + self.__installRequirementsAct = self.__pipMenu.addAction( + self.tr("Install Requirements"), + self.__installRequirements) + self.__uninstallRequirementsAct = self.__pipMenu.addAction( + self.tr("Uninstall Requirements"), + self.__uninstallRequirements) + self.__generateRequirementsAct = self.__pipMenu.addAction( + self.tr("Generate Requirements..."), + self.__generateRequirements) + self.__pipMenu.addSeparator() + # editUserConfigAct + self.__pipMenu.addAction( + self.tr("Edit User Configuration..."), + self.__editUserConfiguration) + self.__editVirtualenvConfigAct = self.__pipMenu.addAction( + self.tr("Edit Current Virtualenv Configuration..."), + self.__editVirtualenvConfiguration) + self.__pipMenu.addSeparator() + # pipConfigAct + self.__pipMenu.addAction( + self.tr("Configure..."), + self.__pipConfigure) + + self.__pipMenu.aboutToShow.connect(self.__aboutToShowPipMenu) self.pipMenuButton.setMenu(self.__pipMenu) + + def __aboutToShowPipMenu(self): + """ + Private slot to set the action enabled status. + """ + enable = bool(self.environmentsComboBox.currentText()) + enablePip = self.__isPipAvailable() + + self.__installPipAct.setEnabled(not enablePip) + self.__installPipUserAct.setEnabled(not enablePip) + self.__repairPipAct.setEnabled(enablePip) + + self.__installPackagesAct.setEnabled(enablePip) + self.__installLocalPackageAct.setEnabled(enablePip) + + self.__installRequirementsAct.setEnabled(enablePip) + self.__uninstallRequirementsAct.setEnabled(enablePip) + self.__generateRequirementsAct.setEnabled(enablePip) + + self.__editVirtualenvConfigAct.setEnabled(enable) + + @pyqtSlot() + def __installPip(self): + """ + Private slot to install pip into the selected environment. + """ + venvName = self.environmentsComboBox.currentText() + if venvName: + self.__pip.installPip(venvName) + + @pyqtSlot() + def __installPipUser(self): + """ + Private slot to install pip into the user site for the selected + environment. + """ + venvName = self.environmentsComboBox.currentText() + if venvName: + self.__pip.installPip(venvName, userSite=True) + + @pyqtSlot() + def __repairPip(self): + """ + Private slot to repair the pip installation of the selected + environment. + """ + venvName = self.environmentsComboBox.currentText() + if venvName: + self.__pip.repairPip(venvName) + + @pyqtSlot() + def __installPackages(self): + """ + Private slot to install packages to be given by the user. + """ + venvName = self.environmentsComboBox.currentText() + if venvName: + from .PipPackagesInputDialog import PipPackagesInputDialog + dlg = PipPackagesInputDialog(self, self.tr("Install Packages")) + if dlg.exec_() == QDialog.Accepted: + packages, user = dlg.getData() + if packages: + self.__pip.installPackages(packages, venvName=venvName, + userSite=user) + + @pyqtSlot() + def __installLocalPackage(self): + """ + Private slot to install a package available on local storage. + """ + venvName = self.environmentsComboBox.currentText() + if venvName: + from .PipFileSelectionDialog import PipFileSelectionDialog + dlg = PipFileSelectionDialog(self, "package") + if dlg.exec_() == QDialog.Accepted: + package, user = dlg.getData() + if package and os.path.exists(package): + self.__pip.installPackages([package], venvName=venvName, + userSite=user) + + @pyqtSlot() + def __installRequirements(self): + """ + + """ + # TODO: call pip.installRequirements() + + @pyqtSlot() + def __uninstallRequirements(self): + """ + + """ + # TODO: call pip.uninstallRequirements() + + @pyqtSlot() + def __generateRequirements(self): + """ + Private slot to generate the contents for a requirements file. + """ + # TODO: modify to get selected environment + from .PipFreezeDialog import PipFreezeDialog + self.__freezeDialog = PipFreezeDialog(self) + self.__freezeDialog.show() + self.__freezeDialog.start() + + @pyqtSlot() + def __editUserConfiguration(self): + """ + Private slot to edit the user configuration. + """ + self.__editConfiguration() + + @pyqtSlot() + def __editVirtualenvConfiguration(self): + """ + Private slot to edit the current virtualenv configuration. + """ + # TODO: modify to get selected environment + 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 + """ + # TODO: modify to use venvName + from QScintilla.MiniEditor import MiniEditor + if virtualenv: + cfgFile = self.__getVirtualenvConfig() + if not cfgFile: + return + 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 __pipConfigure(self): + """ + Private slot to open the configuration page. + """ + e5App().getObject("UserInterface").showPreferences("pipPage")
--- a/PipInterface/PipSearchDialog.py Wed Feb 20 19:44:13 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,465 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> -# - -""" -Module implementing a dialog to search PyPI. -""" - -from __future__ import unicode_literals - -import textwrap - -from PyQt5.QtCore import pyqtSlot, Qt, QEventLoop, QRegExp -from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton, \ - QApplication, QTreeWidgetItem, QHeaderView, QInputDialog - -from E5Gui import E5MessageBox -try: - from E5Network.E5XmlRpcClient import E5XmlRpcClient -except ImportError: - from .E5XmlRpcClient import E5XmlRpcClient - -from .Ui_PipSearchDialog import Ui_PipSearchDialog - - -class PipSearchDialog(QDialog, Ui_PipSearchDialog): - """ - Class implementing a dialog to search PyPI. - """ - VersionRole = Qt.UserRole + 1 - - Stopwords = { - "a", "and", "are", "as", "at", "be", "but", "by", - "for", "if", "in", "into", "is", "it", - "no", "not", "of", "on", "or", "such", - "that", "the", "their", "then", "there", "these", - "they", "this", "to", "was", "will", - } - - def __init__(self, pip, indexUrl, parent=None): - """ - Constructor - - @param pip reference to the master object - @type Pip - @param indexUrl URL of XML RPC interface to the pypi index - @type str - @param parent reference to the parent widget - @type QWidget - """ - super(PipSearchDialog, self).__init__(parent) - self.setupUi(self) - self.setWindowFlags(Qt.Window) - - self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) - - self.__installButton = self.buttonBox.addButton( - self.tr("&Install"), QDialogButtonBox.ActionRole) - self.__installButton.setEnabled(False) - - self.__installUserButton = self.buttonBox.addButton( - self.tr("Install to &User-Site"), QDialogButtonBox.ActionRole) - self.__installUserButton.setEnabled(False) - - self.__showDetailsButton = self.buttonBox.addButton( - self.tr("&Show Details..."), QDialogButtonBox.ActionRole) - self.__showDetailsButton.setEnabled(False) - - self.__pip = pip - self.__client = E5XmlRpcClient(indexUrl, self) - - self.venvComboBox.addItem(self.__pip.getDefaultEnvironmentString()) - projectVenv = self.__pip.getProjectEnvironmentString() - if projectVenv: - self.venvComboBox.addItem(projectVenv) - self.venvComboBox.addItems(self.__pip.getVirtualenvNames()) - - self.searchEdit.setFocus(Qt.OtherFocusReason) - - self.__canceled = False - self.__detailsData = {} - self.__query = [] - - self.__packageDetailsDialog = None - - def closeEvent(self, e): - """ - Protected slot implementing a close event handler. - - @param e close event - @type QCloseEvent - """ - QApplication.restoreOverrideCursor() - - if self.__packageDetailsDialog is not None: - self.__packageDetailsDialog.close() - - e.accept() - - @pyqtSlot(str) - def on_searchEdit_textChanged(self, txt): - """ - Private slot handling a change of the search term. - - @param txt search term - @type str - """ - self.searchButton.setEnabled(bool(txt)) - - @pyqtSlot() - def on_searchButton_clicked(self): - """ - Private slot handling a press of the search button. - """ - self.__search() - - @pyqtSlot() - def on_resultList_itemSelectionChanged(self): - """ - Private slot handling changes of the selection. - """ - self.__installButton.setEnabled( - len(self.resultList.selectedItems()) > 0) - self.__installUserButton.setEnabled( - len(self.resultList.selectedItems()) > 0) - self.__showDetailsButton.setEnabled( - len(self.resultList.selectedItems()) == 1) - - @pyqtSlot(QAbstractButton) - def on_buttonBox_clicked(self, button): - """ - Private slot called by a button of the button box clicked. - - @param button button that was clicked - @type QAbstractButton - """ - if button == self.buttonBox.button(QDialogButtonBox.Close): - self.close() - elif button == self.buttonBox.button(QDialogButtonBox.Cancel): - self.__client.abort() - self.__canceled = True - elif button == self.__installButton: - self.__install() - elif button == self.__installUserButton: - self.__install(userSite=True) - elif button == self.__showDetailsButton: - self.__showDetails() - - def __search(self): - """ - Private method to perform the search. - """ - self.resultList.clear() - self.infoLabel.clear() - - self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) - self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) - self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) - self.searchButton.setEnabled(False) - QApplication.processEvents(QEventLoop.ExcludeUserInputEvents) - - QApplication.setOverrideCursor(Qt.WaitCursor) - QApplication.processEvents(QEventLoop.ExcludeUserInputEvents) - - self.__canceled = False - - self.__query = [term for term in self.searchEdit.text().strip().split() - if term not in PipSearchDialog.Stopwords] - self.__client.call( - "search", - ({"name": self.__query, "summary": self.__query}, "or"), - self.__processSearchResult, - self.__searchError - ) - - def __processSearchResult(self, data): - """ - Private method to process the search result data from PyPI. - - @param data result data with hits in the first element - @type tuple - """ - if data: - packages = self.__transformHits(data[0]) - if packages: - self.infoLabel.setText(self.tr("%n package(s) found.", "", - len(packages))) - wrapper = textwrap.TextWrapper(width=80) - count = 0 - total = 0 - for package in packages: - if self.__canceled: - self.infoLabel.setText( - self.tr("Canceled - only {0} out of %n package(s)" - " shown", "", len(packages)).format(total)) - break - itm = QTreeWidgetItem( - self.resultList, [ - package['name'].strip(), - "{0:4d}".format(package['score']), - "\n".join([ - wrapper.fill(line) for line in - package['summary'].strip().splitlines() - ]) - ]) - itm.setData(0, self.VersionRole, package['version']) - count += 1 - total += 1 - if count == 100: - count = 0 - QApplication.processEvents() - else: - QApplication.restoreOverrideCursor() - E5MessageBox.warning( - self, - self.tr("Search PyPI"), - self.tr("""<p>The package search did not return""" - """ anything.</p>""")) - self.infoLabel.setText( - self.tr("""<p>The package search did not return""" - """ anything.</p>""")) - else: - QApplication.restoreOverrideCursor() - E5MessageBox.warning( - self, - self.tr("Search PyPI"), - self.tr("""<p>The package search did not return anything.""" - """</p>""")) - self.infoLabel.setText( - self.tr("""<p>The package search did not return anything.""" - """</p>""")) - - header = self.resultList.header() - self.resultList.sortItems(1, Qt.DescendingOrder) - header.setStretchLastSection(False) - header.resizeSections(QHeaderView.ResizeToContents) - headerSize = 0 - for col in range(header.count()): - headerSize += header.sectionSize(col) - if headerSize < header.width(): - header.setStretchLastSection(True) - - self.__finish() - - def __finish(self): - """ - Private slot performing the finishing actions. - """ - QApplication.restoreOverrideCursor() - self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) - self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) - self.searchButton.setEnabled(True) - self.searchButton.setDefault(True) - self.searchEdit.setFocus(Qt.OtherFocusReason) - - def __searchError(self, errorCode, errorString): - """ - Private method handling a search error. - - @param errorCode code of the error - @type int - @param errorString error message - @type str - """ - self.__finish() - E5MessageBox.warning( - self, - self.tr("Search PyPI"), - self.tr("""<p>The package search failed.</p><p>Reason: {0}</p>""") - .format(errorString)) - self.infoLabel.setText(self.tr("Error: {0}").format(errorString)) - - def __transformHits(self, hits): - """ - Private method to convert the list returned from pypi into a - packages list. - - @param hits list returned from pypi - @type list of dict - @return list of packages - @rtype list of dict - """ - # we only include the record with the highest score - packages = {} - for hit in hits: - name = hit['name'].strip() - summary = (hit['summary'] or "").strip() - version = hit['version'].strip() - score = self.__score(name, summary) - # cleanup the summary - if summary in ["UNKNOWN", "."]: - summary = "" - - if name not in packages: - packages[name] = { - 'name': name, - 'summary': summary, - 'version': [version.strip()], - 'score': score} - else: - if score > packages[name]['score']: - packages[name]['score'] = score - packages[name]['summary'] = summary - packages[name]['version'].append(version.strip()) - - return list(packages.values()) - - def __score(self, name, summary): - """ - Private method to calculate some score for a search result. - - @param name name of the returned package - @type str - @param summary summary text for the package - @type str - @return score value - @rtype int - """ - score = 0 - for queryTerm in self.__query: - if queryTerm.lower() in name.lower(): - score += 4 - if queryTerm.lower() == name.lower(): - score += 4 - - if queryTerm.lower() in summary.lower(): - if QRegExp(r'\b{0}\b'.format(QRegExp.escape(queryTerm)), - Qt.CaseInsensitive).indexIn(summary) != -1: - # word match gets even higher score - score += 2 - else: - score += 1 - - return score - - def __install(self, userSite=False): - """ - Private slot to install the selected packages. - - @param userSite flag indicating to install to the user directory - @type bool - """ - venvName = self.venvComboBox.currentText() - - packages = [] - for itm in self.resultList.selectedItems(): - packages.append(itm.text(0).strip()) - if packages: - self.__pip.installPackages(packages, venvName=venvName, - userSite=userSite) - - def __showDetails(self): - """ - Private slot to show details about the selected package. - """ - self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) - self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) - self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) - self.__showDetailsButton.setEnabled(False) - QApplication.setOverrideCursor(Qt.WaitCursor) - QApplication.processEvents(QEventLoop.ExcludeUserInputEvents) - - self.__detailsData = {} - - itm = self.resultList.selectedItems()[0] - packageVersions = itm.data(0, self.VersionRole) - if len(packageVersions) == 1: - packageVersion = packageVersions[0] - elif len(packageVersions) == 0: - packageVersion = "" - else: - packageVersion, ok = QInputDialog.getItem( - self, - self.tr("Show Package Details"), - self.tr("Select the package version:"), - packageVersions, - 0, False) - if not ok: - return - - packageName = itm.text(0) - self.__client.call( - "release_data", - (packageName, packageVersion), - lambda d: self.__getPackageDownloadsData(packageVersion, d), - self.__detailsError - ) - - def __getPackageDownloadsData(self, packageVersion, data): - """ - Private method to store the details data and get downloads - information. - - @param packageVersion version info - @type str - @param data result data with package details in the first - element - @type tuple - """ - if data and data[0]: - self.__detailsData = data[0] - itm = self.resultList.selectedItems()[0] - packageName = itm.text(0) - self.__client.call( - "release_urls", - (packageName, packageVersion), - self.__displayPackageDetails, - self.__detailsError - ) - else: - self.__finish() - E5MessageBox.warning( - self, - self.tr("Search PyPI"), - self.tr("""<p>No package details info available.</p>""")) - - def __displayPackageDetails(self, data): - """ - Private method to display the returned package details. - - @param data result data with downloads information in the first element - @type tuple - """ - from .PipPackageDetailsDialog import PipPackageDetailsDialog - - self.__finish() - self.__showDetailsButton.setEnabled(True) - - if self.__packageDetailsDialog is not None: - self.__packageDetailsDialog.close() - - self.__packageDetailsDialog = \ - PipPackageDetailsDialog(self.__detailsData, data[0], self) - self.__packageDetailsDialog.show() - - def __detailsError(self, errorCode, errorString): - """ - Private method handling a details error. - - @param errorCode code of the error - @type int - @param errorString error message - @type str - """ - self.__finish() - self.__showDetailsButton.setEnabled(True) - E5MessageBox.warning( - self, - self.tr("Search PyPI"), - self.tr("""<p>Package details info could not be retrieved.</p>""" - """<p>Reason: {0}</p>""") - .format(errorString)) - - @pyqtSlot(QTreeWidgetItem, int) - def on_resultList_itemActivated(self, item, column): - """ - Private slot reacting on an item activation. - - @param item reference to the activated item - @type QTreeWidgetItem - @param column activated column - @type int - """ - self.__showDetails()
--- a/PipInterface/PipSearchDialog.ui Wed Feb 20 19:44:13 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,138 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>PipSearchDialog</class> - <widget class="QDialog" name="PipSearchDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>700</width> - <height>600</height> - </rect> - </property> - <property name="windowTitle"> - <string>Search PyPI</string> - </property> - <property name="sizeGripEnabled"> - <bool>true</bool> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>Virtual Environment:</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="venvComboBox"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Select the virtual environment to be used</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Query:</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="searchEdit"> - <property name="toolTip"> - <string>Enter the search term</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="searchButton"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="toolTip"> - <string>Press to start the search</string> - </property> - <property name="text"> - <string>Search</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QTreeWidget" name="resultList"> - <property name="alternatingRowColors"> - <bool>true</bool> - </property> - <property name="selectionMode"> - <enum>QAbstractItemView::ExtendedSelection</enum> - </property> - <property name="rootIsDecorated"> - <bool>false</bool> - </property> - <property name="itemsExpandable"> - <bool>false</bool> - </property> - <property name="sortingEnabled"> - <bool>true</bool> - </property> - <property name="allColumnsShowFocus"> - <bool>true</bool> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - <column> - <property name="text"> - <string>Package</string> - </property> - </column> - <column> - <property name="text"> - <string>Score</string> - </property> - </column> - <column> - <property name="text"> - <string>Description</string> - </property> - </column> - </widget> - </item> - <item> - <widget class="QLabel" name="infoLabel"/> - </item> - <item> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Close</set> - </property> - </widget> - </item> - </layout> - </widget> - <tabstops> - <tabstop>venvComboBox</tabstop> - <tabstop>searchEdit</tabstop> - <tabstop>searchButton</tabstop> - <tabstop>resultList</tabstop> - </tabstops> - <resources/> - <connections/> -</ui>
--- a/PipInterface/PipSelectionDialog.py Wed Feb 20 19:44:13 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2018 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> -# - -""" -Module implementing a dialog to select the pip executable to be used. -""" - -from __future__ import unicode_literals - -from PyQt5.QtWidgets import QDialog - -from .Ui_PipSelectionDialog import Ui_PipSelectionDialog - - -class PipSelectionDialog(QDialog, Ui_PipSelectionDialog): - """ - Class implementing a dialog to select the pip executable to be used. - """ - def __init__(self, pip, parent=None): - """ - Constructor - - @param pip reference to the pip object - @type Pip - @param parent reference to the parent widget - @type QWidget - """ - super(PipSelectionDialog, self).__init__(parent) - self.setupUi(self) - - self.venvComboBox.addItem(pip.getDefaultEnvironmentString()) - projectVenv = pip.getProjectEnvironmentString() - if projectVenv: - self.venvComboBox.addItem(projectVenv) - self.venvComboBox.addItems(pip.getVirtualenvNames()) - - msh = self.minimumSizeHint() - self.resize(max(self.width(), msh.width()), msh.height()) - - def getData(self): - """ - Public method to get the entered data. - - @return tuple with the environment name and a flag indicating to - install to the user install directory - @rtype tuple of (str, bool) - """ - return ( - self.venvComboBox.currentText(), - self.userCheckBox.isChecked(), - )
--- a/PipInterface/PipSelectionDialog.ui Wed Feb 20 19:44:13 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>PipSelectionDialog</class> - <widget class="QDialog" name="PipSelectionDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>600</width> - <height>130</height> - </rect> - </property> - <property name="windowTitle"> - <string>Select Virtual Environment</string> - </property> - <property name="sizeGripEnabled"> - <bool>true</bool> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Virtual Environment:</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="venvComboBox"> - <property name="toolTip"> - <string>Select the virtual environment to be used</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="userCheckBox"> - <property name="toolTip"> - <string>Select to install to the Python user install directory</string> - </property> - <property name="text"> - <string>Install into User Directory</string> - </property> - </widget> - </item> - <item> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> - </property> - </widget> - </item> - </layout> - </widget> - <resources/> - <connections> - <connection> - <sender>buttonBox</sender> - <signal>accepted()</signal> - <receiver>PipSelectionDialog</receiver> - <slot>accept()</slot> - <hints> - <hint type="sourcelabel"> - <x>248</x> - <y>254</y> - </hint> - <hint type="destinationlabel"> - <x>157</x> - <y>274</y> - </hint> - </hints> - </connection> - <connection> - <sender>buttonBox</sender> - <signal>rejected()</signal> - <receiver>PipSelectionDialog</receiver> - <slot>reject()</slot> - <hints> - <hint type="sourcelabel"> - <x>316</x> - <y>260</y> - </hint> - <hint type="destinationlabel"> - <x>286</x> - <y>274</y> - </hint> - </hints> - </connection> - </connections> -</ui>
--- a/eric6.e4p Wed Feb 20 19:44:13 2019 +0100 +++ b/eric6.e4p Thu Feb 21 19:55:35 2019 +0100 @@ -478,8 +478,6 @@ <Source>PipInterface/PipPackageDetailsDialog.py</Source> <Source>PipInterface/PipPackagesInputDialog.py</Source> <Source>PipInterface/PipPackagesWidget.py</Source> - <Source>PipInterface/PipSearchDialog.py</Source> - <Source>PipInterface/PipSelectionDialog.py</Source> <Source>PipInterface/__init__.py</Source> <Source>PluginManager/PluginDetailsDialog.py</Source> <Source>PluginManager/PluginExceptions.py</Source> @@ -1830,8 +1828,6 @@ <Form>PipInterface/PipPackageDetailsDialog.ui</Form> <Form>PipInterface/PipPackagesInputDialog.ui</Form> <Form>PipInterface/PipPackagesWidget.ui</Form> - <Form>PipInterface/PipSearchDialog.ui</Form> - <Form>PipInterface/PipSelectionDialog.ui</Form> <Form>PluginManager/PluginDetailsDialog.ui</Form> <Form>PluginManager/PluginInfoDialog.ui</Form> <Form>PluginManager/PluginInstallDialog.ui</Form>