Home | History | Annotate | Download | only in Lib
      1 """Convert a NT pathname to a file URL and vice versa."""
      2 
      3 def url2pathname(url):
      4     """OS-specific conversion from a relative URL of the 'file' scheme
      5     to a file system path; not recommended for general use."""
      6     # e.g.
      7     #   ///C|/foo/bar/spam.foo
      8     # and
      9     #   ///C:/foo/bar/spam.foo
     10     # become
     11     #   C:\foo\bar\spam.foo
     12     import string, urllib.parse
     13     # Windows itself uses ":" even in URLs.
     14     url = url.replace(':', '|')
     15     if not '|' in url:
     16         # No drive specifier, just convert slashes
     17         if url[:4] == '////':
     18             # path is something like ////host/path/on/remote/host
     19             # convert this to \\host\path\on\remote\host
     20             # (notice halving of slashes at the start of the path)
     21             url = url[2:]
     22         components = url.split('/')
     23         # make sure not to convert quoted slashes :-)
     24         return urllib.parse.unquote('\\'.join(components))
     25     comp = url.split('|')
     26     if len(comp) != 2 or comp[0][-1] not in string.ascii_letters:
     27         error = 'Bad URL: ' + url
     28         raise OSError(error)
     29     drive = comp[0][-1].upper()
     30     components = comp[1].split('/')
     31     path = drive + ':'
     32     for comp in components:
     33         if comp:
     34             path = path + '\\' + urllib.parse.unquote(comp)
     35     # Issue #11474 - handing url such as |c/|
     36     if path.endswith(':') and url.endswith('/'):
     37         path += '\\'
     38     return path
     39 
     40 def pathname2url(p):
     41     """OS-specific conversion from a file system path to a relative URL
     42     of the 'file' scheme; not recommended for general use."""
     43     # e.g.
     44     #   C:\foo\bar\spam.foo
     45     # becomes
     46     #   ///C:/foo/bar/spam.foo
     47     import urllib.parse
     48     if not ':' in p:
     49         # No drive specifier, just convert slashes and quote the name
     50         if p[:2] == '\\\\':
     51         # path is something like \\host\path\on\remote\host
     52         # convert this to ////host/path/on/remote/host
     53         # (notice doubling of slashes at the start of the path)
     54             p = '\\\\' + p
     55         components = p.split('\\')
     56         return urllib.parse.quote('/'.join(components))
     57     comp = p.split(':')
     58     if len(comp) != 2 or len(comp[0]) > 1:
     59         error = 'Bad path: ' + p
     60         raise OSError(error)
     61 
     62     drive = urllib.parse.quote(comp[0].upper())
     63     components = comp[1].split('\\')
     64     path = '///' + drive + ':'
     65     for comp in components:
     66         if comp:
     67             path = path + '/' + urllib.parse.quote(comp)
     68     return path
     69