|
1 """Compare local and remote dictionaries and transfer differing files -- like rdist.""" |
|
2 |
|
3 import sys |
|
4 from repr import repr |
|
5 import FSProxy |
|
6 import time |
|
7 import os |
|
8 |
|
9 def main(): |
|
10 pwd = os.getcwd() |
|
11 s = raw_input("chdir [%s] " % pwd) |
|
12 if s: |
|
13 os.chdir(s) |
|
14 pwd = os.getcwd() |
|
15 host = ask("host", 'voorn.cwi.nl') |
|
16 port = 4127 |
|
17 verbose = 1 |
|
18 mode = '' |
|
19 print """\ |
|
20 Mode should be a string of characters, indicating what to do with differences. |
|
21 r - read different files to local file system |
|
22 w - write different files to remote file system |
|
23 c - create new files, either remote or local |
|
24 d - delete disappearing files, either remote or local |
|
25 """ |
|
26 s = raw_input("mode [%s] " % mode) |
|
27 if s: mode = s |
|
28 address = (host, port) |
|
29 t1 = time.time() |
|
30 local = FSProxy.FSProxyLocal() |
|
31 remote = FSProxy.FSProxyClient(address, verbose) |
|
32 compare(local, remote, mode) |
|
33 remote._close() |
|
34 local._close() |
|
35 t2 = time.time() |
|
36 dt = t2-t1 |
|
37 mins, secs = divmod(dt, 60) |
|
38 print mins, "minutes and", round(secs), "seconds" |
|
39 raw_input("[Return to exit] ") |
|
40 |
|
41 def ask(prompt, default): |
|
42 s = raw_input("%s [%s] " % (prompt, default)) |
|
43 return s or default |
|
44 |
|
45 def askint(prompt, default): |
|
46 s = raw_input("%s [%s] " % (prompt, str(default))) |
|
47 if s: return string.atoi(s) |
|
48 return default |
|
49 |
|
50 def compare(local, remote, mode): |
|
51 print |
|
52 print "PWD =", repr(os.getcwd()) |
|
53 sums_id = remote._send('sumlist') |
|
54 subdirs_id = remote._send('listsubdirs') |
|
55 remote._flush() |
|
56 print "calculating local sums ..." |
|
57 lsumdict = {} |
|
58 for name, info in local.sumlist(): |
|
59 lsumdict[name] = info |
|
60 print "getting remote sums ..." |
|
61 sums = remote._recv(sums_id) |
|
62 print "got", len(sums) |
|
63 rsumdict = {} |
|
64 for name, rsum in sums: |
|
65 rsumdict[name] = rsum |
|
66 if not lsumdict.has_key(name): |
|
67 print repr(name), "only remote" |
|
68 if 'r' in mode and 'c' in mode: |
|
69 recvfile(local, remote, name) |
|
70 else: |
|
71 lsum = lsumdict[name] |
|
72 if lsum != rsum: |
|
73 print repr(name), |
|
74 rmtime = remote.mtime(name) |
|
75 lmtime = local.mtime(name) |
|
76 if rmtime > lmtime: |
|
77 print "remote newer", |
|
78 if 'r' in mode: |
|
79 recvfile(local, remote, name) |
|
80 elif lmtime > rmtime: |
|
81 print "local newer", |
|
82 if 'w' in mode: |
|
83 sendfile(local, remote, name) |
|
84 else: |
|
85 print "same mtime but different sum?!?!", |
|
86 print |
|
87 for name in lsumdict.keys(): |
|
88 if not rsumdict.keys(): |
|
89 print repr(name), "only locally", |
|
90 fl() |
|
91 if 'w' in mode and 'c' in mode: |
|
92 sendfile(local, remote, name) |
|
93 elif 'r' in mode and 'd' in mode: |
|
94 os.unlink(name) |
|
95 print "removed." |
|
96 print |
|
97 print "gettin subdirs ..." |
|
98 subdirs = remote._recv(subdirs_id) |
|
99 common = [] |
|
100 for name in subdirs: |
|
101 if local.isdir(name): |
|
102 print "Common subdirectory", repr(name) |
|
103 common.append(name) |
|
104 else: |
|
105 print "Remote subdirectory", repr(name), "not found locally" |
|
106 if 'r' in mode and 'c' in mode: |
|
107 pr = "Create local subdirectory %s? [y] " % \ |
|
108 repr(name) |
|
109 if 'y' in mode: |
|
110 ok = 'y' |
|
111 else: |
|
112 ok = ask(pr, "y") |
|
113 if ok[:1] in ('y', 'Y'): |
|
114 local.mkdir(name) |
|
115 print "Subdirectory %s made" % \ |
|
116 repr(name) |
|
117 common.append(name) |
|
118 lsubdirs = local.listsubdirs() |
|
119 for name in lsubdirs: |
|
120 if name not in subdirs: |
|
121 print "Local subdirectory", repr(name), "not found remotely" |
|
122 for name in common: |
|
123 print "Entering subdirectory", repr(name) |
|
124 local.cd(name) |
|
125 remote.cd(name) |
|
126 compare(local, remote, mode) |
|
127 remote.back() |
|
128 local.back() |
|
129 |
|
130 def sendfile(local, remote, name): |
|
131 try: |
|
132 remote.create(name) |
|
133 except (IOError, os.error), msg: |
|
134 print "cannot create:", msg |
|
135 return |
|
136 |
|
137 print "sending ...", |
|
138 fl() |
|
139 |
|
140 data = open(name).read() |
|
141 |
|
142 t1 = time.time() |
|
143 |
|
144 remote._send_noreply('write', name, data) |
|
145 remote._flush() |
|
146 |
|
147 t2 = time.time() |
|
148 |
|
149 dt = t2-t1 |
|
150 print len(data), "bytes in", round(dt), "seconds", |
|
151 if dt: |
|
152 print "i.e.", round(len(data)/dt), "bytes/sec", |
|
153 print |
|
154 |
|
155 def recvfile(local, remote, name): |
|
156 ok = 0 |
|
157 try: |
|
158 rv = recvfile_real(local, remote, name) |
|
159 ok = 1 |
|
160 return rv |
|
161 finally: |
|
162 if not ok: |
|
163 print "*** recvfile of %r failed, deleting" % (name,) |
|
164 local.delete(name) |
|
165 |
|
166 def recvfile_real(local, remote, name): |
|
167 try: |
|
168 local.create(name) |
|
169 except (IOError, os.error), msg: |
|
170 print "cannot create:", msg |
|
171 return |
|
172 |
|
173 print "receiving ...", |
|
174 fl() |
|
175 |
|
176 f = open(name, 'w') |
|
177 t1 = time.time() |
|
178 |
|
179 length = 4*1024 |
|
180 offset = 0 |
|
181 id = remote._send('read', name, offset, length) |
|
182 remote._flush() |
|
183 while 1: |
|
184 newoffset = offset + length |
|
185 newid = remote._send('read', name, newoffset, length) |
|
186 data = remote._recv(id) |
|
187 id = newid |
|
188 if not data: break |
|
189 f.seek(offset) |
|
190 f.write(data) |
|
191 offset = newoffset |
|
192 size = f.tell() |
|
193 |
|
194 t2 = time.time() |
|
195 f.close() |
|
196 |
|
197 dt = t2-t1 |
|
198 print size, "bytes in", round(dt), "seconds", |
|
199 if dt: |
|
200 print "i.e.", size//dt, "bytes/sec", |
|
201 print |
|
202 remote._recv(id) # ignored |
|
203 |
|
204 def fl(): |
|
205 sys.stdout.flush() |
|
206 |
|
207 if __name__ == '__main__': |
|
208 main() |