Ejemplo n.º 1
0
    def _build_session(self):
        """
        Construct a SQLAlchemy Session() context object. To avoid having to pass session
        objects around between Barbados (backend) and Jamaica (frontend) this function
        will attempt to determine if we're running inside of a Flask context at the time of
        call (scoped session per-request) and use that session. If we're not then generate
        one 'cause we're probably running in a script or something weird like that.
        Flask sessions will close at the end of the request or when explicitly told to
        so to prevent double-committing (which isn't a problem, it just resets the session
        an extra time) this will feed back into the caller.
        https://docs.sqlalchemy.org/en/13/orm/session_basics.html#closing
        :return: Session context object, Boolean of whether to trigger a commit or not.
        """
        commit = False
        try:
            from flask_sqlalchemy_session import current_session as session
            if not session:
                raise RuntimeError
            LogService.debug("Using Flask session")
        except RuntimeError as e:
            session = self.ScopedSession()
            commit = True
            LogService.debug("Using thread scoped session")

        return session, commit
Ejemplo n.º 2
0
    def delete(self):
        LogService.debug("Deleting old data from database")
        with self.pgconn.get_session() as session:
            deleted = session.query(self.model).delete()

        LogService.info("Deleted %s" % deleted)
        Indexes.rebuild(ListIndex)
Ejemplo n.º 3
0
 def get(endpoint, args):
     LogService.debug("Getting %s" % args.slug)
     if args.slug == 'all':
         result = requests.get(endpoint)
     else:
         result = requests.get("%s/%s" % (endpoint, args.slug))
     print(json.dumps(result.json()))
     Resource._handle_error(result)
Ejemplo n.º 4
0
 def init(self):
     """
     Re-initialize all indexes. This calls rebuild on every registered
     index class. There be dragons here.
     :return: None
     """
     for name in self._indexes.keys():
         LogService.debug("Init on %s" % name)
         try:
             self.rebuild(self._indexes.get(name))
         except NotFoundError or KeyError or AttributeError as e:
             LogService.warning("Error re-initing index %s: %s" % (name, e))
Ejemplo n.º 5
0
    def _build_tree(self, passes, root=root_node):
        """
        Construct the treelib.Tree object.
        :param passes: Number of iterations to construct to tree in.
        :param root: String ID of the root node of the tree.
        :return: Completed treelib.Tree object
        """
        tree = Tree()

        with DatabaseService.get_session() as session:

            tree.create_node(root, root)
            for i in IngredientModel.get_by_kind(session, CategoryKind):
                i = IngredientFactory.model_to_obj(i)
                tree.create_node(i.slug, i.slug, parent=root, data=i)

            ingredients_to_place = [
                IngredientFactory.model_to_obj(item)
                for item in IngredientModel.get_usable_ingredients(session)
            ]
            for idx in range(1, passes + 1):
                LogService.debug("Pass %i/%i" % (idx, passes))

                # If you remove items from a list you're iterating over you
                # dynamically change the indexing, making things get out of whack.
                # You can get around this by making a copy of the list and iterating
                # over that while you remove items from the original list.
                # https://thispointer.com/python-remove-elements-from-a-list-while-iterating/
                for i in ingredients_to_place.copy():
                    try:
                        tree.create_node(i.slug,
                                         i.slug,
                                         parent=i.parent,
                                         data=i)
                        # This is to maintain a list of all index elements since finding those
                        # is somewhat hard after the fact.
                        if i.kind == IndexKind:
                            self._index_node_ids.append(i.slug)
                        ingredients_to_place.remove(i)
                    except NodeIDAbsentError:
                        LogService.debug("skipping %s (Attempt %i/%s)" %
                                         (i.slug, idx, passes))

                if len(ingredients_to_place) == 0:
                    LogService.info("All done after pass %i" % idx)
                    break

        LogService.info("Tree has len %i" % len(tree))
        return tree
Ejemplo n.º 6
0
 def _handle_error(result):
     """
     Parse an HTTP request for success/failure. Return a count of the success.
     :param result:
     :return: Integer count of success (THIS IS NOT A RETURN CODE!)
     """
     try:
         result.raise_for_status()
         LogService.debug('Success!')
         return 1
     except requests.exceptions.RequestException as e:
         LogService.error("Error handling URL: %i" % result.status_code)
         LogService.error(result.request.body)
         LogService.error(result.json().get('message'))
         LogService.error(result.json().get('details'))
         return 0
Ejemplo n.º 7
0
    def delete(self, cocktail=None, delete_all=False):

        if cocktail:
            with self.pgconn.get_session() as session:
                existing = session.query(CocktailModel).get(cocktail.slug)

                if existing:
                    LogService.debug("Deleting %s" % existing.slug)
                    deleted = session.delete(existing)
            return

        if delete_all is True:
            with self.pgconn.get_session() as session:
                LogService.debug("Deleting all CocktailModel")
                deleted = session.query(CocktailModel).delete()
                LogService.info("Deleted %s from %s" %
                                (deleted, CocktailModel.__tablename__))
                Indexes.rebuild(RecipeIndex)
Ejemplo n.º 8
0
    def get_session(self):
        """
        Provide a valid SQLAlchemy Session for use in a context.
        Example:
          with get_session() as session:
            result = session.query(CocktailModel).get('mai-tai')
        :return: None
        """
        session, commit = self._build_session()

        try:
            yield session
            if commit:
                session.commit()
        except Exception:
            session.rollback()
            raise

        finally:
            LogService.debug("Database with() context complete.")
Ejemplo n.º 9
0
 def event_end_session(session, transaction):
     LogService.debug("Closing database session: %s" % session)
Ejemplo n.º 10
0
 def event_new_session(session, transaction, connection):
     LogService.debug("Opening new database session: %s" % session)