from flask import Flask, Response, render_template, request, session, redirect, url_for import functools import re from scripts.database.mongo import mongo_database from scripts.scraping.scraper import scrape from scripts.recipes.handle_recipes import recipe_exists, add_single_recipe, get_all_recipes, get_single_recipe, get_facets, delete_single_recipe, search_recipes from scripts.users.handle_users import user_exists, authenticate_user, add_user from flask_bcrypt import Bcrypt # Bcrypt.check_password_hash(hashed_password, "eligible password") app = Flask(__name__) bcrypt = Bcrypt(app) app.config["TEMPLATES_AUTO_RELOAD"] = True app.secret_key = 'wdkbahjfbqb' # Decorator function to check for username in session to protect routes def login_required(func): @functools.wraps(func) def secure_function(*args, **kwargs): if "username" not in session: return redirect(url_for("login")) return func(*args, **kwargs) return secure_function # Pages @app.route("/home") @login_required def home_page(): tags = get_facets(session["username"]) all_recipes = get_all_recipes(session["username"]) return render_template("/pages/home.html",recipes=all_recipes, facets=tags) @app.route("/") def landing_page(): return render_template("/pages/landing.html") @app.route("/recipe/") @login_required def single_recipe_page(recipe_id): recipe_details = get_single_recipe(recipe_id) return render_template("/pages/single-recipe.html", single_recipe=recipe_details) @app.route("/login") def login(): return render_template("/pages/login.html") @app.route("/signup") def signup(): return render_template("/pages/signup.html") @app.route("/account") def account(): if "username" not in session: return redirect(url_for("login")) else: return render_template("/pages/account.html") @app.route("/about") def about(): return render_template("/pages/about.html") # API routes @app.post("/recipes/add") def add_recipe(): req_data = request.form.to_dict() submitted_url = req_data["url"] if submitted_url == '': return "No recipe supplied!" does_recipe_exist = recipe_exists(session["username"], submitted_url) if does_recipe_exist: return "

Recipe already exists

" else: recipe_json = scrape(submitted_url, session["username"]) add_single_recipe(recipe_json) all_recipes = get_all_recipes(session["username"]) all_facets = get_facets(session["username"]) return render_template("/components/app.html", recipes=all_recipes, facets=all_facets) @app.post("/recipes/search") def search(): req_data = request.form.to_dict() all_recipes = search_recipes(req_data, session["username"]) all_facets = get_facets(session["username"], req_data) return render_template("/components/app.html", recipes=all_recipes, facets=all_facets) @app.delete("/recipes/delete/") def delete_recipe(recipe_id): res = delete_single_recipe(recipe_id) if res["success"]: return f'

Recipe {recipe_id} successfully deleted, Go home' else: error_html = f'

Error deleting {recipe_id}

' return error_html @app.post("/login") def login_user(): req_data = request.form.to_dict() user = req_data["username"] pw = req_data["password"] res = user_exists(user) if res["success"] and res["user"] is None: return "

User doesn't exist, signup instead

" elif res["success"] and res["user"] is not None: pw_matches = bcrypt.check_password_hash(res["password"], pw) if pw_matches: session["username"] = user return Response(headers={"HX-Redirect": "/home"}) else: return "Incorrect password, try again" else: return "

Something went wrong with the login

" @app.post("/signup") def signup_user(): req_data = request.form.to_dict() user = req_data["username"] pw = req_data["password"] if user == "" or pw == "": return "

You must fill in both username and password

" res = user_exists(user) if res["success"] and res["user"] is not None: return "

User already exists, Login instead

" elif res["success"] and res["user"] is None: pattern = r'^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$' is_strong = bool(re.match(pattern, pw)) if is_strong: pw_hash = bcrypt.generate_password_hash(pw) res = add_user(user, pw_hash) if res["success"]: session["username"] = user return Response(headers={"HX-Redirect": "/home"}) else: return "

Something went wrong

" else: return "

Password must be at least 8 characters long and contain at least 1 digit and 1 number

" @app.post("/logout") def logout_user(): session.pop('username', None) return Response(headers={"HX-Redirect": "/"})