Esempio n. 1
0
    def from_db(cls, db, id=None, name=None):
        """Search db for user entry by id or name (in that priorty) and return constructed object.
        Returns None if id is not found.
        """
        user = super().from_db(db=db, id=id, name=name)

        if not user:
            return None
        id = user.id

        # Constructing allergies set
        needle = (id, )
        db.c.execute(
            'SELECT allergy_id as id FROM user_allergies WHERE user_id = ?',
            needle)
        rows = db.c.fetchall()
        allergies = {Allergy.from_db(db, row["id"]) for row in rows}

        # Constructing meals set
        needle = (id, )
        db.c.execute(
            'SELECT recipe_id as id FROM user_meals WHERE user_id = ?', needle)
        rows = db.c.fetchall()
        meals = {Recipe.from_db(db, row["id"]) for row in rows}

        user.allergies = allergies
        user.meals = meals

        return user
Esempio n. 2
0
def account(form):
    """Show account settings for GET.
    Write new user settings to  DB for POST.
    """
    user = User.from_db(db=db, id=session.get("user_id"))

    # User reached "/account" route via GET (as by clicking a link or via redirect)
    if request.method == "GET" and not form:
        allergies = db.get_rows("allergies", order_by="name ASC")
        user_allergies = {x.id for x in user.allergies}

        return render_template("account.html", allergies=allergies, user_allergies=user_allergies)

    # User reached "/account/<form>" route via POST (as by submitting a form via POST)
    if form == "allergies":
        allergy_ids = request.form.getlist("allergies")
        allergies = {Allergy.from_db(db, id) for id in allergy_ids}
        user.allergies = allergies
    elif form == "password":
        current_password = request.form.get("current_password")
        new_password = request.form.get("new_password")
        confirmation = request.form.get("confirmation")

        if not current_password:
            flash("Must provide valid current password", category="danger")
            return redirect("account")
        if not all([new_password, confirmation]):
            flash("Must provide new password and repeat it", category="danger")
            return redirect("account")
        if not new_password == confirmation:
            flash("New passwords don't match", category="danger")
            return redirect("account")
        if not check_password_hash(user.password_hash, current_password):
            flash("Incorrect current password", category="danger")
            return redirect("account")

        user.password_hash = generate_password_hash(new_password)

    # Commit the user changes to DB
    try:
        result = user.write_to_db()
    except:
        result = False

    if result:
        flash("Changes saved successfully!")
    else:
        flash("Something went wrong :(", category="danger")

    return redirect("/account")
Esempio n. 3
0
def get_JSON():
    """Get JSON repr of an object"""
    if request.method == "POST" and request.form:
        obj_type = request.form.get("obj_type")
        id = request.form.get("id")
    if request.method  == "GET" and request.args:
        obj_type = request.args.get("obj_type").lower()
        id = request.args.get("id")
    try:
        id = int(id)
    except:
        id = None

    if obj_type in ["user", "valid_meals"]:
        if not session.get("is_admin") or not id:
            id = session.get("user_id")
    elif not id:
        return("Missing or invalid params")


    # Users can access only their own user obj and valid_meals
    user_id = session.get("user_id")
    d = {
        "allergy"            : lambda db, id: Allergy.from_db(db, id),
        "ingredient_category": lambda db, id: IngredientCategory.from_db(db, id),
        "ingredient"         : lambda db, id: Ingredient.from_db(db, id),
        "recipe"             : lambda db, id: Recipe.from_db(db, id),
        "user"               : lambda db, id: User.from_db(db, id),
        "valid_meals"        : lambda db, id: User.from_db(db, id).get_valid_recipes_id(),
    }
    try:
        obj = d[obj_type](db, id)
    except KeyError:
        return("Missing or invalid params")

    response = app.response_class(
        response=enc.encode(obj),
        mimetype='application/json'
    )

    return response
Esempio n. 4
0
def admin_display(obj_type):
    """Show admin page for selected object type"""
    template = obj_type + ".html" if obj_type else "admin.html"
    if obj_type == "allergies":
        kwargs = {"rows":Allergy.get_summary(db)}
    elif obj_type == "ingredient_categories":
        kwargs = {"rows":IngredientCategory.get_summary(db)}
    elif obj_type == "ingredients":
        kwargs = {"rows"      : Ingredient.get_summary(db),
                  "categories": db.get_rows("ingredient_categories"),
                  "allergies" : db.get_rows("allergies")}
    elif obj_type == "recipes":
        kwargs = {"rows"       : Recipe.get_summary(db),
                  "ingredients": db.get_rows("ingredients")}
    elif obj_type == "users":
        kwargs = {"rows"      : User.get_summary(db),
                  "allergies" : db.get_rows("allergies")}
    else:
        kwargs = {}

    return render_template(template, **kwargs)
