blob: e29090c12a2a21d1123c65f0dac1b636cb109a12 [file] [log] [blame]
Guido van Rossumf06ee5f1996-11-27 19:52:01 +00001#! /usr/bin/env python
Guido van Rossum5f07b841995-04-26 22:57:11 +00002
3"""RCS Proxy.
4
5Provide a simplified interface on RCS files, locally or remotely.
6The functionality is geared towards implementing some sort of
7remote CVS like utility. It is modeled after the similar module
8FSProxy.
9
Guido van Rossumab75eb21995-06-23 22:07:17 +000010The module defines two classes:
Guido van Rossum5f07b841995-04-26 22:57:11 +000011
12RCSProxyLocal -- used for local access
13RCSProxyServer -- used on the server side of remote access
Guido van Rossumab75eb21995-06-23 22:07:17 +000014
Guido van Rossumbab47251995-06-23 22:37:53 +000015The corresponding client class, RCSProxyClient, is defined in module
16rcsclient.
Guido van Rossum5f07b841995-04-26 22:57:11 +000017
18The remote classes are instantiated with an IP address and an optional
19verbosity flag.
20"""
21
22import server
Guido van Rossum5f07b841995-04-26 22:57:11 +000023import md5
24import os
25import fnmatch
26import string
27import tempfile
Guido van Rossumab75eb21995-06-23 22:07:17 +000028import rcslib
Guido van Rossum5f07b841995-04-26 22:57:11 +000029
30
Guido van Rossumab75eb21995-06-23 22:07:17 +000031class DirSupport:
32
33 def __init__(self):
34 self._dirstack = []
35
36 def __del__(self):
37 self._close()
38
39 def _close(self):
40 while self._dirstack:
41 self.back()
42
43 def pwd(self):
44 return os.getcwd()
45
46 def cd(self, name):
47 save = os.getcwd()
48 os.chdir(name)
49 self._dirstack.append(save)
50
51 def back(self):
52 if not self._dirstack:
53 raise os.error, "empty directory stack"
54 dir = self._dirstack[-1]
55 os.chdir(dir)
56 del self._dirstack[-1]
57
58 def listsubdirs(self, pat = None):
59 files = os.listdir(os.curdir)
60 files = filter(os.path.isdir, files)
61 return self._filter(files, pat)
62
63 def isdir(self, name):
64 return os.path.isdir(name)
65
66 def mkdir(self, name):
67 os.mkdir(name, 0777)
68
69 def rmdir(self, name):
70 os.rmdir(name)
Guido van Rossum5f07b841995-04-26 22:57:11 +000071
72
Guido van Rossumab75eb21995-06-23 22:07:17 +000073class RCSProxyLocal(rcslib.RCS, DirSupport):
Guido van Rossum5f07b841995-04-26 22:57:11 +000074
Guido van Rossumab75eb21995-06-23 22:07:17 +000075 def __init__(self):
76 rcslib.RCS.__init__(self)
77 DirSupport.__init__(self)
Guido van Rossum5f07b841995-04-26 22:57:11 +000078
Guido van Rossumab75eb21995-06-23 22:07:17 +000079 def __del__(self):
80 DirSupport.__del__(self)
81 rcslib.RCS.__del__(self)
Guido van Rossum5f07b841995-04-26 22:57:11 +000082
Guido van Rossumab75eb21995-06-23 22:07:17 +000083 def sumlist(self, list = None):
84 return self._list(self.sum, list)
Guido van Rossum5f07b841995-04-26 22:57:11 +000085
Guido van Rossumab75eb21995-06-23 22:07:17 +000086 def sumdict(self, list = None):
87 return self._dict(self.sum, list)
Guido van Rossum5f07b841995-04-26 22:57:11 +000088
Guido van Rossumab75eb21995-06-23 22:07:17 +000089 def sum(self, name_rev):
90 f = self._open(name_rev)
91 BUFFERSIZE = 1024*8
92 sum = md5.new()
93 while 1:
94 buffer = f.read(BUFFERSIZE)
95 if not buffer:
96 break
97 sum.update(buffer)
98 self._closepipe(f)
99 return sum.digest()
100
101 def get(self, name_rev):
102 f = self._open(name_rev)
103 data = f.read()
104 self._closepipe(f)
105 return data
106
107 def put(self, name_rev, data, message=None):
108 name, rev = self._unmangle(name_rev)
109 f = open(name, 'w')
110 f.write(data)
111 f.close()
112 self.checkin(name_rev, message)
Guido van Rossumbab47251995-06-23 22:37:53 +0000113 self._remove(name)
Guido van Rossumab75eb21995-06-23 22:07:17 +0000114
115 def _list(self, function, list = None):
116 """INTERNAL: apply FUNCTION to all files in LIST.
117
118 Return a list of the results.
119
120 The list defaults to all files in the directory if None.
121
122 """
123 if list is None:
124 list = self.listfiles()
125 res = []
126 for name in list:
127 try:
128 res.append((name, function(name)))
129 except (os.error, IOError):
130 res.append((name, None))
131 return res
132
133 def _dict(self, function, list = None):
134 """INTERNAL: apply FUNCTION to all files in LIST.
135
136 Return a dictionary mapping files to results.
137
138 The list defaults to all files in the directory if None.
139
140 """
141 if list is None:
142 list = self.listfiles()
143 dict = {}
144 for name in list:
145 try:
146 dict[name] = function(name)
147 except (os.error, IOError):
148 pass
149 return dict
Guido van Rossum5f07b841995-04-26 22:57:11 +0000150
151
Guido van Rossumf3d39ab1995-06-21 02:09:20 +0000152class RCSProxyServer(RCSProxyLocal, server.SecureServer):
Guido van Rossum5f07b841995-04-26 22:57:11 +0000153
Guido van Rossumab75eb21995-06-23 22:07:17 +0000154 def __init__(self, address, verbose = server.VERBOSE):
155 RCSProxyLocal.__init__(self)
156 server.SecureServer.__init__(self, address, verbose)
Guido van Rossum5f07b841995-04-26 22:57:11 +0000157
Guido van Rossumab75eb21995-06-23 22:07:17 +0000158 def _close(self):
159 server.SecureServer._close(self)
160 RCSProxyLocal._close(self)
161
162 def _serve(self):
163 server.SecureServer._serve(self)
164 # Retreat into start directory
165 while self._dirstack: self.back()
Guido van Rossum5f07b841995-04-26 22:57:11 +0000166
167
168def test_server():
Guido van Rossumab75eb21995-06-23 22:07:17 +0000169 import string
170 import sys
171 if sys.argv[1:]:
172 port = string.atoi(sys.argv[1])
173 else:
174 port = 4127
175 proxy = RCSProxyServer(('', port))
176 proxy._serverloop()
Guido van Rossum5f07b841995-04-26 22:57:11 +0000177
178
179def test():
Guido van Rossumab75eb21995-06-23 22:07:17 +0000180 import sys
181 if not sys.argv[1:] or sys.argv[1] and sys.argv[1][0] in '0123456789':
182 test_server()
183 sys.exit(0)
184 proxy = RCSProxyLocal()
185 what = sys.argv[1]
186 if hasattr(proxy, what):
187 attr = getattr(proxy, what)
188 if callable(attr):
189 print apply(attr, tuple(sys.argv[2:]))
Guido van Rossum5f07b841995-04-26 22:57:11 +0000190 else:
Guido van Rossumab75eb21995-06-23 22:07:17 +0000191 print `attr`
192 else:
193 print "%s: no such attribute" % what
194 sys.exit(2)
Guido van Rossum5f07b841995-04-26 22:57:11 +0000195
196
197if __name__ == '__main__':
Guido van Rossumab75eb21995-06-23 22:07:17 +0000198 test()