#! /usr/bin/env python3.3
"""Program to check for product updates at updates.perforce.com.
Using an https call,
retrieve as json the current Git Fusion product version from updates.perforce.com
and send the local Git Fusion and P4D versions to Perforce.
Parse the returned json containing the current Git Fusion version and report a message
whether updates are available.
"""
import urllib.request
import urllib.error
import json
import p4gf_util
import p4gf_version_3
from p4gf_l10n import _
NO_UPDATES_EXISTS = _("""
Your Git Fusion version {version} is up to date.
""")
UPDATES_EXIST = _("""
There are updates available for Git Fusion.
You have version {have_version}. The current version is {current_version}.
""")
PATCH_EXISTS = _("""
There are updates available for Git Fusion.
Your Git Fusion version {version} is up to date.
However there is a patch available.
""")
URL_ERROR_MSG = _("""
Error attempting to determine current Git Fusion product versions.
url: {url}
{error}
""")
ERROR_MSG = _("""
Error attempting to determine current Git Fusion product versions.
""")
JSON_KEY_ERROR_MSG = _("""
Unexpected json format from updates.perforce.com.
""")
GF_PRODUCT_URL = 'https://updates.perforce.com/static/Git%20Fusion/Git%20Fusion.json'
# url format for retrieving as json the current product versions and reporting local versions
# https://updates.perforce.com/static/Git%20Fusion/Git%20Fusion.json?product=Git%20Fusion/NOARCH/2014.1/1013672
# %26product=P4D/DARWIN90X86_64/2015.2.MAIN-TEST_ONLY/1032249
#
def main():
"""Program to check for product updates at updates.perforce.com."""
desc = _("Report if updates are available by checking at updates.perforce.com.")
parser = p4gf_util.create_arg_parser(desc=desc, add_debug_arg=True)
parser.add_argument('--p4port', '-p', metavar='P4PORT',
help=_('P4PORT of server - optional - also report P4D version '
'data to Perforce'))
args = parser.parse_args()
# get the Git Fusion and P4D product version strings
(gf_version, server_version) = get_product_version_strings(args)
# Get the local GF version info as dict
this_version = p4gf_version_3.as_dict(include_checksum=True)
# Munge version strings into url paramters required by updates.perforce.com
# add NOARCH to gf version
gf_version = gf_version.replace('Git Fusion', 'Git%20Fusion/NOARCH')
url = GF_PRODUCT_URL + '?product=' + gf_version
if server_version:
url = url + '%26product=' + server_version
# Ensure all spaces are encoded
url = url.replace(' ', '%20')
if 'debug' in args:
print("debug: url:{}".format(url))
try:
webfile = urllib.request.urlopen(url)
except (urllib.error.URLError, urllib.error.HTTPError) as e:
return URL_ERROR_MSG.format(url=url, error=str(e))
# make the query to the url
data = webfile.read()
if not data:
return ERROR_MSG
product_version = json.loads(data.decode())
if 'debug' in args:
print("debug: json data:{}".format(product_version))
if 'current' not in product_version:
return JSON_KEY_ERROR_MSG
# Parse the data and compare
c = product_version['current']
current_year_sub = year_sub_to_float(c['major'], c['minor'])
this_version_year_sub = year_sub_to_float(this_version['release_year'],
this_version['release_sub'])
message = NO_UPDATES_EXISTS.format(version=current_year_sub)
if this_version_year_sub < current_year_sub:
message = UPDATES_EXIST.format(have_version=this_version_year_sub,
current_version=current_year_sub)
elif this_version_year_sub == current_year_sub and this_version['patchlevel'] < c['build']:
message = PATCH_EXISTS.format(version=current_year_sub)
return message
def get_product_version_strings(args):
"""Return the Git Fusion and (optionally) P4D version strings.
The Git Fusion version line looks like this:
'Rev. Git Fusion/2015.1/1013673 (2014/11/21).'
The P4D version line looks like this:
'Server version: P4D/DARWIN90X86_64/2015.2.MAIN-TEST_ONLY/1032249 (2015/03/26)'
"""
if args and 'p4port' in args and args.p4port:
this_version_array = p4gf_version_3.as_string_extended(
args=args, include_checksum=True).split('\n')
else:
this_version_array = p4gf_version_3.as_string(include_checksum=True).split('\n')
gf_version = None
server_version = None
for l in this_version_array:
if l.startswith('Rev'):
gf_version = l.split('(')[0].split(' ', 1)[1].strip()
if l.startswith('Server version:'):
server_version = l.split(' ')[2].strip()
return (gf_version, server_version)
def year_sub_to_float(year, sub):
"""Convert year, sub to float."""
return float(year + '.' + sub)
if __name__ == "__main__":
print(main())