Home | History | Annotate | Download | only in python2.7
      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