1"""pyversioncheck - Module to help with checking versions"""
2import types
3import rfc822
4import urllib
5import sys
6
7# Verbose options
8VERBOSE_SILENT=0        # Single-line reports per package
9VERBOSE_NORMAL=1        # Single-line reports per package, more info if outdated
10VERBOSE_EACHFILE=2      # Report on each URL checked
11VERBOSE_CHECKALL=3      # Check each URL for each package
12
13# Test directory
14## urllib bug: _TESTDIR="ftp://ftp.cwi.nl/pub/jack/python/versiontestdir/"
15_TESTDIR="http://www.cwi.nl/~jack/versiontestdir/"
16
17def versioncheck(package, url, version, verbose=0):
18    ok, newversion, fp = checkonly(package, url, version, verbose)
19    if verbose > VERBOSE_NORMAL:
20        return ok
21    if ok < 0:
22        print '%s: No correctly formatted current version file found'%(package)
23    elif ok == 1:
24        print '%s: up-to-date (version %s)'%(package, version)
25    else:
26        print '%s: version %s installed, version %s found:' % \
27                        (package, version, newversion)
28        if verbose > VERBOSE_SILENT:
29            while 1:
30                line = fp.readline()
31                if not line: break
32                sys.stdout.write('\t'+line)
33    return ok
34
35def checkonly(package, url, version, verbose=0):
36    if verbose >= VERBOSE_EACHFILE:
37        print '%s:'%package
38    if type(url) == types.StringType:
39        ok, newversion, fp = _check1version(package, url, version, verbose)
40    else:
41        for u in url:
42            ok, newversion, fp = _check1version(package, u, version, verbose)
43            if ok >= 0 and verbose < VERBOSE_CHECKALL:
44                break
45    return ok, newversion, fp
46
47def _check1version(package, url, version, verbose=0):
48    if verbose >= VERBOSE_EACHFILE:
49        print '  Checking %s'%url
50    try:
51        fp = urllib.urlopen(url)
52    except IOError, arg:
53        if verbose >= VERBOSE_EACHFILE:
54            print '    Cannot open:', arg
55        return -1, None, None
56    msg = rfc822.Message(fp, seekable=0)
57    newversion = msg.getheader('current-version')
58    if not newversion:
59        if verbose >= VERBOSE_EACHFILE:
60            print '    No "Current-Version:" header in URL or URL not found'
61        return -1, None, None
62    version = version.lower().strip()
63    newversion = newversion.lower().strip()
64    if version == newversion:
65        if verbose >= VERBOSE_EACHFILE:
66            print '    Version identical (%s)'%newversion
67        return 1, version, fp
68    else:
69        if verbose >= VERBOSE_EACHFILE:
70            print '    Versions different (installed: %s, new: %s)'% \
71                        (version, newversion)
72        return 0, newversion, fp
73
74
75def _test():
76    print '--- TEST VERBOSE=1'
77    print '--- Testing existing and identical version file'
78    versioncheck('VersionTestPackage', _TESTDIR+'Version10.txt', '1.0', verbose=1)
79    print '--- Testing existing package with new version'
80    versioncheck('VersionTestPackage', _TESTDIR+'Version11.txt', '1.0', verbose=1)
81    print '--- Testing package with non-existing version file'
82    versioncheck('VersionTestPackage', _TESTDIR+'nonexistent.txt', '1.0', verbose=1)
83    print '--- Test package with 2 locations, first non-existing second ok'
84    versfiles = [_TESTDIR+'nonexistent.txt', _TESTDIR+'Version10.txt']
85    versioncheck('VersionTestPackage', versfiles, '1.0', verbose=1)
86    print '--- TEST VERBOSE=2'
87    print '--- Testing existing and identical version file'
88    versioncheck('VersionTestPackage', _TESTDIR+'Version10.txt', '1.0', verbose=2)
89    print '--- Testing existing package with new version'
90    versioncheck('VersionTestPackage', _TESTDIR+'Version11.txt', '1.0', verbose=2)
91    print '--- Testing package with non-existing version file'
92    versioncheck('VersionTestPackage', _TESTDIR+'nonexistent.txt', '1.0', verbose=2)
93    print '--- Test package with 2 locations, first non-existing second ok'
94    versfiles = [_TESTDIR+'nonexistent.txt', _TESTDIR+'Version10.txt']
95    versioncheck('VersionTestPackage', versfiles, '1.0', verbose=2)
96
97if __name__ == '__main__':
98    _test()
99