def test_CacheInRam(self): # defaults to mode='http' cache = CacheInRam() self.assertEqual(cache('a', lambda: 1, 0), 1) self.assertEqual(cache('a', lambda: 2, 100), 1) cache.clear('b') self.assertEqual(cache('a', lambda: 2, 100), 1) cache.clear('a') self.assertEqual(cache('a', lambda: 2, 100), 2) cache.clear() self.assertEqual(cache('a', lambda: 3, 100), 3) self.assertEqual(cache('a', lambda: 4, 0), 4) # test singleton behaviour cache = CacheInRam() cache.clear() self.assertEqual(cache('a', lambda: 3, 100), 3) self.assertEqual(cache('a', lambda: 4, 0), 4) # test key deletion cache('a', None) self.assertEqual(cache('a', lambda: 5, 100), 5) # test increment self.assertEqual(cache.increment('a'), 6) self.assertEqual(cache('a', lambda: 1, 100), 6) cache.increment('b') self.assertEqual(cache('b', lambda: 'x', 100), 1)
def copystream_progress(request, chunk_size=10 ** 5): """ Copies request.env.wsgi_input into request.body and stores progress upload status in cache_ram X-Progress-ID:length and X-Progress-ID:uploaded """ env = request.env if not env.get('CONTENT_LENGTH', None): return cStringIO.StringIO() source = env['wsgi.input'] try: size = int(env['CONTENT_LENGTH']) except ValueError: raise HTTP(400, "Invalid Content-Length header") try: # Android requires this dest = tempfile.NamedTemporaryFile() except NotImplementedError: # and GAE this dest = tempfile.TemporaryFile() if not 'X-Progress-ID' in request.get_vars: copystream(source, dest, size, chunk_size) return dest cache_key = 'X-Progress-ID:' + request.get_vars['X-Progress-ID'] cache_ram = CacheInRam(request) # same as cache.ram because meta_storage cache_ram(cache_key + ':length', lambda: size, 0) cache_ram(cache_key + ':uploaded', lambda: 0, 0) while size > 0: if size < chunk_size: data = source.read(size) cache_ram.increment(cache_key + ':uploaded', size) else: data = source.read(chunk_size) cache_ram.increment(cache_key + ':uploaded', chunk_size) length = len(data) if length > size: (data, length) = (data[:size], size) size -= length if length == 0: break dest.write(data) if length < chunk_size: break dest.seek(0) cache_ram(cache_key + ':length', None) cache_ram(cache_key + ':uploaded', None) return dest
def copystream_progress(request, chunk_size=10 ** 5): """ Copies request.env.wsgi_input into request.body and stores progress upload status in cache_ram X-Progress-ID:length and X-Progress-ID:uploaded """ env = request.env if not env.get('CONTENT_LENGTH', None): return StringIO() source = env['wsgi.input'] try: size = int(env['CONTENT_LENGTH']) except ValueError: raise HTTP(400, "Invalid Content-Length header") try: # Android requires this dest = tempfile.NamedTemporaryFile() except NotImplementedError: # and GAE this dest = tempfile.TemporaryFile() if 'X-Progress-ID' not in request.get_vars: copystream(source, dest, size, chunk_size) return dest cache_key = 'X-Progress-ID:' + request.get_vars['X-Progress-ID'] cache_ram = CacheInRam(request) # same as cache.ram because meta_storage cache_ram(cache_key + ':length', lambda: size, 0) cache_ram(cache_key + ':uploaded', lambda: 0, 0) while size > 0: if size < chunk_size: data = source.read(size) cache_ram.increment(cache_key + ':uploaded', size) else: data = source.read(chunk_size) cache_ram.increment(cache_key + ':uploaded', chunk_size) length = len(data) if length > size: (data, length) = (data[:size], size) size -= length if length == 0: break dest.write(data) if length < chunk_size: break dest.seek(0) cache_ram(cache_key + ':length', None) cache_ram(cache_key + ':uploaded', None) return dest