--- a/eric7/UI/UserInterface.py Sun Mar 06 19:53:19 2022 +0100 +++ b/eric7/UI/UserInterface.py Mon Mar 07 19:18:46 2022 +0100 @@ -30,9 +30,7 @@ QApplication, QMenu, QVBoxLayout, QDockWidget, QLabel ) from PyQt6.Qsci import QSCINTILLA_VERSION_STR -from PyQt6.QtNetwork import ( - QNetworkProxyFactory, QNetworkAccessManager, QNetworkRequest, QNetworkReply -) +from PyQt6.QtNetwork import QNetworkProxyFactory, QNetworkAccessManager from .Info import Version, VersionOnly, BugAddress, Program, FeatureAddress from . import Config @@ -45,7 +43,6 @@ from EricWidgets.EricApplication import ericApp from EricWidgets.EricMainWindow import EricMainWindow from EricWidgets.EricZoomWidget import EricZoomWidget -from EricWidgets.EricProgressDialog import EricProgressDialog from EricWidgets.EricClickableLabel import EricClickableLabel import Preferences @@ -631,11 +628,6 @@ ericApp().registerObject("PluginRepositoryViewer", self.pluginRepositoryViewer) - # list of web addresses serving the versions file - self.__httpAlternatives = Preferences.getUI("VersionsUrls7") - self.__inVersionCheck = False - self.__versionCheckProgress = None - # create the various JSON file interfaces self.__sessionFile = SessionFile(True) self.__tasksFile = TasksFile(True) @@ -6618,8 +6610,7 @@ else: self.__setWindowCaption(editor="") - self.__httpAlternatives = Preferences.getUI("VersionsUrls7") - self.performVersionCheck(False) + self.performVersionCheck() from QScintilla.SpellChecker import SpellChecker SpellChecker.setDefaultLanguage( @@ -7557,296 +7548,55 @@ @type bool """ if online: - self.performVersionCheck(False) + self.performVersionCheck() ############################################## ## Below are methods to check for new versions ############################################## - # TODO: change performVersionCheck to check against PyPI and do that - # only for the automatic check - @pyqtSlot() - def performVersionCheck(self, manual=True, alternative=0, - showVersions=False): - """ - Public method to check the internet for an eric update. - - @param manual flag indicating an invocation via the menu (boolean) - @param alternative index of server to download from (integer) - @param showVersions flag indicating the show versions mode (boolean) + def performVersionCheck(self): + """ + Public method to check for an update even if not installed via PyPI. """ if self.isOnline(): - if not manual: - if VersionOnly.startswith("@@"): - return - else: - period = Preferences.getUI("PerformVersionCheck") - if period == 0: - return - elif period in [2, 3, 4]: - lastCheck = Preferences.getSettings().value( - "Updates/LastCheckDate", QDate(1970, 1, 1)) - if lastCheck.isValid(): - now = QDate.currentDate() - if ( - (period == 2 and - lastCheck.day() == now.day()) or - (period == 3 and lastCheck.daysTo(now) < 7) or - (period == 4 and (lastCheck.daysTo(now) < - lastCheck.daysInMonth())) - ): - # daily, weekly, monthly - return - - self.__inVersionCheck = True - self.manualUpdatesCheck = manual - self.showAvailableVersions = showVersions - self.httpAlternative = alternative - url = QUrl(self.__httpAlternatives[alternative]) - self.__versionCheckCanceled = False - if manual: - if self.__versionCheckProgress is None: - self.__versionCheckProgress = EricProgressDialog( - "", self.tr("&Cancel"), - 0, len(self.__httpAlternatives), - self.tr("%v/%m"), self) - self.__versionCheckProgress.setWindowTitle( - self.tr("Version Check")) - self.__versionCheckProgress.setMinimumDuration(0) - self.__versionCheckProgress.canceled.connect( - self.__versionsDownloadCanceled) - self.__versionCheckProgress.setLabelText( - self.tr("Trying host {0}").format(url.host())) - self.__versionCheckProgress.setValue(alternative) - request = QNetworkRequest(url) - request.setAttribute( - QNetworkRequest.Attribute.CacheLoadControlAttribute, - QNetworkRequest.CacheLoadControl.AlwaysNetwork) - reply = self.__networkManager.get(request) - reply.finished.connect(lambda: self.__versionsDownloadDone(reply)) - self.__replies.append(reply) - else: - if manual: - EricMessageBox.warning( - self, - self.tr("Error getting versions information"), - self.tr("The versions information cannot not be" - " downloaded because the Internet is" - " <b>not reachable</b>. Please try again later.") - ) - - @pyqtSlot() - def __versionsDownloadDone(self, reply): - """ - Private slot called, after the versions file has been downloaded - from the internet. - - @param reply reference to the network reply - @type QNetworkReply - """ - if self.__versionCheckCanceled: - self.__inVersionCheck = False - if self.__versionCheckProgress is not None: - self.__versionCheckProgress.reset() - self.__versionCheckProgress = None - return - - reply.deleteLater() - if reply in self.__replies: - self.__replies.remove(reply) - if reply.error() == QNetworkReply.NetworkError.NoError: - ioEncoding = Preferences.getSystem("IOEncoding") - versions = str(reply.readAll(), ioEncoding, 'replace').splitlines() - reply.close() - if ( - reply.error() != QNetworkReply.NetworkError.NoError or - len(versions) == 0 or - versions[0].startswith("<") - ): - # network error or an error page - self.httpAlternative += 1 - if self.httpAlternative >= len(self.__httpAlternatives): - self.__inVersionCheck = False - if self.__versionCheckProgress is not None: - self.__versionCheckProgress.reset() - self.__versionCheckProgress = None - firstFailure = Preferences.getSettings().value( - "Updates/FirstFailedCheckDate", QDate.currentDate()) - failedDuration = firstFailure.daysTo(QDate.currentDate()) - Preferences.getSettings().setValue( - "Updates/FirstFailedCheckDate", firstFailure) - if self.manualUpdatesCheck: - EricMessageBox.warning( - self, - self.tr("Error getting versions information"), - self.tr("""The versions information could not be""" - """ downloaded.""" - """ Please go online and try again.""")) - elif failedDuration > 7: - EricMessageBox.warning( - self, - self.tr("Error getting versions information"), - self.tr("""The versions information could not be""" - """ downloaded for the last 7 days.""" - """ Please go online and try again.""")) + if VersionOnly.startswith(("rev_", "@@")): + # cannot check against development or source installation return else: - self.performVersionCheck(self.manualUpdatesCheck, - self.httpAlternative, - self.showAvailableVersions) - return - - self.__inVersionCheck = False - if self.__versionCheckProgress is not None: - self.__versionCheckProgress.reset() - self.__versionCheckProgress = None - self.__updateVersionsUrls(versions) - if self.showAvailableVersions: - self.__showAvailableVersionInfos(versions) - else: - Preferences.getSettings().remove("Updates/FirstFailedCheckDate") - Preferences.getSettings().setValue( - "Updates/LastCheckDate", QDate.currentDate()) - self.__versionCheckResult(versions) - - def __updateVersionsUrls(self, versions): - """ - Private method to update the URLs from which to retrieve the versions - file. - - @param versions contents of the downloaded versions file (list of - strings) - """ - if len(versions) > 5 and versions[4] == "---": - line = 5 - urls = [] - while line < len(versions): - urls.append(versions[line]) - line += 1 + period = Preferences.getUI("PerformVersionCheck") + if period == 0: + return + elif period in [2, 3, 4]: + lastCheck = Preferences.getSettings().value( + "Updates/LastCheckDate", QDate(1970, 1, 1)) + if lastCheck.isValid(): + now = QDate.currentDate() + if ( + (period == 2 and + lastCheck.day() == now.day()) or + (period == 3 and lastCheck.daysTo(now) < 7) or + (period == 4 and (lastCheck.daysTo(now) < + lastCheck.daysInMonth())) + ): + # daily, weekly, monthly + return - Preferences.setUI("VersionsUrls7", urls) - - def __versionCheckResult(self, versions): - """ - Private method to show the result of the version check action. - - @param versions contents of the downloaded versions file (list of - strings) - """ - url = "" - try: - if "snapshot-" in VersionOnly: - # check snapshot version like snapshot-20170810 - if "snapshot-" in versions[2]: - installedSnapshotDate = VersionOnly.rsplit("-", 1)[-1] - availableSnapshotDate = versions[2].rsplit("-", 1)[-1] - if availableSnapshotDate > installedSnapshotDate: - res = EricMessageBox.yesNo( - self, - self.tr("Update available"), - self.tr( - """The update to <b>{0}</b> of eric is""" - """ available at <b>{1}</b>. Would you like""" - """ to get it?""") - .format(versions[2], versions[3]), - yesDefault=True) - url = res and versions[3] or '' - else: - if self.manualUpdatesCheck: - EricMessageBox.information( - self, - self.tr("Update Check"), - self.tr( - """You are using a snapshot release of""" - """ eric. A more up-to-date stable release""" - """ might be available.""")) - elif VersionOnly.startswith(("rev_", "@@")): - # check installation from source - if self.manualUpdatesCheck: - EricMessageBox.information( - self, - self.tr("Update Check"), - self.tr( - """You installed eric directly from the source""" - """ code. There is no possibility to check""" - """ for the availability of an update.""")) - else: - # check release version - installedVersionTuple = self.__versionToTuple(VersionOnly) - availableVersionTuple = self.__versionToTuple(versions[0]) - if availableVersionTuple > installedVersionTuple: - res = EricMessageBox.yesNo( - self, - self.tr("Update available"), - self.tr( - """The update to <b>{0}</b> of eric is""" - """ available at <b>{1}</b>. Would you like""" - """ to get it?""") - .format(versions[0], versions[1]), - yesDefault=True) - url = res and versions[1] or '' - else: - if self.manualUpdatesCheck: - EricMessageBox.information( - self, - self.tr("eric is up to date"), - self.tr( - """You are using the latest version of""" - """ eric""")) - except (IndexError, TypeError): - EricMessageBox.warning( - self, - self.tr("Error during updates check"), - self.tr("""Could not perform updates check.""")) - - if url: - QDesktopServices.openUrl(QUrl(url)) - - @pyqtSlot() - def __versionsDownloadCanceled(self): - """ - Private slot called to cancel the version check. - """ - if self.__replies: - self.__versionCheckCanceled = True - self.__replies[-1].abort() - - def __showAvailableVersionInfos(self, versions): - """ - Private method to show the versions available for download. - - @param versions contents of the downloaded versions file (list of - strings) - """ - versionText = self.tr( - """<h3>Available versions</h3>""" - """<table>""") - line = 0 - while line < len(versions): - if versions[line] == "---": - break - - versionText += ( - """<tr><td>{0}</td><td><a href="{1}">{2}</a></td></tr>""" - ).format( - versions[line], versions[line + 1], - 'sourceforge' in versions[line + 1] and - "SourceForge" or versions[line + 1]) - line += 2 - versionText += self.tr("""</table>""") - - self.__versionsDialog = EricMessageBox.EricMessageBox( - EricMessageBox.NoIcon, - Program, - versionText, - modal=False, - buttons=EricMessageBox.Ok, - parent=self - ) - self.__versionsDialog.setIconPixmap( - UI.PixmapCache.getPixmap("eric").scaled(64, 64)) - self.__versionsDialog.show() - + availableVersions = ( + self.pipInterface.getPackageVersions("eric-ide") + ) + updateAvailable = bool(v for v in availableVersions + if v > VersionOnly) + if updateAvailable: + EricMessageBox.information( + self, + self.tr("Upgrade available"), + self.tr( + """A newer version of the <b>eric-ide</b> package is""" + """ available at <a href="{0}/eric-ide/">""" + """PyPI</a>.""" + ).format(self.pipInterface.getIndexUrlPypi()) + ) + def __sslErrors(self, reply, errors): """ Private slot to handle SSL errors.