--- a/src/eric7/PipInterface/PipPackageDetailsDialog.py Wed Jul 13 11:16:20 2022 +0200 +++ b/src/eric7/PipInterface/PipPackageDetailsDialog.py Wed Jul 13 14:55:47 2022 +0200 @@ -9,8 +9,12 @@ from PyQt6.QtCore import pyqtSlot, Qt, QLocale from PyQt6.QtWidgets import ( - QDialog, QDialogButtonBox, QTreeWidgetItem, QLabel, QHeaderView, - QAbstractButton + QDialog, + QDialogButtonBox, + QTreeWidgetItem, + QLabel, + QHeaderView, + QAbstractButton, ) from .Ui_PipPackageDetailsDialog import Ui_PipPackageDetailsDialog @@ -20,14 +24,15 @@ """ Class implementing a dialog to show details about a package. """ + ButtonInstall = 1 ButtonRemove = 2 ButtonUpgrade = 4 - + def __init__(self, detailsData, buttonsMode=0, parent=None): """ Constructor - + @param detailsData package details @type dict @param buttonsMode flags telling which convenience buttons to enable @@ -39,16 +44,19 @@ super().__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.WindowType.Window) - + self.__pipWidget = parent - + self.__installButton = self.buttonBox.addButton( - self.tr("Install"), QDialogButtonBox.ButtonRole.ActionRole) + self.tr("Install"), QDialogButtonBox.ButtonRole.ActionRole + ) self.__removeButton = self.buttonBox.addButton( - self.tr("Uninstall"), QDialogButtonBox.ButtonRole.ActionRole) + self.tr("Uninstall"), QDialogButtonBox.ButtonRole.ActionRole + ) self.__upgradeButton = self.buttonBox.addButton( - self.tr("Upgrade"), QDialogButtonBox.ButtonRole.ActionRole) - + self.tr("Upgrade"), QDialogButtonBox.ButtonRole.ActionRole + ) + self.__locale = QLocale() self.__packageTypeMap = { "sdist": self.tr("Source"), @@ -61,59 +69,69 @@ "bdist_dumb": self.tr("Archive"), } self.__packageName = detailsData["info"]["name"] - + self.__populateDetails(detailsData["info"]) self.__populateDownloadUrls(detailsData["urls"]) self.__populateRequiresProvides(detailsData["info"]) - + self.__installButton.setEnabled(buttonsMode & self.ButtonInstall) self.__removeButton.setEnabled(buttonsMode & self.ButtonRemove) self.__upgradeButton.setEnabled(buttonsMode & self.ButtonUpgrade) - + def __populateDetails(self, detailsData): """ Private method to populate the details tab. - + @param detailsData package details @type dict """ self.packageNameLabel.setText( - "<h1>{0} {1}</h1".format(self.__sanitize(detailsData["name"]), - self.__sanitize(detailsData["version"]))) - self.summaryLabel.setText( - self.__sanitize(detailsData["summary"][:240])) - self.descriptionEdit.setPlainText( - self.__sanitize(detailsData["description"])) + "<h1>{0} {1}</h1".format( + self.__sanitize(detailsData["name"]), + self.__sanitize(detailsData["version"]), + ) + ) + self.summaryLabel.setText(self.__sanitize(detailsData["summary"][:240])) + self.descriptionEdit.setPlainText(self.__sanitize(detailsData["description"])) self.authorLabel.setText(self.__sanitize(detailsData["author"])) self.authorEmailLabel.setText( '<a href="mailto:{0}">{0}</a>'.format( - self.__sanitize(detailsData["author_email"]))) + self.__sanitize(detailsData["author_email"]) + ) + ) self.licenseLabel.setText(self.__sanitize(detailsData["license"])) self.platformLabel.setText(self.__sanitize(detailsData["platform"])) self.homePageLabel.setText( '<a href="{0}">{0}</a>'.format( - self.__sanitize(detailsData["home_page"], forUrl=True))) + self.__sanitize(detailsData["home_page"], forUrl=True) + ) + ) self.packageUrlLabel.setText( '<a href="{0}">{0}</a>'.format( - self.__sanitize(detailsData["package_url"], forUrl=True))) + self.__sanitize(detailsData["package_url"], forUrl=True) + ) + ) self.releaseUrlLabel.setText( '<a href="{0}">{0}</a>'.format( - self.__sanitize(detailsData["release_url"], forUrl=True))) + self.__sanitize(detailsData["release_url"], forUrl=True) + ) + ) self.docsUrlLabel.setText( '<a href="{0}">{0}</a>'.format( - self.__sanitize(detailsData["docs_url"], forUrl=True))) + self.__sanitize(detailsData["docs_url"], forUrl=True) + ) + ) self.classifiersList.addItems(detailsData["classifiers"]) - - self.buttonBox.button( - QDialogButtonBox.StandardButton.Close).setDefault(True) - self.buttonBox.button( - QDialogButtonBox.StandardButton.Close).setFocus( - Qt.FocusReason.OtherFocusReason) - + + self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setDefault(True) + self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setFocus( + Qt.FocusReason.OtherFocusReason + ) + def __populateDownloadUrls(self, downloadsData): """ Private method to populate the download URLs tab. - + @param downloadsData downloads information @type dict """ @@ -121,65 +139,72 @@ if downloadsData: self.infoWidget.setTabEnabled(index, True) for download in downloadsData: - itm = QTreeWidgetItem(self.downloadUrlsList, [ - "", - self.__packageTypeMap[download["packagetype"]] - if download["packagetype"] in self.__packageTypeMap - else "", - download["python_version"] - if download["python_version"] != "source" - else "", - self.__formatUploadDate(download["upload_time"]), - self.__formatSize(download["size"]), - ]) + itm = QTreeWidgetItem( + self.downloadUrlsList, + [ + "", + self.__packageTypeMap[download["packagetype"]] + if download["packagetype"] in self.__packageTypeMap + else "", + download["python_version"] + if download["python_version"] != "source" + else "", + self.__formatUploadDate(download["upload_time"]), + self.__formatSize(download["size"]), + ], + ) pgpLink = ( ' (<a href="{0}">pgp</a>)'.format(download["url"] + ".asc") - if download["has_sig"] else - "" + if download["has_sig"] + else "" ) - urlLabel = QLabel('<a href="{0}#md5={2}">{1}</a>{3}'.format( - download["url"], download["filename"], - download["md5_digest"], pgpLink)) + urlLabel = QLabel( + '<a href="{0}#md5={2}">{1}</a>{3}'.format( + download["url"], + download["filename"], + download["md5_digest"], + pgpLink, + ) + ) urlLabel.setTextInteractionFlags( - Qt.TextInteractionFlag.LinksAccessibleByMouse) + Qt.TextInteractionFlag.LinksAccessibleByMouse + ) urlLabel.setOpenExternalLinks(True) self.downloadUrlsList.setItemWidget(itm, 0, urlLabel) header = self.downloadUrlsList.header() header.resizeSections(QHeaderView.ResizeMode.ResizeToContents) else: self.infoWidget.setTabEnabled(index, False) - + def __populateRequiresProvides(self, detailsData): """ Private method to populate the requires/provides tab. - + @param detailsData package details @type dict """ populatedItems = 0 - + if "requires" in detailsData and detailsData["requires"]: self.requiredPackagesList.addItems(detailsData["requires"]) populatedItems += len(detailsData["requires"]) if "requires_dist" in detailsData and detailsData["requires_dist"]: - self.requiredDistributionsList.addItems( - detailsData["requires_dist"]) + self.requiredDistributionsList.addItems(detailsData["requires_dist"]) populatedItems += len(detailsData["requires_dist"]) if "provides" in detailsData and detailsData["provides"]: self.providedPackagesList.addItems(detailsData["provides"]) populatedItems += len(detailsData["provides"]) if "provides_dist" in detailsData and detailsData["provides_dist"]: - self.providedDistributionsList.addItems( - detailsData["provides_dist"]) + self.providedDistributionsList.addItems(detailsData["provides_dist"]) populatedItems += len(detailsData["provides_dist"]) - + index = self.infoWidget.indexOf(self.requires) self.infoWidget.setTabEnabled(index, populatedItems > 0) - + def __sanitize(self, text, forUrl=False): """ Private method to clean-up the given text. - + @param text raw text @type str @param forUrl flag indicating to sanitize an URL text @@ -192,18 +217,18 @@ elif text == "any": text = self.tr("any") if forUrl and ( - not isinstance(text, str) or - not text.startswith(("http://", "https://", "ftp://")) + not isinstance(text, str) + or not text.startswith(("http://", "https://", "ftp://")) ): # ignore if the schema is not one of the listed ones text = "" - + return text - + def __formatUploadDate(self, datetime): """ Private method to format the upload date. - + @param datetime upload date and time @type xmlrpc.DateTime or str @return formatted date string @@ -214,11 +239,11 @@ else: date = datetime.value.split("T")[0] return "{0}-{1}-{2}".format(date[:4], date[4:6], date[6:]) - + def __formatSize(self, size): """ Private slot to format the size. - + @param size size to be formatted @type int @return formatted size @@ -237,12 +262,12 @@ size /= 1024 * 1024 * 1024 unit = self.tr("GB") return self.tr("{0:.1f} {1}", "value, unit").format(size, unit) - + @pyqtSlot(QAbstractButton) def on_buttonBox_clicked(self, button): """ Private slot handling the user pressing an action button. - + @param button button activated by the user @type QAbstractButton """