macurl2path.py 3.3 KB

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