From 1efada3146a23301e565767bd28609c25d805cb8 Mon Sep 17 00:00:00 2001 From: Mercurio <47455213+NotLugozzi@users.noreply.github.com> Date: Sat, 21 Dec 2024 22:35:00 +0100 Subject: [PATCH] refactored calls and endpoints to better handle mobile app --- calls.py | 135 ++--------------------------------------------------- main.py | 138 ++++++++++++++++++++++++++++++++++--------------------- 2 files changed, 91 insertions(+), 182 deletions(-) diff --git a/calls.py b/calls.py index d35c307..7ec7f2c 100644 --- a/calls.py +++ b/calls.py @@ -5,6 +5,8 @@ import secrets import time import json + +# USER MANAGEMENT FUNCTIONS def register_user(email, display_name, password): hashed_password = bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode() conn = get_db_connection() @@ -45,24 +47,6 @@ def authenticate_user(email, password): conn.close() -def reauth_user(token): - conn = get_db_connection() - cursor = conn.cursor() - try: - cursor.execute("SELECT email, display_name, current_elo, session_token FROM users WHERE session_token = %s;", (token,)) - user = cursor.fetchone() - if user: - user_data = { - "email": user["email"], - "display_name": user["display_name"], - "elo": user["current_elo"] - } - return user_data - return None - finally: - cursor.close() - conn.close() - def add_friend(token, friend_uid): conn = get_db_connection() cursor = conn.cursor() @@ -98,6 +82,8 @@ def add_friend(token, friend_uid): conn.close() +# MATCHMAKING ENDPOINTS + def get_leaderboard(): conn = get_db_connection() cursor = conn.cursor() @@ -109,116 +95,6 @@ def get_leaderboard(): finally: cursor.close() conn.close() - - -def send_match_invite(sender_uid, receiver_uid): - conn = get_db_connection() - cursor = conn.cursor() - try: - cursor.execute( - "INSERT INTO matches (player1_uid, player2_uid) VALUES (%s, %s) RETURNING match_id;", - (sender_uid, receiver_uid) - ) - match_id = cursor.fetchone()["match_id"] - conn.commit() - return match_id - except Exception as e: - conn.rollback() - raise e - finally: - cursor.close() - conn.close() - -def accept_match_invite(match_id, player2_uid): - conn = get_db_connection() - cursor = conn.cursor() - try: - cursor.execute( - "UPDATE matches SET match_date = CURRENT_TIMESTAMP WHERE match_id = %s AND player2_uid = %s;", - (match_id, player2_uid) - ) - conn.commit() - return True - except Exception as e: - conn.rollback() - raise e - finally: - cursor.close() - conn.close() - - -def get_all_matches(): - conn = get_db_connection() - cursor = conn.cursor() - try: - query = """ - SELECT - m.match_id, - u1.display_name AS player1_name, - u2.display_name AS player2_name, - m.player1_score, - m.player2_score, - CASE - WHEN m.player1_score IS NULL AND m.player2_score IS NULL THEN 'upcoming' - WHEN m.player1_score IS NOT NULL AND m.player2_score IS NOT NULL THEN 'completed' - ELSE 'ongoing' - END AS status, - m.match_date - FROM matches m - LEFT JOIN users u1 ON m.player1_uid = u1.uid - LEFT JOIN users u2 ON m.player2_uid = u2.uid - ORDER BY - CASE - WHEN m.player1_score IS NULL AND m.player2_score IS NULL THEN 2 -- Upcoming - WHEN m.player1_score IS NOT NULL AND m.player2_score IS NOT NULL THEN 3 -- Completed - ELSE 1 -- Ongoing - END, - m.match_date; - """ - cursor.execute(query) - matches = cursor.fetchall() - return matches - finally: - cursor.close() - conn.close() - - -def get_elo(auth_header): - if not auth_header.startswith('Basic '): - raise ValueError("Invalid Authorization header") - - encoded_credentials = auth_header.split(' ', 1)[1] - decoded_credentials = base64.b64decode(encoded_credentials).decode() - - try: - email, password = decoded_credentials.split(':', 1) - except ValueError: - raise ValueError("Invalid credentials format") - - conn = get_db_connection() - cursor = conn.cursor() - try: - cursor.execute("SELECT email, display_name, password_hash, elo FROM users WHERE email = %s;", (email,)) - user = cursor.fetchone() - - if not user: - raise ValueError("User not found") - - if not bcrypt.checkpw(password.encode(), user["password_hash"].encode()): - raise ValueError("Invalid password") - return { - "email": user["email"], - "elo": user["elo"], - "display_name": user["display_name"] - } - - except Exception as e: - raise e - - finally: - cursor.close() - conn.close() - def update_elo(player1_display_name, player2_display_name, player1_score, player2_score, winner): conn = get_db_connection() @@ -233,7 +109,6 @@ def update_elo(player1_display_name, player2_display_name, player1_score, player """, (player1_display_name, player2_display_name)) players = cursor.fetchall() - if len(players) != 2: return {"error": "Both players must exist in the database."} @@ -241,6 +116,7 @@ def update_elo(player1_display_name, player2_display_name, player1_score, player player2_elo = players[1]["current_elo"] expected_player1 = 1 / (1 + 10 ** ((player2_elo - player1_elo) / 400)) expected_player2 = 1 / (1 + 10 ** ((player1_elo - player2_elo) / 400)) + if winner == player1_display_name: actual_player1 = 1 @@ -279,4 +155,3 @@ def update_elo(player1_display_name, player2_display_name, player1_score, player finally: cursor.close() conn.close() - diff --git a/main.py b/main.py index e18c51c..9feae36 100644 --- a/main.py +++ b/main.py @@ -21,24 +21,21 @@ class LoginRequest(BaseModel): email: str password: str -class ReloginRequest(BaseModel): - token: str class FriendRequest(BaseModel): token: str friend_uid: int -class MatchInviteRequest(BaseModel): - sender_uid: int - receiver_uid: int - -class AcceptInviteRequest(BaseModel): - match_id: int - player2_uid: int - class getFriendList(BaseModel): token: str +class CreateMatchRequest(BaseModel): + token: str + +class JoinMatchRequest(BaseModel): + token: str + match_id: int + @app.post("/register") def register(request: RegisterRequest): try: @@ -55,14 +52,7 @@ def login(request: LoginRequest): else: raise HTTPException(status_code=401, detail="Invalid credentials") -@app.post("/auth") -def login(request: ReloginRequest): - sessiontoken = reauth_user(request.token) - if sessiontoken: - return {"message": "Login successful", "uid": sessiontoken} - else: - raise HTTPException(status_code=503, detail="Bad Token") - + @app.post("/add_friend") def add_friend_endpoint(request: FriendRequest): try: @@ -70,30 +60,6 @@ def add_friend_endpoint(request: FriendRequest): return {"message": "Friend added successfully"} if success else HTTPException(400, "Failed to add friend") except Exception as e: raise HTTPException(status_code=400, detail=str(e)) - -@app.post("/send_match_invite") -def send_invite(request: MatchInviteRequest): - try: - match_id = send_match_invite(request.sender_uid, request.receiver_uid) - return {"message": "Match invite sent successfully", "match_id": match_id} - except Exception as e: - raise HTTPException(status_code=400, detail=str(e)) - -@app.post("/accept_match_invite") -def accept_invite(request: AcceptInviteRequest): - try: - success = accept_match_invite(request.match_id, request.player2_uid) - return {"message": "Match invite accepted"} if success else HTTPException(400, "Failed to accept invite") - except Exception as e: - raise HTTPException(status_code=400, detail=str(e)) - -@app.get("/matches") -def get_matches(): - try: - matches = get_all_matches() - return {"matches": matches} - except Exception as e: - raise HTTPException(status_code=400, detail=str(e)) @app.get("/leaderboards") def leaderboard(): @@ -102,15 +68,8 @@ def leaderboard(): return leaderboard except Exception as e: raise HTTPException(status_code=400, detail=str(e)) - -@app.post("/elo") -def get_elo_endpoint(authorization: str): - print(f"Received Authorization header: {authorization}") - try: - result = get_elo(authorization) - return result - except Exception as e: - raise HTTPException(status_code=400, detail=str(e)) + + def get_friend_details(friend_uid): conn = get_db_connection() @@ -124,6 +83,20 @@ def get_friend_details(friend_uid): finally: cursor.close() conn.close() + +def get_uid_by_token(token): + conn = get_db_connection() + cursor = conn.cursor() + try: + cursor.execute("SELECT uid FROM users WHERE session_token = %s;", (token,)) + result = cursor.fetchone() + if not result: + raise ValueError("Invalid token") + return result["uid"] + finally: + cursor.close() + conn.close() + @app.post("/get_friends") def get_friends_list(request: getFriendList): @@ -149,4 +122,65 @@ def get_friends_list(request: getFriendList): raise HTTPException(status_code=400, detail=str(e)) finally: cursor.close() - conn.close() \ No newline at end of file + conn.close() + +@app.post("/creatematch") +def create_match(request: CreateMatchRequest): + conn = get_db_connection() + cursor = conn.cursor() + try: + player1_uid = get_uid_by_token(request.token) + cursor.execute( + """ + INSERT INTO matches (player1_uid) + VALUES (%s) + RETURNING match_id; + """, + (player1_uid,) + ) + match_id = cursor.fetchone()["match_id"] + conn.commit() + return {"match_id": match_id} + except Exception as e: + conn.rollback() + raise HTTPException(status_code=400, detail=str(e)) + finally: + cursor.close() + conn.close() + + +@app.post("/joinmatch") +def join_match(request: JoinMatchRequest): + conn = get_db_connection() + cursor = conn.cursor() + try: + player2_uid = get_uid_by_token(request.token) + cursor.execute( + """ + SELECT player1_uid, player2_uid + FROM matches + WHERE match_id = %s; + """, + (request.match_id,) + ) + match = cursor.fetchone() + if not match: + raise HTTPException(status_code=404, detail="Match not found") + if match["player2_uid"] is not None: + raise HTTPException(status_code=400, detail="Match is already full") + cursor.execute( + """ + UPDATE matches + SET player2_uid = %s + WHERE match_id = %s; + """, + (player2_uid, request.match_id) + ) + conn.commit() + return {"message": "Joined match successfully", "match_id": request.match_id} + except Exception as e: + conn.rollback() + raise HTTPException(status_code=400, detail=str(e)) + finally: + cursor.close() + conn.close()