Esempio n. 5
0
    def from_db(cls, db, id=None, name=None):
        """Search db for ingredient entry by id or name (in that priorty) and return constructed object.
        Returns None if id is not found.
        """
        db_attrs = cls.get_db_attrs(db, id, name)

        if not db_attrs:
            return None
        id = db_attrs["id"]

        # Constructing category
        category_id = db_attrs["category_id"]
        del db_attrs["category_id"]
        category = IngredientCategory.from_db(db, category_id)

        # Constructing allergies set
        needle = (id,)
        db.c.execute('SELECT allergy_id as id FROM ingredient_allergies WHERE ingredient_id = ?', needle)
        rows = db.c.fetchall()
        allergies = {Allergy.from_db(db, row["id"]) for row in rows}

        return cls(db=db, category=category, allergies=allergies, **db_attrs)
Esempio n. 6
0
def admin_remove(obj_type):
    """Remove an object from DB"""
    if request.method == "POST" and request.form:
        id = request.form.get("id")
    if request.method  == "GET" and request.args:
        id = request.args.get("id")
    try:
        id = int(id)
    except:
        id = None

    if not id:
        return("Missing or invalid params")

    d = {
        "allergies"            : lambda db, id: Allergy.from_db(db, id).remove_from_db(),
        "ingredient_categories": lambda db, id: IngredientCategory.from_db(db, id).remove_from_db(),
        "ingredients"          : lambda db, id: Ingredient.from_db(db, id).remove_from_db(),
        "recipes"              : lambda db, id: Recipe.from_db(db, id).remove_from_db(),
        "users"                : lambda db, id: User.from_db(db, id).remove_from_db(),
    }
    try:
        d[obj_type](db, id)
        # If a recipe was removed remove its image
        if obj_type == "recipes":
            filename = str(id) + ".jpg"
            try:
                os.remove(os.path.join(app.config["RECIPE_IMG_PATH"], filename))
            except FileNotFoundError:
                pass
        flash("Entry deleted successfully!")
    except KeyError:
        return ("Object type not found")
    except DBError:
        flash("Cannot delete entry with dependents (referenced by other entries)!", category="danger")
    except:
        flash("Something went wrong :(", category="danger")

    return redirect("admin/" + obj_type)
Esempio n. 7
0
def admin_write(obj_type):
    """Write new object to DB or edit an existing one based on submitted form"""
    # Set basic values present for all object types
    name = request.form.get("name")
    try:
        id = int(request.form.get("id"))
        if not id:
            id = None
    except ValueError:
        id = None

    # Construct object to be written
    if obj_type == "allergies":
        obj = Allergy(name, db, id)
    elif obj_type == "ingredient_categories":
        obj = IngredientCategory(name, db, id)
    elif obj_type == "ingredients":
        category_id = request.form.get("category_id")
        category = IngredientCategory.from_db(db=db, id=category_id)
        allergy_ids = request.form.getlist("allergies")
        allergies = {Allergy.from_db(db=db, id=id) for id in allergy_ids}

        obj = Ingredient(name, category, allergies, db, id)
    elif obj_type == "recipes":
        instructions = request.form.get("instructions")

        contents = set()
        try:
            form_contents = json.loads(request.form.get("contents"))
        except:
            form_contents = None
        for fc in form_contents:
            ingredient = Ingredient.from_db(db=db, id=fc["ingredient_id"])
            try:
                amount = float(fc["amount"])
            except KeyError:
                amount = 0
            units = fc["units"] if fc["units"] != "" else None

            contents.add(Content(ingredient, amount, units))

        obj = Recipe(name, instructions, contents, db, id)

        # Define function to be called only if object is written to DB successfully
        def if_written():
            # Apply image changes to the filesystem
            filename = str(obj.id) + ".jpg"
            if request.form.get("image-delete"):
                # Current image is to be deleted if exists
                try:
                    os.remove(os.path.join(app.config["RECIPE_IMG_PATH"], filename))
                except FileNotFoundError:
                    pass
            else:
                # New image is to be saved
                image = request.files.get("image")
                if image:
                    extension = image.filename.split(".").pop()
                    if extension in ALLOWED_IMG_EXTENSIONS:
                        image.save(os.path.join(app.config["RECIPE_IMG_PATH"], filename))
                    else:
                        flash("Only .jpg, .jpeg images allowed", category=danger)
    elif obj_type == "users":
        obj = User.from_db(db, id)
        obj.is_admin = request.form.get("is_admin")
        obj.name = request.form.get("name")
    else:
        return ("Object type not found")


    try:
        result = obj.write_to_db()
    except:
        result = False

    if result:
        flash("Changes saved successfully!")
        try:
            if_written()
        except UnboundLocalError:
            pass
    else:
        flash("Something went wrong :(", category="danger")

    return redirect("admin/" + obj_type)