/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: Andrew Bennetts
  • Date: 2007-08-30 08:11:54 UTC
  • mfrom: (2766 +trunk)
  • mto: (2535.3.55 repo-refactor)
  • mto: This revision was merged to the branch mainline in revision 2772.
  • Revision ID: andrew.bennetts@canonical.com-20070830081154-16hebp2xwr15x2hc
Merge from bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
66
66
from bzrlib import registry
67
67
 
68
68
 
 
69
# a dictionary of open file streams. Keys are absolute paths, values are
 
70
# transport defined.
 
71
_file_streams = {}
 
72
 
 
73
 
69
74
def _get_protocol_handlers():
70
75
    """Return a dictionary of {urlprefix: [factory]}"""
71
76
    return transport_list_registry
252
257
        self._fail()
253
258
 
254
259
 
 
260
class FileStream(object):
 
261
    """Base class for FileStreams."""
 
262
 
 
263
    def __init__(self, transport, relpath):
 
264
        """Create a FileStream for relpath on transport."""
 
265
        self.transport = transport
 
266
        self.relpath = relpath
 
267
 
 
268
    def _close(self):
 
269
        """A hook point for subclasses that need to take action on close."""
 
270
 
 
271
    def close(self):
 
272
        self._close()
 
273
        del _file_streams[self.transport.abspath(self.relpath)]
 
274
 
 
275
 
 
276
class FileFileStream(FileStream):
 
277
    """A file stream object returned by open_write_stream.
 
278
    
 
279
    This version uses a file like object to perform writes.
 
280
    """
 
281
 
 
282
    def __init__(self, transport, relpath, file_handle):
 
283
        FileStream.__init__(self, transport, relpath)
 
284
        self.file_handle = file_handle
 
285
 
 
286
    def _close(self):
 
287
        self.file_handle.close()
 
288
 
 
289
    def write(self, bytes):
 
290
        self.file_handle.write(bytes)
 
291
 
 
292
 
 
293
class AppendBasedFileStream(FileStream):
 
294
    """A file stream object returned by open_write_stream.
 
295
    
 
296
    This version uses append on a transport to perform writes.
 
297
    """
 
298
 
 
299
    def write(self, bytes):
 
300
        self.transport.append_bytes(self.relpath, bytes)
 
301
 
 
302
 
255
303
class Transport(object):
256
304
    """This class encapsulates methods for retrieving or putting a file
257
305
    from/to a storage location.
351
399
        """
352
400
        raise NotImplementedError(self.external_url)
353
401
 
354
 
    def should_cache(self):
355
 
        """Return True if the data pulled across should be cached locally.
356
 
        """
357
 
        return False
358
 
 
359
402
    def _pump(self, from_file, to_file):
360
403
        """Most children will need to copy from one file-like 
361
404
        object or string to another one.
460
503
            path = '/' + path
461
504
        return path
462
505
 
 
506
    def recommended_page_size(self):
 
507
        """Return the recommended page size for this transport.
 
508
 
 
509
        This is potentially different for every path in a given namespace.
 
510
        For example, local transports might use an operating system call to 
 
511
        get the block size for a given path, which can vary due to mount
 
512
        points.
 
513
 
 
514
        :return: The page size in bytes.
 
515
        """
 
516
        return 4 * 1024
 
517
 
463
518
    def relpath(self, abspath):
464
519
        """Return the local path portion from a given absolute path.
465
520
 
693
748
            yield self.get(relpath)
694
749
            count += 1
695
750
 
696
 
    @deprecated_method(zero_eleven)
697
 
    def put(self, relpath, f, mode=None):
698
 
        """Copy the file-like object into the location.
699
 
 
700
 
        :param relpath: Location to put the contents, relative to base.
701
 
        :param f:       File-like object.
702
 
        :param mode: The mode for the newly created file, 
703
 
                     None means just use the default
704
 
        """
705
 
        if isinstance(f, str):
706
 
            return self.put_bytes(relpath, f, mode=mode)
707
 
        else:
708
 
            return self.put_file(relpath, f, mode=mode)
709
 
 
710
751
    def put_bytes(self, relpath, bytes, mode=None):
711
752
        """Atomically put the supplied bytes into the given location.
712
753
 
794
835
                self.mkdir(parent_dir, mode=dir_mode)
795
836
                return self.put_file(relpath, f, mode=mode)
796
837
 
797
 
    @deprecated_method(zero_eleven)
798
 
    def put_multi(self, files, mode=None, pb=None):
799
 
        """Put a set of files into the location.
800
 
 
801
 
        :param files: A list of tuples of relpath, file object [(path1, file1), (path2, file2),...]
802
 
        :param pb:  An optional ProgressBar for indicating percent done.
803
 
        :param mode: The mode for the newly created files
804
 
        :return: The number of files copied.
805
 
        """
806
 
        def _put(path, f):
807
 
            if isinstance(f, str):
808
 
                self.put_bytes(path, f, mode=mode)
809
 
            else:
810
 
                self.put_file(path, f, mode=mode)
811
 
        return len(self._iterate_over(files, _put, pb, 'put', expand=True))
812
 
 
813
838
    def mkdir(self, relpath, mode=None):
814
839
        """Create a directory at the given path."""
815
840
        raise NotImplementedError(self.mkdir)
820
845
            self.mkdir(path, mode=mode)
821
846
        return len(self._iterate_over(relpaths, mkdir, pb, 'mkdir', expand=False))
822
847
 
823
 
    @deprecated_method(zero_eleven)
824
 
    def append(self, relpath, f, mode=None):
825
 
        """Append the text in the file-like object to the supplied location.
826
 
 
827
 
        returns the length of relpath before the content was written to it.
828
 
        
829
 
        If the file does not exist, it is created with the supplied mode.
 
848
    def open_write_stream(self, relpath, mode=None):
 
849
        """Open a writable file stream at relpath.
 
850
 
 
851
        A file stream is a file like object with a write() method that accepts
 
852
        bytes to write.. Buffering may occur internally until the stream is
 
853
        closed with stream.close().  Calls to readv or the get_* methods will
 
854
        be synchronised with any internal buffering that may be present.
 
855
 
 
856
        :param relpath: The relative path to the file.
 
857
        :param mode: The mode for the newly created file, 
 
858
                     None means just use the default
 
859
        :return: A FileStream. FileStream objects have two methods, write() and
 
860
            close(). There is no guarantee that data is committed to the file
 
861
            if close() has not been called (even if get() is called on the same
 
862
            path).
830
863
        """
831
 
        return self.append_file(relpath, f, mode=mode)
 
864
        raise NotImplementedError(self.open_write_stream)
832
865
 
833
866
    def append_file(self, relpath, f, mode=None):
834
867
        """Append bytes from a file-like object to a file at relpath.
1437
1470
            'URLs must be properly escaped (protocol: %s)')
1438
1471
 
1439
1472
    transport = None
1440
 
    if possible_transports:
 
1473
    if possible_transports is not None:
1441
1474
        for t in possible_transports:
1442
1475
            t_same_connection = t._reuse_for(base)
1443
1476
            if t_same_connection is not None:
1450
1483
        if proto is not None and base.startswith(proto):
1451
1484
            transport, last_err = _try_transport_factories(base, factory_list)
1452
1485
            if transport:
1453
 
                if possible_transports:
 
1486
                if possible_transports is not None:
1454
1487
                    assert transport not in possible_transports
1455
1488
                    possible_transports.append(transport)
1456
1489
                return transport