From 84b036b926d90b52956350d99b3a070b3dd1d7ac Mon Sep 17 00:00:00 2001 From: JJ Date: Wed, 19 Mar 2025 14:53:53 +0000 Subject: first commit --- server.py | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 server.py (limited to 'server.py') diff --git a/server.py b/server.py new file mode 100644 index 0000000..013089a --- /dev/null +++ b/server.py @@ -0,0 +1,144 @@ +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": "/"}) \ No newline at end of file -- cgit v1.2.3