from __future__ import with_statement import MySQLdb as mysql import glob import difflib import os import time import sys import string ## Usage: vcs.py ## ## You must manually create the database 'vcs' ## ## Function: ## --------- ## ## install - install the table/s required for the operation of vcs ## commit - forcefully update all files ## start_service [#]- start periodic update service. Where # is defined, update ever # seconds ## default: 300 secs ## update - update ## regress - revert or all db = mysql.connect(user='root', passwd='', db='vcs').cursor() def get_project(name = None): if not name: proj_file = glob.glob('*.PROJ') if len(proj_file) == 0: proj_name = raw_input('\nPlease enter a name for the project: ') if proj_name: with open('%s.PROJ' % proj_name, 'w') as f: f.write(proj_name) else: sys.stderr.write('Error: Must enter a name for the project!!') sys.exit(1) else: return proj_file[0] else: with open('%s.PROJ' % name, 'w') as f: f.write(name) project = get_project() def install(): sys.stdout.write('\nInstalling tables...\n') sys.stdout.write('Installing FILES table\n') sql = r'''CREATE TABLE files ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, project VARCHAR(255), name VARCHAR(255), last_chg VARCHAR(24), data LONGTEXT ) ''' db.execute(sql) sys.stdout.write('Done!\n') def update(f): with open(f, 'r') as data: buffer = data.read() t = time.time() #print 'INSERT INTO files VALUES (NULL, "%s", "%s", "%s")' % (f, t, buffer) db.execute('INSERT INTO files VALUES (0, "%s", "%s", "%s", "%s")' % (project, f, t, buffer)) def start_service(period=300): sys.stdout.write('\nStarting VCS periodic update service...\n') files = glob.glob('*.py') diff = {} for f in files: diff[f] = os.stat(f) while(1): files = glob.glob('*.py') num_files = len(files) count = 0 sys.stdout.write('\nExecuting periodic update\n') sys.stdout.write('Time: %s\n' % time.strftime('%H:%M:%S')) sys.stdout.write('Checking %s files...\n' % num_files) for f in files: if f is 'vcs.py': continue if diff[f] <> os.stat(f): update(f) sys.stdout.write('Updating %s\n' % f) count += 1 sys.stdout.write('Finished!\n\nUpdated %s files\n' % count) time.sleep(period) def commit(): sys.stdout.write('\nInitiating update all...\n\n') files = glob.glob('*.py') count = 0 for f in files: if f == 'vcs.py': continue sys.stdout.write('Updating %s\n' % f) update(f) count += 1 sys.stdout.write('\nUpdated %s files\n' % count) def revert_one(name): sql = 'SELECT * FROM files WHERE name="%s" AND project="%s" ORDER BY last_chg DESC LIMIT 1' % (name, project) db.execute(sql) latest = db.fetchone() if not latest: sys.stderr.write('Warning: Database contains no file %s!!\n' % name) #sys.exit(1) return os.remove(name) with open(name, 'w') as f: f.write(latest[4]) sys.stdout.write('File: %s reverted to database version stored: %s\n' % (name, time.strftime("%a, %d %b %Y %H:%M:%S", time.gmtime(float(latest[3]))))) def regress(name=None): if name: name = name if name.endswith('.py') else name + '.py' revert_one(name) else: files = glob.glob('*.py') for f in files: if f == 'vcs.py': continue revert_one(f) def start_project(): commit() #other init stuff as it comes up if __name__ == '__main__': arg = sys.argv if arg[0] == 'python': arg = arg[1:] if len(arg) == 1: sys.stderr.write('\nUsage: python vcs \n') sys.exit(1) if arg[1] in dir(): if len(arg) > 2: exec('%s("%s")' % (arg[1], string.join(arg[2:],','))) else: exec('%s()' % arg[1]) else: sys.stderr.write('\nUsage: python vcs \n') sys.exit(1)