~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/store/__init__.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2008-06-25 10:36:36 UTC
  • mfrom: (3350.6.12 versionedfiles)
  • Revision ID: pqm@pqm.ubuntu.com-20080625103636-6kxh4e1gmyn82f50
(mbp for robertc) VersionedFiles refactoring

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
    osutils,
36
36
    symbol_versioning,
37
37
    urlutils,
 
38
    versionedfile,
38
39
    )
39
40
from bzrlib.errors import BzrError, UnlistableStore, TransportNotPossible
40
41
from bzrlib.symbol_versioning import (
184
185
        raise NotImplementedError('children need to implement this function.')
185
186
 
186
187
    def _check_fileid(self, fileid):
187
 
        if not isinstance(fileid, basestring):
188
 
            raise TypeError('Fileids should be a string type: %s %r' % (type(fileid), fileid))
 
188
        if type(fileid) != str:
 
189
            raise TypeError('Fileids should be bytestrings: %s %r' % (
 
190
                type(fileid), fileid))
189
191
        if '\\' in fileid or '/' in fileid:
190
192
            raise ValueError("invalid store id %r" % fileid)
191
193
 
251
253
        # will just use the filesystem defaults
252
254
        self._dir_mode = dir_mode
253
255
        self._file_mode = file_mode
254
 
 
255
 
    def _unescape(self, file_id):
256
 
        """If filename escaping is enabled for this store, unescape and return the filename."""
257
 
        if self._escaped:
258
 
            return urllib.unquote(file_id)
 
256
        # Create a key mapper to use
 
257
        if escaped and prefixed:
 
258
            self._mapper = versionedfile.HashEscapedPrefixMapper()
 
259
        elif not escaped and prefixed:
 
260
            self._mapper = versionedfile.HashPrefixMapper()
 
261
        elif self._escaped:
 
262
            raise ValueError(
 
263
                "%r: escaped unprefixed stores are not permitted."
 
264
                % (self,))
259
265
        else:
260
 
            return file_id
 
266
            self._mapper = versionedfile.PrefixMapper()
261
267
 
262
268
    def _iter_files_recursive(self):
263
269
        """Iterate through the files in the transport."""
264
270
        for quoted_relpath in self._transport.iter_files_recursive():
265
 
            # transport iterator always returns quoted paths, regardless of
266
 
            # escaping
267
 
            yield urllib.unquote(quoted_relpath)
 
271
            yield quoted_relpath
268
272
 
269
273
    def __iter__(self):
270
274
        for relpath in self._iter_files_recursive():
278
282
                    if name.endswith('.' + suffix):
279
283
                        skip = True
280
284
            if not skip:
281
 
                yield self._unescape(name)
 
285
                yield self._mapper.unmap(name)[0]
282
286
 
283
287
    def __len__(self):
284
288
        return len(list(self.__iter__()))
292
296
                self._check_fileid(suffix)
293
297
        else:
294
298
            suffixes = []
295
 
        fileid = self._escape_file_id(fileid)
296
 
        if self._prefixed:
297
 
            # hash_prefix adds the '/' separator
298
 
            prefix = self.hash_prefix(fileid, escaped=True)
299
 
        else:
300
 
            prefix = ''
301
 
        path = prefix + fileid
302
 
        full_path = u'.'.join([path] + suffixes)
303
 
        return urlutils.escape(full_path)
304
 
 
305
 
    def _escape_file_id(self, file_id):
306
 
        """Turn a file id into a filesystem safe string.
307
 
 
308
 
        This is similar to a plain urllib.quote, except
309
 
        it uses specific safe characters, so that it doesn't
310
 
        have to translate a lot of valid file ids.
311
 
        """
312
 
        if not self._escaped:
313
 
            return file_id
314
 
        if isinstance(file_id, unicode):
315
 
            file_id = file_id.encode('utf-8')
316
 
        # @ does not get escaped. This is because it is a valid
317
 
        # filesystem character we use all the time, and it looks
318
 
        # a lot better than seeing %40 all the time.
319
 
        safe = "abcdefghijklmnopqrstuvwxyz0123456789-_@,."
320
 
        r = [((c in safe) and c or ('%%%02x' % ord(c)))
321
 
             for c in file_id]
322
 
        return ''.join(r)
323
 
 
324
 
    def hash_prefix(self, fileid, escaped=False):
325
 
        # fileid should be unescaped
326
 
        if not escaped and self._escaped:
327
 
            fileid = self._escape_file_id(fileid)
328
 
        return "%02x/" % (adler32(fileid) & 0xff)
 
299
        path = self._mapper.map((fileid,))
 
300
        full_path = '.'.join([path] + suffixes)
 
301
        return full_path
329
302
 
330
303
    def __repr__(self):
331
304
        if self._transport is None: