Change version checker to use regular GitHub API

This commit is contained in:
Veronica Berglyd Olsen
2024-02-14 21:46:10 +01:00
parent 3a1f77b8f8
commit 5917c9da08
+27 -35
View File
@@ -26,8 +26,9 @@ from __future__ import annotations
import json import json
import logging import logging
from random import shuffle from time import sleep
from datetime import datetime from datetime import datetime
from urllib.error import HTTPError
from urllib.request import Request, urlopen from urllib.request import Request, urlopen
from PyQt5.QtGui import QDesktopServices from PyQt5.QtGui import QDesktopServices
@@ -40,11 +41,7 @@ from novelwriter.constants import nwConst
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
LOOKUPS = [ API_URL = "https://api.github.com/repos/vkbo/novelwriter/releases/latest"
"https://novelwriter.io/release-latest.json",
"https://vkbo.github.io/novelWriter.io/release-latest.json",
"https://raw.githubusercontent.com/vkbo/novelWriter.io/main/source/_extra/release-latest.json",
]
class VersionInfoWidget(QWidget): class VersionInfoWidget(QWidget):
@@ -102,16 +99,16 @@ class VersionInfoWidget(QWidget):
# Private Slots # Private Slots
## ##
@pyqtSlot(dict) @pyqtSlot(str, str)
def _updateReleaseInfo(self, result: dict) -> None: def _updateReleaseInfo(self, tag: str, reason: str) -> None:
"""Update the widget release info.""" """Update the widget release info."""
if version := result.get("version"): if version := tag.lstrip("v"):
download = f"<a href='#website'>{__domain__}</a>" download = f"<a href='#website'>{__domain__}</a>"
self._lblRelease.setText(self._trLatest.format( self._lblRelease.setText(self._trLatest.format(
f"{version} \u2013 {self._trDownload.format(download)}" f"{version} \u2013 {self._trDownload.format(download)}"
)) ))
else: else:
self._lblRelease.setText(self._trLatest.format(self.tr("Failed"))) self._lblRelease.setText(self._trLatest.format(reason or self.tr("Failed")))
return return
# END Class VersionInfoWidget # END Class VersionInfoWidget
@@ -125,38 +122,33 @@ class _Retriever(QRunnable):
self.signals = _RetrieverSignal() self.signals = _RetrieverSignal()
return return
def isRunning(self) -> bool:
return self._isRunning
@pyqtSlot() @pyqtSlot()
def run(self) -> None: def run(self) -> None:
"""Poll the urls in the background.""" """Poll the GitHub API in the background.
self._isRunning = True Note: The GitHub API is rate limited at 60 requests per hour.
"""
shuffle(LOOKUPS) logger.info("Contacting: %s", API_URL)
for url in LOOKUPS: req = Request(API_URL)
req = Request(url) req.add_header("User-Agent", nwConst.USER_AGENT)
req.add_header("User-Agent", nwConst.USER_AGENT) req.add_header("Accept", "application/vnd.github.v3+json")
req.add_header("Accept", "application/json") sleep(0.2)
try: try:
logger.info("Contacting: %s", url) with urlopen(req, timeout=15) as ret:
data = urlopen(req, timeout=10).read().decode() if isinstance(raw := json.loads(ret.read().decode()), dict):
if isinstance(release := json.loads(data).get("release"), dict): self.signals.dataReady.emit(raw.get("tag_name", ""), "")
self.signals.dataReady.emit(release) except HTTPError as e:
break reason = f"{e.reason.capitalize()} (HTTP {e.code})"
except Exception: logger.error(reason)
logger.error("Failed to retrieve release info") self.signals.dataReady.emit("", reason)
else: except Exception as e:
self.signals.dataReady.emit({}) logger.error("Failed to retrieve release info")
self.signals.dataReady.emit("", str(e))
self._isRunning = False
return return
# END Class _Retriever # END Class _Retriever
class _RetrieverSignal(QObject): class _RetrieverSignal(QObject):
dataReady = pyqtSignal(dict) dataReady = pyqtSignal(str, str)
# END Class _RetrieverSignal # END Class _RetrieverSignal