def test_list_recipes_in_store(): _cleanup() config = { "server_store": ["tiddlywebplugins.devstore", {"store_root": STORE_DIR}], "instance_tiddlers": {}, "root_dir": "", } env = {"tiddlyweb.config": config} store = Store(config["server_store"][0], config["server_store"][1], env) for name in ["alpha", "bravo", "charlie"]: filepath = "%s.recipe" % os.path.join(STORE_DIR, name) open(filepath, "w").close() actual = [recipe.name for recipe in store.list_recipes()] expected = ["bravo", "alpha", "charlie"] assert set(actual) == set(expected)
class Store(StorageInterface): def __init__(self, store_config=None, environ=None): super(Store, self).__init__(store_config, environ) self.main_store = None self.stores = [] self._init_store() def _init_store(self): server_store = self.environ['tiddlyweb.config']['server_store'] server_store_copy = copy.deepcopy(server_store) extra_store_config = server_store[1]['extras'] main_store_config = server_store[1]['main'] self.environ['tiddlyweb.config']['server_store'] = main_store_config self.main_store = Storer(main_store_config[0], main_store_config[1], self.environ) for rule, store in extra_store_config: pattern = re.compile(rule) self.environ['tiddlyweb.config']['server_store'] = store self.environ['tiddlyweb.config']['main_store'] = self.main_store self.stores.append((pattern, Storer(store[0], store[1], self.environ))) self.environ['tiddlyweb.config']['server_store'] = server_store_copy def recipe_delete(self, recipe): self.main_store.delete(recipe) def recipe_get(self, recipe): return self.main_store.get(recipe) def recipe_put(self, recipe): self.main_store.put(recipe) def bag_delete(self, bag): store = self._determine_store(bag.name) store.delete(bag) def bag_get(self, bag): store = self._determine_store(bag.name) return store.get(bag) def bag_put(self, bag): store = self._determine_store(bag.name) store.put(bag) def tiddler_delete(self, tiddler): store = self._determine_store(tiddler.bag) store.delete(tiddler) def tiddler_get(self, tiddler): store = self._determine_store(tiddler.bag) return store.get(tiddler) def tiddler_put(self, tiddler): store = self._determine_store(tiddler.bag) store.put(tiddler) def user_delete(self, user): self.main_store.delete(user) def user_get(self, user): return self.main_store.get(user) def user_put(self, user): return self.main_store.put(user) def list_recipes(self): return self.main_store.list_recipes() def list_bags(self): bags = [] for rule, store in self.stores: bags.extend(store.list_bags()) bags.extend(self.main_store.list_bags()) return bags def list_bag_tiddlers(self, bag): store = self._determine_store(bag.name) return store.list_bag_tiddlers(bag) def list_users(self): return self.main_store.list_users() def list_tiddler_revisions(self, tiddler): store = self._determine_store(tiddler.bag) return store.list_tiddler_revisions(tiddler) def search(self, search_query): tiddlers = [] searched = False for rule, store in self.stores: try: tiddlers.extend(store.search(search_query)) searched = True except StoreMethodNotImplemented: pass # just ride right over those stores that don't search try: tiddlers.extend(self.main_store.search(search_query)) searched = True except StoreMethodNotImplemented: pass if not searched: raise StoreMethodNotImplemented return tiddlers def _determine_store(self, name): for pattern, store in self.stores: # XXX should this be search or match? if pattern.match(name): return store return self.main_store
class Store(StorageInterface): def __init__(self, store_config=None, environ=None): super(Store, self).__init__(store_config, environ) self.main_store = None self.stores = [] self._init_store() def _init_store(self): server_store = self.environ['tiddlyweb.config']['server_store'] server_store_copy = copy.deepcopy(server_store) extra_store_config = server_store[1]['extras'] main_store_config = server_store[1]['main'] self.environ['tiddlyweb.config']['server_store'] = main_store_config self.main_store = Storer(main_store_config[0], main_store_config[1], self.environ) for rule, store in extra_store_config: pattern = re.compile(rule) self.environ['tiddlyweb.config']['server_store'] = store self.environ['tiddlyweb.config']['main_store'] = self.main_store self.stores.append( (pattern, Storer(store[0], store[1], self.environ))) self.environ['tiddlyweb.config']['server_store'] = server_store_copy def recipe_delete(self, recipe): self.main_store.delete(recipe) def recipe_get(self, recipe): return self.main_store.get(recipe) def recipe_put(self, recipe): self.main_store.put(recipe) def bag_delete(self, bag): store = self._determine_store(bag.name) store.delete(bag) def bag_get(self, bag): store = self._determine_store(bag.name) return store.get(bag) def bag_put(self, bag): store = self._determine_store(bag.name) store.put(bag) def tiddler_delete(self, tiddler): store = self._determine_store(tiddler.bag) store.delete(tiddler) def tiddler_get(self, tiddler): store = self._determine_store(tiddler.bag) return store.get(tiddler) def tiddler_put(self, tiddler): store = self._determine_store(tiddler.bag) store.put(tiddler) def user_delete(self, user): self.main_store.delete(user) def user_get(self, user): return self.main_store.get(user) def user_put(self, user): return self.main_store.put(user) def list_recipes(self): return self.main_store.list_recipes() def list_bags(self): bags = [] for rule, store in self.stores: bags.extend(store.list_bags()) bags.extend(self.main_store.list_bags()) return bags def list_users(self): return self.main_store.list_users() def list_tiddler_revisions(self, tiddler): store = self._determine_store(tiddler.bag) return store.list_tiddler_revisions(tiddler) def search(self, search_query): tiddlers = [] searched = False for rule, store in self.stores: try: tiddlers.extend(store.search(search_query)) searched = True except StoreMethodNotImplemented: pass # just ride right over those stores that don't search try: tiddlers.extend(self.main_store.search(search_query)) searched = True except StoreMethodNotImplemented: pass if not searched: raise StoreMethodNotImplemented return tiddlers def _determine_store(self, name): for pattern, store in self.stores: # XXX should this be search or match? if pattern.match(name): return store return self.main_store
class Store(StorageInterface): _MC = None def __init__(self, store_config=None, environ=None): if store_config is None: store_config = {} if environ is None: environ = {} self.environ = environ self.config = environ.get("tiddlyweb.config") self._mc = self._MC if self._mc == None: try: from google.appengine.api import memcache self._MC = memcache except ImportError: import memcache try: self._MC = memcache.Client(self.config["memcache_hosts"]) except KeyError: from tiddlyweb.config import config self.config = config self._MC = memcache.Client(self.config["memcache_hosts"]) self._mc = self._MC self.cached_store = StoreBoss( self.config["cached_store"][0], self.config["cached_store"][1], environ=environ ) self.prefix = self.config["server_prefix"] self.host = self.config["server_host"]["host"] def recipe_delete(self, recipe): key = self._recipe_key(recipe) self._mc.delete(key) self.cached_store.delete(recipe) def recipe_get(self, recipe): key = self._recipe_key(recipe) cached_recipe = self._get(key) if cached_recipe: recipe = cached_recipe else: recipe = self.cached_store.get(recipe) del recipe.store self._mc.set(key, recipe) return recipe def recipe_put(self, recipe): key = self._recipe_key(recipe) self.cached_store.put(recipe) self._mc.delete(key) def bag_delete(self, bag): key = self._bag_key(bag) if self._mc.delete(key): tiddlers_in_bag = bag.list_tiddlers() for tiddler in tiddlers_in_bag: self._mc.delete_multi( [ self._tiddler_revision_key(self._create_tiddler_revision(tiddler, revision_id)) for revision_id in self.list_tiddler_revisions(tiddler) ] ) self._mc.delete_multi([self._tiddler_key(tiddler) for tiddler in tiddlers_in_bag]) self.cached_store.delete(bag) def bag_get(self, bag): if hasattr(bag, "skinny") and bag.skinny: key = self._bag_key(bag) cached_bag = self._get(key) if cached_bag: bag = cached_bag else: bag = self.cached_store.get(bag) del bag.store self._mc.set(key, bag) else: bag = self.cached_store.get(bag) del bag.store return bag def bag_put(self, bag): key = self._bag_key(bag) self.cached_store.put(bag) self._mc.delete(key) def tiddler_delete(self, tiddler): key = self._tiddler_key(tiddler) if self._mc.delete(key): self._mc.delete(self._bag_key(Bag(tiddler.bag))) self._mc.delete_multi( [ self._tiddler_revision_key(self._create_tiddler_revision(tiddler, revision_id)) for revision_id in self.list_tiddler_revisions(tiddler) ] ) self.cached_store.delete(tiddler) def tiddler_get(self, tiddler): if not tiddler.revision or tiddler.revision == 0: key = self._tiddler_key(tiddler) else: key = self._tiddler_revision_key(tiddler) cached_tiddler = self._get(key) if cached_tiddler: cached_tiddler.recipe = tiddler.recipe tiddler = cached_tiddler else: tiddler = self.cached_store.get(tiddler) del tiddler.store self._mc.set(key, tiddler) return tiddler def tiddler_put(self, tiddler): key = self._tiddler_key(tiddler) self.cached_store.put(tiddler) self._mc.delete(self._bag_key(Bag(tiddler.bag))) self._mc.delete(key) def user_delete(self, user): key = self._user_key(user) self._mc.delete(key) self.cached_store.delete(user) def user_get(self, user): key = self._user_key(user) cached_user = self._get(key) if cached_user: user = cached_user else: user = self.cached_store.get(user) del user.store self._mc.set(key, user) return user def user_put(self, user): key = self._user_key(user) self.cached_store.put(user) self._mc.delete(key) def list_recipes(self): return self.cached_store.list_recipes() def list_bags(self): return self.cached_store.list_bags() def list_users(self): return self.cached_store.list_users() def list_tiddler_revisions(self, tiddler): return self.cached_store.list_tiddler_revisions(tiddler) def search(self, search_query): return self.cached_store.search(search_query) def _create_tiddler_revision(self, tiddler, revision_id): revision = Tiddler(tiddler.title, tiddler.bag) revision.revision = revision_id return revision def _tiddler_key(self, tiddler): key = "tiddler:%s/%s" % (tiddler.bag, tiddler.title) return self._mangle(key) def _tiddler_revision_key(self, tiddler): key = "tiddler:%s/%s/%s" % (tiddler.bag, tiddler.title, tiddler.revision) return self._mangle(key) def _user_key(self, user): key = "user:%s" % user.usersign return self._mangle(key) def _bag_key(self, bag): key = "bag:%s" % bag.name return self._mangle(key) def _recipe_key(self, recipe): key = "recipe:%s" % recipe.name return self._mangle(key) def _mangle(self, key): key = "%s:%s:%s" % (self.host, self.prefix, key) return quote(key.encode("UTF-8"), safe="") def _get(self, key): object = self._mc.get(key) if object: logging.debug("cache hit for %s" % key) else: logging.debug("cache miss for %s" % key) return object
class Store(StorageInterface): def __init__(self, environ=None): logging.debug("initializing SSL Store") super(Store, self).__init__(environ) config = self.environ["tiddlyweb.config"] self.ssl_bags = config["ssl_bags"] # intentionally not providing empty fallback -- XXX: rename? real_store = config["server_store"][1]["store_module"] # XXX: rename? -- TODO: use pop method to keep config clean? self.real_store = Storage(real_store, self.environ) def recipe_delete(self, recipe): logging.debug("delete recipe %s" % recipe) self.real_store.delete(recipe) def recipe_get(self, recipe): logging.debug("get recipe %s" % recipe) return self.real_store.get(recipe) def recipe_put(self, recipe): logging.debug("put recipe %s" % recipe) self.real_store.put(recipe) def bag_delete(self, bag): logging.debug("delete bag %s" % bag) self._check_security(bag.name) self.real_store.delete(bag) def bag_get(self, bag): logging.debug("get bag %s" % bag) self._check_security(bag.name) return self.real_store.get(bag) def bag_put(self, bag): logging.debug("put bag %s" % bag) self._check_security(bag.name) self.real_store.put(bag) def tiddler_delete(self, tiddler): logging.debug("delete tiddler %s" % tiddler) self.real_store.delete(tiddler) def tiddler_get(self, tiddler): logging.debug("get tiddler %s" % tiddler) return self.real_store.get(tiddler) def tiddler_put(self, tiddler): logging.debug("put tiddler %s" % tiddler) self.real_store.put(tiddler) def user_delete(self, user): logging.debug("delete user %s" % user) self.real_store.delete(user) def user_get(self, user): logging.debug("get user %s" % user) return self.real_store.get(user) def user_put(self, user): logging.debug("put user %s" % user) self.real_store.put(user) def list_recipes(self): logging.debug("list recipes") return self.real_store.list_recipes() def list_bags(self): logging.debug("list bags") return self.real_store.list_bags() def list_users(self): logging.debug("list users") return self.real_store.list_users() def list_tiddler_revisions(self, tiddler): logging.debug("list revisions %s" % tiddler) return self.real_store.list_tiddler_revisions(tiddler) def search(self, search_query): logging.debug("search %s" % search_query) return self.real_store.search(search_query) def _check_security(self, bag_name): # TODO: rename? -- TODO: should be decorator!? protocol = self.environ.get("wsgi.url_scheme") if protocol != "https" and bag_name in self.ssl_bags: raise SecureConnectionError("secure connection required")
class Store(StorageInterface): _MC = None def __init__(self, store_config=None, environ=None): if store_config is None: store_config = {} if environ is None: environ = {} self.environ = environ self.config = environ.get('tiddlyweb.config') self._mc = self._MC if self._mc == None: try: from google.appengine.api import memcache self._MC = memcache except ImportError: import memcache try: self._MC = memcache.Client(self.config['memcache_hosts']) except KeyError: from tiddlyweb.config import config self.config = config self._MC = memcache.Client(self.config['memcache_hosts']) self._mc = self._MC self.cached_store = StoreBoss(self.config['cached_store'][0], self.config['cached_store'][1], environ=environ) self.prefix = self.config['server_prefix'] self.host = self.config['server_host']['host'] def recipe_delete(self, recipe): key = self._recipe_key(recipe) self._mc.delete(key) self.cached_store.delete(recipe) def recipe_get(self, recipe): key = self._recipe_key(recipe) cached_recipe = self._get(key) if cached_recipe: recipe = cached_recipe else: recipe = self.cached_store.get(recipe) del recipe.store self._mc.set(key, recipe) return recipe def recipe_put(self, recipe): key = self._recipe_key(recipe) self.cached_store.put(recipe) self._mc.delete(key) def bag_delete(self, bag): key = self._bag_key(bag) if self._mc.delete(key): tiddlers_in_bag = bag.list_tiddlers() for tiddler in tiddlers_in_bag: self._mc.delete_multi([ self._tiddler_revision_key( self._create_tiddler_revision(tiddler, revision_id)) for revision_id in self.list_tiddler_revisions(tiddler) ]) self._mc.delete_multi( [self._tiddler_key(tiddler) for tiddler in tiddlers_in_bag]) self.cached_store.delete(bag) def bag_get(self, bag): if (hasattr(bag, 'skinny') and bag.skinny): key = self._bag_key(bag) cached_bag = self._get(key) if cached_bag: bag = cached_bag else: bag = self.cached_store.get(bag) del bag.store self._mc.set(key, bag) else: bag = self.cached_store.get(bag) del bag.store return bag def bag_put(self, bag): key = self._bag_key(bag) self.cached_store.put(bag) self._mc.delete(key) def tiddler_delete(self, tiddler): key = self._tiddler_key(tiddler) if self._mc.delete(key): self._mc.delete(self._bag_key(Bag(tiddler.bag))) self._mc.delete_multi([ self._tiddler_revision_key( self._create_tiddler_revision(tiddler, revision_id)) for revision_id in self.list_tiddler_revisions(tiddler) ]) self.cached_store.delete(tiddler) def tiddler_get(self, tiddler): if not tiddler.revision or tiddler.revision == 0: key = self._tiddler_key(tiddler) else: key = self._tiddler_revision_key(tiddler) cached_tiddler = self._get(key) if cached_tiddler: cached_tiddler.recipe = tiddler.recipe tiddler = cached_tiddler else: tiddler = self.cached_store.get(tiddler) del tiddler.store self._mc.set(key, tiddler) return tiddler def tiddler_put(self, tiddler): key = self._tiddler_key(tiddler) self.cached_store.put(tiddler) self._mc.delete(self._bag_key(Bag(tiddler.bag))) self._mc.delete(key) def user_delete(self, user): key = self._user_key(user) self._mc.delete(key) self.cached_store.delete(user) def user_get(self, user): key = self._user_key(user) cached_user = self._get(key) if cached_user: user = cached_user else: user = self.cached_store.get(user) del user.store self._mc.set(key, user) return user def user_put(self, user): key = self._user_key(user) self.cached_store.put(user) self._mc.delete(key) def list_recipes(self): return self.cached_store.list_recipes() def list_bags(self): return self.cached_store.list_bags() def list_users(self): return self.cached_store.list_users() def list_tiddler_revisions(self, tiddler): return self.cached_store.list_tiddler_revisions(tiddler) def search(self, search_query): return self.cached_store.search(search_query) def _create_tiddler_revision(self, tiddler, revision_id): revision = Tiddler(tiddler.title, tiddler.bag) revision.revision = revision_id return revision def _tiddler_key(self, tiddler): key = 'tiddler:%s/%s' % (tiddler.bag, tiddler.title) return self._mangle(key) def _tiddler_revision_key(self, tiddler): key = 'tiddler:%s/%s/%s' % (tiddler.bag, tiddler.title, tiddler.revision) return self._mangle(key) def _user_key(self, user): key = 'user:%s' % user.usersign return self._mangle(key) def _bag_key(self, bag): key = 'bag:%s' % bag.name return self._mangle(key) def _recipe_key(self, recipe): key = 'recipe:%s' % recipe.name return self._mangle(key) def _mangle(self, key): key = '%s:%s:%s' % (self.host, self.prefix, key) return quote(key.encode('UTF-8'), safe='') def _get(self, key): object = self._mc.get(key) if object: logging.debug('cache hit for %s' % key) else: logging.debug('cache miss for %s' % key) return object
class Store(StorageInterface): def __init__(self, store_config=None, environ=None): super(Store, self).__init__(store_config, environ) self.config = environ.get('tiddlyweb.config') self.binary_store = StoreBoss('text', { 'store_root': 'binarystore' }, environ=environ).storage self.core_store = StoreBoss(self.config['binarystore.child'][0], self.config['binarystore.child'][1], environ=environ).storage def bag_put(self, bag): self.core_store.bag_put(bag) def bag_get(self, bag): return self.core_store.bag_get(bag) def bag_delete(self, bag): try: self.binary_store.bag_delete(bag) except NoBagError: pass return self.core_store.bag_delete(bag) def recipe_put(self, recipe): self.core_store.recipe_put(recipe) def recipe_get(self, recipe): return self.core_store.recipe_get(recipe) def recipe_delete(self, recipe): return self.core_store.recipe_delete(recipe) def user_put(self, user): self.core_store.user_put(user) def user_get(self, user): return self.core_store.user_get(user) def user_delete(self, user): return self.core_store.user_delete(user) def tiddler_delete(self, tiddler): self.core_store.tiddler_delete(tiddler) if binary_tiddler(tiddler): self.binary_store.tiddler_delete(tiddler) def tiddler_put(self, tiddler): if binary_tiddler(tiddler): try: self.binary_store.tiddler_put(tiddler) except NoBagError: self.binary_store.bag_put(Bag(tiddler.bag)) self.binary_store.tiddler_put(tiddler) tiddler.text = '' self.core_store.tiddler_put(tiddler) def tiddler_get(self, tiddler): found_tiddler = self.core_store.tiddler_get(tiddler) if binary_tiddler(found_tiddler): found_tiddler.__class__ = BinaryTiddler found_tiddler._text = None return found_tiddler def list_recipes(self): return self.core_store.list_recipes() def list_bags(self): return self.core_store.list_bags() def list_users(self): return self.core_store.list_users() def list_bag_tiddlers(self, bag): return self.core_store.list_bag_tiddlers(bag) def list_tiddler_revisions(self, tiddler): return self.core_store.list_tiddler_revisions(tiddler) def search(self, search_query): return self.core_store.search(search_query)
class Store(StorageInterface): def __init__(self, store_config=None, environ=None): super(Store, self).__init__(store_config, environ) self.config = environ.get('tiddlyweb.config') self.binary_store = StoreBoss('text', {'store_root': 'binarystore'}, environ=environ).storage self.core_store = StoreBoss(self.config['binarystore.child'][0], self.config['binarystore.child'][1], environ=environ).storage def bag_put(self, bag): self.core_store.bag_put(bag) def bag_get(self, bag): return self.core_store.bag_get(bag) def bag_delete(self, bag): try: self.binary_store.bag_delete(bag) except NoBagError: pass return self.core_store.bag_delete(bag) def recipe_put(self, recipe): self.core_store.recipe_put(recipe) def recipe_get(self, recipe): return self.core_store.recipe_get(recipe) def recipe_delete(self, recipe): return self.core_store.recipe_delete(recipe) def user_put(self, user): self.core_store.user_put(user) def user_get(self, user): return self.core_store.user_get(user) def user_delete(self, user): return self.core_store.user_delete(user) def tiddler_delete(self, tiddler): self.core_store.tiddler_delete(tiddler) if binary_tiddler(tiddler): self.binary_store.tiddler_delete(tiddler) def tiddler_put(self, tiddler): if binary_tiddler(tiddler): try: self.binary_store.tiddler_put(tiddler) except NoBagError: self.binary_store.bag_put(Bag(tiddler.bag)) self.binary_store.tiddler_put(tiddler) tiddler.text = '' self.core_store.tiddler_put(tiddler) def tiddler_get(self, tiddler): found_tiddler = self.core_store.tiddler_get(tiddler) if binary_tiddler(found_tiddler): found_tiddler.__class__ = BinaryTiddler found_tiddler._text = None return found_tiddler def list_recipes(self): return self.core_store.list_recipes() def list_bags(self): return self.core_store.list_bags() def list_users(self): return self.core_store.list_users() def list_bag_tiddlers(self, bag): return self.core_store.list_bag_tiddlers(bag) def list_tiddler_revisions(self, tiddler): return self.core_store.list_tiddler_revisions(tiddler) def search(self, search_query): return self.core_store.search(search_query)
class Store(StorageInterface): def __init__(self, environ=None): if environ is None: environ = {} self.environ = environ internal_store_environ = { 'tiddlyweb.config': { 'server_store': config['cached_store'], } } self.cached_store = StoreBoss('text', environ=internal_store_environ) def recipe_delete(self, recipe): key = _recipe_key(recipe) MC.delete(key) self.cached_store.delete(recipe) def recipe_get(self, recipe): key = _recipe_key(recipe) cached_recipe = _get(key) if cached_recipe: recipe = cached_recipe else: recipe = self.cached_store.get(recipe) MC.set(key, recipe) return recipe def recipe_put(self, recipe): key = _recipe_key(recipe) self.cached_store.put(recipe) MC.delete(key) def bag_delete(self, bag): key = _bag_key(bag) if MC.delete(key): MC.delete_multi([_tiddler_key(tiddler) for tiddler in bag.list_tiddlers()]) self.cached_store.delete(bag) def bag_get(self, bag): key = _bag_key(bag) cached_bag = _get(key) if cached_bag: bag = cached_bag else: bag = self.cached_store.get(bag) MC.set(key, bag) return bag def bag_put(self, bag): key = _bag_key(bag) self.cached_store.put(bag) MC.delete(key) def tiddler_delete(self, tiddler): key = _tiddler_key(tiddler) if MC.delete(key): MC.delete(_bag_key(Bag(tiddler.bag))) self.cached_store.delete(tiddler) def tiddler_get(self, tiddler): key = _tiddler_key(tiddler) if not tiddler.revision or tiddler.revision == 0: cached_tiddler = _get(key) if cached_tiddler: tiddler = cached_tiddler else: tiddler = self.cached_store.get(tiddler) MC.set(key, tiddler) else: tiddler = self.cached_store.get(tiddler) return tiddler def tiddler_put(self, tiddler): key = _tiddler_key(tiddler) self.cached_store.put(tiddler) MC.delete(_bag_key(Bag(tiddler.bag))) MC.delete(key) def user_delete(self, user): key = _user_key(user) MC.delete(key) self.cached_store.delete(user) def user_get(self, user): key = _user_key(user) cached_user = _get(key) if cached_user: user = cached_user else: user = self.cached_store.get(user) MC.set(key, user) return user def user_put(self, user): key = _user_key(user) self.cached_store.put(user) MC.delete(key) def list_recipes(self): return self.cached_store.list_recipes() def list_bags(self): return self.cached_store.list_bags() def list_users(self): return self.cached_store.list_users() def list_tiddler_revisions(self, tiddler): return self.cached_store.list_tiddler_revisions(tiddler) def search(self, search_query): return self.cached_store.search(search_query)