• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()
209