/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/transport/__init__.py

  • Committer: Benoît Pierre
  • Date: 2009-02-24 00:25:32 UTC
  • mfrom: (4035 +trunk)
  • mto: (4056.1.1 trunk2)
  • mto: This revision was merged to the branch mainline in revision 4058.
  • Revision ID: benoit.pierre@gmail.com-20090224002532-i2f64ou15pa7if2y
Merge with upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
    errors,
42
42
    osutils,
43
43
    symbol_versioning,
 
44
    ui,
44
45
    urlutils,
45
46
    )
46
47
""")
84
85
def _get_transport_modules():
85
86
    """Return a list of the modules providing transports."""
86
87
    modules = set()
87
 
    for prefix, factory_list in transport_list_registry.iteritems():
 
88
    for prefix, factory_list in transport_list_registry.items():
88
89
        for factory in factory_list:
89
90
            if hasattr(factory, "_module_name"):
90
91
                modules.add(factory._module_name)
242
243
 
243
244
class FileFileStream(FileStream):
244
245
    """A file stream object returned by open_write_stream.
245
 
    
 
246
 
246
247
    This version uses a file like object to perform writes.
247
248
    """
248
249
 
259
260
 
260
261
class AppendBasedFileStream(FileStream):
261
262
    """A file stream object returned by open_write_stream.
262
 
    
 
263
 
263
264
    This version uses append on a transport to perform writes.
264
265
    """
265
266
 
272
273
    from/to a storage location.
273
274
 
274
275
    Most functions have a _multi variant, which allows you to queue up
275
 
    multiple requests. They generally have a dumb base implementation 
 
276
    multiple requests. They generally have a dumb base implementation
276
277
    which just iterates over the arguments, but smart Transport
277
278
    implementations can do pipelining.
278
279
    In general implementations should support having a generator or a list
323
324
 
324
325
    def clone(self, offset=None):
325
326
        """Return a new Transport object, cloned from the current location,
326
 
        using a subdirectory or parent directory. This allows connections 
 
327
        using a subdirectory or parent directory. This allows connections
327
328
        to be pooled, rather than a new one needed for each subdir.
328
329
        """
329
330
        raise NotImplementedError(self.clone)
367
368
        raise NotImplementedError(self.external_url)
368
369
 
369
370
    def _pump(self, from_file, to_file):
370
 
        """Most children will need to copy from one file-like 
 
371
        """Most children will need to copy from one file-like
371
372
        object or string to another one.
372
373
        This just gives them something easy to call.
373
374
        """
382
383
        except TypeError: # We can't tell how many, because relpaths is a generator
383
384
            return None
384
385
 
 
386
    def _report_activity(self, bytes, direction):
 
387
        """Notify that this transport has activity.
 
388
 
 
389
        Implementations should call this from all methods that actually do IO.
 
390
        Be careful that it's not called twice, if one method is implemented on
 
391
        top of another.
 
392
 
 
393
        :param bytes: Number of bytes read or written.
 
394
        :param direction: 'read' or 'write' or None.
 
395
        """
 
396
        ui.ui_factory.report_transport_activity(self, bytes, direction)
 
397
 
385
398
    def _update_pb(self, pb, msg, count, total):
386
399
        """Update the progress bar based on the current count
387
400
        and total available, total may be None if it was
439
452
            t._combine_paths('/home/sarah', '/etc')
440
453
                => '/etc'
441
454
 
442
 
        :param base_path: urlencoded path for the transport root; typically a 
 
455
        :param base_path: urlencoded path for the transport root; typically a
443
456
             URL but need not contain scheme/host/etc.
444
457
        :param relpath: relative url string for relative part of remote path.
445
458
        :return: urlencoded string for final path.
472
485
        """Return the recommended page size for this transport.
473
486
 
474
487
        This is potentially different for every path in a given namespace.
475
 
        For example, local transports might use an operating system call to 
 
488
        For example, local transports might use an operating system call to
476
489
        get the block size for a given path, which can vary due to mount
477
490
        points.
478
491
 
484
497
        """Return the local path portion from a given absolute path.
485
498
 
486
499
        This default implementation is not suitable for filesystems with
487
 
        aliasing, such as that given by symlinks, where a path may not 
488
 
        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
489
502
        resolved.
490
503
        """
491
504
        # TODO: This might want to use bzrlib.osutils.relpath
