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
def add_meal(self, id): """Add a meal to user by recipe id. Commit changes to DB""" present_ids = {m.id for m in self.meals} if not (id in present_ids): meal = Recipe.from_db(db=self.db, id=id) self.meals.add(meal) t = (self.id, id) self.db.c.execute( 'INSERT INTO user_meals (user_id, recipe_id) VALUES (?, ?)', t) self.db.conn.commit()
def index(): """Show user's home page""" user = User.from_db(db=db, id=session.get("user_id")) try: recipe_ids = {m.id for m in user.meals} recipes = [Recipe.from_db(db=db, id=id) for id in recipe_ids] except AttributeError: recipes=[] return render_template("index.html", meals=recipes)
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
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)
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)
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)