|
1 """Macintosh-specific module for conversion between pathnames and URLs. |
|
2 |
|
3 Do not import directly; use urllib instead.""" |
|
4 |
|
5 import urllib |
|
6 import os |
|
7 |
|
8 __all__ = ["url2pathname","pathname2url"] |
|
9 |
|
10 def url2pathname(pathname): |
|
11 """OS-specific conversion from a relative URL of the 'file' scheme |
|
12 to a file system path; not recommended for general use.""" |
|
13 # |
|
14 # XXXX The .. handling should be fixed... |
|
15 # |
|
16 tp = urllib.splittype(pathname)[0] |
|
17 if tp and tp != 'file': |
|
18 raise RuntimeError, 'Cannot convert non-local URL to pathname' |
|
19 # Turn starting /// into /, an empty hostname means current host |
|
20 if pathname[:3] == '///': |
|
21 pathname = pathname[2:] |
|
22 elif pathname[:2] == '//': |
|
23 raise RuntimeError, 'Cannot convert non-local URL to pathname' |
|
24 components = pathname.split('/') |
|
25 # Remove . and embedded .. |
|
26 i = 0 |
|
27 while i < len(components): |
|
28 if components[i] == '.': |
|
29 del components[i] |
|
30 elif components[i] == '..' and i > 0 and \ |
|
31 components[i-1] not in ('', '..'): |
|
32 del components[i-1:i+1] |
|
33 i = i-1 |
|
34 elif components[i] == '' and i > 0 and components[i-1] != '': |
|
35 del components[i] |
|
36 else: |
|
37 i = i+1 |
|
38 if not components[0]: |
|
39 # Absolute unix path, don't start with colon |
|
40 rv = ':'.join(components[1:]) |
|
41 else: |
|
42 # relative unix path, start with colon. First replace |
|
43 # leading .. by empty strings (giving ::file) |
|
44 i = 0 |
|
45 while i < len(components) and components[i] == '..': |
|
46 components[i] = '' |
|
47 i = i + 1 |
|
48 rv = ':' + ':'.join(components) |
|
49 # and finally unquote slashes and other funny characters |
|
50 return urllib.unquote(rv) |
|
51 |
|
52 def pathname2url(pathname): |
|
53 """OS-specific conversion from a file system path to a relative URL |
|
54 of the 'file' scheme; not recommended for general use.""" |
|
55 if '/' in pathname: |
|
56 raise RuntimeError, "Cannot convert pathname containing slashes" |
|
57 components = pathname.split(':') |
|
58 # Remove empty first and/or last component |
|
59 if components[0] == '': |
|
60 del components[0] |
|
61 if components[-1] == '': |
|
62 del components[-1] |
|
63 # Replace empty string ('::') by .. (will result in '/../' later) |
|
64 for i in range(len(components)): |
|
65 if components[i] == '': |
|
66 components[i] = '..' |
|
67 # Truncate names longer than 31 bytes |
|
68 components = map(_pncomp2url, components) |
|
69 |
|
70 if os.path.isabs(pathname): |
|
71 return '/' + '/'.join(components) |
|
72 else: |
|
73 return '/'.join(components) |
|
74 |
|
75 def _pncomp2url(component): |
|
76 component = urllib.quote(component[:31], safe='') # We want to quote slashes |
|
77 return component |
|
78 |
|
79 def test(): |
|
80 for url in ["index.html", |
|
81 "bar/index.html", |
|
82 "/foo/bar/index.html", |
|
83 "/foo/bar/", |
|
84 "/"]: |
|
85 print '%r -> %r' % (url, url2pathname(url)) |
|
86 for path in ["drive:", |
|
87 "drive:dir:", |
|
88 "drive:dir:file", |
|
89 "drive:file", |
|
90 "file", |
|
91 ":file", |
|
92 ":dir:", |
|
93 ":dir:file"]: |
|
94 print '%r -> %r' % (path, pathname2url(path)) |
|
95 |
|
96 if __name__ == '__main__': |
|
97 test() |