diff options
-rwxr-xr-x | Demo/pdist/RCSProxy.py | 405 |
1 files changed, 158 insertions, 247 deletions
diff --git a/Demo/pdist/RCSProxy.py b/Demo/pdist/RCSProxy.py index 90eaff4..c22b81d 100755 --- a/Demo/pdist/RCSProxy.py +++ b/Demo/pdist/RCSProxy.py @@ -7,279 +7,190 @@ The functionality is geared towards implementing some sort of remote CVS like utility. It is modeled after the similar module FSProxy. -The module defines three classes: +The module defines two classes: RCSProxyLocal -- used for local access RCSProxyServer -- used on the server side of remote access -RCSProxyClient -- used on the client side of remote access + +An additional class, RCSProxyClient, is defined in module rcsclient. The remote classes are instantiated with an IP address and an optional verbosity flag. """ import server -import client import md5 import os import fnmatch import string import tempfile +import rcslib + + +class DirSupport: + + def __init__(self): + self._dirstack = [] + + def __del__(self): + self._close() + + def _close(self): + while self._dirstack: + self.back() + + def pwd(self): + return os.getcwd() + + def cd(self, name): + save = os.getcwd() + os.chdir(name) + self._dirstack.append(save) + + def back(self): + if not self._dirstack: + raise os.error, "empty directory stack" + dir = self._dirstack[-1] + os.chdir(dir) + del self._dirstack[-1] + + def listsubdirs(self, pat = None): + files = os.listdir(os.curdir) + files = filter(os.path.isdir, files) + return self._filter(files, pat) + + def isdir(self, name): + return os.path.isdir(name) + + def mkdir(self, name): + os.mkdir(name, 0777) + + def rmdir(self, name): + os.rmdir(name) + +class RCSProxyLocal(rcslib.RCS, DirSupport): -okchars = string.letters + string.digits + '-_=+.' - - -class RCSProxyLocal: - - def __init__(self): - self._dirstack = [] - - def _close(self): - while self._dirstack: - self.back() - - def pwd(self): - return os.getcwd() - - def cd(self, name): - save = os.getcwd() - os.chdir(name) - self._dirstack.append(save) - - def back(self): - if not self._dirstack: - raise os.error, "empty directory stack" - dir = self._dirstack[-1] - os.chdir(dir) - del self._dirstack[-1] - - def _filter(self, files, pat = None): - if pat: - def keep(name, pat = pat): - return fnmatch.fnmatch(name, pat) - files = filter(keep, files) - files.sort() - return files - - def isfile(self, name): - namev = name + ',v' - return os.path.isfile(namev) or \ - os.path.isfile(os.path.join('RCS', namev)) - - def _unmangle(self, name): - if type(name) == type(''): - rev = '' - else: - name, rev = name - return name, rev - - def checkfile(self, name): - name, rev = self._unmangle(name) - if not self.isfile(name): - raise os.error, 'not an rcs file %s' % `name` - for c in rev: - if c not in okchars: - raise ValueError, "bad char in rev" - return name, rev - - def listfiles(self, pat = None): - def isrcs(name): return name[-2:] == ',v' - def striprcs(name): return name[:-2] - files = os.listdir(os.curdir) - files = filter(isrcs, files) - if os.path.isdir('RCS'): - files2 = os.listdir('RCS') - files2 = filter(isrcs, files2) - files = files + files2 - files = map(striprcs, files) - return self._filter(files, pat) - - def listsubdirs(self, pat = None): - files = os.listdir(os.curdir) - files = filter(os.path.isdir, files) - return self._filter(files, pat) - - def isdir(self, name): - return os.path.isdir(name) - - def _open(self, name, cmd = 'co -p'): - name, rev = self.checkfile(name) - namev = name + ',v' - if rev: - cmd = cmd + ' -r' + rev - return os.popen('%s %s' % (cmd, `namev`)) - - def _closepipe(self, f): - sts = f.close() - if sts: - raise IOError, "Exit status %d" % sts - - def _remove(self, fn): - try: - os.unlink(fn) - except os.error: - pass - - def sum(self, name): - f = self._open(name) - BUFFERSIZE = 1024*8 - sum = md5.new() - while 1: - buffer = f.read(BUFFERSIZE) - if not buffer: - break - sum.update(buffer) - self._closepipe(f) - return sum.digest() - - def _list(self, function, list): - if list is None: - list = self.listfiles() - res = [] - for name in list: - try: - res.append((name, function(name))) - except (os.error, IOError): - res.append((name, None)) - return res - - def sumlist(self, list = None): - return self.list(self.sum, list) - - def _dict(self, function, list): - if list is None: - list = self.listfiles() - dict = {} - for name in list: - try: - dict[name] = function(name) - except (os.error, IOError): - pass - return dict - - def sumdict(self, list = None): - return self.dict(self.sum, list) - - def get(self, name): - f = self._open(name) - data = f.read() - self._closepipe(f) - return data - - def info(self, name): - f = self._open(name, 'rlog -h') - dict = {} - while 1: - line = f.readline() - if not line: break - if line[0] == '\t': - continue # XXX lock details, later - i = string.find(line, ':') - if i > 0: - key, value = line[:i], string.strip(line[i+1:]) - dict[key] = value - self._closepipe(f) - return dict - - def head(self, name): - dict = self.info(name) - return dict['head'] - - def log(self, name, flags = ''): - f = self._open(name, 'rlog %s 2>&1' % flags) - log = f.read() - self._closepipe(f) - return log - - def put(self, fullname, data, message = ""): - if message and message[-1] != '\n': - message = message + '\n' - name, rev = self._unmangle(fullname) - new = not self.isfile(name) - if new: - for c in name: - if c not in okchars: - raise ValueError, "bad char in name" - else: - self._remove(name) - f = open(name, 'w') - f.write(data) - f.close() - tf = tempfile.mktemp() - try: - if not new: - cmd = "rcs -l%s %s >>%s 2>&1" % (rev, name, tf) - sts = os.system(cmd) - if sts: - raise IOError, "rcs -l exit status %d" % sts - cmd = "ci -r%s %s >>%s 2>&1" % (rev, name, tf) - p = os.popen(cmd, 'w') - p.write(message) - sts = p.close() - if sts: - raise IOError, "ci exit status %d" % sts - messages = open(tf).read() - return messages or None - finally: - self._remove(tf) - - def mkdir(self, name): - os.mkdir(name, 0777) - - def rmdir(self, name): - os.rmdir(name) + def __init__(self): + rcslib.RCS.__init__(self) + DirSupport.__init__(self) + + def __del__(self): + DirSupport.__del__(self) + rcslib.RCS.__del__(self) + + def sumlist(self, list = None): + return self._list(self.sum, list) + + def sumdict(self, list = None): + return self._dict(self.sum, list) + + def sum(self, name_rev): + f = self._open(name_rev) + BUFFERSIZE = 1024*8 + sum = md5.new() + while 1: + buffer = f.read(BUFFERSIZE) + if not buffer: + break + sum.update(buffer) + self._closepipe(f) + return sum.digest() + + def get(self, name_rev): + f = self._open(name_rev) + data = f.read() + self._closepipe(f) + return data + + def put(self, name_rev, data, message=None): + name, rev = self._unmangle(name_rev) + f = open(name, 'w') + f.write(data) + f.close() + self.checkin(name_rev, message) + + def _list(self, function, list = None): + """INTERNAL: apply FUNCTION to all files in LIST. + + Return a list of the results. + + The list defaults to all files in the directory if None. + + """ + if list is None: + list = self.listfiles() + res = [] + for name in list: + try: + res.append((name, function(name))) + except (os.error, IOError): + res.append((name, None)) + return res + + def _dict(self, function, list = None): + """INTERNAL: apply FUNCTION to all files in LIST. + + Return a dictionary mapping files to results. + + The list defaults to all files in the directory if None. + + """ + if list is None: + list = self.listfiles() + dict = {} + for name in list: + try: + dict[name] = function(name) + except (os.error, IOError): + pass + return dict class RCSProxyServer(RCSProxyLocal, server.SecureServer): - - def __init__(self, address, verbose = server.VERBOSE): - RCSProxyLocal.__init__(self) - server.SecureServer.__init__(self, address, verbose) - - def _close(self): - server.SecureServer._close(self) - RCSProxyLocal._close(self) - - def _serve(self): - server.SecureServer._serve(self) - # Retreat into start directory - while self._dirstack: self.back() - - -class RCSProxyClient(client.SecureClient): - - def __init__(self, address, verbose = client.VERBOSE): - client.SecureClient.__init__(self, address, verbose) + + def __init__(self, address, verbose = server.VERBOSE): + RCSProxyLocal.__init__(self) + server.SecureServer.__init__(self, address, verbose) + + def _close(self): + server.SecureServer._close(self) + RCSProxyLocal._close(self) + + def _serve(self): + server.SecureServer._serve(self) + # Retreat into start directory + while self._dirstack: self.back() def test_server(): - import string - import sys - if sys.argv[1:]: - port = string.atoi(sys.argv[1]) - else: - port = 4127 - proxy = RCSProxyServer(('', port)) - proxy._serverloop() + import string + import sys + if sys.argv[1:]: + port = string.atoi(sys.argv[1]) + else: + port = 4127 + proxy = RCSProxyServer(('', port)) + proxy._serverloop() def test(): - import sys - if not sys.argv[1:] or sys.argv[1] and sys.argv[1][0] in '0123456789': - test_server() - sys.exit(0) - proxy = RCSProxyLocal() - what = sys.argv[1] - if hasattr(proxy, what): - attr = getattr(proxy, what) - if callable(attr): - print apply(attr, tuple(sys.argv[2:])) - else: - print `attr` + import sys + if not sys.argv[1:] or sys.argv[1] and sys.argv[1][0] in '0123456789': + test_server() + sys.exit(0) + proxy = RCSProxyLocal() + what = sys.argv[1] + if hasattr(proxy, what): + attr = getattr(proxy, what) + if callable(attr): + print apply(attr, tuple(sys.argv[2:])) else: - print "%s: no such attribute" % what - sys.exit(2) + print `attr` + else: + print "%s: no such attribute" % what + sys.exit(2) if __name__ == '__main__': - test() + test() |