506
519
 
507
520
    def has(self, relpath):
508
521
        """Does the file relpath exist?
509
 
        
 
522
 
510
523
        Note that some transports MAY allow querying on directories, but this
511
 
        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
512
525
        t.has("a_directory_name") are undefined.
513
526
 
514
527
        :rtype: bool
535
548
        """Iter the relative paths of files in the transports sub-tree.
536
549
 
537
550
        *NOTE*: This only lists *files*, not subdirectories!
538
 
        
 
551
 
539
552
        As with other listing functions, only some transports implement this,.
540
553
        you may check via listable() to determine if it will.
541
554
        """
568
581
 
569
582
        :param relpath: The relative path to the file
570
583
        """
571
 
        return self.get(relpath).read()
 
584
        f = self.get(relpath)
 
585
        try:
 
586
            return f.read()
 
587
        finally:
 
588
            f.close()
572
589
 
573
590
    @deprecated_method(one_four)
574
591
    def get_smart_client(self):
673
690
        # Cache the results, but only until they have been fulfilled
674
691
        data_map = {}
675
692
        for c_offset in coalesced:
676
 
            # 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
677
694
            #       we are already at the right location. This should be
678
695
            #       benchmarked.
679
696
            fp.seek(c_offset.start)
860
877
                             dir_mode=None):
861
878
        """Copy the string into the target location.
862
879
 
863
 
        This function is not strictly safe to use. See 
 
880
        This function is not strictly safe to use. See
864
881
        Transport.put_bytes_non_atomic for more information.
865
882
 
866
883
        :param relpath: The remote location to put the contents.
948
965
        be synchronised with any internal buffering that may be present.
949
966
 
950
967
        :param relpath: The relative path to the file.
951
 
        :param mode: The mode for the newly created file, 
 
968
        :param mode: The mode for the newly created file,
952
969
                     None means just use the default
953
970
        :return: A FileStream. FileStream objects have two methods, write() and
954
971
            close(). There is no guarantee that data is committed to the file
1003
1020
 
1004
1021
    def copy(self, rel_from, rel_to):
1005
1022
        """Copy the item at rel_from to the location at rel_to.
1006
 
        
1007
 
        Override this for efficiency if a specific transport can do it 
 
1023
 
 
1024
        Override this for efficiency if a specific transport can do it
1008
1025
        faster than this default implementation.
1009
1026
        """
1010
1027
        self.put_file(rel_to, self.get(rel_from))
1011
1028
 
1012
1029
    def copy_multi(self, relpaths, pb=None):
1013
1030
        """Copy a bunch of entries.
1014
 
        
 
1031
 
1015
1032
        :param relpaths: A list of tuples of the form [(from, to), (from, to),...]
1016
1033
        """
1017
1034
        # This is the non-pipelined implementation, so that
1035
1052
    def copy_tree(self, from_relpath, to_relpath):
1036
1053
        """Copy a subtree from one relpath to another.
1037
1054
 
1038
 
        If a faster implementation is available, specific transports should 
 
1055
        If a faster implementation is available, specific transports should
1039
1056
        implement it.
1040
1057
        """
1041
1058
        source = self.clone(from_relpath)
1089
1106
 
1090
1107
        The destination is deleted if possible, even if it's a non-empty
1091
1108
        directory tree.
1092
 
        
 
1109
 
1093
1110
        If a transport can directly implement this it is suggested that
1094
1111
        it do so for efficiency.
1095
1112
        """
1102
1119
 
1103
1120
    def move_multi(self, relpaths, pb=None):
1104
1121
        """Move a bunch of entries.
1105
 
        
 
1122
 
1106
1123
        :param relpaths: A list of tuples of the form [(from1, to1), (from2, to2),...]
1107
1124
        """
1108
1125
        return self._iterate_over(relpaths, self.move, pb, 'move', expand=True)
1161
1178
        NOTE: This returns an object with fields such as 'st_size'. It MAY
1162
1179
        or MAY NOT return the literal result of an os.stat() call, so all
1163
1180
        access should be via named fields.
1164
 
        ALSO NOTE: Stats of directories may not be supported on some 
 
1181
        ALSO NOTE: Stats of directories may not be supported on some
1165
1182
        transports.
