484 @type bool |
487 @type bool |
485 """ |
488 """ |
486 self.searchWidget.setVisible(checked) |
489 self.searchWidget.setVisible(checked) |
487 |
490 |
488 if checked: |
491 if checked: |
489 self.searchEdit.setFocus(Qt.OtherFocusReason) |
492 self.searchEditName.setFocus(Qt.OtherFocusReason) |
490 self.searchEdit.selectAll() |
493 self.searchEditName.selectAll() |
491 |
494 |
492 self.__updateSearchActionButtons() |
495 self.__updateSearchActionButtons() |
493 self.__updateSearchButton() |
496 self.__updateSearchButton() |
494 |
497 |
495 @pyqtSlot(str) |
498 @pyqtSlot(str) |
496 def on_searchEdit_textChanged(self, txt): |
499 def on_searchEditName_textChanged(self, txt): |
497 """ |
500 """ |
498 Private slot handling a change of the search term. |
501 Private slot handling a change of the search term. |
499 |
502 |
500 @param txt search term |
503 @param txt search term |
501 @type str |
504 @type str |
502 """ |
505 """ |
503 self.__updateSearchButton() |
506 self.__updateSearchButton() |
504 |
507 |
505 @pyqtSlot() |
508 @pyqtSlot() |
506 def on_searchEdit_returnPressed(self): |
509 def on_searchEditName_returnPressed(self): |
|
510 """ |
|
511 Private slot initiating a search via a press of the Return key. |
|
512 """ |
|
513 self.__search() |
|
514 |
|
515 @pyqtSlot(str) |
|
516 def on_searchEditSummary_textChanged(self, txt): |
|
517 """ |
|
518 Private slot handling a change of the search term. |
|
519 |
|
520 @param txt search term |
|
521 @type str |
|
522 """ |
|
523 self.__updateSearchButton() |
|
524 |
|
525 @pyqtSlot() |
|
526 def on_searchEditSummary_returnPressed(self): |
507 """ |
527 """ |
508 Private slot initiating a search via a press of the Return key. |
528 Private slot initiating a search via a press of the Return key. |
509 """ |
529 """ |
510 self.__search() |
530 self.__search() |
511 |
531 |
532 |
552 |
533 self.searchButton.setEnabled(False) |
553 self.searchButton.setEnabled(False) |
534 QApplication.setOverrideCursor(Qt.WaitCursor) |
554 QApplication.setOverrideCursor(Qt.WaitCursor) |
535 QApplication.processEvents(QEventLoop.ExcludeUserInputEvents) |
555 QApplication.processEvents(QEventLoop.ExcludeUserInputEvents) |
536 |
556 |
537 self.__query = [term for term in self.searchEdit.text().strip().split() |
557 self.__queryName = [ |
538 if term not in self.SearchStopwords] |
558 term for term in self.searchEditName.text().strip().split() |
|
559 if term not in self.SearchStopwords |
|
560 ] |
|
561 self.__querySummary = [ |
|
562 term for term in self.searchEditSummary.text().strip().split() |
|
563 if term not in self.SearchStopwords |
|
564 ] |
539 self.__client.call( |
565 self.__client.call( |
540 "search", |
566 "search", |
541 ({"name": self.__query, "summary": self.__query}, "or"), |
567 ({"name": self.__queryName, |
|
568 "summary": self.__querySummary}, |
|
569 self.searchTermCombineComboBox.currentText()), |
542 self.__processSearchResult, |
570 self.__processSearchResult, |
543 self.__searchError |
571 self.__searchError |
544 ) |
572 ) |
545 |
573 |
546 def __processSearchResult(self, data): |
574 def __processSearchResult(self, data): |
680 @type str |
708 @type str |
681 @return score value |
709 @return score value |
682 @rtype int |
710 @rtype int |
683 """ |
711 """ |
684 score = 0 |
712 score = 0 |
685 for queryTerm in self.__query: |
713 for queryTerm in self.__queryName: |
686 if queryTerm.lower() in name.lower(): |
714 if queryTerm.lower() in name.lower(): |
687 score += 4 |
715 score += 4 |
688 if queryTerm.lower() == name.lower(): |
716 if queryTerm.lower() == name.lower(): |
689 score += 4 |
717 score += 4 |
690 |
718 |
|
719 for queryTerm in self.__querySummary: |
691 if queryTerm.lower() in summary.lower(): |
720 if queryTerm.lower() in summary.lower(): |
692 if QRegExp(r'\b{0}\b'.format(QRegExp.escape(queryTerm)), |
721 if QRegExp(r'\b{0}\b'.format(QRegExp.escape(queryTerm)), |
693 Qt.CaseInsensitive).indexIn(summary) != -1: |
722 Qt.CaseInsensitive).indexIn(summary) != -1: |
694 # word match gets even higher score |
723 # word match gets even higher score |
695 score += 2 |
724 score += 2 |
775 self.tr("Select the package version:"), |
802 self.tr("Select the package version:"), |
776 packageVersions, |
803 packageVersions, |
777 0, False) |
804 0, False) |
778 if not ok: |
805 if not ok: |
779 return |
806 return |
780 |
|
781 packageName = item.text(0) |
807 packageName = item.text(0) |
782 self.__client.call( |
808 packageData = self.__pip.getPackageDetails(packageName, packageVersion) |
783 "release_data", |
809 |
784 (packageName, packageVersion), |
810 QApplication.restoreOverrideCursor() |
785 lambda d: self.__getPackageDownloadsData(packageName, |
811 if packageData: |
786 packageVersion, |
812 from .PipPackageDetailsDialog import PipPackageDetailsDialog |
787 d), |
813 |
788 lambda c, s: self.__detailsError(packageName, c, s) |
814 self.showDetailsButton.setEnabled(True) |
789 ) |
815 |
790 |
816 if self.__packageDetailsDialog is not None: |
791 def __getPackageDownloadsData(self, packageName, packageVersion, data): |
817 self.__packageDetailsDialog.close() |
792 """ |
818 |
793 Private method to store the details data and get downloads |
819 self.__packageDetailsDialog = \ |
794 information. |
820 PipPackageDetailsDialog(packageData, self) |
795 |
821 self.__packageDetailsDialog.show() |
796 @param packageName name of the package |
|
797 @type str |
|
798 @param packageVersion version info |
|
799 @type str |
|
800 @param data result data with package details in the first |
|
801 element |
|
802 @type tuple |
|
803 """ |
|
804 if data and data[0]: |
|
805 self.__detailsData = data[0] |
|
806 self.__client.call( |
|
807 "release_urls", |
|
808 (packageName, packageVersion), |
|
809 self.__displayPackageDetails, |
|
810 lambda c, s: self.__detailsError(packageName, c, s) |
|
811 ) |
|
812 else: |
822 else: |
813 QApplication.restoreOverrideCursor() |
|
814 E5MessageBox.warning( |
823 E5MessageBox.warning( |
815 self, |
824 self, |
816 self.tr("Search PyPI"), |
825 self.tr("Search PyPI"), |
817 self.tr("""<p>No package details info for <b>{0}</b>""" |
826 self.tr("""<p>No package details info for <b>{0}</b>""" |
818 """ available.</p>""").format(packageName)) |
827 """ available.</p>""").format(packageName)) |
819 |
|
820 def __displayPackageDetails(self, data): |
|
821 """ |
|
822 Private method to display the returned package details. |
|
823 |
|
824 @param data result data with downloads information in the first element |
|
825 @type tuple |
|
826 """ |
|
827 from .PipPackageDetailsDialog import PipPackageDetailsDialog |
|
828 |
|
829 QApplication.restoreOverrideCursor() |
|
830 self.showDetailsButton.setEnabled(True) |
|
831 |
|
832 if self.__packageDetailsDialog is not None: |
|
833 self.__packageDetailsDialog.close() |
|
834 |
|
835 self.__packageDetailsDialog = \ |
|
836 PipPackageDetailsDialog(self.__detailsData, data[0], self) |
|
837 self.__packageDetailsDialog.show() |
|
838 |
|
839 def __detailsError(self, packageName, errorCode, errorString): |
|
840 """ |
|
841 Private method handling a details error. |
|
842 |
|
843 @param packageName name of the package |
|
844 @type str |
|
845 @param errorCode code of the error |
|
846 @type int |
|
847 @param errorString error message |
|
848 @type str |
|
849 """ |
|
850 QApplication.restoreOverrideCursor() |
|
851 self.showDetailsButton.setEnabled(True) |
|
852 E5MessageBox.warning( |
|
853 self, |
|
854 self.tr("Search PyPI"), |
|
855 self.tr("""<p>Package details info for <b>{0}</b> could not be""" |
|
856 """ retrieved.</p><p>Reason: {1}</p>""") |
|
857 .format(packageName, errorString) |
|
858 ) |
|
859 |
828 |
860 ####################################################################### |
829 ####################################################################### |
861 ## Menu related methods below |
830 ## Menu related methods below |
862 ####################################################################### |
831 ####################################################################### |
863 |
832 |
991 userSite=user) |
960 userSite=user) |
992 |
961 |
993 @pyqtSlot() |
962 @pyqtSlot() |
994 def __installRequirements(self): |
963 def __installRequirements(self): |
995 """ |
964 """ |
996 |
965 Private slot to install packages as given in a requirements file. |
997 """ |
966 """ |
998 # TODO: call pip.installRequirements() |
967 venvName = self.environmentsComboBox.currentText() |
|
968 if venvName: |
|
969 self.__pip.installRequirements(venvName) |
999 |
970 |
1000 @pyqtSlot() |
971 @pyqtSlot() |
1001 def __uninstallRequirements(self): |
972 def __uninstallRequirements(self): |
1002 """ |
973 """ |
1003 |
974 Private slot to uninstall packages as given in a requirements file. |
1004 """ |
975 """ |
1005 # TODO: call pip.uninstallRequirements() |
976 venvName = self.environmentsComboBox.currentText() |
|
977 if venvName: |
|
978 self.__pip.uninstallRequirements(venvName) |
1006 |
979 |
1007 @pyqtSlot() |
980 @pyqtSlot() |
1008 def __generateRequirements(self): |
981 def __generateRequirements(self): |
1009 """ |
982 """ |
1010 Private slot to generate the contents for a requirements file. |
983 Private slot to generate the contents for a requirements file. |
1011 """ |
984 """ |
1012 # TODO: modify to get selected environment |
985 venvName = self.environmentsComboBox.currentText() |
1013 from .PipFreezeDialog import PipFreezeDialog |
986 if venvName: |
1014 self.__freezeDialog = PipFreezeDialog(self) |
987 from .PipFreezeDialog import PipFreezeDialog |
1015 self.__freezeDialog.show() |
988 self.__freezeDialog = PipFreezeDialog(self.__pip, self) |
1016 self.__freezeDialog.start() |
989 self.__freezeDialog.show() |
|
990 self.__freezeDialog.start(venvName) |
1017 |
991 |
1018 @pyqtSlot() |
992 @pyqtSlot() |
1019 def __editUserConfiguration(self): |
993 def __editUserConfiguration(self): |
1020 """ |
994 """ |
1021 Private slot to edit the user configuration. |
995 Private slot to edit the user configuration. |
1023 self.__editConfiguration() |
997 self.__editConfiguration() |
1024 |
998 |
1025 @pyqtSlot() |
999 @pyqtSlot() |
1026 def __editVirtualenvConfiguration(self): |
1000 def __editVirtualenvConfiguration(self): |
1027 """ |
1001 """ |
1028 Private slot to edit the current virtualenv configuration. |
1002 Private slot to edit the configuration of the selected environment. |
1029 """ |
1003 """ |
1030 # TODO: modify to get selected environment |
1004 venvName = self.environmentsComboBox.currentText() |
1031 self.__editConfiguration(virtualenv=True) |
1005 if venvName: |
1032 |
1006 self.__editConfiguration(venvName=venvName) |
1033 def __editConfiguration(self, virtualenv=False): |
1007 |
|
1008 def __editConfiguration(self, venvName=""): |
1034 """ |
1009 """ |
1035 Private method to edit a configuration. |
1010 Private method to edit a configuration. |
1036 |
1011 |
1037 @param virtualenv flag indicating to edit the current virtualenv |
1012 @param venvName name of the environment to act upon |
1038 configuration file |
1013 @type str |
1039 @type bool |
1014 """ |
1040 """ |
|
1041 # TODO: modify to use venvName |
|
1042 from QScintilla.MiniEditor import MiniEditor |
1015 from QScintilla.MiniEditor import MiniEditor |
1043 if virtualenv: |
1016 if venvName: |
1044 cfgFile = self.__getVirtualenvConfig() |
1017 cfgFile = self.__pip.getVirtualenvConfig(venvName) |
1045 if not cfgFile: |
1018 if not cfgFile: |
1046 return |
1019 return |
1047 else: |
1020 else: |
1048 cfgFile = self.__getUserConfig() |
1021 cfgFile = self.__pip.getUserConfig() |
1049 cfgDir = os.path.dirname(cfgFile) |
1022 cfgDir = os.path.dirname(cfgFile) |
1050 if not cfgDir: |
1023 if not cfgDir: |
1051 E5MessageBox.critical( |
1024 E5MessageBox.critical( |
1052 None, |
1025 None, |
1053 self.tr("Edit Configuration"), |
1026 self.tr("Edit Configuration"), |
1054 self.tr("""No valid configuration path determined.""" |
1027 self.tr("""No valid configuration path determined.""" |
1055 """ Is a virtual environment selected? Aborting""")) |
1028 """ Aborting""")) |
1056 return |
1029 return |
1057 |
1030 |
1058 try: |
1031 try: |
1059 if not os.path.isdir(cfgDir): |
1032 if not os.path.isdir(cfgDir): |
1060 os.makedirs(cfgDir) |
1033 os.makedirs(cfgDir) |
1061 except OSError: |
1034 except OSError: |
1062 E5MessageBox.critical( |
1035 E5MessageBox.critical( |
1063 None, |
1036 None, |
1064 self.tr("Edit Configuration"), |
1037 self.tr("Edit Configuration"), |
1065 self.tr("""No valid configuration path determined.""" |
1038 self.tr("""No valid configuration path determined.""" |
1066 """ Is a virtual environment selected? Aborting""")) |
1039 """ Aborting""")) |
1067 return |
1040 return |
1068 |
1041 |
1069 if not os.path.exists(cfgFile): |
1042 if not os.path.exists(cfgFile): |
1070 try: |
1043 try: |
1071 f = open(cfgFile, "w") |
1044 f = open(cfgFile, "w") |