"""Compare local and remote dictionaries and transfer differing files -- like rdist.""" import sys from reprlib import repr import FSProxy import time import os def raw_input(prompt): sys.stdout.write(prompt) sys.stdout.flush() return sys.stdin.readline() def main(): pwd = os.getcwd() s = 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 = 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") input("[Return to exit] ") def ask(prompt, default): s = input("%s [%s] " % (prompt, default)) return s or default def askint(prompt, default): s = input("%s [%s] " % (prompt, str(default))) if s: return string.atoi(s) return default def compare(local, remote, mode): print() print("PWD =", repr(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 name not in lsumdict: print(repr(name), "only remote") if 'r' in mode and 'c' in mode: recvfile(local, remote, name) else: lsum = lsumdict[name] if lsum != rsum: print(repr(name), end=' ') rmtime = remote.mtime(name) lmtime = local.mtime(name) if rmtime > lmtime: print("remote newer", end=' ') if 'r' in mode: recvfile(local, remote, name) elif lmtime > rmtime: print("local newer", end=' ') if 'w' in mode: sendfile(local, remote, name) else: print("same mtime but different sum?!?!", end=' ') print() for name in lsumdict.keys(): if not list(rsumdict.keys()): print(repr(name), "only locally", end=' ') 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) as msg: print("cannot create:", msg) return print("sending ...", end=' ') 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", end=' ') if dt: print("i.e.", round(len(data)/dt), "bytes/sec", end=' ') 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 %r failed, deleting" % (name,)) local.delete(name) def recvfile_real(local, remote, name): try: local.create(name) except (IOError, os.error) as msg: print("cannot create:", msg) return print("receiving ...", end=' ') 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", end=' ') if dt: print("i.e.", int(size//dt), "bytes/sec", end=' ') print() remote._recv(id) # ignored def fl(): sys.stdout.flush() if __name__ == '__main__': main()