| """Compare local and remote dictionaries and transfer differing files -- like rdist.""" |
| |
| import sys |
| from repr import repr |
| import FSProxy |
| import time |
| import os |
| |
| def main(): |
| pwd = os.getcwd() |
| s = raw_input("chdir [%s] " % pwd) |
| if s: |
| os.chdir(s) |
| pwd = os.getcwd() |
| host = ask("host", 'voorn.cwi.nl') |
| port = 4127 |
| verbose = 1 |
| mode = '' |
| print """\ |
| Mode should be a string of characters, indicating what to do with differences. |
| r - read different files to local file system |
| w - write different files to remote file system |
| c - create new files, either remote or local |
| d - delete disappearing files, either remote or local |
| """ |
| s = raw_input("mode [%s] " % mode) |
| if s: mode = s |
| address = (host, port) |
| t1 = time.time() |
| local = FSProxy.FSProxyLocal() |
| remote = FSProxy.FSProxyClient(address, verbose) |
| compare(local, remote, mode) |
| remote._close() |
| local._close() |
| t2 = time.time() |
| dt = t2-t1 |
| mins, secs = divmod(dt, 60) |
| print mins, "minutes and", round(secs), "seconds" |
| raw_input("[Return to exit] ") |
| |
| def ask(prompt, default): |
| s = raw_input("%s [%s] " % (prompt, default)) |
| return s or default |
| |
| def askint(prompt, default): |
| s = raw_input("%s [%s] " % (prompt, str(default))) |
| if s: return string.atoi(s) |
| return default |
| |
| def compare(local, remote, mode): |
| print |
| print "PWD =", `os.getcwd()` |
| sums_id = remote._send('sumlist') |
| subdirs_id = remote._send('listsubdirs') |
| remote._flush() |
| print "calculating local sums ..." |
| lsumdict = {} |
| for name, info in local.sumlist(): |
| lsumdict[name] = info |
| print "getting remote sums ..." |
| sums = remote._recv(sums_id) |
| print "got", len(sums) |
| rsumdict = {} |
| for name, rsum in sums: |
| rsumdict[name] = rsum |
| if not lsumdict.has_key(name): |
| print `name`, "only remote" |
| if 'r' in mode and 'c' in mode: |
| recvfile(local, remote, name) |
| else: |
| lsum = lsumdict[name] |
| if lsum != rsum: |
| print `name`, |
| rmtime = remote.mtime(name) |
| lmtime = local.mtime(name) |
| if rmtime > lmtime: |
| print "remote newer", |
| if 'r' in mode: |
| recvfile(local, remote, name) |
| elif lmtime > rmtime: |
| print "local newer", |
| if 'w' in mode: |
| sendfile(local, remote, name) |
| else: |
| print "same mtime but different sum?!?!", |
| print |
| for name in lsumdict.keys(): |
| if not rsumdict.keys(): |
| print `name`, "only locally", |
| fl() |
| if 'w' in mode and 'c' in mode: |
| sendfile(local, remote, name) |
| elif 'r' in mode and 'd' in mode: |
| os.unlink(name) |
| print "removed." |
| print |
| print "gettin subdirs ..." |
| subdirs = remote._recv(subdirs_id) |
| common = [] |
| for name in subdirs: |
| if local.isdir(name): |
| print "Common subdirectory", repr(name) |
| common.append(name) |
| else: |
| print "Remote subdirectory", repr(name), "not found locally" |
| if 'r' in mode and 'c' in mode: |
| pr = "Create local subdirectory %s? [y] " % \ |
| repr(name) |
| if 'y' in mode: |
| ok = 'y' |
| else: |
| ok = ask(pr, "y") |
| if ok[:1] in ('y', 'Y'): |
| local.mkdir(name) |
| print "Subdirectory %s made" % \ |
| repr(name) |
| common.append(name) |
| lsubdirs = local.listsubdirs() |
| for name in lsubdirs: |
| if name not in subdirs: |
| print "Local subdirectory", repr(name), "not found remotely" |
| for name in common: |
| print "Entering subdirectory", repr(name) |
| local.cd(name) |
| remote.cd(name) |
| compare(local, remote, mode) |
| remote.back() |
| local.back() |
| |
| def sendfile(local, remote, name): |
| try: |
| remote.create(name) |
| except (IOError, os.error), msg: |
| print "cannot create:", msg |
| return |
| |
| print "sending ...", |
| fl() |
| |
| data = open(name).read() |
| |
| t1 = time.time() |
| |
| remote._send_noreply('write', name, data) |
| remote._flush() |
| |
| t2 = time.time() |
| |
| dt = t2-t1 |
| print len(data), "bytes in", round(dt), "seconds", |
| if dt: |
| print "i.e.", round(len(data)/dt), "bytes/sec", |
| print |
| |
| def recvfile(local, remote, name): |
| ok = 0 |
| try: |
| rv = recvfile_real(local, remote, name) |
| ok = 1 |
| return rv |
| finally: |
| if not ok: |
| print "*** recvfile of %s failed, deleting" % `name` |
| local.delete(name) |
| |
| def recvfile_real(local, remote, name): |
| try: |
| local.create(name) |
| except (IOError, os.error), msg: |
| print "cannot create:", msg |
| return |
| |
| print "receiving ...", |
| fl() |
| |
| f = open(name, 'w') |
| t1 = time.time() |
| |
| length = 4*1024 |
| offset = 0 |
| id = remote._send('read', name, offset, length) |
| remote._flush() |
| while 1: |
| newoffset = offset + length |
| newid = remote._send('read', name, newoffset, length) |
| data = remote._recv(id) |
| id = newid |
| if not data: break |
| f.seek(offset) |
| f.write(data) |
| offset = newoffset |
| size = f.tell() |
| |
| t2 = time.time() |
| f.close() |
| |
| dt = t2-t1 |
| print size, "bytes in", round(dt), "seconds", |
| if dt: |
| print "i.e.", int(size/dt), "bytes/sec", |
| print |
| remote._recv(id) # ignored |
| |
| def fl(): |
| sys.stdout.flush() |
| |
| if __name__ == '__main__': |
| main() |