commit 0400b224c2007854f237b4893098d432461ba37b Author: Mercury Date: Tue Nov 19 21:19:56 2024 +0100 Initial Commit diff --git a/calls.py b/calls.py new file mode 100644 index 0000000..f3e0901 --- /dev/null +++ b/calls.py @@ -0,0 +1,90 @@ +import bcrypt +from db import get_db_connection + +def register_user(email, display_name, password): + hashed_password = bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode() + conn = get_db_connection() + cursor = conn.cursor() + try: + cursor.execute( + "INSERT INTO users (email, display_name, password_hash) VALUES (%s, %s, %s) RETURNING uid;", + (email, display_name, hashed_password) + ) + uid = cursor.fetchone()["uid"] + conn.commit() + return uid + except Exception as e: + conn.rollback() + raise e + finally: + cursor.close() + conn.close() + +def authenticate_user(email, password): + conn = get_db_connection() + cursor = conn.cursor() + try: + cursor.execute("SELECT uid, password_hash FROM users WHERE email = %s;", (email,)) + user = cursor.fetchone() + if user and bcrypt.checkpw(password.encode(), user["password_hash"].encode()): + return user["uid"] + return None + finally: + cursor.close() + conn.close() + +def add_friend(user_uid, friend_uid): + conn = get_db_connection() + cursor = conn.cursor() + try: + cursor.execute("SELECT friend_list FROM users WHERE uid = %s;", (user_uid,)) + friends = cursor.fetchone()["friend_list"] + if friend_uid not in friends: + friends.append(friend_uid) + cursor.execute( + "UPDATE users SET friend_list = %s WHERE uid = %s;", + (friends, user_uid) + ) + conn.commit() + return True + except Exception as e: + conn.rollback() + raise e + 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() diff --git a/db.py b/db.py new file mode 100644 index 0000000..034f694 --- /dev/null +++ b/db.py @@ -0,0 +1,17 @@ +import psycopg2 +from psycopg2.extras import RealDictCursor +import os +from dotenv import load_dotenv + +load_dotenv() + +def get_db_connection(): + conn = psycopg2.connect( + host=os.getenv("DB_HOST"), + port=os.getenv("DB_PORT"), + database=os.getenv("DB_NAME"), + user=os.getenv("DB_USER"), + password=os.getenv("DB_PASSWORD"), + cursor_factory=RealDictCursor + ) + return conn diff --git a/main.py b/main.py new file mode 100644 index 0000000..e556323 --- /dev/null +++ b/main.py @@ -0,0 +1,132 @@ +from fastapi import FastAPI, HTTPException +from pydantic import BaseModel +from calls import register_user, authenticate_user, add_friend, send_match_invite, accept_match_invite + +app = FastAPI() + +class RegisterRequest(BaseModel): + email: str + display_name: str + password: str + +class LoginRequest(BaseModel): + email: str + password: str + +class FriendRequest(BaseModel): + user_uid: int + friend_uid: int + +class MatchInviteRequest(BaseModel): + sender_uid: int + receiver_uid: int + +class AcceptInviteRequest(BaseModel): + match_id: int + player2_uid: int + +@app.post("/register") +def register(request: RegisterRequest): + try: + uid = register_user(request.email, request.display_name, request.password) + return {"message": "User registered successfully", "uid": uid} + except Exception as e: + raise HTTPException(status_code=400, detail=str(e)) + +@app.post("/login") +def login(request: LoginRequest): + uid = authenticate_user(request.email, request.password) + if uid: + return {"message": "Login successful", "uid": uid} + else: + raise HTTPException(status_code=401, detail="Invalid credentials") + +@app.post("/add_friend") +def add_friend_endpoint(request: FriendRequest): + try: + success = add_friend(request.user_uid, request.friend_uid) + 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)) +from fastapi import FastAPI, HTTPException +from pydantic import BaseModel +from calls import register_user, authenticate_user, add_friend, send_match_invite, accept_match_invite + +app = FastAPI() + +class RegisterRequest(BaseModel): + email: str + display_name: str + password: str + +class LoginRequest(BaseModel): + email: str + password: str + +class FriendRequest(BaseModel): + user_uid: int + friend_uid: int + +class MatchInviteRequest(BaseModel): + sender_uid: int + receiver_uid: int + +class AcceptInviteRequest(BaseModel): + match_id: int + player2_uid: int + +@app.post("/register") +def register(request: RegisterRequest): + try: + uid = register_user(request.email, request.display_name, request.password) + return {"message": "User registered successfully", "uid": uid} + except Exception as e: + raise HTTPException(status_code=400, detail=str(e)) + +@app.post("/login") +def login(request: LoginRequest): + uid = authenticate_user(request.email, request.password) + if uid: + return {"message": "Login successful", "uid": uid} + else: + raise HTTPException(status_code=401, detail="Invalid credentials") + +@app.post("/add_friend") +def add_friend_endpoint(request: FriendRequest): + try: + success = add_friend(request.user_uid, request.friend_uid) + 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)) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..4cc7e7b --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +fastapi +psycopg2-binary +python-dotenv +bcrypt +uvicorn