import cStringIO as StringIO import hashlib from collections import defaultdict from uuid import uuid4 from storage.basestorage import BaseStorageV2 _FAKE_STORAGE_MAP = defaultdict(StringIO.StringIO) class FakeStorage(BaseStorageV2): def __init__(self, context): super(FakeStorage, self).__init__() def _init_path(self, path=None, create=False): return path def get_direct_download_url(self, path, expires_in=60, requires_cors=False, head=False): try: if self.get_content('supports_direct_download') == 'true': return 'http://somefakeurl?goes=here' except: pass return None def get_content(self, path): if not path in _FAKE_STORAGE_MAP: raise IOError('Fake file %s not found' % path) _FAKE_STORAGE_MAP.get(path).seek(0) return _FAKE_STORAGE_MAP.get(path).read() def put_content(self, path, content): _FAKE_STORAGE_MAP.pop(path, None) _FAKE_STORAGE_MAP[path].write(content) def stream_read(self, path): io_obj = _FAKE_STORAGE_MAP[path] io_obj.seek(0) while True: buf = io_obj.read(self.buffer_size) if not buf: break yield buf def stream_read_file(self, path): return StringIO.StringIO(self.get_content(path)) def stream_write(self, path, fp, content_type=None, content_encoding=None): out_fp = _FAKE_STORAGE_MAP[path] out_fp.seek(0) self.stream_write_to_fp(fp, out_fp) def remove(self, path): _FAKE_STORAGE_MAP.pop(path, None) def exists(self, path): if _FAKE_STORAGE_MAP.get('all_files_exist', None): return True return path in _FAKE_STORAGE_MAP def get_checksum(self, path): return hashlib.sha256(_FAKE_STORAGE_MAP[path].read()).hexdigest()[:7] def initiate_chunked_upload(self): new_uuid = str(uuid4()) _FAKE_STORAGE_MAP[new_uuid].seek(0) return new_uuid, {} def stream_upload_chunk(self, uuid, offset, length, in_fp, _, content_type=None): upload_storage = _FAKE_STORAGE_MAP[uuid] upload_storage.seek(offset) try: return self.stream_write_to_fp(in_fp, upload_storage, length), {}, None except IOError as ex: return 0, {}, ex def complete_chunked_upload(self, uuid, final_path, _): _FAKE_STORAGE_MAP[final_path] = _FAKE_STORAGE_MAP[uuid] _FAKE_STORAGE_MAP.pop(uuid, None) def cancel_chunked_upload(self, uuid, _): _FAKE_STORAGE_MAP.pop(uuid, None) def copy_to(self, destination, path): content = self.get_content(path) destination.put_content(path, content)