30
30
from collections import deque
31
31
from copy import deepcopy
34
35
from unittest import TestSuite
38
from bzrlib.trace import mutter, warning
39
39
import bzrlib.errors as errors
40
40
from bzrlib.errors import DependencyNotPresent
41
import bzrlib.osutils as osutils
41
42
from bzrlib.symbol_versioning import *
43
from bzrlib.trace import mutter, warning
44
import bzrlib.urlutils as urlutils
43
46
# {prefix: [transport_classes]}
44
47
# Transports are inserted onto the list LIFO and tried in order; as a result
129
132
def split_url(url):
133
# TODO: jam 20060606 urls should only be ascii, or they should raise InvalidURL
130
134
if isinstance(url, unicode):
131
135
url = url.encode('utf-8')
132
136
(scheme, netloc, path, params,
284
288
pl = len(self.base)
285
289
return abspath[pl:].strip('/')
291
def local_abspath(self, relpath):
292
"""Return the absolute path on the local filesystem.
294
This function will only be defined for Transports which have a
295
physical local filesystem representation.
297
# TODO: jam 20060426 Should this raise NotLocalUrl instead?
298
raise errors.TransportNotPossible('This is not a LocalTransport,'
299
' so there is no local representation for a path')
287
301
def has(self, relpath):
288
302
"""Does the file relpath exist?
679
# jam 20060426 For compatibility we copy the functions here
680
# TODO: The should be marked as deprecated
681
urlescape = urlutils.escape
682
urlunescape = urlutils.unescape
683
_urlRE = re.compile(r'^(?P<proto>[^:/\\]+)://(?P<path>.*)$')
665
686
def get_transport(base):
666
687
"""Open a transport to access a URL or directory.
671
692
# handler for the scheme?
672
693
global _protocol_handlers
697
def convert_path_to_url(base, error_str):
698
m = _urlRE.match(base)
700
# This looks like a URL, but we weren't able to
701
# instantiate it as such raise an appropriate error
702
raise errors.InvalidURL(base, error_str % m.group('proto'))
703
# This doesn't look like a protocol, consider it a local path
704
new_base = urlutils.local_path_to_url(base)
705
mutter('converting os path %r => url %s' , base, new_base)
708
# Catch any URLs which are passing Unicode rather than ASCII
710
base = base.encode('ascii')
712
# Only local paths can be Unicode
713
base = convert_path_to_url(base,
714
'URLs must be properly escaped (protocol: %s)')
677
716
for proto, factory_list in _protocol_handlers.iteritems():
678
717
if proto is not None and base.startswith(proto):
679
718
t = _try_transport_factories(base, factory_list)
722
# We tried all the different protocols, now try one last time
723
# as a local protocol
724
base = convert_path_to_url(base, 'Unsupported protocol: %s')
682
726
# The default handler is the filesystem handler, stored as protocol None
683
727
return _try_transport_factories(base, _protocol_handlers[None])
697
def urlescape(relpath):
698
"""Escape relpath to be a valid url."""
699
if isinstance(relpath, unicode):
700
relpath = relpath.encode('utf-8')
701
return urllib.quote(relpath)
704
def urlunescape(relpath):
705
"""Unescape relpath from url format."""
706
return urllib.unquote(relpath)
707
# TODO de-utf8 it last. relpath = utf8relpath.decode('utf8')
710
741
class Server(object):
711
742
"""A Transport Server.
831
862
register_lazy_transport('https://', 'bzrlib.transport.http._pycurl', 'PyCurlTransport')
832
863
register_lazy_transport('ftp://', 'bzrlib.transport.ftp', 'FtpTransport')
833
864
register_lazy_transport('aftp://', 'bzrlib.transport.ftp', 'FtpTransport')
834
register_lazy_transport('memory:/', 'bzrlib.transport.memory', 'MemoryTransport')
865
register_lazy_transport('memory://', 'bzrlib.transport.memory', 'MemoryTransport')
835
866
register_lazy_transport('readonly+', 'bzrlib.transport.readonly', 'ReadonlyTransportDecorator')
836
867
register_lazy_transport('fakenfs+', 'bzrlib.transport.fakenfs', 'FakeNFSTransportDecorator')
837
868
register_lazy_transport('vfat+',