1166
1183
        """
1167
1184
        raise NotImplementedError(self.stat)
1204
1221
        These methods may be removed in the future.
1205
1222
 
1206
1223
        Transports may raise TransportNotPossible if OS-level locks cannot be
1207
 
        taken over this transport.  
 
1224
        taken over this transport.
1208
1225
 
1209
1226
        :return: A lock object, which should contain an unlock() function.
1210
1227
        """
1231
1248
        """Return true if this transport can store and retrieve unix modebits.
1232
1249
 
1233
1250
        (For example, 0700 to make a directory owner-private.)
1234
 
        
1235
 
        Note: most callers will not want to switch on this, but should rather 
 
1251
 
 
1252
        Note: most callers will not want to switch on this, but should rather
1236
1253
        just try and set permissions and let them be either stored or not.
1237
1254
        This is intended mainly for the use of the test suite.
1238
 
        
1239
 
        Warning: this is not guaranteed to be accurate as sometimes we can't 
 
1255
 
 
1256
        Warning: this is not guaranteed to be accurate as sometimes we can't
1240
1257
        be sure: for example with vfat mounted on unix, or a windows sftp
1241
1258
        server."""
1242
1259
        # TODO: Perhaps return a e.g. TransportCharacteristics that can answer
1249
1266
        # should be asked to ConnectedTransport only.
1250
1267
        return None
1251
1268
 
 
1269
    def _redirected_to(self, source, target):
 
1270
        """Returns a transport suitable to re-issue a redirected request.
 
1271
 
 
1272
        :param source: The source url as returned by the server.
 
1273
        :param target: The target url as returned by the server.
 
1274
 
 
1275
        The redirection can be handled only if the relpath involved is not
 
1276
        renamed by the redirection.
 
1277
 
 
1278
        :returns: A transport or None.
 
1279
        """
 
1280
        # This returns None by default, meaning the transport can't handle the
 
1281
        # redirection.
 
1282
        return None
 
1283
 
 
1284
 
1252
1285
 
1253
1286
class _SharedConnection(object):
1254
1287
    """A connection shared between several transports."""
1420
1453
 
1421
1454
    def abspath(self, relpath):
1422
1455
        """Return the full url to the given relative path.
1423
 
        
 
1456
 
1424
1457
        :param relpath: the relative path urlencoded
1425
1458
 
1426
1459
        :returns: the Unicode version of the absolute path for relpath.
1486
1519
 
1487
1520
        Some protocols can renegociate the credentials within a connection,
1488
1521
        this method allows daughter classes to share updated credentials.
1489
 
        
 
1522
 
1490
1523
        :param credentials: the updated credentials.
1491
1524
        """
1492
1525
        # We don't want to call _set_connection here as we are only updating
1560
1593
    def convert_path_to_url(base, error_str):
1561
1594
        m = _urlRE.match(base)
1562
1595
        if m:
1563
 
            # This looks like a URL, but we weren't able to 
 
1596
            # This looks like a URL, but we weren't able to
1564
1597
            # instantiate it as such raise an appropriate error
1565
1598
            # FIXME: we have a 'error_str' unused and we use last_err below
1566
1599
            raise errors.UnsupportedProtocol(base, last_err)
1587
1620
                    possible_transports.append(t_same_connection)
1588
1621
                return t_same_connection
1589
1622
 
1590
 
    for proto, factory_list in transport_list_registry.iteritems():
 
1623
    for proto, factory_list in transport_list_registry.items():
1591
1624
        if proto is not None and base.startswith(proto):
1592
1625
            transport, last_err = _try_transport_factories(base, factory_list)
1593
1626
            if transport:
1632
1665
    :param action: A callable, what the caller want to do while catching
1633
1666
                  redirections.
1634
1667
    :param transport: The initial transport used.
1635
 
    :param redirected: A callable receiving the redirected transport and the 
 
1668
    :param redirected: A callable receiving the redirected transport and the
1636
1669
                  RedirectRequested exception.
1637
1670
 
1638
1671
    :return: Whatever 'action' returns
1665
1698
 
1666
1699
class Server(object):
1667
1700
    """A Transport Server.
1668
 
    
 
1701
 
1669
1702
    The Server interface provides a server for a given transport. We use
1670
1703
    these servers as loopback testing tools. For any given transport the
1671
1704
    Servers it provides must either allow writing, or serve the contents
1672
1705
    of os.getcwdu() at the time setUp is called.
1673
 
    
 
1706
 
1674
1707
    Note that these are real servers - they must implement all the things
1675
1708
    that we want bzr transports to take advantage of.
1676
1709
    """
