2024-08-26 18:37:38 +05:30

420 lines
14 KiB
Python

import json
import flask
import sqlite3
from werkzeug.datastructures.file_storage import FileStorage
from solution_handler import SolutionHandler
from user_handler import UserHandler, User
from bounty_handler import BountyHandler, Bounty
app = flask.Flask(__name__)
app.secret_key = "few`3r9i3r"
app.config['SESSION_TYPE'] = 'filesystem'
@app.get("/")
def a():
return flask.send_file("../assets/apifiletest/index.html")
# ---------- USER ----------
@app.get("/index.js")
def an():
return flask.send_file("../assets/apifiletest/index.js")
#@app.post("/get-user-by-email")
#def get_user_by_email() -> flask.Response:
# request_data = dict(flask.request.form)
# if "email" not in request_data:
# return flask.Response("email or password missing", status=422)
# try:
# user = UserHandler.get_user_by_email(
# request_data["email"],
# )
# except KeyError:
# return flask.Response("User does not exist", status=404)
# return flask.Response(
# response=json.dumps({
# "handle": user.handle,
# "display_name": user.display_name,
# }),
# status=200,
# mimetype='application/json'
# )
#
#
@app.post("/get-user-by-id")
def get_user_by_id() -> flask.Response:
request_data = dict(flask.request.form)
try:
user_id = int(request_data["user_id"])
except KeyError:
return flask.Response("user_id missing", status=422)
except ValueError:
return flask.Response("user_id wasn't int", status=422)
try:
user = UserHandler.get_user_by_id(user_id)
except KeyError:
return flask.Response("User does not exist", status=404)
return flask.Response(
response=json.dumps({
"handle": user.handle,
"display_name": user.display_name,
}),
status=200,
mimetype='application/json'
)
@app.post("/get-user-by-handle")
def get_user_by_handle() -> flask.Response:
request_data = dict(flask.request.form)
try:
handle = request_data["handle"]
except KeyError:
return flask.Response("handle or password missing", status=422)
try:
user = UserHandler.get_user_by_handle(handle)
except KeyError:
return flask.Response("User does not exist", status=404)
return flask.Response(
response=json.dumps({
"handle": user.handle,
"display_name": user.display_name,
}),
status=200,
mimetype='application/json'
)
@app.post("/register")
def register() -> flask.Response:
request_data = dict(flask.request.form)
try:
email = request_data["email"]
handle = request_data["handle"]
password = request_data["password"]
except KeyError:
return flask.Response("email, handle or password missing", status=422)
if "display_name" not in request_data:
request_data["display_name"] = request_data["handle"]
try:
UserHandler.create_user(
User(
-1,
email,
request_data["handle"],
request_data["password"],
request_data["display_name"],
)
)
except sqlite3.IntegrityError as error:
if "handle" in str(error):
return flask.Response("Handle exists", status=409)
else:
return flask.Response("Email exists", status=409)
if "profile_picture" in flask.request.files:
flask.request.files["profile_picture"].save(f"../assets/profile_pictures/{request_data['handle']}")
return flask.Response(status=200)
@app.post("/validate-login")
def validate_login():
if "user_id" not in flask.session:
return flask.Response("Authentication error", status=401)
if not isinstance(flask.session["user_id"], int):
return flask.Response("Authentication error", status=401)
return flask.Response(status=200)
@app.post("/login")
def login() -> flask.Response:
request_data = dict(flask.request.form)
try:
email = request_data["email"]
password = request_data["password"]
except KeyError:
return flask.Response("email or password missing", status=422)
try:
assert UserHandler.verify_password_by_email(email, password)
except KeyError:
return flask.Response("User does not exist", status=404)
except AssertionError:
return flask.Response("Wrong password", status=409)
user = UserHandler.get_user_by_email(request_data["email"])
flask.session["user_id"] = user.user_id
return flask.Response(status=200)
@app.post("/logout")
def logout() -> flask.Response:
if "user_id" not in flask.session:
return flask.Response("Authentication error", status=401)
flask.session.pop("user_id")
return flask.Response(status=200)
@app.post("/change-user-profile-picture")
def change_user_profile_picture() -> flask.Response:
login_validation = validate_login()
if login_validation.status_code != 200:
return login_validation
try:
image = flask.request.files["image"]
except KeyError:
return flask.Response("image is missing", status=422)
image_name = UserHandler.get_user_by_id(flask.session["user_id"]).handle
image.save(
f"../assets/profile_pictures/{image_name}"
)
return flask.Response(status=200)
@app.post("/change-user-display-name")
def change_user_display_name():
login_validation = validate_login()
if login_validation.status_code != 200:
return login_validation
request_data = dict(flask.request.form)
if "display_name" not in request_data:
return flask.Response("display_name is missing", status=422)
UserHandler.change_display_name(flask.session["user_id"], request_data["display_name"])
return flask.Response(status=200)
@app.get("/profile-picture/<handle>")
def get_profile_picture(handle: str) -> flask.Response:
try:
return flask.send_file(f"../assets/profile_pictures/{handle}")
except FileNotFoundError:
return flask.Response(f"{handle} does not exist", 404)
# ---------- BOUNTY ----------
@app.post("/create-bounty")
def create_bounty() -> flask.Response:
request_data = dict(flask.request.form)
login_validation = validate_login()
if login_validation.status_code != 200:
return login_validation
if "title" not in request_data or \
"description" not in request_data:
return flask.Response("title or description is missing", status=422)
if "field" not in request_data:
request_data["field"] = "other"
if "languages" not in request_data:
request_data["language"] = "any"
try:
BountyHandler.create_bounty(Bounty(
-1,
flask.session["user_id"],
request_data["title"],
request_data["description"],
languages=request_data["languages"],
field=request_data["field"]
))
return flask.Response(status=200)
except AssertionError:
return flask.Response("Unknown language/ field", status=403)
@app.post("/get-bounty-by-id")
def bounty_get_by_id() -> flask.Response:
login_validation = validate_login()
user_id = -1
if login_validation.status_code == 200:
user_id = flask.session["user_id"]
request_data = dict(flask.request.form)
if "bounty_id" not in request_data:
return flask.Response("bounty_id is missing", status=422)
try:
bounty_id = int(request_data["bounty_id"])
except ValueError:
return flask.Response("user_id wasn't int", status=422)
try:
bounty = BountyHandler.get_bounty_by_id(bounty_id)
except KeyError:
return flask.Response("Doesn't exist", status=404)
number_of_ratings: int = BountyHandler.get_number_of_ratings(bounty_id)
return flask.Response(
response=json.dumps({
"title": bounty.title,
"description": bounty.description,
"languages": bounty.languages,
"field": bounty.field,
"average_rating": BountyHandler.get_sum_of_ratings(bounty_id) / number_of_ratings,
"number_of_ratings": number_of_ratings,
"users_rating": BountyHandler.get_rating_of_user(user_id, bounty.bounty_id),
}),
status=200,
mimetype='application/json'
)
@app.post("/create-session-for-bounty-get-random")
def create_session_for_bounty_get_random() -> flask.Response:
login_validation = validate_login()
rater_id = -1
if login_validation.status_code == 200:
rater_id = flask.session["user_id"]
bounties = BountyHandler.get_randomized_bounty_list()
bounties = [
{
"id": bounty.bounty_id,
"creator_identifie": bounty.user_id,
"title": bounty.title,
"description": bounty.description,
"languages": bounty.languages,
"field": bounty.field,
"average_rating": BountyHandler.get_sum_of_ratings(bounty.bounty_id) /\
BountyHandler.get_number_of_ratings(bounty.bounty_id),
"number_of_ratings": BountyHandler.get_number_of_ratings(bounty.bounty_id),
"users_rating": BountyHandler.get_rating_of_user(rater_id, bounty.bounty_id),
} for bounty in bounties
]
flask.session["bounties"] = bounties
response = flask.Response(status=200)
return response
@app.post("/bounty-get-random")
def bounty_get_random() -> flask.Response:
request_data = dict(flask.request.form)
if "bounties" not in flask.session:
return flask.Response("/create-session-for-bounty-get-random not called", status=401)
try:
page_number = int(request_data["page_number"])
except KeyError:
return flask.Response("page_number is missing", status=422)
except ValueError:
return flask.Response("page_number wasn't int", status=422)
return flask.Response(
response=json.dumps(
flask.session["bounties"][page_number * 20 : (page_number + 1) * 20]
),
status=200,
mimetype='application/json'
)
@app.post("/bounty-rate")
def bounty_rate() -> flask.Response:
request_data = dict(flask.request.form)
login_validation = validate_login()
if login_validation.status_code != 200:
return login_validation
try:
BountyHandler.rate(
int(request_data["bounty_id"]),
flask.session["user_id"],
int(request_data["rating"]),
)
except sqlite3.IntegrityError:
return flask.Response("Rating gotta be between 1 and 10", status=403)
except ValueError:
return flask.Response("bounty_id or rating wasn't int", status=422)
except KeyError:
return flask.Response("bounty_id or rating missing", status=422)
return flask.Response(status=200)
# ---------- SOLUTIONS ----------
@app.post("/test")
def test():
files = flask.request.files.getlist("files")
for file in files:
if file.filename:
file.filename = file.filename.replace("/", r"|")
file.save(f"../assets/{file.filename}")
else:
return flask.Response(status=400)
return flask.Response()
@app.post("/submit-solution")
def submit_answer() -> flask.Response:
request_data = dict(flask.request.form)
login_validation = validate_login()
if login_validation.status_code != 200:
return login_validation
user_id = flask.session["user_id"]
try:
bounty_id = int(request_data["bounty_id"])
except KeyError:
return flask.Response("Bounty id missing", status=422)
except ValueError:
return flask.Response("bounty_id wasn't int", status=422)
files : list[FileStorage]= flask.request.files.getlist("files")
if not files:
return flask.Response("files missing", status=422)
SolutionHandler.submit_solution(files, bounty_id, user_id)
return flask.Response()
@app.post("/get-solution-by-id")
def get_solution_by_id() -> flask.Response:
request_data = dict(flask.request.form)
try:
solution_id = request_data["solution_id"]
except KeyError:
return flask.Response("Solution id missing", status=422)
try:
return flask.jsonify(SolutionHandler.get_solution_by_id(solution_id))
except KeyError:
return flask.Response("Solution doesn't exist", status=404)
@app.post("/get-solution-list")
def get_solution_list() -> flask.Response:
request_data = dict(flask.request.form)
try:
solution_id = int(request_data["bounty_id"])
except KeyError:
return flask.Response("Bounty id missing", status=422)
except ValueError:
return flask.Response("bounty_id wasn't int", status=422)
return flask.jsonify(SolutionHandler.get_solution_list(solution_id))
@app.post("/like-solution")
def like_solution() -> flask.Response:
request_data = dict(flask.request.form)
login_validation = validate_login()
if login_validation.status_code != 200:
return login_validation
try:
solution_id = request_data["solution_id"]
user_id = flask.session["user_id"]
except KeyError:
return flask.Response("Solution id missing", status=422)
SolutionHandler.like(solution_id=solution_id, user_id=user_id)
return flask.Response(status=200)
@app.post("/unlike-solution")
def unlike_solution() -> flask.Response:
request_data = dict(flask.request.form)
login_validation = validate_login()
if login_validation.status_code != 200:
return login_validation
try:
solution_id = request_data["solution_id"]
user_id = flask.session["user_id"]
except KeyError:
return flask.Response("Solution id missing", status=422)
SolutionHandler.unlike(solution_id=solution_id, user_id=user_id)
return flask.Response(status=200)
@app.post("/has-user-liked")
def has_user_liked() -> flask.Response:
request_data = dict(flask.request.form)
login_validation = validate_login()
if login_validation.status_code != 200:
return login_validation
try:
solution_id = request_data["solution_id"]
user_id = flask.session["user_id"]
except KeyError:
return flask.Response("Solution id missing", status=422)
return flask.jsonify(SolutionHandler.has_user_liked(user_id=user_id, solution_id=solution_id))