~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/urlutils.py

  • Committer: Parth Malwankar
  • Date: 2010-06-12 02:58:42 UTC
  • mto: This revision was merged to the branch mainline in revision 5291.
  • Revision ID: parth.malwankar@gmail.com-20100612025842-amc5em04efepm069
reduced STEP in recordcounter to allow more frequent updates
on progress bar for slower connections.

Show diffs side-by-side

added added

removed removed

Lines of Context:
101
101
    first_path_slash = path.find('/')
102
102
    if first_path_slash == -1:
103
103
        return len(scheme), None
104
 
    return len(scheme), first_path_slash+m.start('path')
105
 
 
106
 
 
107
 
def is_url(url):
108
 
    """Tests whether a URL is in actual fact a URL."""
109
 
    return _url_scheme_re.match(url) is not None
 
104
    return len(scheme), first_path_slash+len(scheme)+3
110
105
 
111
106
 
112
107
def join(base, *args):
123
118
    """
124
119
    if not args:
125
120
        return base
126
 
    scheme_end, path_start = _find_scheme_and_separator(base)
127
 
    if scheme_end is None and path_start is None:
128
 
        path_start = 0
129
 
    elif path_start is None:
130
 
        path_start = len(base)
131
 
    path = base[path_start:]
 
121
    match = _url_scheme_re.match(base)
 
122
    scheme = None
 
123
    if match:
 
124
        scheme = match.group('scheme')
 
125
        path = match.group('path').split('/')
 
126
        if path[-1:] == ['']:
 
127
            # Strip off a trailing slash
 
128
            # This helps both when we are at the root, and when
 
129
            # 'base' has an extra slash at the end
 
130
            path = path[:-1]
 
131
    else:
 
132
        path = base.split('/')
 
133
 
 
134
    if scheme is not None and len(path) >= 1:
 
135
        host = path[:1]
 
136
        # the path should be represented as an abs path.
 
137
        # we know this must be absolute because of the presence of a URL scheme.
 
138
        remove_root = True
 
139
        path = [''] + path[1:]
 
140
    else:
 
141
        # create an empty host, but dont alter the path - this might be a
 
142
        # relative url fragment.
 
143
        host = []
 
144
        remove_root = False
 
145
 
132
146
    for arg in args:
133
 
        arg_scheme_end, arg_path_start = _find_scheme_and_separator(arg)
134
 
        if arg_scheme_end is None and arg_path_start is None:
135
 
            arg_path_start = 0
136
 
        elif arg_path_start is None:
137
 
            arg_path_start = len(arg)
138
 
        if arg_scheme_end is not None:
139
 
            base = arg
140
 
            path = arg[arg_path_start:]
141
 
            scheme_end = arg_scheme_end
142
 
            path_start = arg_path_start
 
147
        match = _url_scheme_re.match(arg)
 
148
        if match:
 
149
            # Absolute URL
 
150
            scheme = match.group('scheme')
 
151
            # this skips .. normalisation, making http://host/../../..
 
152
            # be rather strange.
 
153
            path = match.group('path').split('/')
 
154
            # set the host and path according to new absolute URL, discarding
 
155
            # any previous values.
 
156
            # XXX: duplicates mess from earlier in this function.  This URL
 
157
            # manipulation code needs some cleaning up.
 
158
            if scheme is not None and len(path) >= 1:
 
159
                host = path[:1]
 
160
                path = path[1:]
 
161
                # url scheme implies absolute path.
 
162
                path = [''] + path
 
163
            else:
 
164
                # no url scheme we take the path as is.
 
165
                host = []
143
166
        else:
 
167
            path = '/'.join(path)
144
168
            path = joinpath(path, arg)
145
 
    return base[:path_start] + path
 
169
            path = path.split('/')
 
170
    if remove_root and path[0:1] == ['']:
 
171
        del path[0]
 
172
    if host:
 
173
        # Remove the leading slash from the path, so long as it isn't also the
 
174
        # trailing slash, which we want to keep if present.
 
175
        if path and path[0] == '' and len(path) > 1:
 
176
            del path[0]
 
177
        path = host + path
 
178
 
 
179
    if scheme is None:
 
180
        return '/'.join(path)
 
181
    return scheme + '://' + '/'.join(path)
146
182
 
147
183
 
148
184
def joinpath(base, *args):
224
260
        return '/'
225
261
 
226
262
    # usual local path with drive letter
227
 
    if (len(win32_url) < 6
228
 
        or win32_url[3] not in ('abcdefghijklmnopqrstuvwxyz'
229
 
                                'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
 
263
    if (win32_url[3] not in ('abcdefghijklmnopqrstuvwxyz'
 
264
                             'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
230
265
        or win32_url[4] not in  '|:'
231
266
        or win32_url[5] != '/'):
232
267
        raise errors.InvalidURL(url, 'Win32 file urls start with'
268
303
    MIN_ABS_FILEURL_LENGTH = WIN32_MIN_ABS_FILEURL_LENGTH
269
304
 
270
305
 
271
 
_url_scheme_re = re.compile(r'^(?P<scheme>[^:/]{2,}):(//)?(?P<path>.*)$')
 
306
_url_scheme_re = re.compile(r'^(?P<scheme>[^:/]{2,})://(?P<path>.*)$')
272
307
_url_hex_escapes_re = re.compile(r'(%[0-9a-fA-F]{2})')
273
308
 
274
309
 
304
339
    :param url: Either a hybrid URL or a local path
305
340
    :return: A normalized URL which only includes 7-bit ASCII characters.
306
341
    """
307
 
    scheme_end, path_start = _find_scheme_and_separator(url)
308
 
    if scheme_end is None:
 
342
    m = _url_scheme_re.match(url)
 
343
    if not m:
309
344
        return local_path_to_url(url)
310
 
    prefix = url[:path_start]
311
 
    path = url[path_start:]
 
345
    scheme = m.group('scheme')
 
346
    path = m.group('path')
312
347
    if not isinstance(url, unicode):
313
348
        for c in url:
314
349
            if c not in _url_safe_characters:
315
350
                raise errors.InvalidURL(url, 'URLs can only contain specific'
316
351
                                            ' safe characters (not %r)' % c)
317
352
        path = _url_hex_escapes_re.sub(_unescape_safe_chars, path)
318
 
        return str(prefix + ''.join(path))
 
353
        return str(scheme + '://' + ''.join(path))
319
354
 
320
355
    # We have a unicode (hybrid) url
321
356
    path_chars = list(path)
327
362
                ['%%%02X' % ord(c) for c in path_chars[i].encode('utf-8')])
328
363
    path = ''.join(path_chars)
329
364
    path = _url_hex_escapes_re.sub(_unescape_safe_chars, path)
330
 
    return str(prefix + path)
 
365
    return str(scheme + '://' + path)
331
366
 
332
367
 
333
368
def relative_url(base, other):