cpython/Demo/pdist/cmptree.py

214 lines
5.9 KiB
Python
Executable File

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