~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/__init__.py

[merge] from robert and fix up tests

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
        ## mutter('registering transport: %s => %s' % (prefix, klass.__name__))
41
41
        _protocol_handlers[prefix] = klass
42
42
 
 
43
 
43
44
class Transport(object):
44
45
    """This class encapsulates methods for retrieving or putting a file
45
46
    from/to a storage location.
122
123
    def abspath(self, relpath):
123
124
        """Return the full url to the given relative path.
124
125
        This can be supplied with a string or a list
 
126
 
 
127
        XXX: Robert Collins 20051016 - is this really needed in the public
 
128
             interface ?
125
129
        """
126
130
        raise NotImplementedError
127
131
 
128
132
    def relpath(self, abspath):
129
133
        """Return the local path portion from a given absolute path.
 
134
 
 
135
        This default implementation is not suitable for filesystems with
 
136
        aliasing, such as that given by symlinks, where a path may not 
 
137
        start with our base, but still be a relpath once aliasing is 
 
138
        resolved.
130
139
        """
131
 
        raise NotImplementedError
 
140
        if not abspath.startswith(self.base):
 
141
            raise NonRelativePath('path %r is not under base URL %r'
 
142
                           % (abspath, self.base))
 
143
        pl = len(self.base)
 
144
        return abspath[pl:].lstrip('/')
 
145
 
132
146
 
133
147
    def has(self, relpath):
134
 
        """Does the target location exist?"""
 
148
        """Does the file relpath exist?
 
149
        
 
150
        Note that some transports MAY allow querying on directories, but this
 
151
        is not part of the protocol.
 
152
        """
135
153
        raise NotImplementedError
136
154
 
137
155
    def has_multi(self, relpaths, pb=None):
143
161
            yield self.has(relpath)
144
162
            count += 1
145
163
 
 
164
    def iter_files_recursive(self):
 
165
        """Iter the relative paths of files in the transports sub-tree.
 
166
        
 
167
        As with other listing functions, only some transports implement this,.
 
168
        you may check via is_listable to determine if it will.
 
169
        """
 
170
        raise NotImplementedError
 
171
 
146
172
    def get(self, relpath):
147
173
        """Get the file at the given relative path.
148
174
 
167
193
            yield self.get(relpath)
168
194
            count += 1
169
195
 
170
 
    def get_partial(self, relpath, start, length=None):
171
 
        """Get just part of a file.
172
 
 
173
 
        :param relpath: Path to the file, relative to base
174
 
        :param start: The starting position to read from
175
 
        :param length: The length to read. A length of None indicates
176
 
                       read to the end of the file.
177
 
        :return: A file-like object containing at least the specified bytes.
178
 
                 Some implementations may return objects which can be read
179
 
                 past this length, but this is not guaranteed.
180
 
        """
181
 
        raise NotImplementedError
182
 
 
183
 
    def get_partial_multi(self, offsets, pb=None):
184
 
        """Put a set of files or strings into the location.
185
 
 
186
 
        Requesting multiple portions of the same file can be dangerous.
187
 
 
188
 
        :param offsets: A list of tuples of relpath, start, length
189
 
                         [(path1, start1, length1),
190
 
                          (path2, start2, length2),
191
 
                          (path3, start3), ...]
192
 
                         length is optional, defaulting to None
193
 
        :param pb:  An optional ProgressBar for indicating percent done.
194
 
        :return: A generator of file-like objects.
195
 
        """
196
 
        total = self._get_total(offsets)
197
 
        count = 0
198
 
        for offset in offsets:
199
 
            self._update_pb(pb, 'get_partial', count, total)
200
 
            yield self.get_partial(*offset)
201
 
            count += 1
202
 
 
203
196
    def put(self, relpath, f):
204
197
        """Copy the file-like or string object into the location.
205
198
 
301
294
        """Return the stat information for a file.
302
295
        WARNING: This may not be implementable for all protocols, so use
303
296
        sparingly.
 
297
        NOTE: This returns an object with fields such as 'st_size'. It MAY
 
298
        or MAY NOT return the literal result of an os.stat() call, so all
 
299
        access should be via named fields.
 
300
        ALSO NOTE: Stats of directories may not be supported on some 
 
301
        transports.
304
302
        """
305
303
        raise NotImplementedError
306
304