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()
|
---|