273
273
from/to a storage location.
275
275
Most functions have a _multi variant, which allows you to queue up
276
multiple requests. They generally have a dumb base implementation
276
multiple requests. They generally have a dumb base implementation
277
277
which just iterates over the arguments, but smart Transport
278
278
implementations can do pipelining.
279
279
In general implementations should support having a generator or a list
325
325
def clone(self, offset=None):
326
326
"""Return a new Transport object, cloned from the current location,
327
using a subdirectory or parent directory. This allows connections
327
using a subdirectory or parent directory. This allows connections
328
328
to be pooled, rather than a new one needed for each subdir.
330
330
raise NotImplementedError(self.clone)
368
368
raise NotImplementedError(self.external_url)
370
370
def _pump(self, from_file, to_file):
371
"""Most children will need to copy from one file-like
371
"""Most children will need to copy from one file-like
372
372
object or string to another one.
373
373
This just gives them something easy to call.
452
452
t._combine_paths('/home/sarah', '/etc')
455
:param base_path: urlencoded path for the transport root; typically a
455
:param base_path: urlencoded path for the transport root; typically a
456
456
URL but need not contain scheme/host/etc.
457
457
:param relpath: relative url string for relative part of remote path.
458
458
:return: urlencoded string for final path.
485
485
"""Return the recommended page size for this transport.
487
487
This is potentially different for every path in a given namespace.
488
For example, local transports might use an operating system call to
488
For example, local transports might use an operating system call to
489
489
get the block size for a given path, which can vary due to mount
497
497
"""Return the local path portion from a given absolute path.
499
499
This default implementation is not suitable for filesystems with
500
aliasing, such as that given by symlinks, where a path may not
501
start with our base, but still be a relpath once aliasing is
500
aliasing, such as that given by symlinks, where a path may not
501
start with our base, but still be a relpath once aliasing is
504
504
# TODO: This might want to use bzrlib.osutils.relpath
520
520
def has(self, relpath):
521
521
"""Does the file relpath exist?
523
523
Note that some transports MAY allow querying on directories, but this
524
is not part of the protocol. In other words, the results of
524
is not part of the protocol. In other words, the results of
525
525
t.has("a_directory_name") are undefined.
548
548
"""Iter the relative paths of files in the transports sub-tree.
550
550
*NOTE*: This only lists *files*, not subdirectories!
552
552
As with other listing functions, only some transports implement this,.
553
553
you may check via listable() to determine if it will.
690
690
# Cache the results, but only until they have been fulfilled
692
692
for c_offset in coalesced:
693
# TODO: jam 20060724 it might be faster to not issue seek if
693
# TODO: jam 20060724 it might be faster to not issue seek if
694
694
# we are already at the right location. This should be
696
696
fp.seek(c_offset.start)
878
878
"""Copy the string into the target location.
880
This function is not strictly safe to use. See
880
This function is not strictly safe to use. See
881
881
Transport.put_bytes_non_atomic for more information.
883
883
:param relpath: The remote location to put the contents.
965
965
be synchronised with any internal buffering that may be present.
967
967
:param relpath: The relative path to the file.
968
:param mode: The mode for the newly created file,
968
:param mode: The mode for the newly created file,
969
969
None means just use the default
970
970
:return: A FileStream. FileStream objects have two methods, write() and
971
971
close(). There is no guarantee that data is committed to the file
1021
1021
def copy(self, rel_from, rel_to):
1022
1022
"""Copy the item at rel_from to the location at rel_to.
1024
Override this for efficiency if a specific transport can do it
1024
Override this for efficiency if a specific transport can do it
1025
1025
faster than this default implementation.
1027
1027
self.put_file(rel_to, self.get(rel_from))
1029
1029
def copy_multi(self, relpaths, pb=None):
1030
1030
"""Copy a bunch of entries.
1032
1032
:param relpaths: A list of tuples of the form [(from, to), (from, to),...]
1034
1034
# This is the non-pipelined implementation, so that
1052
1052
def copy_tree(self, from_relpath, to_relpath):
1053
1053
"""Copy a subtree from one relpath to another.
1055
If a faster implementation is available, specific transports should
1055
If a faster implementation is available, specific transports should
1058
1058
source = self.clone(from_relpath)
1120
1120
def move_multi(self, relpaths, pb=None):
1121
1121
"""Move a bunch of entries.
1123
1123
:param relpaths: A list of tuples of the form [(from1, to1), (from2, to2),...]
1125
1125
return self._iterate_over(relpaths, self.move, pb, 'move', expand=True)
1178
1178
NOTE: This returns an object with fields such as 'st_size'. It MAY
1179
1179
or MAY NOT return the literal result of an os.stat() call, so all
1180
1180
access should be via named fields.
1181
ALSO NOTE: Stats of directories may not be supported on some
1181
ALSO NOTE: Stats of directories may not be supported on some
1184
1184
raise NotImplementedError(self.stat)
1221
1221
These methods may be removed in the future.
1223
1223
Transports may raise TransportNotPossible if OS-level locks cannot be
1224
taken over this transport.
1224
taken over this transport.
1226
1226
:return: A lock object, which should contain an unlock() function.
1248
1248
"""Return true if this transport can store and retrieve unix modebits.
1250
1250
(For example, 0700 to make a directory owner-private.)
1252
Note: most callers will not want to switch on this, but should rather
1252
Note: most callers will not want to switch on this, but should rather
1253
1253
just try and set permissions and let them be either stored or not.
1254
1254
This is intended mainly for the use of the test suite.
1256
Warning: this is not guaranteed to be accurate as sometimes we can't
1256
Warning: this is not guaranteed to be accurate as sometimes we can't
1257
1257
be sure: for example with vfat mounted on unix, or a windows sftp
1259
1259
# TODO: Perhaps return a e.g. TransportCharacteristics that can answer
1454
1454
def abspath(self, relpath):
1455
1455
"""Return the full url to the given relative path.
1457
1457
:param relpath: the relative path urlencoded
1459
1459
:returns: the Unicode version of the absolute path for relpath.
1520
1520
Some protocols can renegociate the credentials within a connection,
1521
1521
this method allows daughter classes to share updated credentials.
1523
1523
:param credentials: the updated credentials.
1525
1525
# We don't want to call _set_connection here as we are only updating
1593
1593
def convert_path_to_url(base, error_str):
1594
1594
m = _urlRE.match(base)
1596
# This looks like a URL, but we weren't able to
1596
# This looks like a URL, but we weren't able to
1597
1597
# instantiate it as such raise an appropriate error
1598
1598
# FIXME: we have a 'error_str' unused and we use last_err below
1599
1599
raise errors.UnsupportedProtocol(base, last_err)
1665
1665
:param action: A callable, what the caller want to do while catching
1667
1667
:param transport: The initial transport used.
1668
:param redirected: A callable receiving the redirected transport and the
1668
:param redirected: A callable receiving the redirected transport and the
1669
1669
RedirectRequested exception.
1671
1671
:return: Whatever 'action' returns
1699
1699
class Server(object):
1700
1700
"""A Transport Server.
1702
1702
The Server interface provides a server for a given transport. We use
1703
1703
these servers as loopback testing tools. For any given transport the
1704
1704
Servers it provides must either allow writing, or serve the contents
1705
1705
of os.getcwdu() at the time setUp is called.
1707
1707
Note that these are real servers - they must implement all the things
1708
1708
that we want bzr transports to take advantage of.
1717
1717
def get_url(self):
1718
1718
"""Return a url for this server.
1720
If the transport does not represent a disk directory (i.e. it is
1720
If the transport does not represent a disk directory (i.e. it is
1721
1721
a database like svn, or a memory only transport, it should return
1722
1722
a connection to a newly established resource for this Server.
1723
1723
Otherwise it should return a url that will provide access to the path
1724
1724
that was os.getcwdu() when setUp() was called.
1726
1726
Subsequent calls will return the same resource.
1728
1728
raise NotImplementedError
1730
1730
def get_bogus_url(self):
1731
1731
"""Return a url for this protocol, that will fail to connect.
1733
1733
This may raise NotImplementedError to indicate that this server cannot
1734
1734
provide bogus urls.
1790
1790
# Default to trying GSSAPI authentication (if the kerberos module is available)
1791
1791
register_transport_proto('ftp+gssapi://', register_netloc=True)
1792
register_lazy_transport('ftp+gssapi://', 'bzrlib.transport.ftp._gssapi',
1792
register_lazy_transport('ftp+gssapi://', 'bzrlib.transport.ftp._gssapi',
1793
1793
'GSSAPIFtpTransport')
1794
1794
register_transport_proto('aftp+gssapi://', register_netloc=True)
1795
register_lazy_transport('aftp+gssapi://', 'bzrlib.transport.ftp._gssapi',
1795
register_lazy_transport('aftp+gssapi://', 'bzrlib.transport.ftp._gssapi',
1796
1796
'GSSAPIFtpTransport')
1797
1797
register_transport_proto('ftp+nogssapi://', register_netloc=True)
1798
1798
register_transport_proto('aftp+nogssapi://', register_netloc=True)
1800
register_lazy_transport('ftp://', 'bzrlib.transport.ftp._gssapi',
1801
'GSSAPIFtpTransport')
1802
register_lazy_transport('aftp://', 'bzrlib.transport.ftp._gssapi',
1803
'GSSAPIFtpTransport')
1804
register_lazy_transport('ftp+nogssapi://', 'bzrlib.transport.ftp',
1800
register_lazy_transport('ftp://', 'bzrlib.transport.ftp._gssapi',
1801
'GSSAPIFtpTransport')
1802
register_lazy_transport('aftp://', 'bzrlib.transport.ftp._gssapi',
1803
'GSSAPIFtpTransport')
1804
register_lazy_transport('ftp+nogssapi://', 'bzrlib.transport.ftp',
1805
1805
'FtpTransport')
1806
register_lazy_transport('aftp+nogssapi://', 'bzrlib.transport.ftp',
1806
register_lazy_transport('aftp+nogssapi://', 'bzrlib.transport.ftp',
1807
1807
'FtpTransport')
1809
1809
register_transport_proto('memory://')