167
167
def _win32_local_path_from_url(url):
168
"""Convert a url like file:///C|/path/to/foo into C:/path/to/foo"""
168
"""Convert a url like file:///C:/path/to/foo into C:/path/to/foo"""
169
169
if not url.startswith('file:///'):
170
170
raise errors.InvalidURL(url, 'local urls must start with file:///')
171
171
# We strip off all 3 slashes
172
172
win32_url = url[len('file:///'):]
173
if (win32_url[0] not in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
173
if (win32_url[0] not in ('abcdefghijklmnopqrstuvwxyz'
174
'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
174
175
or win32_url[1] not in '|:'
175
176
or win32_url[2] != '/'):
176
raise errors.InvalidURL(url, 'Win32 file urls start with file:///X|/, where X is a valid drive letter')
177
# TODO: jam 20060426, we could .upper() or .lower() the drive letter
178
# for better consistency.
177
raise errors.InvalidURL(url, 'Win32 file urls start with'
178
' file:///X:/, where X is a valid drive letter')
179
179
return win32_url[0].upper() + u':' + unescape(win32_url[2:])
182
182
def _win32_local_path_to_url(path):
183
"""Convert a local path like ./foo into a URL like file:///C|/path/to/foo
183
"""Convert a local path like ./foo into a URL like file:///C:/path/to/foo
185
185
This also handles transforming escaping unicode characters, etc.
187
187
# importing directly from ntpath allows us to test this
188
# on non-win32 platforms
188
# on non-win32 platform
189
# FIXME: It turns out that on nt, ntpath.abspath uses nt._getfullpathname
190
# which actually strips trailing space characters.
191
# The worst part is that under linux ntpath.abspath has different
192
# semantics, since 'nt' is not an available module.
189
193
win32_path = bzrlib.osutils._nt_normpath(
190
194
bzrlib.osutils._win32_abspath(path)).replace('\\', '/')
191
195
return 'file:///' + win32_path[0].upper() + ':' + escape(win32_path[2:])
199
203
local_path_to_url = _win32_local_path_to_url
200
204
local_path_from_url = _win32_local_path_from_url
202
MIN_ABS_FILEURL_LENGTH = len('file:///C|/')
206
MIN_ABS_FILEURL_LENGTH = len('file:///C:/')
205
209
_url_scheme_re = re.compile(r'^(?P<scheme>[^:/]{2,})://(?P<path>.*)$')
352
356
file:///foo/ => file:///foo
353
357
# This is unique on win32 platforms, and is the only URL
354
358
# format which does it differently.
355
file:///C|/ => file:///C|/
359
file:///C|/ => file:///C:/
357
361
if not url.endswith('/'):