1"""Compare local and remote dictionaries and transfer differing files -- like rdist.""" 2 3import sys 4from repr import repr 5import FSProxy 6import time 7import os 8 9def 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 """\ 20Mode should be a string of characters, indicating what to do with differences. 21r - read different files to local file system 22w - write different files to remote file system 23c - create new files, either remote or local 24d - 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 41def ask(prompt, default): 42 s = raw_input("%s [%s] " % (prompt, default)) 43 return s or default 44 45def askint(prompt, default): 46 s = raw_input("%s [%s] " % (prompt, str(default))) 47 if s: return string.atoi(s) 48 return default 49 50def 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 130def 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 155def 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 166def 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 204def fl(): 205 sys.stdout.flush() 206 207if __name__ == '__main__': 208 main() 209