PageRenderTime 325ms CodeModel.GetById 150ms app.highlight 63ms RepoModel.GetById 109ms app.codeStats 0ms

/Demo/pdist/cmptree.py

http://unladen-swallow.googlecode.com/
Python | 208 lines | 205 code | 2 blank | 1 comment | 1 complexity | 3436a17bd9b1eaaede8f6d94a3a49d61 MD5 | raw file
  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()