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