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() 98