diff -r ffa851df0825 -r 2fb8b9db1c86 symbian-qemu-0.9.1-12/python-2.6.1/Demo/pdist/cvslib.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/symbian-qemu-0.9.1-12/python-2.6.1/Demo/pdist/cvslib.py Fri Jul 31 15:01:17 2009 +0100 @@ -0,0 +1,364 @@ +"""Utilities for CVS administration.""" + +import string +import os +import time +import md5 +import fnmatch + +if not hasattr(time, 'timezone'): + time.timezone = 0 + +class File: + + """Represent a file's status. + + Instance variables: + + file -- the filename (no slashes), None if uninitialized + lseen -- true if the data for the local file is up to date + eseen -- true if the data from the CVS/Entries entry is up to date + (this implies that the entry must be written back) + rseen -- true if the data for the remote file is up to date + proxy -- RCSProxy instance used to contact the server, or None + + Note that lseen and rseen don't necessary mean that a local + or remote file *exists* -- they indicate that we've checked it. + However, eseen means that this instance corresponds to an + entry in the CVS/Entries file. + + If lseen is true: + + lsum -- checksum of the local file, None if no local file + lctime -- ctime of the local file, None if no local file + lmtime -- mtime of the local file, None if no local file + + If eseen is true: + + erev -- revision, None if this is a no revision (not '0') + enew -- true if this is an uncommitted added file + edeleted -- true if this is an uncommitted removed file + ectime -- ctime of last local file corresponding to erev + emtime -- mtime of last local file corresponding to erev + extra -- 5th string from CVS/Entries file + + If rseen is true: + + rrev -- revision of head, None if non-existent + rsum -- checksum of that revision, Non if non-existent + + If eseen and rseen are both true: + + esum -- checksum of revision erev, None if no revision + + Note + """ + + def __init__(self, file = None): + if file and '/' in file: + raise ValueError, "no slash allowed in file" + self.file = file + self.lseen = self.eseen = self.rseen = 0 + self.proxy = None + + def __cmp__(self, other): + return cmp(self.file, other.file) + + def getlocal(self): + try: + self.lmtime, self.lctime = os.stat(self.file)[-2:] + except os.error: + self.lmtime = self.lctime = self.lsum = None + else: + self.lsum = md5.new(open(self.file).read()).digest() + self.lseen = 1 + + def getentry(self, line): + words = string.splitfields(line, '/') + if self.file and words[1] != self.file: + raise ValueError, "file name mismatch" + self.file = words[1] + self.erev = words[2] + self.edeleted = 0 + self.enew = 0 + self.ectime = self.emtime = None + if self.erev[:1] == '-': + self.edeleted = 1 + self.erev = self.erev[1:] + if self.erev == '0': + self.erev = None + self.enew = 1 + else: + dates = words[3] + self.ectime = unctime(dates[:24]) + self.emtime = unctime(dates[25:]) + self.extra = words[4] + if self.rseen: + self.getesum() + self.eseen = 1 + + def getremote(self, proxy = None): + if proxy: + self.proxy = proxy + try: + self.rrev = self.proxy.head(self.file) + except (os.error, IOError): + self.rrev = None + if self.rrev: + self.rsum = self.proxy.sum(self.file) + else: + self.rsum = None + if self.eseen: + self.getesum() + self.rseen = 1 + + def getesum(self): + if self.erev == self.rrev: + self.esum = self.rsum + elif self.erev: + name = (self.file, self.erev) + self.esum = self.proxy.sum(name) + else: + self.esum = None + + def putentry(self): + """Return a line suitable for inclusion in CVS/Entries. + + The returned line is terminated by a newline. + If no entry should be written for this file, + return "". + """ + if not self.eseen: + return "" + + rev = self.erev or '0' + if self.edeleted: + rev = '-' + rev + if self.enew: + dates = 'Initial ' + self.file + else: + dates = gmctime(self.ectime) + ' ' + \ + gmctime(self.emtime) + return "/%s/%s/%s/%s/\n" % ( + self.file, + rev, + dates, + self.extra) + + def report(self): + print '-'*50 + def r(key, repr=repr, self=self): + try: + value = repr(getattr(self, key)) + except AttributeError: + value = "?" + print "%-15s:" % key, value + r("file") + if self.lseen: + r("lsum", hexify) + r("lctime", gmctime) + r("lmtime", gmctime) + if self.eseen: + r("erev") + r("enew") + r("edeleted") + r("ectime", gmctime) + r("emtime", gmctime) + if self.rseen: + r("rrev") + r("rsum", hexify) + if self.eseen: + r("esum", hexify) + + +class CVS: + + """Represent the contents of a CVS admin file (and more). + + Class variables: + + FileClass -- the class to be instantiated for entries + (this should be derived from class File above) + IgnoreList -- shell patterns for local files to be ignored + + Instance variables: + + entries -- a dictionary containing File instances keyed by + their file name + proxy -- an RCSProxy instance, or None + """ + + FileClass = File + + IgnoreList = ['.*', '@*', ',*', '*~', '*.o', '*.a', '*.so', '*.pyc'] + + def __init__(self): + self.entries = {} + self.proxy = None + + def setproxy(self, proxy): + if proxy is self.proxy: + return + self.proxy = proxy + for e in self.entries.values(): + e.rseen = 0 + + def getentries(self): + """Read the contents of CVS/Entries""" + self.entries = {} + f = self.cvsopen("Entries") + while 1: + line = f.readline() + if not line: break + e = self.FileClass() + e.getentry(line) + self.entries[e.file] = e + f.close() + + def putentries(self): + """Write CVS/Entries back""" + f = self.cvsopen("Entries", 'w') + for e in self.values(): + f.write(e.putentry()) + f.close() + + def getlocalfiles(self): + list = self.entries.keys() + addlist = os.listdir(os.curdir) + for name in addlist: + if name in list: + continue + if not self.ignored(name): + list.append(name) + list.sort() + for file in list: + try: + e = self.entries[file] + except KeyError: + e = self.entries[file] = self.FileClass(file) + e.getlocal() + + def getremotefiles(self, proxy = None): + if proxy: + self.proxy = proxy + if not self.proxy: + raise RuntimeError, "no RCS proxy" + addlist = self.proxy.listfiles() + for file in addlist: + try: + e = self.entries[file] + except KeyError: + e = self.entries[file] = self.FileClass(file) + e.getremote(self.proxy) + + def report(self): + for e in self.values(): + e.report() + print '-'*50 + + def keys(self): + keys = self.entries.keys() + keys.sort() + return keys + + def values(self): + def value(key, self=self): + return self.entries[key] + return map(value, self.keys()) + + def items(self): + def item(key, self=self): + return (key, self.entries[key]) + return map(item, self.keys()) + + def cvsexists(self, file): + file = os.path.join("CVS", file) + return os.path.exists(file) + + def cvsopen(self, file, mode = 'r'): + file = os.path.join("CVS", file) + if 'r' not in mode: + self.backup(file) + return open(file, mode) + + def backup(self, file): + if os.path.isfile(file): + bfile = file + '~' + try: os.unlink(bfile) + except os.error: pass + os.rename(file, bfile) + + def ignored(self, file): + if os.path.isdir(file): return True + for pat in self.IgnoreList: + if fnmatch.fnmatch(file, pat): return True + return False + + +# hexify and unhexify are useful to print MD5 checksums in hex format + +hexify_format = '%02x' * 16 +def hexify(sum): + "Return a hex representation of a 16-byte string (e.g. an MD5 digest)" + if sum is None: + return "None" + return hexify_format % tuple(map(ord, sum)) + +def unhexify(hexsum): + "Return the original from a hexified string" + if hexsum == "None": + return None + sum = '' + for i in range(0, len(hexsum), 2): + sum = sum + chr(string.atoi(hexsum[i:i+2], 16)) + return sum + + +unctime_monthmap = {} +def unctime(date): + if date == "None": return None + if not unctime_monthmap: + months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] + i = 0 + for m in months: + i = i+1 + unctime_monthmap[m] = i + words = string.split(date) # Day Mon DD HH:MM:SS YEAR + year = string.atoi(words[4]) + month = unctime_monthmap[words[1]] + day = string.atoi(words[2]) + [hh, mm, ss] = map(string.atoi, string.splitfields(words[3], ':')) + ss = ss - time.timezone + return time.mktime((year, month, day, hh, mm, ss, 0, 0, 0)) + +def gmctime(t): + if t is None: return "None" + return time.asctime(time.gmtime(t)) + +def test_unctime(): + now = int(time.time()) + t = time.gmtime(now) + at = time.asctime(t) + print 'GMT', now, at + print 'timezone', time.timezone + print 'local', time.ctime(now) + u = unctime(at) + print 'unctime()', u + gu = time.gmtime(u) + print '->', gu + print time.asctime(gu) + +def test(): + x = CVS() + x.getentries() + x.getlocalfiles() +## x.report() + import rcsclient + proxy = rcsclient.openrcsclient() + x.getremotefiles(proxy) + x.report() + + +if __name__ == "__main__": + test()