Change version checker to use regular GitHub API
This commit is contained in:
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user