Skip to content

Commit 3761a7c

Browse files
Feature/version checker (#50)
* Add version check functionality
1 parent 62e9a96 commit 3761a7c

File tree

10 files changed

+108
-3
lines changed

10 files changed

+108
-3
lines changed

atcoder-tools

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,33 @@
11
#!/usr/bin/env python3
22
import sys
33

4+
from atcodertools.release_management.version_check import get_latest_version
45
from atcodertools.tools.envgen import main as envgen_main
56
from atcodertools.tools.tester import main as tester_main
67
from atcodertools.tools.submit import main as submit_main
8+
from atcodertools.release_management.version import __version__
9+
from colorama import Fore, Style
710

811

912
def exit_program(success: bool):
1013
sys.exit(0 if success else -1)
1114

1215

16+
def notify_if_latest_version_found():
17+
latest = get_latest_version()
18+
if latest != __version__:
19+
print(Fore.YELLOW, end='')
20+
print("The latest version {0} is available! (The current version: {1})".format(
21+
latest, __version__))
22+
print("To upgrade, run the following command:")
23+
print("")
24+
print("pip3 install atcoder-tools --upgrade")
25+
print(Style.RESET_ALL)
26+
27+
1328
if __name__ == '__main__':
29+
notify_if_latest_version_found()
30+
1431
if len(sys.argv) < 2 or sys.argv[1] not in ("gen", "test", "submit"):
1532
print("Usage:")
1633
print("{} gen -- to generate workspace".format(sys.argv[0]))

atcodertools/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from atcodertools.release_management.version import __version__ # noqa

atcodertools/client/atcoder.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import requests
99
from bs4 import BeautifulSoup
1010

11+
from atcodertools.fileutils.artifacts_cache import get_cache_file_path
1112
from atcodertools.models.contest import Contest
1213
from atcodertools.models.problem import Problem
1314
from atcodertools.models.problem_content import ProblemContent, InputFormatDetectionError, SampleDetectionError
@@ -18,8 +19,7 @@ class LoginError(Exception):
1819
pass
1920

2021

21-
default_cookie_path = os.path.join(
22-
os.path.expanduser('~/.local/share'), 'atcoder-tools', 'cookie.txt')
22+
default_cookie_path = get_cache_file_path('cookie.txt')
2323

2424

2525
def save_cookie(session: requests.Session, cookie_path: Optional[str] = None):
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import os
2+
3+
4+
def _get_cache_dir_path():
5+
return os.path.join(os.path.expanduser('~/.local/share'), 'atcoder-tools')
6+
7+
8+
def get_cache_file_path(filename: str):
9+
return os.path.join(_get_cache_dir_path(), filename)

atcodertools/release_management/__init__.py

Whitespace-only changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
__version__ = "1.0.4"
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import json
2+
import os
3+
import time
4+
5+
import requests
6+
7+
from atcodertools.fileutils.artifacts_cache import get_cache_file_path
8+
9+
10+
class VersionCheckError(Exception):
11+
pass
12+
13+
14+
cache_file_path = get_cache_file_path('version_cache.txt')
15+
16+
HOUR_IN_SEC = 60 * 60
17+
18+
19+
def _fetch_latest_version():
20+
dic = json.loads(requests.get(
21+
"https://pypi.org/pypi/atcoder-tools/json").text)
22+
return dic["info"]["version"]
23+
24+
25+
def _get_latest_version_cache():
26+
if not os.path.exists(cache_file_path):
27+
return None
28+
with open(cache_file_path, 'r') as f:
29+
version, timestamp_ms = f.read().split()
30+
timestamp_sec = float(timestamp_ms)
31+
32+
if time.time() - timestamp_sec > HOUR_IN_SEC:
33+
return None
34+
35+
return version
36+
37+
38+
def store_version_cache(version):
39+
os.makedirs(os.path.dirname(cache_file_path), exist_ok=True)
40+
with open(cache_file_path, 'w') as f:
41+
f.write("{} {}".format(version, time.time()))
42+
43+
44+
def get_latest_version(user_cache=True):
45+
try:
46+
if user_cache:
47+
cached_version = _get_latest_version_cache()
48+
if cached_version:
49+
return cached_version
50+
51+
version = _fetch_latest_version()
52+
53+
if user_cache:
54+
store_version_cache(version)
55+
56+
return version
57+
except Exception:
58+
raise VersionCheckError

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
beautifulsoup4
22
requests
3+
colorama

setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from __future__ import unicode_literals
55

66
from setuptools import setup, find_packages
7+
from atcodertools.release_management.version import __version__
78

89
try:
910
with open('README.md') as f:
@@ -18,7 +19,7 @@ def _requires_from_file(filename):
1819

1920
setup(
2021
name="atcoder-tools",
21-
version="1.0.4",
22+
version=__version__,
2223
description="Convenient modules & tools for AtCoder users, written in Python 3.5",
2324
url='https://github.com/kyuridenamida/atcoder-tools',
2425
author='kyuridenamida',

tests/test_version_check.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import os
2+
import unittest
3+
4+
from atcodertools.release_management.version_check import get_latest_version
5+
6+
RESOURCE_DIR = os.path.abspath(os.path.join(
7+
os.path.dirname(os.path.abspath(__file__)),
8+
"./resources/test_tester/"))
9+
10+
11+
class TestTester(unittest.TestCase):
12+
def test_get_latest_version_with_no_error(self):
13+
get_latest_version(user_cache=False)
14+
15+
16+
if __name__ == '__main__':
17+
unittest.main()

0 commit comments

Comments
 (0)