diff --git a/doc/README.txt b/doc/README.txt index 87250af50..21567b374 100644 --- a/doc/README.txt +++ b/doc/README.txt @@ -79,7 +79,7 @@ or if you do not have root permissions: Dependencies ------------- -Python version 2.7 or higher, which can be downloaded +Python version 2.7.x or Python 3.3 or higher. Both can be downloaded from http://www.python.org/ Also the python-requests module is used, which can be downloaded diff --git a/dosage b/dosage index 1d114c686..eb3e5e784 100755 --- a/dosage +++ b/dosage @@ -16,11 +16,10 @@ import argparse import pydoc from io import StringIO -from dosagelib import events, scraper +from dosagelib import events, scraper, configuration from dosagelib.output import out from dosagelib.util import internal_error, getDirname, strlimit, getLangName from dosagelib.ansicolor import get_columns -from dosagelib.configuration import App, Freeware, Copyright, SupportUrl class ArgumentParser(argparse.ArgumentParser): @@ -80,6 +79,7 @@ def setupOptions(): parser.add_argument('-t', '--timestamps', action='store_true', help='print timestamps for all output at any info level') parser.add_argument('-o', '--output', action='append', dest='handler', choices=events.getHandlerNames(), help='sets output handlers for downloaded comics') parser.add_argument('--adult', action='store_true', help='confirms that you are old enough to view adult content') + # multimatch is only used for development, eg. testing if all comics of a scripted plugin are working parser.add_argument('--multimatch', action='store_true', help=argparse.SUPPRESS) parser.add_argument('comic', nargs='*', help='comic module name (including case insensitive substrings)') try: @@ -90,12 +90,37 @@ def setupOptions(): return parser -def displayVersion(): +def displayVersion(verbose): """Display application name, version, copyright and license.""" - print(App) - print(Copyright) - print(Freeware) - print("For support see", SupportUrl) + print(configuration.App) + print(configuration.Copyright) + print(configuration.Freeware) + print("For support see", configuration.SupportUrl) + if verbose: + # search for updates + from dosagelib.updater import check_update + result, value = check_update() + if result: + if value: + version, url = value + if url is None: + # current version is newer than online version + text = ('Detected local or development version %(currentversion)s. ' + 'Available version of %(app)s is %(version)s.') + else: + # display update link + text = ('A new version %(version)s of %(app)s is ' + 'available at %(url)s.') + attrs = dict(version=version, app=configuration.AppName, + url=url, currentversion=configuration.Version) + print(text % attrs) + else: + if value is None: + value = 'invalid update file syntax' + text = ('An error occured while checking for an ' + 'update of %(app)s: %(error)s.') + attrs = dict(error=value, app=configuration.AppName) + print(text % attrs) return 0 @@ -196,7 +221,7 @@ def run(options): """Execute comic commands.""" setOutputInfo(options) if options.version: - return displayVersion() + return displayVersion(options.verbose) if options.list: return doList() if options.singlelist: diff --git a/dosage.freecode b/dosage.freecode index 69cc5df64..869a77c53 100644 --- a/dosage.freecode +++ b/dosage.freecode @@ -4,7 +4,7 @@ Release-Focus: Minor feature enhancements Hide: N Website-URL: http://wummel.github.com/dosage/ Changelog-URL: https://github.com/wummel/dosage/blob/master/doc/changelog.txt -Tar/GZ-URL: http://github.com/downloads/wummel/dosage/dosage-${version}.tar.gz +Source-Package-URL: http://github.com/downloads/wummel/dosage/dosage-${version}.tar.gz GIT-Tree-URL: https://github.com/wummel/dosage.git Windows-installer-URL: http://github.com/downloads/wummel/dosage/dosage-${version}.exe diff --git a/dosagelib/updater.py b/dosagelib/updater.py new file mode 100644 index 000000000..64c12aa38 --- /dev/null +++ b/dosagelib/updater.py @@ -0,0 +1,58 @@ +# -*- coding: iso-8859-1 -*- +""" +Function to check for updates. +""" +import os +from .configuration import Version as CurrentVersion +from .util import urlopen +from distutils.version import StrictVersion +import requests + +# Use the Freecode submit file as source since that file gets updated +# only when releasing a new version. +UPDATE_URL = "https://raw.github.com/wummel/dosage/master/dosage.freecode" +VERSION_TAG = 'Version:' +if os.name == 'nt': + URL_TAG = 'Windows-installer-URL:' +else: + URL_TAG = 'Source-Package-URL:' + + +def check_update (): + """Return the following values: + (False, errmsg) - online version could not be determined + (True, None) - user has newest version + (True, (version, url string)) - update available + (True, (version, None)) - current version is newer than online version + """ + version, value = get_online_version() + if version is None: + # value is an error message + return False, value + if version == CurrentVersion: + # user has newest version + return True, None + if is_newer_version(version): + # value is an URL linking to the update package + return True, (version, value) + # user is running a local or development version + return True, (version, None) + + +def get_online_version (): + """Download update info and parse it.""" + session = requests.session() + page = urlopen(UPDATE_URL, session, stream=False) + version, url = None, None + for line in page.text.splitlines(): + if line.startswith(VERSION_TAG): + version = line.split(':', 1)[1].strip() + elif line.startswith(URL_TAG): + url = line.split(':', 1)[1].strip() + url = url.replace('${version}', version) + return version, url + + +def is_newer_version (version): + """Check if given version is newer than current version.""" + return StrictVersion(version) > StrictVersion(CurrentVersion)