def get_tiddlers_from_recipe(recipe, environ=None): """ Return the list of tiddlers that result from processing the ``recipe``. This list of tiddlers is unique by title with tiddlers later in the recipe taking precedence over those earlier in the recipe. The tiddlers returned are empty objects (i.e. not loaded from the :py:mod:`store <tiddlyweb.store>`). """ template = recipe_template(environ) store = recipe.store uniquifier = {} for bag, filter_string in recipe.get_recipe(template): if isinstance(bag, basestring): retriever = get_bag_retriever(environ, bag) if not retriever: bag = Bag(name=bag) retriever = store.list_bag_tiddlers else: retriever = retriever[0] else: retriever = store.list_bag_tiddlers try: for tiddler in filter_tiddlers(retriever(bag), filter_string, environ=environ): uniquifier[tiddler.title] = tiddler except SpecialBagError as exc: raise NoBagError('unable to retrieve from special bag: %s, %s' % (bag, exc)) return uniquifier.values()
def determine_bag_from_recipe(recipe, tiddler, environ=None): """ Given a ``recipe`` and a ``tiddler`` determine the :py:class:`bag <tiddlyweb.model.bag.Bag>` in which this :py:class:`tiddler <tiddlyweb.model.tiddler.Tiddler>` can be found. This is different from :py:func:`determine_bag_for_tiddler`. That one finds the bag the tiddler *could* be in. This is the bag the tiddler *is* in. This is done by reversing the recipe's list, and filtering each bag according to any :py:mod:`filters <tiddlyweb.filters>` present. The resulting tiddlers are checked. If an ``indexer`` is configured use the index to determine if a tiddler exists in a bag. """ store = recipe.store template = recipe_template(environ) try: indexer = environ.get('tiddlyweb.config', {}).get('indexer', None) if indexer: index_module = __import__(indexer, {}, {}, ['index_query']) else: index_module = None except (AttributeError, KeyError): index_module = None for bag, filter_string in reversed(recipe.get_recipe(template)): bag = _look_for_tiddler_in_bag(tiddler, bag, filter_string, environ, store, index_module) if bag: return bag raise NoBagError('no suitable bag for %s' % tiddler.title)
def determine_bag_from_recipe(recipe, tiddler, environ=None): """ We have a recipe and a tiddler. We need to know the bag in which this tiddler can be found. This is different from determine_bag_for_tiddler(). That one finds the bag the tiddler _could_ be in. This is the bag the tiddler _is_ in. We reverse the recipe_list, and filter each bag according to the rule. Then we look in the list of tiddlers and see if ours is in there. If an indexer is configured use the index to determine if a bag exists in a bag. """ store = recipe.store template = recipe_template(environ) try: indexer = environ.get('tiddlyweb.config', {}).get('indexer', None) if indexer: index_module = __import__(indexer, {}, {}, ['index_query']) else: index_module = None except (AttributeError, KeyError): index_module = None for bag, filter_string in reversed(recipe.get_recipe(template)): bag = _look_for_tiddler_in_bag(tiddler, bag, filter_string, environ, store, index_module) if bag: return bag raise NoBagError('no suitable bag for %s' % tiddler.title)
def bag_delete(self, bag): try: sbag = self.session.query(sBag).filter(sBag.name == bag.name).one() self.session.delete(sbag) self.session.commit() except NoResultFound, exc: raise NoBagError('Bag %s not found: %s' % (bag.name, exc))
def tiddler_put(self, tiddler): if not tiddler.bag: raise NoBagError('bag required to save') stiddler = self._store_tiddler(tiddler) self.session.merge(stiddler) self.session.commit() self.tiddler_written(tiddler)
def _bag_path(self, bag_name): """ Return a string that is the path to a bag. """ try: return os.path.join(self._store_root(), 'bags', _encode_filename(bag_name)) except (AttributeError, StoreEncodingError) as exc: raise NoBagError('No bag name: %s' % exc)
def list_bag_tiddlers(self, bag): """ List all the tiddlers in the provided bag. """ tiddlers_dir = self._tiddlers_dir(bag.name) try: tiddlers = (filename for filename in self._files_in_dir(tiddlers_dir) if os.path.isdir(os.path.join(tiddlers_dir, filename))) except (IOError, OSError), exc: raise NoBagError('unable to list tiddlers in bag: %s' % exc)
def bag_get(self, bag): try: sbag = self.session.query(sBag).filter(sBag.name == bag.name).one() bag = self._map_bag(bag, sbag) if not (hasattr(bag, 'skinny') and bag.skinny): tiddlers = sbag.tiddlers bag.add_tiddlers( Tiddler(tiddler.title) for tiddler in tiddlers) return bag except NoResultFound, exc: raise NoBagError('Bag %s not found: %s' % (bag.name, exc))
def bag_get(self, bag): """ Read a bag from the store and get a list of its tiddlers. """ bag_path = self._bag_path(bag.name) try: bag.desc = self._read_bag_description(bag_path) bag.policy = self._read_policy(bag_path) except IOError, exc: raise NoBagError('unable to read policy or description at %s: %s' % (bag_path, exc))
def bag_delete(self, bag): """ Delete a bag AND THE TIDDLERS WITHIN from the system. """ bag_path = self._bag_path(bag.name) try: if not os.path.exists(bag_path): raise NoBagError('%s not present' % bag_path) shutil.rmtree(bag_path) except NoBagError: raise except Exception, exc: raise IOError('unable to delete bag %s: %s' % (bag.name, exc))
def bag_delete(self, bag): """ Delete :py:class:`bag <tiddlyweb.model.bag.Bag>` **and** the :py:class:`tiddlers <tiddlyweb.model.tiddler.Tiddler>` within from the system. """ bag_path = self._bag_path(bag.name) try: if not os.path.exists(bag_path): raise NoBagError('%s not present' % bag_path) shutil.rmtree(bag_path) except NoBagError: raise except Exception as exc: raise IOError('unable to delete bag %s: %s' % (bag.name, exc))
def bag_get(self, bag): """ Fill :py:class:`bag <tiddlyweb.model.bag.Bag>` with data from the store. """ bag_path = self._bag_path(bag.name) try: bag.desc = self._read_bag_description(bag_path) bag.policy = self._read_policy(bag_path) except IOError as exc: raise NoBagError( 'unable to read policy or description at %s: %s' % (bag_path, exc)) return bag
def list_bag_tiddlers(self, bag): """ List all the :py:class:`tiddlers <tiddlyweb.model.tiddler.Tiddler>` in the provided :py:class:`bag <tiddlyweb.model.bag.Bag>`. """ tiddlers_dir = self._tiddlers_dir(bag.name) try: tiddlers = (filename for filename in self._files_in_dir(tiddlers_dir) if os.path.isdir(os.path.join(tiddlers_dir, filename))) except (IOError, OSError) as exc: raise NoBagError('unable to list tiddlers in bag: %s' % exc) for title in tiddlers: title = unquote(title) tiddler = Tiddler(title, bag.name) yield tiddler
def _tiddler_base_filename(self, tiddler): """ Return the string that is the pathname to a tiddler's directory. """ # should we get a Bag or a name here? bag_name = tiddler.bag store_dir = self._tiddlers_dir(bag_name) if not os.path.exists(store_dir): raise NoBagError('%s does not exist' % store_dir) try: return os.path.join(store_dir, _encode_filename(tiddler.title)) except StoreEncodingError as exc: raise NoTiddlerError(exc)
def determine_bag_for_tiddler(recipe, tiddler, environ=None): """ Return the bag which this tiddler would be in if we were to save it to the recipe rather than to a default bag. This is a matter of reversing the recipe list and seeing if the tiddler is a part of the bag + filter. If bag+filter is true, return that bag. """ template = recipe_template(environ) for bag, filter_string in reversed(recipe.get_recipe(template)): for candidate_tiddler in filter_tiddlers([tiddler], filter_string, environ=environ): if tiddler.title == candidate_tiddler.title: if isinstance(bag, basestring): bag = Bag(name=bag) return bag raise NoBagError('no suitable bag for %s' % tiddler.title)
def determine_bag_for_tiddler(recipe, tiddler, environ=None): """ Return the :py:class:`bag <tiddlyweb.model.bag.Bag>` which this :py:class:`tiddler <tiddlyweb.model.tiddler.Tiddler>` would be in if we were to save it to the named :py:class:`recipe <tiddlyweb.model.recipe.Recipe>` rather than to a bag. This is done reversing the recipe list and seeing if the tiddler passes the constraint of the bag and its associated :py:mod:`filter <tiddlyweb.filters>`. If bag+filter is true, return that bag. """ template = recipe_template(environ) for bag, filter_string in reversed(recipe.get_recipe(template)): for candidate_tiddler in filter_tiddlers([tiddler], filter_string, environ=environ): if tiddler.title == candidate_tiddler.title: if isinstance(bag, basestring): bag = Bag(name=bag) return bag raise NoBagError('no suitable bag for %s' % tiddler.title)
def bag_get(self, bag): try: sbag = self.session.query(sBag).filter(sBag.name == bag.name).one() bag = self._load_bag(bag, sbag) try: store = self.environ['tiddlyweb.store'] except KeyError: store = False if not (hasattr(bag, 'skinny') and bag.skinny): def _bags_tiddler(stiddler): tiddler = Tiddler(stiddler.title) tiddler = self._load_tiddler(tiddler, stiddler) tiddler.store = store return tiddler stiddlers = sbag.tiddlers bag.add_tiddlers( _bags_tiddler(stiddler) for stiddler in stiddlers) return bag except NoResultFound, exc: raise NoBagError('Bag %s not found: %s' % (bag.name, exc))
def _validate_bag_name(self, name): bag_name = self.environ['tiddlyweb.config']['mappingsql.bag'] if name != bag_name: raise NoBagError('Bag %s does not exist' % name)