1683
1716
 
1684
1717
    def get_url(self):
1685
1718
        """Return a url for this server.
1686
 
        
1687
 
        If the transport does not represent a disk directory (i.e. it is 
 
1719
 
 
1720
        If the transport does not represent a disk directory (i.e. it is
1688
1721
        a database like svn, or a memory only transport, it should return
1689
1722
        a connection to a newly established resource for this Server.
1690
1723
        Otherwise it should return a url that will provide access to the path
1691
1724
        that was os.getcwdu() when setUp() was called.
1692
 
        
 
1725
 
1693
1726
        Subsequent calls will return the same resource.
1694
1727
        """
1695
1728
        raise NotImplementedError
1696
1729
 
1697
1730
    def get_bogus_url(self):
1698
1731
        """Return a url for this protocol, that will fail to connect.
1699
 
        
 
1732
 
1700
1733
        This may raise NotImplementedError to indicate that this server cannot
1701
1734
        provide bogus urls.
1702
1735
        """
1739
1772
                 help="Read-only access of branches exported on the web.")
1740
1773
register_transport_proto('https://',
1741
1774
            help="Read-only access of branches exported on the web using SSL.")
 
1775
# The default http implementation is urllib, but https is pycurl if available
 
1776
register_lazy_transport('http://', 'bzrlib.transport.http._pycurl',
 
1777
                        'PyCurlTransport')
1742
1778
register_lazy_transport('http://', 'bzrlib.transport.http._urllib',
1743
1779
                        'HttpTransport_urllib')
1744
1780
register_lazy_transport('https://', 'bzrlib.transport.http._urllib',
1745
1781
                        'HttpTransport_urllib')
1746
 
register_lazy_transport('http://', 'bzrlib.transport.http._pycurl',
1747
 
                        'PyCurlTransport')
1748
1782
register_lazy_transport('https://', 'bzrlib.transport.http._pycurl',
1749
1783
                        'PyCurlTransport')
1750
1784
 
1755
1789
 
1756
1790
# Default to trying GSSAPI authentication (if the kerberos module is available)
1757
1791
register_transport_proto('ftp+gssapi://', register_netloc=True)
1758
 
register_lazy_transport('ftp+gssapi://', 'bzrlib.transport.ftp._gssapi', 
 
1792
register_lazy_transport('ftp+gssapi://', 'bzrlib.transport.ftp._gssapi',
1759
1793
                        'GSSAPIFtpTransport')
1760
1794
register_transport_proto('aftp+gssapi://', register_netloc=True)
1761
 
register_lazy_transport('aftp+gssapi://', 'bzrlib.transport.ftp._gssapi', 
 
1795
register_lazy_transport('aftp+gssapi://', 'bzrlib.transport.ftp._gssapi',
1762
1796
                        'GSSAPIFtpTransport')
1763
1797
register_transport_proto('ftp+nogssapi://', register_netloc=True)
1764
1798
register_transport_proto('aftp+nogssapi://', register_netloc=True)
1765
1799
 
1766
 
register_lazy_transport('ftp://', 'bzrlib.transport.ftp._gssapi', 
1767
 
                        'GSSAPIFtpTransport')
1768
 
register_lazy_transport('aftp://', 'bzrlib.transport.ftp._gssapi', 
1769
 
                        'GSSAPIFtpTransport')
1770
 
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',
1771
1805
                        'FtpTransport')
1772
 
register_lazy_transport('aftp+nogssapi://', 'bzrlib.transport.ftp', 
 
1806
register_lazy_transport('aftp+nogssapi://', 'bzrlib.transport.ftp',
1773
1807
                        'FtpTransport')
1774
1808
 
1775
1809
register_transport_proto('memory://')
1845
1879
            register_netloc=True)
1846
1880
register_lazy_transport('bzr+ssh://', 'bzrlib.transport.remote',
1847
1881
                        'RemoteSSHTransport')
 
1882
 
 
1883
register_transport_proto('ssh:')
 
1884
register_lazy_transport('ssh:', 'bzrlib.transport.remote',
 
1885
                        'HintingSSHTransport')