Skip to content

Commit

Permalink
Check for updates on unix systems not using package management
Browse files Browse the repository at this point in the history
  • Loading branch information
squiddy committed Jun 9, 2017
1 parent 0c4a3df commit c950506
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 30 deletions.
35 changes: 26 additions & 9 deletions horizons/util/checkupdates.py
Expand Up @@ -20,11 +20,14 @@
# ###################################################

import json
import os
import platform
import threading
import urllib.error
import urllib.request
import webbrowser
from pathlib import PurePath
from typing import Optional

from fife.extensions.pychan.widgets import Button

Expand All @@ -33,18 +36,36 @@
from horizons.extscheduler import ExtScheduler
from horizons.gui.windows import Popup
from horizons.i18n import gettext as T
from horizons.util.platform import get_home_directory
from horizons.util.python.callback import Callback


TIMEOUT = 5.0 # we should be done before the user can start a game


def is_system_installed(uh_path: Optional[PurePath]) -> bool:
"""
Returns whether UH is likely to have been installed with the systems package manager.
In typical usage, you don't need to pass any parameters.
"""
if uh_path is None:
uh_path = PurePath(os.path.abspath(__file__))

home_directory = get_home_directory()
try:
uh_path.relative_to(home_directory)
return False
except ValueError:
return True


def is_version_newer(original, candidate):
"""
Returns whether the version identifier `candidate` is a newer version than `original`.
"""
def parse(value):
return tuple(map(int, value.split('.')))
version = value.split('-')[0]
return tuple(map(int, version.split('.')))

try:
return parse(candidate) > parse(original)
Expand All @@ -56,17 +77,13 @@ def check_for_updates():
"""
Check if there's a new version, returns the data from the server, otherwise None.
"""
# no updates for git version
if VERSION.IS_DEV_VERSION:
return

# only updates for operating systems missing a package management
if platform.system() not in ('Windows', 'Darwin'):
# skip check for platforms that have proper package managements
if platform.system() not in ('Windows', 'Darwin') and is_system_installed():
return

try:
with urllib.request.urlopen(NETWORK.UPDATE_FILE_URL, timeout=TIMEOUT) as f:
data = json.loads(f.read())
data = json.loads(f.read().decode('ascii'))
if is_version_newer(VERSION.RELEASE_VERSION, data['version']):
return data
except (urllib.error.URLError, ValueError, KeyError):
Expand Down
40 changes: 19 additions & 21 deletions tests/unittests/util/test_check_updates.py
Expand Up @@ -20,33 +20,21 @@
# ###################################################

import urllib.request
from pathlib import PurePosixPath, PureWindowsPath
from unittest import mock

import pytest

from horizons.util.checkupdates import check_for_updates, is_version_newer
from horizons.util.checkupdates import check_for_updates, is_system_installed, is_version_newer


def test_check_for_updates_dev_version(mocker):
def test_check_for_updates(mocker):
"""
Skip update check for development version.
Skip update check for platforms other than Windows or iOS where it's likely that the game
was installed using the system's package manager.
"""
mocker.patch('horizons.constants.VERSION.IS_DEV_VERSION',
new_callable=mock.PropertyMock, return_value=True)
urlopen = mocker.patch.object(urllib.request, 'urlopen')

check_for_updates()

assert not urlopen.called


def test_check_for_updates_ignored_platforms(mocker):
"""
Skip update check for platforms other than Windows or iOS.
"""
mocker.patch('horizons.constants.VERSION.IS_DEV_VERSION',
new_callable=mock.PropertyMock, return_value=False)
mocker.patch('platform.system', return_value='Linux')
mocker.patch('horizons.util.checkupdates.is_system_installed', return_value=True)
urlopen = mocker.patch.object(urllib.request, 'urlopen')

check_for_updates()
Expand All @@ -64,8 +52,6 @@ def test_check_for_updates_json_data(json_data, result, mocker):
"""
Test various cases for the JSON data.
"""
mocker.patch('horizons.constants.VERSION.IS_DEV_VERSION',
new_callable=mock.PropertyMock, return_value=False)
mocker.patch('horizons.constants.VERSION.RELEASE_VERSION',
new_callable=mock.PropertyMock, return_value='2017.1')
mocker.patch('platform.system', return_value='Windows')
Expand All @@ -86,6 +72,18 @@ def test_check_for_updates_json_data(json_data, result, mocker):
('2017.2', 'something wrong', False),
('2017.2', '2017.1', False),
('2017.2', '2017.2', False),
('2017.2', '2017.3', True)])
('2017.2', '2017.3', True),
('2017.2-610-g6f1c0da66', '2017.2', False),
('2017.2-610-g6f1c0da66', '2017.3', True)])
def test_is_version_newer(original, candidate, result):
assert is_version_newer(original, candidate) == result


@pytest.mark.parametrize('uh_path,home_dir,result', [
(PurePosixPath('/usr/local/share/games/'), PurePosixPath('/home/max/'), True),
(PurePosixPath('/home/max/games/'), PurePosixPath('/home/max/'), False),
(PureWindowsPath('C:\\Programs\\Uh'), PureWindowsPath('C:\\Users\\max'), True),
(PureWindowsPath('C:\\Users\\max\\uh'), PureWindowsPath('C:\\Users\\max'), False)])
def test_is_system_installed(uh_path, home_dir, result, mocker):
mocker.patch('horizons.util.checkupdates.get_home_directory', return_value=home_dir)
assert is_system_installed(uh_path) == result

0 comments on commit c950506

Please sign in to comment.