420 lines
14 KiB
Python
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))
|