#!/usr/bin/env python # -*- coding: iso-8859-15 -*- # Distributed under the terms of the GNU General Public License v2 # Version 0.1 import urllib, urllib2, re, os, sys from urlparse import urlparse def help(): print """ $ vc [URL] [OPTIONS] VC is a Version Control application. VC reads the version number from a text file in a website and checks it against the local version number. If your files are outdated, it patches them with ones downloaded from the server. The URL has to include the full path to the file. For example, this would be a valid URL: http://www.domain.com/directory/versions.txt '-v' makes vc verbose. In verbose mode, the output of all subprocesses are piped to you. Verbose mode is off my default.""" sys.exit() def get_text(url): """Makes a request to the specified URL and returns the content of the remote vc.txt file.""" request = urllib2.Request(url) return urllib2.urlopen(request).read() def get_version_numbers(text, type): """Uses a regular expression to grab the version numbers from the code retrieved by get_text() and returns it in the form of a list.""" versions = [] raw_versions = re.compile('\w\d+[.]\d+').findall(text) for x in raw_versions: if "a" or "b" or "c" in raw_versions: versions.append(x) else: print "Warning: non-matching version numbers in remote text file\n" if len(versions) == 3: versions.sort() if type == 1: version_result = """These are the latest version numbers: Program: %s Code: %s Graphics: %s\n""" % (versions[0], versions[1], versions[2]) else: version_result = """These are the version numbers in your text file: Program: %s Code: %s Graphics: %s\n""" % (versions[0], versions[1], versions[2]) print version_result else: sys.stderr.write("Could not find version numbers in text file.\n") sys.exit() return versions def get_file_urls(text): """Uses a regular expression to grab the urls from the code retrieved by get_text() and returns it in the form of a list.""" raw_files = re.compile('http://[.a-z~\-\/]+').findall(text) files = [] for x in raw_files: if "program" or "code" or "graphics" in x: files.append(x) else: print "Warning: non-matching file URL found in remote text file.\n" if len(files) == 3: files.sort() else: sys.stderr.write("Could not find file URLs in text file.\n") sys.exit() return files def get_files(url): """Uses wget to download the files specifies by get_file_urls() to the current directory.""" if verbose == True: down_command = "wget %s" % url else: down_command = "wget -q %s" % url os.popen(down_command) def get_local_version_numbers(): """Extracts and returns a list of the local version numbers from the vc.txt file.""" try: local_file = open("vc.txt", "r") except: sys.stderr.write("Could not find local version file (vc.txt)\n") sys.exit() file_lines = local_file.readlines() local_versions = "".join(file_lines) local_file.close() local_versions = local_versions.split() local_versions.sort() if len(local_versions) < 3: sys.stderr.write("Could not find enough version numbers in local version file (vc.txt)\n") sys.exit() else: return local_versions def update(local, remote): """Compares the local version numbers against the remote ones. If something is found to be outdated, it runs get_files() and decompress() on it.""" components = ["program is", "code is", "graphics are"] for x in range(len(local)): local_number = (local[x]) remote_number = (remote[x]) if local_number < remote_number: print "The %s outdated. Getting files now.\n" % components[x] url_temp = get_file_urls(text)[x] try: get_files(url_temp) except: sys.stderr.write("Unexpected error while downloading file\n") sys.exit() try: decompress(get_filename(get_file_urls(text)[x])) except: sys.stderr.write("Unexpected error while decompressing file\n") sys.exit() else: print "The %s up to date. Checking next component.\n" % components[x] def decompress(file): """Checks that the file is tar.gz. If so, it runs tar to decompress and unpack it. Verbose toggling applies here.""" if file[-6:] != "tar.gz": sys.stderr.write("Downloaded file is not compatible\n") sys.exit() else: if verbose == True: decom_command = "tar -xzvf %s" % file else: decom_command = "tar -xzf %s" % file print file os.popen(decom_command) def get_filename(url): """From the full url, it returns the filename only.""" url = urlparse(url) url = list(url) filename = url[2].split("/") filename = filename[-1] return filename def update_file(local_versions, versions): """Writes new version numbers to local file.""" try: local_file = open("vc.txt", "w") except: sys.stderr.write("Could not find local version file (vc.txt)\n") sys.exit() for x in range(len(local_versions)): local_versions[x] = versions[x] local_file.write(local_versions[x]) local_file.write("\n") local_file.close() verbose = False if len(sys.argv) < 2: help() else: url = sys.argv[1] if url.count("://") == 0: url = "http://" + url if sys.argv > 2 and sys.argv[-1] == "-v": verbose = True text = get_text(url) try: update(get_local_version_numbers(), get_version_numbers(text, 1)) except: sys.stderr.write("Unexpected error while updating.\n") sys.exit() try: update_file(get_local_version_numbers(), get_version_numbers(text, 0), ) except: sys.stderr.write("Unexpected error while updating local file.\n") sys.exit()