summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xDemo/pdist/RCSProxy.py405
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()