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