diff --git a/requirements.txt b/requirements.txt index 1490c6d..a0f97cc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,4 +9,5 @@ python-dateutil psutil psutil pillow-simd -python-magic \ No newline at end of file +python-magic +semver \ No newline at end of file diff --git a/wowlet_backend/factory.py b/wowlet_backend/factory.py index a1f1633..272deee 100644 --- a/wowlet_backend/factory.py +++ b/wowlet_backend/factory.py @@ -59,7 +59,7 @@ async def _setup_tasks(app: Quart): from wowlet_backend.tasks import ( BlockheightTask, HistoricalPriceTask, FundingProposalsTask, CryptoRatesTask, FiatRatesTask, RedditTask, RPCNodeCheckTask, - XmrigTask, SuchWowTask) + XmrigTask, SuchWowTask, WowletReleasesTask) asyncio.create_task(BlockheightTask().start()) asyncio.create_task(HistoricalPriceTask().start()) @@ -69,6 +69,7 @@ async def _setup_tasks(app: Quart): asyncio.create_task(RPCNodeCheckTask().start()) asyncio.create_task(XmrigTask().start()) asyncio.create_task(SuchWowTask().start()) + asyncio.create_task(WowletReleasesTask().start()) if settings.COIN_SYMBOL in ["xmr", "wow"]: asyncio.create_task(FundingProposalsTask().start()) diff --git a/wowlet_backend/tasks/__init__.py b/wowlet_backend/tasks/__init__.py index c8e7071..0333417 100644 --- a/wowlet_backend/tasks/__init__.py +++ b/wowlet_backend/tasks/__init__.py @@ -166,3 +166,4 @@ from wowlet_backend.tasks.reddit import RedditTask from wowlet_backend.tasks.rpc_nodes import RPCNodeCheckTask from wowlet_backend.tasks.xmrig import XmrigTask from wowlet_backend.tasks.suchwow import SuchWowTask +from wowlet_backend.tasks.wowlet import WowletReleasesTask diff --git a/wowlet_backend/tasks/wowlet.py b/wowlet_backend/tasks/wowlet.py new file mode 100644 index 0000000..e2d0f7b --- /dev/null +++ b/wowlet_backend/tasks/wowlet.py @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2020, The Monero Project. +# Copyright (c) 2020, dsc@xmr.pm + +import semver +from dateutil.parser import parse + +import settings +from wowlet_backend.utils import httpget +from wowlet_backend.tasks import WowletTask + + +class WowletReleasesTask(WowletTask): + """Fetches the latest Wowlet releases using gitea's API""" + def __init__(self, interval: int = 3600): + super(WowletReleasesTask, self).__init__(interval) + + self._cache_key = "wowlet_releases" + self._cache_expiry = self.interval * 10 + + self._websocket_cmd = "wowlet_releases" + + self._http_endpoint = "https://git.wownero.com/api/v1/repos/wowlet/wowlet/releases?limit=1" + + async def task(self) -> dict: + blob = await httpget(self._http_endpoint) + if not isinstance(blob, list) or not blob: + raise Exception(f"Invalid JSON response for {self._http_endpoint}") + + blob = blob[0] + + data = {} + for asset in blob['assets']: + operating_system = "linux" + if "msvc" in asset['name'] or "win64" in asset['name'] or "windows" in asset['name']: + operating_system = "windows" + elif "macos" in asset["name"]: + operating_system = "macos" + + data[operating_system] = { + "name": asset["name"], + "created_at": parse(asset["created_at"]).strftime("%Y-%m-%d"), + "url": asset['browser_download_url'], + "download_count": asset["download_count"], + "size": asset['size'] + } + + _semver = self.parse_semver(blob) + + return { + "version": { + "major": _semver.major, + "minor": _semver.minor, + "patch": _semver.patch + }, + "assets": data + } + + def parse_semver(self, blob): + tag = blob['tag_name'] # valid tag name example: v0.2.0.0 + if tag.startswith("v"): + tag = tag[1:] + tag = tag.split(".") + tag = [t for t in tag if t.isdigit()] + if tag[0] == '0': + tag = tag[1:] + + return semver.VersionInfo.parse(f"{tag[0]}.{tag[1]}.{tag[2]}")