X-Git-Url: http://git.vrable.net/?a=blobdiff_plain;f=python%2Fcumulus%2F__init__.py;h=b120436bf958b68c6d9711fb488e2dfd0d0a21e6;hb=81b1c38dbd530d3be599605d3241089780bd9141;hp=51d3ee82f49ec0e072714d343f1e9b38cd552ac3;hpb=2ee97034047db53780a52d803b1c577b4c23c303;p=cumulus.git diff --git a/python/cumulus/__init__.py b/python/cumulus/__init__.py index 51d3ee8..b120436 100644 --- a/python/cumulus/__init__.py +++ b/python/cumulus/__init__.py @@ -23,6 +23,28 @@ MAX_RECURSION_DEPTH = 3 # All segments which have been accessed this session. accessed_segments = set() +# Table of methods used to filter segments before storage, and corresponding +# filename extensions. These are listed in priority order (methods earlier in +# the list are tried first). +SEGMENT_FILTERS = [ + (".gpg", "lbs-filter-gpg --decrypt"), + (".gz", "gzip -dc"), + (".bz2", "bzip2 -dc"), +] + +def uri_decode(s): + """Decode a URI-encoded (%xx escapes) string.""" + def hex_decode(m): return chr(int(m.group(1), 16)) + return re.sub(r"%([0-9a-f]{2})", hex_decode, s) +def uri_encode(s): + """Encode a string to URI-encoded (%xx escapes) form.""" + def hex_encode(c): + if c > '+' and c < '\x7f' and c != '@': + return c + else: + return "%%%02x" % (ord(c),) + return ''.join(hex_encode(c) for c in s) + class Struct: """A class which merely acts as a data container. @@ -84,7 +106,9 @@ class LowlevelDataStore: """ def __init__(self, path): - if path.find(":") >= 0: + if isinstance(path, cumulus.store.Store): + self.store = path + elif path.find(":") >= 0: self.store = cumulus.store.open(path) else: self.store = cumulus.store.file.FileStore(path) @@ -171,19 +195,26 @@ class ObjectStore: def get_segment(self, segment): accessed_segments.add(segment) - raw = self.store.lowlevel_open(segment + ".tar.gpg") - (input, output) = os.popen2("lbs-filter-gpg --decrypt") - def copy_thread(src, dst): - BLOCK_SIZE = 4096 - while True: - block = src.read(BLOCK_SIZE) - if len(block) == 0: break - dst.write(block) - dst.close() + for (extension, filter) in SEGMENT_FILTERS: + try: + raw = self.store.lowlevel_open(segment + ".tar" + extension) + + (input, output) = os.popen2(filter) + def copy_thread(src, dst): + BLOCK_SIZE = 4096 + while True: + block = src.read(BLOCK_SIZE) + if len(block) == 0: break + dst.write(block) + dst.close() + + thread.start_new_thread(copy_thread, (raw, input)) + return output + except: + pass - thread.start_new_thread(copy_thread, (raw, input)) - return output + raise cumulus.store.NotFoundError def load_segment(self, segment): seg = tarfile.open(segment, 'r|', self.get_segment(segment)) @@ -347,8 +378,7 @@ class MetadataItem: @staticmethod def decode_str(s): """Decode a URI-encoded (%xx escapes) string.""" - def hex_decode(m): return chr(int(m.group(1), 16)) - return re.sub(r"%([0-9a-f]{2})", hex_decode, s) + return uri_decode(s) @staticmethod def raw_str(s):