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