]>
Commit | Line | Data |
---|---|---|
4710c53d | 1 | """Compare local and remote dictionaries and transfer differing files -- like rdist."""\r |
2 | \r | |
3 | import sys\r | |
4 | from repr import repr\r | |
5 | import FSProxy\r | |
6 | import time\r | |
7 | import os\r | |
8 | \r | |
9 | def main():\r | |
10 | pwd = os.getcwd()\r | |
11 | s = raw_input("chdir [%s] " % pwd)\r | |
12 | if s:\r | |
13 | os.chdir(s)\r | |
14 | pwd = os.getcwd()\r | |
15 | host = ask("host", 'voorn.cwi.nl')\r | |
16 | port = 4127\r | |
17 | verbose = 1\r | |
18 | mode = ''\r | |
19 | print """\\r | |
20 | Mode should be a string of characters, indicating what to do with differences.\r | |
21 | r - read different files to local file system\r | |
22 | w - write different files to remote file system\r | |
23 | c - create new files, either remote or local\r | |
24 | d - delete disappearing files, either remote or local\r | |
25 | """\r | |
26 | s = raw_input("mode [%s] " % mode)\r | |
27 | if s: mode = s\r | |
28 | address = (host, port)\r | |
29 | t1 = time.time()\r | |
30 | local = FSProxy.FSProxyLocal()\r | |
31 | remote = FSProxy.FSProxyClient(address, verbose)\r | |
32 | compare(local, remote, mode)\r | |
33 | remote._close()\r | |
34 | local._close()\r | |
35 | t2 = time.time()\r | |
36 | dt = t2-t1\r | |
37 | mins, secs = divmod(dt, 60)\r | |
38 | print mins, "minutes and", round(secs), "seconds"\r | |
39 | raw_input("[Return to exit] ")\r | |
40 | \r | |
41 | def ask(prompt, default):\r | |
42 | s = raw_input("%s [%s] " % (prompt, default))\r | |
43 | return s or default\r | |
44 | \r | |
45 | def askint(prompt, default):\r | |
46 | s = raw_input("%s [%s] " % (prompt, str(default)))\r | |
47 | if s: return string.atoi(s)\r | |
48 | return default\r | |
49 | \r | |
50 | def compare(local, remote, mode):\r | |
51 | print\r | |
52 | print "PWD =", repr(os.getcwd())\r | |
53 | sums_id = remote._send('sumlist')\r | |
54 | subdirs_id = remote._send('listsubdirs')\r | |
55 | remote._flush()\r | |
56 | print "calculating local sums ..."\r | |
57 | lsumdict = {}\r | |
58 | for name, info in local.sumlist():\r | |
59 | lsumdict[name] = info\r | |
60 | print "getting remote sums ..."\r | |
61 | sums = remote._recv(sums_id)\r | |
62 | print "got", len(sums)\r | |
63 | rsumdict = {}\r | |
64 | for name, rsum in sums:\r | |
65 | rsumdict[name] = rsum\r | |
66 | if not lsumdict.has_key(name):\r | |
67 | print repr(name), "only remote"\r | |
68 | if 'r' in mode and 'c' in mode:\r | |
69 | recvfile(local, remote, name)\r | |
70 | else:\r | |
71 | lsum = lsumdict[name]\r | |
72 | if lsum != rsum:\r | |
73 | print repr(name),\r | |
74 | rmtime = remote.mtime(name)\r | |
75 | lmtime = local.mtime(name)\r | |
76 | if rmtime > lmtime:\r | |
77 | print "remote newer",\r | |
78 | if 'r' in mode:\r | |
79 | recvfile(local, remote, name)\r | |
80 | elif lmtime > rmtime:\r | |
81 | print "local newer",\r | |
82 | if 'w' in mode:\r | |
83 | sendfile(local, remote, name)\r | |
84 | else:\r | |
85 | print "same mtime but different sum?!?!",\r | |
86 | print\r | |
87 | for name in lsumdict.keys():\r | |
88 | if not rsumdict.keys():\r | |
89 | print repr(name), "only locally",\r | |
90 | fl()\r | |
91 | if 'w' in mode and 'c' in mode:\r | |
92 | sendfile(local, remote, name)\r | |
93 | elif 'r' in mode and 'd' in mode:\r | |
94 | os.unlink(name)\r | |
95 | print "removed."\r | |
96 | print\r | |
97 | print "gettin subdirs ..."\r | |
98 | subdirs = remote._recv(subdirs_id)\r | |
99 | common = []\r | |
100 | for name in subdirs:\r | |
101 | if local.isdir(name):\r | |
102 | print "Common subdirectory", repr(name)\r | |
103 | common.append(name)\r | |
104 | else:\r | |
105 | print "Remote subdirectory", repr(name), "not found locally"\r | |
106 | if 'r' in mode and 'c' in mode:\r | |
107 | pr = "Create local subdirectory %s? [y] " % \\r | |
108 | repr(name)\r | |
109 | if 'y' in mode:\r | |
110 | ok = 'y'\r | |
111 | else:\r | |
112 | ok = ask(pr, "y")\r | |
113 | if ok[:1] in ('y', 'Y'):\r | |
114 | local.mkdir(name)\r | |
115 | print "Subdirectory %s made" % \\r | |
116 | repr(name)\r | |
117 | common.append(name)\r | |
118 | lsubdirs = local.listsubdirs()\r | |
119 | for name in lsubdirs:\r | |
120 | if name not in subdirs:\r | |
121 | print "Local subdirectory", repr(name), "not found remotely"\r | |
122 | for name in common:\r | |
123 | print "Entering subdirectory", repr(name)\r | |
124 | local.cd(name)\r | |
125 | remote.cd(name)\r | |
126 | compare(local, remote, mode)\r | |
127 | remote.back()\r | |
128 | local.back()\r | |
129 | \r | |
130 | def sendfile(local, remote, name):\r | |
131 | try:\r | |
132 | remote.create(name)\r | |
133 | except (IOError, os.error), msg:\r | |
134 | print "cannot create:", msg\r | |
135 | return\r | |
136 | \r | |
137 | print "sending ...",\r | |
138 | fl()\r | |
139 | \r | |
140 | data = open(name).read()\r | |
141 | \r | |
142 | t1 = time.time()\r | |
143 | \r | |
144 | remote._send_noreply('write', name, data)\r | |
145 | remote._flush()\r | |
146 | \r | |
147 | t2 = time.time()\r | |
148 | \r | |
149 | dt = t2-t1\r | |
150 | print len(data), "bytes in", round(dt), "seconds",\r | |
151 | if dt:\r | |
152 | print "i.e.", round(len(data)/dt), "bytes/sec",\r | |
153 | print\r | |
154 | \r | |
155 | def recvfile(local, remote, name):\r | |
156 | ok = 0\r | |
157 | try:\r | |
158 | rv = recvfile_real(local, remote, name)\r | |
159 | ok = 1\r | |
160 | return rv\r | |
161 | finally:\r | |
162 | if not ok:\r | |
163 | print "*** recvfile of %r failed, deleting" % (name,)\r | |
164 | local.delete(name)\r | |
165 | \r | |
166 | def recvfile_real(local, remote, name):\r | |
167 | try:\r | |
168 | local.create(name)\r | |
169 | except (IOError, os.error), msg:\r | |
170 | print "cannot create:", msg\r | |
171 | return\r | |
172 | \r | |
173 | print "receiving ...",\r | |
174 | fl()\r | |
175 | \r | |
176 | f = open(name, 'w')\r | |
177 | t1 = time.time()\r | |
178 | \r | |
179 | length = 4*1024\r | |
180 | offset = 0\r | |
181 | id = remote._send('read', name, offset, length)\r | |
182 | remote._flush()\r | |
183 | while 1:\r | |
184 | newoffset = offset + length\r | |
185 | newid = remote._send('read', name, newoffset, length)\r | |
186 | data = remote._recv(id)\r | |
187 | id = newid\r | |
188 | if not data: break\r | |
189 | f.seek(offset)\r | |
190 | f.write(data)\r | |
191 | offset = newoffset\r | |
192 | size = f.tell()\r | |
193 | \r | |
194 | t2 = time.time()\r | |
195 | f.close()\r | |
196 | \r | |
197 | dt = t2-t1\r | |
198 | print size, "bytes in", round(dt), "seconds",\r | |
199 | if dt:\r | |
200 | print "i.e.", size//dt, "bytes/sec",\r | |
201 | print\r | |
202 | remote._recv(id) # ignored\r | |
203 | \r | |
204 | def fl():\r | |
205 | sys.stdout.flush()\r | |
206 | \r | |
207 | if __name__ == '__main__':\r | |
208 | main()\r |