From b77f1ddaa9e1746033a86e1f8b3f8431bb185beb Mon Sep 17 00:00:00 2001 From: ben Date: Tue, 4 Aug 2026 11:02:28 +0200 Subject: [PATCH] update endpoints --- backend/event_signups.py | 18 +- backend/events.py | 58 ++++++ backend/main.py | 339 ++++++++++++++++++++++++++++++++++- backend/rooms.py | 32 +++- database/calendar.db | Bin 0 -> 57344 bytes database/calendar.db-journal | Bin 0 -> 12824 bytes 6 files changed, 439 insertions(+), 8 deletions(-) create mode 100644 database/calendar.db create mode 100644 database/calendar.db-journal diff --git a/backend/event_signups.py b/backend/event_signups.py index f707eef..c5b0b2a 100644 --- a/backend/event_signups.py +++ b/backend/event_signups.py @@ -36,4 +36,20 @@ def count_confirmations(event_id): (event_id,) ) - return result["amount"] \ No newline at end of file + return result["amount"] + +def get_event_responses(event_id): + + return fetch_all( + """ + SELECT + users.id, + users.username, + event_signups.status + FROM event_signups + JOIN users + ON users.id = event_signups.user_id + WHERE event_signups.event_id = ? + """, + (event_id,) + ) \ No newline at end of file diff --git a/backend/events.py b/backend/events.py index ceae02c..fc66a5b 100644 --- a/backend/events.py +++ b/backend/events.py @@ -116,3 +116,61 @@ def check_event_threshold(event_id): """, (event_id,) ) + +def delete_event(event_id): + + from database import execute + + execute( + """ + DELETE FROM events + WHERE id = ? + """, + (event_id,) + ) + +def update_event( + event_id, + title, + description, + start_time, + end_time, + min_people +): + + from database import execute + + execute( + """ + UPDATE events + SET + title = COALESCE(?, title), + description = COALESCE(?, description), + start_time = COALESCE(?, start_time), + end_time = COALESCE(?, end_time), + min_people = COALESCE(?, min_people) + WHERE id = ? + """, + ( + title, + description, + start_time, + end_time, + min_people, + event_id + ) + ) + +def get_room_events(room_id): + + from database import fetch_all + + return fetch_all( + """ + SELECT * + FROM events + WHERE room_id = ? + ORDER BY start_time + """, + (room_id,) + ) \ No newline at end of file diff --git a/backend/main.py b/backend/main.py index 4802143..5ee74bf 100644 --- a/backend/main.py +++ b/backend/main.py @@ -14,6 +14,8 @@ import sqlite3 from typing import Literal from fastapi.middleware.cors import CORSMiddleware +from events import delete_event + class Login(BaseModel): username: str password: str @@ -51,6 +53,13 @@ class RoomSearch(BaseModel): class RoomJoin(BaseModel): invite_code: str +class EventUpdate(BaseModel): + title: str | None = None + description: str | None = None + start_time: str | None = None + end_time: str | None = None + min_people: int | None = None + app = FastAPI( title="Calendar API", @@ -134,10 +143,17 @@ def api_login(login: Login): def get_me( user_id: int = Depends(get_current_user) ): - return { - "user_id": user_id - } + user = fetch_one( + """ + SELECT id, username + FROM users + WHERE id = ? + """, + (user_id,) + ) + + return dict(user) # rooms @@ -157,7 +173,9 @@ def delete_room( "reason": "no_permission" } return { - "status": "deleted" + "status": "not deleted", + "reason": "you are a poopie", + "actual Reason": "i have not built it yet" } @@ -359,8 +377,8 @@ def respond_event( "going": count_confirmations(event_id) } -@app.get("/part_of_rooms") -def get_the_rooms( +@app.get("/rooms") +def api_get_rooms( user_id: int = Depends(get_current_user) ): rooms = get_rooms(user_id) @@ -388,6 +406,315 @@ def api_get_room( return room +@app.get("/rooms/{room_id}/members") +def api_room_members( + room_id: int, + user_id: int = Depends(get_current_user) +): + + room = get_room(room_id, user_id) + + if room is None: + raise HTTPException( + status_code=404, + detail="room not found or no permission" + ) + + members = get_room_members(room_id) + + return { + "members": [dict(member) for member in members] + } + +@app.get("/events/{event_id}") +def api_get_event( + event_id: int, + user_id: int = Depends(get_current_user) +): + + event = fetch_one( + """ + SELECT * + FROM events + WHERE id = ? + """, + (event_id,) + ) + + if event is None: + raise HTTPException( + status_code=404, + detail="event not found" + ) + + member = fetch_one( + """ + SELECT * + FROM room_members + WHERE room_id = ? + AND user_id = ? + """, + ( + event["room_id"], + user_id + ) + ) + + if member is None: + raise HTTPException( + status_code=403, + detail="no access" + ) + + return dict(event) + +@app.get("/events/{event_id}/responses") +def api_event_responses( + event_id: int, + user_id: int = Depends(get_current_user) +): + + event = fetch_one( + """ + SELECT room_id + FROM events + WHERE id = ? + """, + (event_id,) + ) + + if event is None: + raise HTTPException( + status_code=404, + detail="event not found" + ) + + member = fetch_one( + """ + SELECT * + FROM room_members + WHERE room_id = ? + AND user_id = ? + """, + ( + event["room_id"], + user_id + ) + ) + + if member is None: + raise HTTPException( + status_code=403, + detail="no access" + ) + + responses = get_event_responses(event_id) + + return { + "responses": [dict(r) for r in responses] + } + +@app.get("/users/{user_id}") +def api_get_user( + user_id: int, + current_user: int = Depends(get_current_user) +): + + user = fetch_one( + """ + SELECT id, username + FROM users + WHERE id = ? + """, + (user_id,) + ) + + if user is None: + raise HTTPException( + status_code=404, + detail="user not found" + ) + + return dict(user) + +@app.delete("/events/{event_id}") +def api_delete_event( + event_id: int, + user_id: int = Depends(get_current_user) +): + + event = fetch_one( + """ + SELECT creator_id + FROM events + WHERE id = ? + """, + (event_id,) + ) + + if event is None: + raise HTTPException( + status_code=404, + detail="event not found" + ) + + if event["creator_id"] != user_id: + raise HTTPException( + status_code=403, + detail="not event owner" + ) + + delete_event(event_id) + + return { + "status": "deleted" + } + +@app.patch("/events/{event_id}") +def api_update_event( + event_id: int, + event: EventUpdate, + user_id: int = Depends(get_current_user) +): + + old = fetch_one( + """ + SELECT creator_id + FROM events + WHERE id = ? + """, + (event_id,) + ) + + if old is None: + raise HTTPException( + status_code=404, + detail="event not found" + ) + + if old["creator_id"] != user_id: + raise HTTPException( + status_code=403, + detail="not owner" + ) + + + update_event( + event_id, + event.title, + event.description, + event.start_time, + event.end_time, + event.min_people + ) + + + return { + "status": "updated" + } + +@app.delete("/rooms/{room_id}/members/me") +def api_leave_room( + room_id: int, + user_id: int = Depends(get_current_user) +): + + member = fetch_one( + """ + SELECT * + FROM room_members + WHERE room_id = ? + AND user_id = ? + """, + ( + room_id, + user_id + ) + ) + + if member is None: + raise HTTPException( + status_code=404, + detail="not member" + ) + + + leave_room( + room_id, + user_id + ) + + + return { + "status": "left" + } + +@app.get("/rooms/{room_id}/events") +def api_room_events( + room_id: int, + user_id: int = Depends(get_current_user) +): + + member = fetch_one( + """ + SELECT * + FROM room_members + WHERE room_id = ? + AND user_id = ? + """, + ( + room_id, + user_id + ) + ) + + if member is None: + raise HTTPException( + status_code=403, + detail="no access" + ) + + + events = get_room_events(room_id) + + + return { + "events": [ + dict(event) + for event in events + ] + } + +from fastapi.responses import PlainTextResponse +import requests + + +@app.get("/ascii-art", response_class=PlainTextResponse) +def ascii_art(): + response = requests.get( + "http://localhost:8000/me" + ) + + data = response.json() + me_endpoint = data + status = "online" + + return f""" + ██████╗ █████╗ ██╗ ███████╗███╗ ██╗██████╗ █████╗ ██████╗ + ██╔════╝██╔══██╗██║ ██╔════╝████╗ ██║██╔══██╗██╔══██╗██╔══██╗ + ██║ ███████║██║ █████╗ ██╔██╗ ██║██║ ██║███████║██████╔╝ + ██║ ██╔══██║██║ ██╔══╝ ██║╚██╗██║██║ ██║██╔══██║██╔══██╗ + ╚██████╗██║ ██║███████╗███████╗██║ ╚████║██████╔╝██║ ██║██║ ██║ + ╚═════╝╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═══╝╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ + + status: {status} + + "You are a stinky Poo" + - Ben de Roo, programmer +""" + +print() +print() print() print("YOU CAN NOT START THE SERVER WITH PYTHON") print("start with:") diff --git a/backend/rooms.py b/backend/rooms.py index 868a98d..36f09c4 100644 --- a/backend/rooms.py +++ b/backend/rooms.py @@ -201,4 +201,34 @@ def get_room(room_id, user_id): "members": [dict(member) for member in members], "events": [dict(event) for event in events] } - \ No newline at end of file + +def get_room_members(room_id): + + return fetch_all( + """ + SELECT + users.id, + users.username + FROM room_members + JOIN users + ON users.id = room_members.user_id + WHERE room_members.room_id = ? + """, + (room_id,) + ) + +def leave_room(room_id, user_id): + + from database import execute + + execute( + """ + DELETE FROM room_members + WHERE room_id = ? + AND user_id = ? + """, + ( + room_id, + user_id + ) + ) \ No newline at end of file diff --git a/database/calendar.db b/database/calendar.db new file mode 100644 index 0000000000000000000000000000000000000000..d0ecf6483666db0965880c59485acfa1d90f360a GIT binary patch literal 57344 zcmeI*&2Q6Y90zc}HK|ilSE`W75Rwm6Nkm~um{vMz(n9L8LYvZ(ZonmT5>pI`9c-u2 z!wwx9nzX-Q=bd)mW%pgT-8fBSmu(uLX=7s3rg7NwJa$qigrbf~w9?mt#Ln|#KcC;@ zr?F!v7giQ6-_))+Zp-ksliUQy^W0mS#&O(u_@6wnDNY`xaGpN#k@;uMj&mpKd{X&~ zOU7Q~l$`SQ_`T#Op)zcnc}y^UX?7R zWwvUj>s33R=|*2jK2?1*m1UAD@q_SksH~fyLRrHIb zP*_l#)8~t8ixn-s?pXGEnq{P`D!r|j&Sk#izesy7~xOz!Dr(eo+H+EXUMfMJ z(-(CT=~D4RsW_((sk6JfUZF^pG|kKGSYskPI~G%y(mcodhIgY$-mg@Rj!%F{_Y3-7 zH!#(FUkDF;_^upRQz`yqc{|ual)c2$;q}6}Mj{#!)QW4B<%KdSwxpLUVMAFLi{$SH zGUx$y*ED>GcDrYF0)Mk@_IH6EQxI~Nfd#znS{sJXB36BW*J(SR(cF%>Z~4uE z3WH5)m|oqr+P>x3Y<=POlOE;zRo`k2Eo9n_p=oRzH!RPpStJ^pJ2oJaZCEp^j@@K! zp_1F}*m>t@xW*NKr=26n&=Vs21evcp_7%%*g$ssVH=E7q-qNz{YTI<$1hBh9cX!9! z)BRfO4PL#7MLITZ&2u{TuqwAZ%=SJOsdamI$=;rd$JMDR{!Wth?C4MzogeM%<0R2doV_<1nUOQP1|&7RE!33r!!%RVS`uCdZ)pw zmuV;+ZRdXo$O{i%Govx}+|;uMuV_H3`RJ0o)s*6@s`9sIdI9!WBSxMI>F&lY8duvG z+~Kvg^1{j*8NX>V3(oLSizZw41|5UzPGexy=vBgMiTq*FGTkb(+VK9Ijm6YA)t#KY zYJs&so*j99R%YqN&Wq%o$}#>DBMkp^c;=0cNp}8$MX8T_|L9nBYx zR%$CN=H)Z>d8acwzrIpCbG>!-*78zoDK6*rx%Lgmu~*D%XLGX~%Qs3B zyu=+=uN#KfGHiNUAfFT^?x5PXOrI{EJRnHiq;;^HJvPAW(V@vt187Z?=}^7Mp&NYluv z0D&}tUeKQ;|3&3{PWeN5K%Ou`00Izz00bZa0SG_<0uX=z1R${g1Y}W6$?TpuPZmU# zXLnEtGEZjNeEi{vDLOh5nU zmCrcx4-*6+009U<00Izz00bZa0SG_<0xw%&jX%K2@{v^b`0;~B__ph`9nWZV@rix;q~LWQ^)f;EkFB4E*DuY6v#6D4S=A$*${*8|G!VK|G)pTn~3#8 z00Izz00bZa0SG_<0uX=z1R(H&0ttEpfGVszmc1Ta|IcQF@Be$uuK$0*HJ~^IAOHaf zKmY;|fB*y_009U<00MhRAbS0OaR2`UPI*Fp0pNl1+aB6XYzhP*009U<00Izz00bZa z0SG_<0=pI%5y^J|Nc2$@*}Nc%vP_TvdF2T?{@-68*mx~Z;svY)2?!QyqlL4Hm@CNgZm~N<(#+HC z#~L%Nwmht~n;YZwSPUPiauz6OI$e;~$XlM$$}Q(%nGFF15I_I{1Q0*~0R#|00D=4k zM&4Q%((Zj%JMUxs=035{0nSEVa+j-|^Y>sv1Q0*~0R#|0009ILKmY**G8LEvs~La` z;}BB{&>h-__{#yNrH&rtXyhRmIcdQ{009ILKmY**5I_I{1Q0*~fj<{0g5LNm=eGMz cy(_$4`)d-;KeoF5FKAzGcZvX%Q literal 0 HcmV?d00001