307 lines
5.3 KiB
Python
307 lines
5.3 KiB
Python
from fastapi import FastAPI, Depends
|
|
from pydantic import BaseModel
|
|
|
|
from database import fetch_all, fetch_one
|
|
from events import create_event, get_user_events
|
|
from auth import create_user, verify_user, create_token, get_current_user
|
|
from rooms import create_room, search_room, accept_room
|
|
from permissions import has_role
|
|
from events import create_event, get_user_events, check_event_threshold
|
|
|
|
from fastapi import HTTPException
|
|
import sqlite3
|
|
from typing import Literal
|
|
|
|
class Login(BaseModel):
|
|
username: str
|
|
password: str
|
|
|
|
|
|
class UserCreate(BaseModel):
|
|
username: str
|
|
password: str
|
|
|
|
|
|
class EventCreate(BaseModel):
|
|
room_id: int
|
|
type: str
|
|
title: str
|
|
description: str
|
|
start_time: str
|
|
end_time: str
|
|
visibility: str
|
|
status: str
|
|
min_people: int
|
|
|
|
|
|
class RoomCreate(BaseModel):
|
|
room_name: str
|
|
invite_code: str
|
|
|
|
|
|
class RoomSearch(BaseModel):
|
|
invite_code: str
|
|
|
|
|
|
class RoomJoin(BaseModel):
|
|
invite_code: str
|
|
|
|
|
|
app = FastAPI(
|
|
title="Calendar API",
|
|
description="Room based agenda system",
|
|
version="1.0"
|
|
)
|
|
|
|
|
|
@app.get("/")
|
|
def home():
|
|
return {
|
|
"status": "online",
|
|
"service": "Calendar API"
|
|
}
|
|
|
|
|
|
@app.get("/database")
|
|
def database_status():
|
|
tables = fetch_all(
|
|
"SELECT name FROM sqlite_master WHERE type='table';"
|
|
)
|
|
|
|
return {
|
|
"tables": [table["name"] for table in tables]
|
|
}
|
|
|
|
|
|
# users
|
|
|
|
|
|
@app.post("/create-user")
|
|
def api_create_user(user: UserCreate):
|
|
|
|
user_id = create_user(
|
|
user.username,
|
|
user.password
|
|
)
|
|
|
|
return {
|
|
"status": "created",
|
|
"user_id": user_id
|
|
}
|
|
|
|
|
|
@app.post("/login")
|
|
def api_login(login: Login):
|
|
|
|
user_id = verify_user(
|
|
login.username,
|
|
login.password
|
|
)
|
|
|
|
if user_id is None:
|
|
return {
|
|
"status": "failed"
|
|
}
|
|
|
|
token = create_token(user_id)
|
|
|
|
return {
|
|
"status": "success",
|
|
"access_token": token,
|
|
"token_type": "bearer"
|
|
}
|
|
|
|
|
|
@app.get("/me")
|
|
def get_me(
|
|
user_id: int = Depends(get_current_user)
|
|
):
|
|
return {
|
|
"user_id": user_id
|
|
}
|
|
|
|
|
|
# rooms
|
|
|
|
@app.delete("/room/{room_id}")
|
|
def delete_room(
|
|
room_id: int,
|
|
user_id: int = Depends(get_current_user)
|
|
):
|
|
|
|
if not has_role(
|
|
room_id,
|
|
user_id,
|
|
["owner", "admin"]
|
|
):
|
|
return {
|
|
"status": "denied",
|
|
"reason": "no_permission"
|
|
}
|
|
return {
|
|
"status": "deleted"
|
|
}
|
|
|
|
|
|
# @app.post("/create-room")
|
|
# def api_create_room(
|
|
# room: RoomCreate,
|
|
# user_id: int = Depends(get_current_user)
|
|
# ):
|
|
|
|
# room_id = create_room(
|
|
# user_id,
|
|
# room.room_name,
|
|
# room.invite_code
|
|
# )
|
|
|
|
# return {
|
|
# "status": "created",
|
|
# **room_id
|
|
# }
|
|
|
|
@app.post("/create-room")
|
|
def api_create_room(
|
|
room: RoomCreate,
|
|
user_id: int = Depends(get_current_user)
|
|
):
|
|
|
|
try:
|
|
room_id = create_room(
|
|
user_id,
|
|
room.room_name,
|
|
room.invite_code
|
|
)
|
|
|
|
except sqlite3.IntegrityError:
|
|
raise HTTPException(
|
|
status_code=409,
|
|
detail="invite_code already exists"
|
|
)
|
|
|
|
return {
|
|
"status": "created",
|
|
"room_id": room_id
|
|
}
|
|
|
|
@app.post("/search-room")
|
|
def api_search_room(
|
|
room: RoomSearch
|
|
):
|
|
|
|
room_name = search_room(
|
|
room.invite_code
|
|
)
|
|
|
|
if room_name is None:
|
|
return {
|
|
"status": "failed",
|
|
"reason": "room_not_found"
|
|
}
|
|
|
|
return {
|
|
"status": "found",
|
|
"room_name": room_name
|
|
}
|
|
|
|
|
|
@app.post("/join-room")
|
|
def api_join_room(
|
|
room: RoomJoin,
|
|
user_id: int = Depends(get_current_user)
|
|
):
|
|
|
|
result = accept_room(
|
|
user_id,
|
|
room.invite_code
|
|
)
|
|
|
|
if result is None:
|
|
return {
|
|
"status": "failed",
|
|
"reason": "room_not_found"
|
|
}
|
|
|
|
return {
|
|
"status": "joined",
|
|
**result
|
|
}
|
|
|
|
# events
|
|
|
|
@app.post("/events")
|
|
def api_create_event(
|
|
event: EventCreate,
|
|
user_id: int = Depends(get_current_user)
|
|
):
|
|
|
|
member = fetch_one(
|
|
"""
|
|
SELECT *
|
|
FROM room_members
|
|
WHERE room_id = ?
|
|
AND user_id = ?
|
|
""",
|
|
(
|
|
event.room_id,
|
|
user_id
|
|
)
|
|
)
|
|
|
|
if member is None:
|
|
return {
|
|
"status": "failed",
|
|
"reason": "not_room_member"
|
|
}
|
|
|
|
|
|
event_id = create_event(
|
|
room_id=event.room_id,
|
|
creator_id=user_id,
|
|
type=event.type,
|
|
title=event.title,
|
|
description=event.description,
|
|
start_time=event.start_time,
|
|
end_time=event.end_time,
|
|
visibility=event.visibility,
|
|
status=event.status,
|
|
min_people=event.min_people
|
|
)
|
|
|
|
return {
|
|
"status": "created",
|
|
"event_id": event_id
|
|
}
|
|
|
|
|
|
@app.get("/events")
|
|
def get_events(
|
|
user_id: int = Depends(get_current_user)
|
|
):
|
|
|
|
events = get_user_events(user_id)
|
|
|
|
return {
|
|
"events": [dict(event) for event in events]
|
|
}
|
|
|
|
|
|
@app.post("/events/{event_id}/respond")
|
|
def respond_event(
|
|
event_id: int,
|
|
status: Literal["going", "maybe", "declined"],
|
|
user_id: int = Depends(get_current_user)
|
|
):
|
|
|
|
respond_to_event(
|
|
event_id,
|
|
user_id,
|
|
status
|
|
)
|
|
|
|
check_event_threshold(event_id)
|
|
|
|
return {
|
|
"status": "response_saved",
|
|
"going": count_confirmations(event_id)
|
|
} |