dosage/dosagelib/updater.py

69 lines
2.1 KiB
Python
Raw Normal View History

# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: © 2004 Tristan Seligmann and Jonathan Jacobs
# SPDX-FileCopyrightText: © 2012 Bastian Kleineidam
# SPDX-FileCopyrightText: © 2015 Tobias Gruetzmacher
2013-04-08 18:17:02 +00:00
import os
import re
from typing import Any, Dict, Optional, Tuple
import dosagelib
from . import http
2013-04-08 18:17:02 +00:00
UPDATE_URL = 'https://api.github.com/repos/webcomics/dosage/releases/latest'
EXTPRIO = {
'.exe': 1 if os.name == 'nt' else 9,
'.whl': 2,
'.gz': 3,
}
2013-04-08 18:17:02 +00:00
2017-05-14 22:54:02 +00:00
def check_update() -> Optional[Tuple[str, Optional[str]]]:
2013-04-08 18:17:02 +00:00
"""Return the following values:
throws exception - online version could not be determined
None - user has newest version
(version, url string) - update available
(version, None) - current version is newer than online version
2013-04-08 18:17:02 +00:00
"""
version, value = get_online_version()
if version == dosagelib.__version__:
2013-04-08 18:17:02 +00:00
# user has newest version
return None
2013-04-08 18:17:02 +00:00
if is_newer_version(version):
# value is an URL linking to the update package
return (version, value)
2013-04-08 18:17:02 +00:00
# user is running a local or development version
return (version, None)
2013-04-08 18:17:02 +00:00
def asset_key(asset: Dict[str, Any]) -> int:
return EXTPRIO.get(os.path.splitext(asset['browser_download_url'])[1], 99)
def get_online_version() -> Tuple[str, Optional[str]]:
2013-04-08 18:17:02 +00:00
"""Download update info and parse it."""
response = http.default_session.get(UPDATE_URL)
response.raise_for_status()
page = response.json()
version = page['tag_name']
url = None
try:
assets = sorted(page['assets'], key=asset_key)
if len(assets) > 0:
url = assets[0]['browser_download_url']
except KeyError:
pass
2013-04-08 18:17:02 +00:00
return version, url
def version_nums(ver: str) -> Tuple[int, ...]:
"""Extract all numeric "sub-parts" of a version string. Not very exact, but
works for our use case."""
return tuple(int(s) for s in re.split(r'\D+', ver + '0'))
def is_newer_version(version) -> bool:
2013-04-08 18:17:02 +00:00
"""Check if given version is newer than current version."""
return version_nums(version) > version_nums(dosagelib.__version__)