1 | Sun Jul 11 20:55:25 GMT Daylight Time 2010 david-sarah@jacaranda.org |
---|
2 | * Allow URIs passed in the initial JSON for t=mkdir-with-children, t=mkdir-immutable to be Unicode. Also pass the name of each child into nodemaker.create_from_cap for error reporting. |
---|
3 | |
---|
4 | Mon Jul 12 01:30:15 GMT Daylight Time 2010 david-sarah@jacaranda.org |
---|
5 | * Rename stringutils to encodingutil, and drop listdir_unicode and open_unicode (since the Python stdlib functions work fine with Unicode paths). Also move some utility functions to fileutil. |
---|
6 | |
---|
7 | New patches: |
---|
8 | |
---|
9 | [Allow URIs passed in the initial JSON for t=mkdir-with-children, t=mkdir-immutable to be Unicode. Also pass the name of each child into nodemaker.create_from_cap for error reporting. |
---|
10 | david-sarah@jacaranda.org**20100711195525 |
---|
11 | Ignore-this: deac32d8b91ba26ede18905d3f7d2b93 |
---|
12 | ] { |
---|
13 | hunk ./src/allmydata/web/common.py 14 |
---|
14 | EmptyPathnameComponentError, MustBeDeepImmutableError, \ |
---|
15 | MustBeReadonlyError, MustNotBeUnknownRWError |
---|
16 | from allmydata.mutable.common import UnrecoverableFileError |
---|
17 | -from allmydata.util import abbreviate # TODO: consolidate |
---|
18 | +from allmydata.util import abbreviate |
---|
19 | +from allmydata.util.stringutils import to_str |
---|
20 | |
---|
21 | class IOpHandleTable(Interface): |
---|
22 | pass |
---|
23 | hunk ./src/allmydata/web/common.py 68 |
---|
24 | children = {} |
---|
25 | if children_json: |
---|
26 | data = simplejson.loads(children_json) |
---|
27 | - for (name, (ctype, propdict)) in data.iteritems(): |
---|
28 | - name = unicode(name) |
---|
29 | - writecap = propdict.get("rw_uri") |
---|
30 | - if writecap is not None: |
---|
31 | - writecap = str(writecap) |
---|
32 | - readcap = propdict.get("ro_uri") |
---|
33 | - if readcap is not None: |
---|
34 | - readcap = str(readcap) |
---|
35 | + for (namex, (ctype, propdict)) in data.iteritems(): |
---|
36 | + namex = unicode(namex) |
---|
37 | + writecap = to_str(propdict.get("rw_uri")) |
---|
38 | + readcap = to_str(propdict.get("ro_uri")) |
---|
39 | metadata = propdict.get("metadata", {}) |
---|
40 | hunk ./src/allmydata/web/common.py 73 |
---|
41 | - childnode = nodemaker.create_from_cap(writecap, readcap) |
---|
42 | - children[name] = (childnode, metadata) |
---|
43 | + # name= argument is just for error reporting |
---|
44 | + childnode = nodemaker.create_from_cap(writecap, readcap, name=namex) |
---|
45 | + children[namex] = (childnode, metadata) |
---|
46 | return children |
---|
47 | |
---|
48 | def abbreviate_time(data): |
---|
49 | } |
---|
50 | [Rename stringutils to encodingutil, and drop listdir_unicode and open_unicode (since the Python stdlib functions work fine with Unicode paths). Also move some utility functions to fileutil. |
---|
51 | david-sarah@jacaranda.org**20100712003015 |
---|
52 | Ignore-this: 103b809d180df17a7283077c3104c7be |
---|
53 | ] { |
---|
54 | move ./src/allmydata/test/test_stringutils.py ./src/allmydata/test/test_encodingutil.py |
---|
55 | move ./src/allmydata/util/stringutils.py ./src/allmydata/util/encodingutil.py |
---|
56 | hunk ./src/allmydata/dirnode.py 19 |
---|
57 | DeepCheckAndRepairResults |
---|
58 | from allmydata.monitor import Monitor |
---|
59 | from allmydata.util import hashutil, mathutil, base32, log |
---|
60 | -from allmydata.util.stringutils import quote_output |
---|
61 | +from allmydata.util.encodingutil import quote_output |
---|
62 | from allmydata.util.assertutil import precondition |
---|
63 | from allmydata.util.netstring import netstring, split_netstring |
---|
64 | from allmydata.util.consumer import download_to_data |
---|
65 | hunk ./src/allmydata/scripts/cli.py 4 |
---|
66 | import os.path, re, sys, fnmatch |
---|
67 | from twisted.python import usage |
---|
68 | from allmydata.scripts.common import BaseOptions, get_aliases |
---|
69 | -from allmydata.util.stringutils import argv_to_unicode |
---|
70 | +from allmydata.util.encodingutil import argv_to_unicode |
---|
71 | |
---|
72 | NODEURL_RE=re.compile("http(s?)://([^:]*)(:([1-9][0-9]*))?") |
---|
73 | |
---|
74 | hunk ./src/allmydata/scripts/common.py 5 |
---|
75 | import os, sys, urllib |
---|
76 | import codecs |
---|
77 | from twisted.python import usage |
---|
78 | -from allmydata.util.stringutils import unicode_to_url, quote_output |
---|
79 | +from allmydata.util.encodingutil import unicode_to_url, quote_output |
---|
80 | from allmydata.util.assertutil import precondition |
---|
81 | |
---|
82 | class BaseOptions: |
---|
83 | hunk ./src/allmydata/scripts/common_http.py 6 |
---|
84 | import urlparse, httplib |
---|
85 | import allmydata # for __full_version__ |
---|
86 | |
---|
87 | -from allmydata.util.stringutils import quote_output |
---|
88 | +from allmydata.util.encodingutil import quote_output |
---|
89 | from allmydata.scripts.common import TahoeError |
---|
90 | |
---|
91 | |
---|
92 | hunk ./src/allmydata/scripts/slow_operation.py 7 |
---|
93 | UnknownAliasError |
---|
94 | from allmydata.scripts.common_http import do_http, format_http_error |
---|
95 | from allmydata.util import base32 |
---|
96 | -from allmydata.util.stringutils import quote_output, is_printable_ascii |
---|
97 | +from allmydata.util.encodingutil import quote_output, is_printable_ascii |
---|
98 | import urllib |
---|
99 | import simplejson |
---|
100 | |
---|
101 | hunk ./src/allmydata/scripts/tahoe_add_alias.py 8 |
---|
102 | from allmydata.scripts.common_http import do_http, check_http_error |
---|
103 | from allmydata.scripts.common import get_aliases |
---|
104 | from allmydata.util.fileutil import move_into_place |
---|
105 | -from allmydata.util.stringutils import unicode_to_output, quote_output |
---|
106 | +from allmydata.util.encodingutil import unicode_to_output, quote_output |
---|
107 | |
---|
108 | |
---|
109 | def add_line_to_aliasfile(aliasfile, alias, cap): |
---|
110 | hunk ./src/allmydata/scripts/tahoe_backup.py 12 |
---|
111 | from allmydata.scripts.common_http import do_http, HTTPError, format_http_error |
---|
112 | from allmydata.util import time_format |
---|
113 | from allmydata.scripts import backupdb |
---|
114 | -from allmydata.util.stringutils import listdir_unicode, open_unicode, quote_output, to_str |
---|
115 | +from allmydata.util.encodingutil import quote_output, to_str |
---|
116 | +from allmydata.util.fileutil import open_expanduser |
---|
117 | from allmydata.util.assertutil import precondition |
---|
118 | |
---|
119 | |
---|
120 | hunk ./src/allmydata/scripts/tahoe_backup.py 170 |
---|
121 | compare_contents = {} # childname -> rocap |
---|
122 | |
---|
123 | try: |
---|
124 | - children = listdir_unicode(localpath) |
---|
125 | + children = os.listdir(localpath) |
---|
126 | except EnvironmentError: |
---|
127 | self.directories_skipped += 1 |
---|
128 | self.warn("WARNING: permission denied on directory %s" % quote_output(localpath)) |
---|
129 | hunk ./src/allmydata/scripts/tahoe_backup.py 175 |
---|
130 | children = [] |
---|
131 | + except (UnicodeEncodeError, UnicodeDecodeError): |
---|
132 | + self.directories_skipped += 1 |
---|
133 | + self.warn("WARNING: could not list directory %s due to an encoding error" % quote_output(localpath)) |
---|
134 | + children = [] |
---|
135 | |
---|
136 | for child in self.options.filter_listdir(children): |
---|
137 | assert isinstance(child, unicode), child |
---|
138 | hunk ./src/allmydata/scripts/tahoe_backup.py 300 |
---|
139 | |
---|
140 | if must_upload: |
---|
141 | self.verboseprint("uploading %s.." % quote_output(childpath)) |
---|
142 | - infileobj = open_unicode(childpath, "rb") |
---|
143 | + infileobj = open_expanduser(childpath, "rb") |
---|
144 | url = self.options['node-url'] + "uri" |
---|
145 | resp = do_http("PUT", url, infileobj) |
---|
146 | if resp.status not in (200, 201): |
---|
147 | hunk ./src/allmydata/scripts/tahoe_check.py 8 |
---|
148 | from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \ |
---|
149 | UnknownAliasError |
---|
150 | from allmydata.scripts.common_http import do_http, format_http_error |
---|
151 | -from allmydata.util.stringutils import quote_output, quote_path |
---|
152 | +from allmydata.util.encodingutil import quote_output, quote_path |
---|
153 | |
---|
154 | class Checker: |
---|
155 | pass |
---|
156 | hunk ./src/allmydata/scripts/tahoe_cp.py 11 |
---|
157 | DefaultAliasMarker, TahoeError |
---|
158 | from allmydata.scripts.common_http import do_http, HTTPError |
---|
159 | from allmydata import uri |
---|
160 | -from allmydata.util.stringutils import unicode_to_url, listdir_unicode, open_unicode, \ |
---|
161 | - abspath_expanduser_unicode, quote_output, to_str |
---|
162 | +from allmydata.util.encodingutil import unicode_to_url, quote_output, to_str |
---|
163 | +from allmydata.util import fileutil |
---|
164 | +from allmydata.util.fileutil import open_expanduser, abspath_expanduser |
---|
165 | from allmydata.util.assertutil import precondition |
---|
166 | |
---|
167 | |
---|
168 | hunk ./src/allmydata/scripts/tahoe_cp.py 17 |
---|
169 | -def _put_local_file(pathname, inf): |
---|
170 | - # TODO: create temporary file and move into place? |
---|
171 | - # TODO: move this to fileutil. |
---|
172 | - outf = open_unicode(pathname, "wb") |
---|
173 | - try: |
---|
174 | - while True: |
---|
175 | - data = inf.read(32768) |
---|
176 | - if not data: |
---|
177 | - break |
---|
178 | - outf.write(data) |
---|
179 | - finally: |
---|
180 | - outf.close() |
---|
181 | - |
---|
182 | - |
---|
183 | class MissingSourceError(TahoeError): |
---|
184 | def __init__(self, name): |
---|
185 | TahoeError.__init__(self, "No such file or directory %s" % quote_output(name)) |
---|
186 | hunk ./src/allmydata/scripts/tahoe_cp.py 71 |
---|
187 | return True |
---|
188 | |
---|
189 | def open(self, caps_only): |
---|
190 | - return open_unicode(self.pathname, "rb") |
---|
191 | + return open_expanduser(self.pathname, "rb") |
---|
192 | |
---|
193 | |
---|
194 | class LocalFileTarget: |
---|
195 | hunk ./src/allmydata/scripts/tahoe_cp.py 80 |
---|
196 | self.pathname = pathname |
---|
197 | |
---|
198 | def put_file(self, inf): |
---|
199 | - _put_local_file(self.pathname, inf) |
---|
200 | + fileutil.put_file(self.pathname, inf) |
---|
201 | |
---|
202 | |
---|
203 | class LocalMissingTarget: |
---|
204 | hunk ./src/allmydata/scripts/tahoe_cp.py 89 |
---|
205 | self.pathname = pathname |
---|
206 | |
---|
207 | def put_file(self, inf): |
---|
208 | - _put_local_file(self.pathname, inf) |
---|
209 | + fileutil.put_file(self.pathname, inf) |
---|
210 | |
---|
211 | |
---|
212 | class LocalDirectorySource: |
---|
213 | hunk ./src/allmydata/scripts/tahoe_cp.py 104 |
---|
214 | if self.children is not None: |
---|
215 | return |
---|
216 | self.children = {} |
---|
217 | - children = listdir_unicode(self.pathname) |
---|
218 | + children = os.listdir(self.pathname) |
---|
219 | for i,n in enumerate(children): |
---|
220 | self.progressfunc("examining %d of %d" % (i, len(children))) |
---|
221 | pn = os.path.join(self.pathname, n) |
---|
222 | hunk ./src/allmydata/scripts/tahoe_cp.py 132 |
---|
223 | if self.children is not None: |
---|
224 | return |
---|
225 | self.children = {} |
---|
226 | - children = listdir_unicode(self.pathname) |
---|
227 | + children = os.listdir(self.pathname) |
---|
228 | for i,n in enumerate(children): |
---|
229 | self.progressfunc("examining %d of %d" % (i, len(children))) |
---|
230 | n = unicode(n) |
---|
231 | hunk ./src/allmydata/scripts/tahoe_cp.py 158 |
---|
232 | def put_file(self, name, inf): |
---|
233 | precondition(isinstance(name, unicode), name) |
---|
234 | pathname = os.path.join(self.pathname, name) |
---|
235 | - _put_local_file(pathname, inf) |
---|
236 | + fileutil.put_file(pathname, inf) |
---|
237 | |
---|
238 | def set_children(self): |
---|
239 | pass |
---|
240 | hunk ./src/allmydata/scripts/tahoe_cp.py 515 |
---|
241 | rootcap, path = get_alias(self.aliases, destination_spec, None) |
---|
242 | if rootcap == DefaultAliasMarker: |
---|
243 | # no alias, so this is a local file |
---|
244 | - pathname = abspath_expanduser_unicode(path.decode('utf-8')) |
---|
245 | + pathname = abspath_expanduser(path.decode('utf-8')) |
---|
246 | if not os.path.exists(pathname): |
---|
247 | t = LocalMissingTarget(pathname) |
---|
248 | elif os.path.isdir(pathname): |
---|
249 | hunk ./src/allmydata/scripts/tahoe_cp.py 555 |
---|
250 | rootcap, path = get_alias(self.aliases, source_spec, None) |
---|
251 | if rootcap == DefaultAliasMarker: |
---|
252 | # no alias, so this is a local file |
---|
253 | - pathname = abspath_expanduser_unicode(path.decode('utf-8')) |
---|
254 | + pathname = abspath_expanduser(path.decode('utf-8')) |
---|
255 | name = os.path.basename(pathname) |
---|
256 | if not os.path.exists(pathname): |
---|
257 | raise MissingSourceError(source_spec) |
---|
258 | hunk ./src/allmydata/scripts/tahoe_get.py 6 |
---|
259 | from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \ |
---|
260 | UnknownAliasError |
---|
261 | from allmydata.scripts.common_http import do_http, format_http_error |
---|
262 | -from allmydata.util.stringutils import open_unicode |
---|
263 | +from allmydata.util.fileutil import open_expanduser |
---|
264 | |
---|
265 | def get(options): |
---|
266 | nodeurl = options['node-url'] |
---|
267 | hunk ./src/allmydata/scripts/tahoe_get.py 30 |
---|
268 | resp = do_http("GET", url) |
---|
269 | if resp.status in (200, 201,): |
---|
270 | if to_file: |
---|
271 | - outf = open_unicode(to_file, "wb") |
---|
272 | + outf = open_expanduser(to_file, "wb") |
---|
273 | else: |
---|
274 | outf = stdout |
---|
275 | while True: |
---|
276 | hunk ./src/allmydata/scripts/tahoe_ls.py 7 |
---|
277 | from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \ |
---|
278 | UnknownAliasError |
---|
279 | from allmydata.scripts.common_http import do_http, format_http_error |
---|
280 | -from allmydata.util.stringutils import unicode_to_output, quote_output, is_printable_ascii, to_str |
---|
281 | +from allmydata.util.encodingutil import unicode_to_output, quote_output, is_printable_ascii, to_str |
---|
282 | |
---|
283 | def list(options): |
---|
284 | nodeurl = options['node-url'] |
---|
285 | hunk ./src/allmydata/scripts/tahoe_manifest.py 9 |
---|
286 | from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \ |
---|
287 | UnknownAliasError |
---|
288 | from allmydata.scripts.common_http import do_http, format_http_error |
---|
289 | -from allmydata.util.stringutils import quote_output, quote_path |
---|
290 | +from allmydata.util.encodingutil import quote_output, quote_path |
---|
291 | |
---|
292 | class FakeTransport: |
---|
293 | disconnecting = False |
---|
294 | hunk ./src/allmydata/scripts/tahoe_mkdir.py 5 |
---|
295 | import urllib |
---|
296 | from allmydata.scripts.common_http import do_http, check_http_error |
---|
297 | from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, UnknownAliasError |
---|
298 | -from allmydata.util.stringutils import quote_output |
---|
299 | +from allmydata.util.encodingutil import quote_output |
---|
300 | |
---|
301 | def mkdir(options): |
---|
302 | nodeurl = options['node-url'] |
---|
303 | hunk ./src/allmydata/scripts/tahoe_mv.py 8 |
---|
304 | from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \ |
---|
305 | UnknownAliasError |
---|
306 | from allmydata.scripts.common_http import do_http, format_http_error |
---|
307 | -from allmydata.util.stringutils import to_str |
---|
308 | +from allmydata.util.encodingutil import to_str |
---|
309 | |
---|
310 | # this script is used for both 'mv' and 'ln' |
---|
311 | |
---|
312 | hunk ./src/allmydata/scripts/tahoe_put.py 7 |
---|
313 | from allmydata.scripts.common_http import do_http, format_http_success, format_http_error |
---|
314 | from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \ |
---|
315 | UnknownAliasError |
---|
316 | -from allmydata.util.stringutils import quote_output, open_unicode |
---|
317 | +from allmydata.util.encodingutil import quote_output |
---|
318 | +from allmydata.util.fileutil import open_expanduser |
---|
319 | |
---|
320 | def put(options): |
---|
321 | """ |
---|
322 | hunk ./src/allmydata/scripts/tahoe_put.py 68 |
---|
323 | if mutable: |
---|
324 | url += "?mutable=true" |
---|
325 | if from_file: |
---|
326 | - infileobj = open_unicode(from_file, "rb") |
---|
327 | + infileobj = open_expanduser(from_file, "rb") |
---|
328 | else: |
---|
329 | # do_http() can't use stdin directly: for one thing, we need a |
---|
330 | # Content-Length field. So we currently must copy it. |
---|
331 | hunk ./src/allmydata/test/test_backupdb.py 7 |
---|
332 | from twisted.trial import unittest |
---|
333 | |
---|
334 | from allmydata.util import fileutil |
---|
335 | -from allmydata.util.stringutils import listdir_unicode, get_filesystem_encoding, unicode_platform |
---|
336 | +from allmydata.util.encodingutil import get_filesystem_encoding, unicode_platform |
---|
337 | from allmydata.util.assertutil import precondition |
---|
338 | from allmydata.scripts import backupdb |
---|
339 | |
---|
340 | hunk ./src/allmydata/test/test_backupdb.py 252 |
---|
341 | self.failUnless(bdb) |
---|
342 | |
---|
343 | self.writeto(u"f\u00f6\u00f6.txt", "foo.txt") |
---|
344 | - files = [fn for fn in listdir_unicode(unicode(basedir)) if fn.endswith(".txt")] |
---|
345 | + files = [fn for fn in os.listdir(unicode(basedir)) if fn.endswith(".txt")] |
---|
346 | self.failUnlessEqual(len(files), 1) |
---|
347 | foo_fn = os.path.join(basedir, files[0]) |
---|
348 | #print foo_fn, type(foo_fn) |
---|
349 | hunk ./src/allmydata/test/test_cli.py 34 |
---|
350 | from twisted.python import usage |
---|
351 | |
---|
352 | from allmydata.util.assertutil import precondition |
---|
353 | -from allmydata.util.stringutils import listdir_unicode, open_unicode, unicode_platform, \ |
---|
354 | - quote_output, get_output_encoding, get_argv_encoding, get_filesystem_encoding, \ |
---|
355 | +from allmydata.util.encodingutil import unicode_platform, quote_output, \ |
---|
356 | + get_output_encoding, get_argv_encoding, get_filesystem_encoding, \ |
---|
357 | unicode_to_output, to_str |
---|
358 | |
---|
359 | timeout = 480 # deep_check takes 360s on Zandr's linksys box, others take > 240s |
---|
360 | hunk ./src/allmydata/test/test_cli.py 442 |
---|
361 | fileutil.make_dirs(basedir) |
---|
362 | |
---|
363 | for name in filenames: |
---|
364 | - open_unicode(os.path.join(unicode(basedir), name), "wb").close() |
---|
365 | + open(os.path.join(unicode(basedir), name), "wb").close() |
---|
366 | |
---|
367 | hunk ./src/allmydata/test/test_cli.py 444 |
---|
368 | - for file in listdir_unicode(unicode(basedir)): |
---|
369 | + for file in os.listdir(unicode(basedir)): |
---|
370 | self.failUnlessIn(normalize(file), filenames) |
---|
371 | |
---|
372 | |
---|
373 | hunk ./src/allmydata/test/test_cli.py 977 |
---|
374 | rel_fn = os.path.join(unicode(self.basedir), u"à trier.txt") |
---|
375 | # we make the file small enough to fit in a LIT file, for speed |
---|
376 | DATA = "short file" |
---|
377 | - f = open_unicode(rel_fn, "wb") |
---|
378 | - try: |
---|
379 | - f.write(DATA) |
---|
380 | - finally: |
---|
381 | - f.close() |
---|
382 | + fileutil.write(rel_fn, DATA) |
---|
383 | |
---|
384 | d = self.do_cli("create-alias", "tahoe") |
---|
385 | |
---|
386 | hunk ./src/allmydata/test/test_cli.py 1348 |
---|
387 | self.set_up_grid() |
---|
388 | |
---|
389 | DATA1 = "unicode file content" |
---|
390 | - f = open_unicode(fn1, "wb") |
---|
391 | - try: |
---|
392 | - f.write(DATA1) |
---|
393 | - finally: |
---|
394 | - f.close() |
---|
395 | + fileutil.write(fn1, DATA1) |
---|
396 | |
---|
397 | fn2 = os.path.join(self.basedir, "Metallica") |
---|
398 | DATA2 = "non-unicode file content" |
---|
399 | hunk ./src/allmydata/test/test_encodingutil.py 16 |
---|
400 | # systems. |
---|
401 | |
---|
402 | if __name__ == "__main__": |
---|
403 | - import sys, os |
---|
404 | - import tempfile |
---|
405 | - import shutil |
---|
406 | + import sys |
---|
407 | import platform |
---|
408 | |
---|
409 | if len(sys.argv) != 2: |
---|
410 | hunk ./src/allmydata/test/test_encodingutil.py 32 |
---|
411 | print " filesystem_encoding = '%s'" % sys.getfilesystemencoding() |
---|
412 | print " output_encoding = '%s'" % sys.stdout.encoding |
---|
413 | print " argv_encoding = '%s'" % (sys.platform == "win32" and 'ascii' or sys.stdout.encoding) |
---|
414 | - |
---|
415 | - try: |
---|
416 | - tmpdir = tempfile.mkdtemp() |
---|
417 | - for fname in TEST_FILENAMES: |
---|
418 | - open(os.path.join(tmpdir, fname), 'w').close() |
---|
419 | - |
---|
420 | - # Use Unicode API under Windows or MacOS X |
---|
421 | - if sys.platform in ('win32', 'darwin'): |
---|
422 | - dirlist = os.listdir(unicode(tmpdir)) |
---|
423 | - else: |
---|
424 | - dirlist = os.listdir(tmpdir) |
---|
425 | - |
---|
426 | - print " dirlist = %s" % repr(dirlist) |
---|
427 | - except: |
---|
428 | - print " # Oops, I cannot write filenames containing non-ascii characters" |
---|
429 | print |
---|
430 | |
---|
431 | hunk ./src/allmydata/test/test_encodingutil.py 34 |
---|
432 | - shutil.rmtree(tmpdir) |
---|
433 | sys.exit(0) |
---|
434 | |
---|
435 | from twisted.trial import unittest |
---|
436 | hunk ./src/allmydata/test/test_encodingutil.py 41 |
---|
437 | import sys |
---|
438 | |
---|
439 | from allmydata.test.common_util import ReallyEqualMixin |
---|
440 | -from allmydata.util.stringutils import argv_to_unicode, unicode_to_url, \ |
---|
441 | - unicode_to_output, unicode_platform, listdir_unicode, open_unicode, \ |
---|
442 | - FilenameEncodingError, get_output_encoding, _reload |
---|
443 | -from allmydata.dirnode import normalize |
---|
444 | +from allmydata.util.encodingutil import argv_to_unicode, unicode_to_url, \ |
---|
445 | + unicode_to_output, unicode_platform, get_output_encoding, _reload |
---|
446 | |
---|
447 | from twisted.python import usage |
---|
448 | |
---|
449 | hunk ./src/allmydata/test/test_encodingutil.py 85 |
---|
450 | _reload() |
---|
451 | self.failUnlessRaises(UnicodeEncodeError, unicode_to_output, lumiere_nfc) |
---|
452 | |
---|
453 | - @patch('os.listdir') |
---|
454 | - def test_no_unicode_normalization(self, mock): |
---|
455 | - # Pretend to run on a Unicode platform. |
---|
456 | - # We normalized to NFC in 1.7beta, but we now don't. |
---|
457 | - orig_platform = sys.platform |
---|
458 | - try: |
---|
459 | - sys.platform = 'darwin' |
---|
460 | - mock.return_value = [Artonwall_nfd] |
---|
461 | - _reload() |
---|
462 | - self.failUnlessReallyEqual(listdir_unicode(u'/dummy'), [Artonwall_nfd]) |
---|
463 | - finally: |
---|
464 | - sys.platform = orig_platform |
---|
465 | - |
---|
466 | -# The following tests applies only to platforms which don't store filenames as |
---|
467 | -# Unicode entities on the filesystem. |
---|
468 | -class StringUtilsNonUnicodePlatform(unittest.TestCase): |
---|
469 | - def setUp(self): |
---|
470 | - # Mock sys.platform because unicode_platform() uses it |
---|
471 | - self.original_platform = sys.platform |
---|
472 | - sys.platform = 'linux' |
---|
473 | - |
---|
474 | - def tearDown(self): |
---|
475 | - sys.platform = self.original_platform |
---|
476 | - _reload() |
---|
477 | - |
---|
478 | - @patch('sys.getfilesystemencoding') |
---|
479 | - @patch('os.listdir') |
---|
480 | - def test_listdir_unicode(self, mock_listdir, mock_getfilesystemencoding): |
---|
481 | - # What happens if latin1-encoded filenames are encountered on an UTF-8 |
---|
482 | - # filesystem? |
---|
483 | - mock_listdir.return_value = [ |
---|
484 | - lumiere_nfc.encode('utf-8'), |
---|
485 | - lumiere_nfc.encode('latin1')] |
---|
486 | - |
---|
487 | - mock_getfilesystemencoding.return_value = 'utf-8' |
---|
488 | - _reload() |
---|
489 | - self.failUnlessRaises(FilenameEncodingError, |
---|
490 | - listdir_unicode, |
---|
491 | - u'/dummy') |
---|
492 | - |
---|
493 | - # We're trying to list a directory whose name cannot be represented in |
---|
494 | - # the filesystem encoding. This should fail. |
---|
495 | - mock_getfilesystemencoding.return_value = 'ascii' |
---|
496 | - _reload() |
---|
497 | - self.failUnlessRaises(FilenameEncodingError, |
---|
498 | - listdir_unicode, |
---|
499 | - u'/' + lumiere_nfc) |
---|
500 | - |
---|
501 | - @patch('sys.getfilesystemencoding') |
---|
502 | - def test_open_unicode(self, mock): |
---|
503 | - mock.return_value = 'ascii' |
---|
504 | - _reload() |
---|
505 | - self.failUnlessRaises(FilenameEncodingError, |
---|
506 | - open_unicode, |
---|
507 | - lumiere_nfc, 'rb') |
---|
508 | |
---|
509 | class StringUtils(ReallyEqualMixin): |
---|
510 | def setUp(self): |
---|
511 | hunk ./src/allmydata/test/test_encodingutil.py 130 |
---|
512 | _reload() |
---|
513 | self.failUnlessReallyEqual(unicode_platform(), matrix[self.platform]) |
---|
514 | |
---|
515 | - @patch('sys.getfilesystemencoding') |
---|
516 | - @patch('os.listdir') |
---|
517 | - def test_listdir_unicode(self, mock_listdir, mock_getfilesystemencoding): |
---|
518 | - if 'dirlist' not in dir(self): |
---|
519 | - return |
---|
520 | - |
---|
521 | - try: |
---|
522 | - u"test".encode(self.filesystem_encoding) |
---|
523 | - except (LookupError, AttributeError): |
---|
524 | - raise unittest.SkipTest("This platform does not support the '%s' filesystem encoding " |
---|
525 | - "that we are testing for the benefit of a different platform." |
---|
526 | - % (self.filesystem_encoding,)) |
---|
527 | - |
---|
528 | - mock_listdir.return_value = self.dirlist |
---|
529 | - mock_getfilesystemencoding.return_value = self.filesystem_encoding |
---|
530 | - |
---|
531 | - _reload() |
---|
532 | - filenames = listdir_unicode(u'/dummy') |
---|
533 | - |
---|
534 | - self.failUnlessEqual(set([normalize(fname) for fname in filenames]), |
---|
535 | - set(TEST_FILENAMES)) |
---|
536 | - |
---|
537 | - @patch('sys.getfilesystemencoding') |
---|
538 | - @patch('__builtin__.open') |
---|
539 | - def test_open_unicode(self, mock_open, mock_getfilesystemencoding): |
---|
540 | - mock_getfilesystemencoding.return_value = self.filesystem_encoding |
---|
541 | - fn = u'/dummy_directory/" + lumiere_nfc + ".txt' |
---|
542 | - |
---|
543 | - try: |
---|
544 | - u"test".encode(self.filesystem_encoding) |
---|
545 | - except (LookupError, AttributeError): |
---|
546 | - raise unittest.SkipTest("This platform does not support the '%s' filesystem encoding " |
---|
547 | - "that we are testing for the benefit of a different platform." |
---|
548 | - % (self.filesystem_encoding,)) |
---|
549 | - |
---|
550 | - _reload() |
---|
551 | - try: |
---|
552 | - open_unicode(fn, 'rb') |
---|
553 | - except FilenameEncodingError: |
---|
554 | - return |
---|
555 | - |
---|
556 | - # Pass Unicode string to open() on Unicode platforms |
---|
557 | - if unicode_platform(): |
---|
558 | - mock_open.assert_called_with(fn, 'rb') |
---|
559 | - |
---|
560 | - # Pass correctly encoded bytestrings to open() on non-Unicode platforms |
---|
561 | - else: |
---|
562 | - fn_bytestring = fn.encode(self.filesystem_encoding) |
---|
563 | - mock_open.assert_called_with(fn_bytestring, 'rb') |
---|
564 | - |
---|
565 | |
---|
566 | class UbuntuKarmicUTF8(StringUtils, unittest.TestCase): |
---|
567 | uname = 'Linux korn 2.6.31-14-generic #48-Ubuntu SMP Fri Oct 16 14:05:01 UTC 2009 x86_64' |
---|
568 | hunk ./src/allmydata/test/test_encodingutil.py 139 |
---|
569 | filesystem_encoding = 'UTF-8' |
---|
570 | output_encoding = 'UTF-8' |
---|
571 | argv_encoding = 'UTF-8' |
---|
572 | - dirlist = ['test_file', '\xc3\x84rtonwall.mp3', 'Blah blah.txt'] |
---|
573 | |
---|
574 | class UbuntuKarmicLatin1(StringUtils, unittest.TestCase): |
---|
575 | uname = 'Linux korn 2.6.31-14-generic #48-Ubuntu SMP Fri Oct 16 14:05:01 UTC 2009 x86_64' |
---|
576 | hunk ./src/allmydata/test/test_encodingutil.py 148 |
---|
577 | filesystem_encoding = 'ISO-8859-1' |
---|
578 | output_encoding = 'ISO-8859-1' |
---|
579 | argv_encoding = 'ISO-8859-1' |
---|
580 | - dirlist = ['test_file', 'Blah blah.txt', '\xc4rtonwall.mp3'] |
---|
581 | |
---|
582 | class WindowsXP(StringUtils, unittest.TestCase): |
---|
583 | uname = 'Windows XP 5.1.2600 x86 x86 Family 15 Model 75 Step ping 2, AuthenticAMD' |
---|
584 | hunk ./src/allmydata/test/test_encodingutil.py 156 |
---|
585 | filesystem_encoding = 'mbcs' |
---|
586 | output_encoding = 'cp850' |
---|
587 | argv_encoding = 'ascii' |
---|
588 | - dirlist = [u'Blah blah.txt', u'test_file', u'\xc4rtonwall.mp3'] |
---|
589 | |
---|
590 | class WindowsXP_UTF8(StringUtils, unittest.TestCase): |
---|
591 | uname = 'Windows XP 5.1.2600 x86 x86 Family 15 Model 75 Step ping 2, AuthenticAMD' |
---|
592 | hunk ./src/allmydata/test/test_encodingutil.py 164 |
---|
593 | filesystem_encoding = 'mbcs' |
---|
594 | output_encoding = 'cp65001' |
---|
595 | argv_encoding = 'ascii' |
---|
596 | - dirlist = [u'Blah blah.txt', u'test_file', u'\xc4rtonwall.mp3'] |
---|
597 | |
---|
598 | class WindowsVista(StringUtils, unittest.TestCase): |
---|
599 | uname = 'Windows Vista 6.0.6000 x86 x86 Family 6 Model 15 Stepping 11, GenuineIntel' |
---|
600 | hunk ./src/allmydata/test/test_encodingutil.py 172 |
---|
601 | filesystem_encoding = 'mbcs' |
---|
602 | output_encoding = 'cp850' |
---|
603 | argv_encoding = 'ascii' |
---|
604 | - dirlist = [u'Blah blah.txt', u'test_file', u'\xc4rtonwall.mp3'] |
---|
605 | |
---|
606 | class MacOSXLeopard(StringUtils, unittest.TestCase): |
---|
607 | uname = 'Darwin g5.local 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:57:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_PPC Power Macintosh powerpc' |
---|
608 | hunk ./src/allmydata/test/test_encodingutil.py 181 |
---|
609 | filesystem_encoding = 'utf-8' |
---|
610 | output_encoding = 'UTF-8' |
---|
611 | argv_encoding = 'UTF-8' |
---|
612 | - dirlist = [u'A\u0308rtonwall.mp3', u'Blah blah.txt', u'test_file'] |
---|
613 | |
---|
614 | class MacOSXLeopard7bit(StringUtils, unittest.TestCase): |
---|
615 | uname = 'Darwin g5.local 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:57:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_PPC Power Macintosh powerpc' |
---|
616 | hunk ./src/allmydata/test/test_encodingutil.py 188 |
---|
617 | filesystem_encoding = 'utf-8' |
---|
618 | output_encoding = 'US-ASCII' |
---|
619 | argv_encoding = 'US-ASCII' |
---|
620 | - dirlist = [u'A\u0308rtonwall.mp3', u'Blah blah.txt', u'test_file'] |
---|
621 | |
---|
622 | class OpenBSD(StringUtils, unittest.TestCase): |
---|
623 | uname = 'OpenBSD 4.1 GENERIC#187 i386 Intel(R) Celeron(R) CPU 2.80GHz ("GenuineIntel" 686-class)' |
---|
624 | hunk ./src/allmydata/util/encodingutil.py 7 |
---|
625 | """ |
---|
626 | |
---|
627 | import sys |
---|
628 | -import os |
---|
629 | import re |
---|
630 | from allmydata.util.assertutil import precondition |
---|
631 | from twisted.python import usage |
---|
632 | hunk ./src/allmydata/util/encodingutil.py 176 |
---|
633 | Does the current platform handle Unicode filenames natively? |
---|
634 | """ |
---|
635 | return is_unicode_platform |
---|
636 | - |
---|
637 | -class FilenameEncodingError(Exception): |
---|
638 | - """ |
---|
639 | - Filename cannot be encoded using the current encoding of your filesystem |
---|
640 | - (%s). Please configure your locale correctly or rename this file. |
---|
641 | - """ |
---|
642 | - pass |
---|
643 | - |
---|
644 | -def listdir_unicode_fallback(path): |
---|
645 | - """ |
---|
646 | - This function emulates a fallback Unicode API similar to one available |
---|
647 | - under Windows or MacOS X. |
---|
648 | - |
---|
649 | - If badly encoded filenames are encountered, an exception is raised. |
---|
650 | - """ |
---|
651 | - precondition(isinstance(path, unicode), path) |
---|
652 | - |
---|
653 | - try: |
---|
654 | - byte_path = path.encode(filesystem_encoding) |
---|
655 | - except (UnicodeEncodeError, UnicodeDecodeError): |
---|
656 | - raise FilenameEncodingError(path) |
---|
657 | - |
---|
658 | - try: |
---|
659 | - return [unicode(fn, filesystem_encoding) for fn in os.listdir(byte_path)] |
---|
660 | - except UnicodeDecodeError: |
---|
661 | - raise FilenameEncodingError(fn) |
---|
662 | - |
---|
663 | -def listdir_unicode(path): |
---|
664 | - """ |
---|
665 | - Wrapper around listdir() which provides safe access to the convenient |
---|
666 | - Unicode API even under platforms that don't provide one natively. |
---|
667 | - """ |
---|
668 | - precondition(isinstance(path, unicode), path) |
---|
669 | - |
---|
670 | - # On Windows and MacOS X, the Unicode API is used |
---|
671 | - # On other platforms (ie. Unix systems), the byte-level API is used |
---|
672 | - |
---|
673 | - if is_unicode_platform: |
---|
674 | - return os.listdir(path) |
---|
675 | - else: |
---|
676 | - return listdir_unicode_fallback(path) |
---|
677 | - |
---|
678 | -def open_unicode(path, mode): |
---|
679 | - """ |
---|
680 | - Wrapper around open() which provides safe access to the convenient Unicode |
---|
681 | - API even under Unix. |
---|
682 | - """ |
---|
683 | - precondition(isinstance(path, unicode), path) |
---|
684 | - |
---|
685 | - if is_unicode_platform: |
---|
686 | - return open(os.path.expanduser(path), mode) |
---|
687 | - else: |
---|
688 | - try: |
---|
689 | - return open(os.path.expanduser(path.encode(filesystem_encoding)), mode) |
---|
690 | - except UnicodeEncodeError: |
---|
691 | - raise FilenameEncodingError(path) |
---|
692 | - |
---|
693 | -def abspath_expanduser_unicode(path): |
---|
694 | - precondition(isinstance(path, unicode), path) |
---|
695 | - |
---|
696 | - if is_unicode_platform: |
---|
697 | - return os.path.abspath(os.path.expanduser(path)) |
---|
698 | - else: |
---|
699 | - try: |
---|
700 | - pathstr = path.encode(filesystem_encoding) |
---|
701 | - return os.path.abspath(os.path.expanduser(pathstr)).decode(filesystem_encoding) |
---|
702 | - except (UnicodeEncodeError, UnicodeDecodeError): |
---|
703 | - raise FilenameEncodingError(path) |
---|
704 | hunk ./src/allmydata/util/fileutil.py 212 |
---|
705 | finally: |
---|
706 | rf.close() |
---|
707 | |
---|
708 | +def put_file(pathname, inf): |
---|
709 | + # TODO: create temporary file and move into place? |
---|
710 | + outf = open_expanduser(pathname, "wb") |
---|
711 | + try: |
---|
712 | + while True: |
---|
713 | + data = inf.read(32768) |
---|
714 | + if not data: |
---|
715 | + break |
---|
716 | + outf.write(data) |
---|
717 | + finally: |
---|
718 | + outf.close() |
---|
719 | + |
---|
720 | +def open_expanduser(path, mode): |
---|
721 | + assert isinstance(path, unicode), path |
---|
722 | + return open(os.path.expanduser(path), mode) |
---|
723 | + |
---|
724 | +def abspath_expanduser(path): |
---|
725 | + assert isinstance(path, unicode), path |
---|
726 | + return os.path.abspath(os.path.expanduser(path)) |
---|
727 | + |
---|
728 | hunk ./src/allmydata/web/common.py 15 |
---|
729 | MustBeReadonlyError, MustNotBeUnknownRWError |
---|
730 | from allmydata.mutable.common import UnrecoverableFileError |
---|
731 | from allmydata.util import abbreviate |
---|
732 | -from allmydata.util.stringutils import to_str |
---|
733 | +from allmydata.util.encodingutil import to_str |
---|
734 | |
---|
735 | class IOpHandleTable(Interface): |
---|
736 | pass |
---|
737 | } |
---|
738 | |
---|
739 | Context: |
---|
740 | |
---|
741 | [upcase_since_on_welcome |
---|
742 | terrellrussell@gmail.com**20100708193903] |
---|
743 | [server_version_on_welcome_page.dpatch.txt |
---|
744 | freestorm77@gmail.com**20100605191721 |
---|
745 | Ignore-this: b450c76dc875f5ac8cca229a666cbd0a |
---|
746 | |
---|
747 | |
---|
748 | - The storage server version is 0 for all storage nodes in the Welcome Page |
---|
749 | |
---|
750 | |
---|
751 | ] |
---|
752 | [NEWS: add NEWS snippets about two recent patches |
---|
753 | zooko@zooko.com**20100708162058 |
---|
754 | Ignore-this: 6c9da6a0ad7351a960bdd60f81532899 |
---|
755 | ] |
---|
756 | [directory_html_top_banner.dpatch |
---|
757 | freestorm77@gmail.com**20100622205301 |
---|
758 | Ignore-this: 1d770d975e0c414c996564774f049bca |
---|
759 | |
---|
760 | The div tag with the link "Return to Welcome page" on the directory.xhtml page is not correct |
---|
761 | |
---|
762 | ] |
---|
763 | [tahoe_css_toolbar.dpatch |
---|
764 | freestorm77@gmail.com**20100622210046 |
---|
765 | Ignore-this: 5b3ebb2e0f52bbba718a932f80c246c0 |
---|
766 | |
---|
767 | CSS modification to be correctly diplayed with Internet Explorer 8 |
---|
768 | |
---|
769 | The links on the top of page directory.xhtml are not diplayed in the same line as display with Firefox. |
---|
770 | |
---|
771 | ] |
---|
772 | [runnin_test_tahoe_css.dpatch |
---|
773 | freestorm77@gmail.com**20100622214714 |
---|
774 | Ignore-this: e0db73d68740aad09a7b9ae60a08c05c |
---|
775 | |
---|
776 | Runnin test for changes in tahoe.css file |
---|
777 | |
---|
778 | ] |
---|
779 | [runnin_test_directory_xhtml.dpatch |
---|
780 | freestorm77@gmail.com**20100622201403 |
---|
781 | Ignore-this: f8962463fce50b9466405cb59fe11d43 |
---|
782 | |
---|
783 | Runnin test for diretory.xhtml top banner |
---|
784 | |
---|
785 | ] |
---|
786 | [stringutils.py: tolerate sys.stdout having no 'encoding' attribute. |
---|
787 | david-sarah@jacaranda.org**20100626040817 |
---|
788 | Ignore-this: f42cad81cef645ee38ac1df4660cc850 |
---|
789 | ] |
---|
790 | [quickstart.html: python 2.5 -> 2.6 as recommended version |
---|
791 | david-sarah@jacaranda.org**20100705175858 |
---|
792 | Ignore-this: bc3a14645ea1d5435002966ae903199f |
---|
793 | ] |
---|
794 | [SFTP: don't call .stopProducing on the producer registered with OverwriteableFileConsumer (which breaks with warner's new downloader). |
---|
795 | david-sarah@jacaranda.org**20100628231926 |
---|
796 | Ignore-this: 131b7a5787bc85a9a356b5740d9d996f |
---|
797 | ] |
---|
798 | [docs/how_to_make_a_tahoe-lafs_release.txt: trivial correction, install.html should now be quickstart.html. |
---|
799 | david-sarah@jacaranda.org**20100625223929 |
---|
800 | Ignore-this: 99a5459cac51bd867cc11ad06927ff30 |
---|
801 | ] |
---|
802 | [setup: in the Makefile, refuse to upload tarballs unless someone has passed the environment variable "BB_BRANCH" with value "trunk" |
---|
803 | zooko@zooko.com**20100619034928 |
---|
804 | Ignore-this: 276ddf9b6ad7ec79e27474862e0f7d6 |
---|
805 | ] |
---|
806 | [trivial: tiny update to in-line comment |
---|
807 | zooko@zooko.com**20100614045715 |
---|
808 | Ignore-this: 10851b0ed2abfed542c97749e5d280bc |
---|
809 | (I'm actually committing this patch as a test of the new eager-annotation-computation of trac-darcs.) |
---|
810 | ] |
---|
811 | [docs: about.html link to home page early on, and be decentralized storage instead of cloud storage this time around |
---|
812 | zooko@zooko.com**20100619065318 |
---|
813 | Ignore-this: dc6db03f696e5b6d2848699e754d8053 |
---|
814 | ] |
---|
815 | [docs: update about.html, especially to have a non-broken link to quickstart.html, and also to comment out the broken links to "for Paranoids" and "for Corporates" |
---|
816 | zooko@zooko.com**20100619065124 |
---|
817 | Ignore-this: e292c7f51c337a84ebfeb366fbd24d6c |
---|
818 | ] |
---|
819 | [TAG allmydata-tahoe-1.7.0 |
---|
820 | zooko@zooko.com**20100619052631 |
---|
821 | Ignore-this: d21e27afe6d85e2e3ba6a3292ba2be1 |
---|
822 | ] |
---|
823 | Patch bundle hash: |
---|
824 | 5dd0b81c02ed648d4eb4ab565a237c53ccbf4ff3 |
---|