generateur_v3/backend/api/routes/room/routes.py

139 lines
7.9 KiB
Python
Raw Normal View History

2022-10-10 01:34:38 +02:00
from services.database import generate_unique_code
from services.io import add_fast_api_root
from generateur.generateur_main import generate_from_path, parseGeneratorOut, parseOut
from database.exercices.models import Exercice
from database.room.crud import CorrigedChallenge, change_correction, corrige_challenge, create_parcours_db, delete_parcours_db, create_room_db, get_member_dep, check_room, serialize_room, update_parcours_db, get_parcours, get_room, check_admin, get_exercices, get_challenge, get_correction, create_tmp_correction, create_challenge, change_challenge
2022-09-26 10:04:02 +02:00
2022-09-18 22:43:04 +02:00
from pydantic import BaseModel
from typing import Any, Callable, Dict, List, Optional
2022-10-10 01:34:38 +02:00
from fastapi import APIRouter, Depends, WebSocket, status, Query, Body
2022-09-18 22:43:04 +02:00
from config import ALGORITHM, SECRET_KEY
from database.auth.crud import get_user_from_clientId_db
from database.auth.models import User
from database.db import get_session
2022-09-25 22:32:19 +02:00
2022-10-10 01:34:38 +02:00
from sqlmodel import Session, col, select
from database.room.models import Challenge, ChallengeRead, Challenges, CorrigedGeneratorOut, Member, Note, Parcours, ParcoursCreate, ParcoursRead, ParcoursReadShort, ParsedGeneratorOut, Room, RoomConnectionInfos, RoomCreate, RoomAndMember, RoomInfo, TmpCorrection
2022-09-26 10:04:02 +02:00
from routes.room.consumer import RoomConsumer
from routes.room.manager import RoomManager
2022-09-18 22:43:04 +02:00
from services.auth import get_current_user_optional
from fastapi.exceptions import HTTPException
2022-09-26 10:04:02 +02:00
from database.auth.crud import get_user_from_token
from services.websocket import Consumer
2022-10-10 01:34:38 +02:00
from services.misc import noteOn20, stripKeyDict
2022-09-16 21:50:55 +02:00
router = APIRouter(tags=["room"])
2022-10-10 01:34:38 +02:00
manager = RoomManager()
2022-09-16 21:50:55 +02:00
2022-10-10 01:34:38 +02:00
def get_manager():
return manager
2022-09-18 22:43:04 +02:00
2022-10-10 01:34:38 +02:00
@router.post('/room', response_model=RoomConnectionInfos)
2022-09-18 22:43:04 +02:00
def create_room(room: RoomCreate, username: Optional[str] = Query(default=None, max_length=20), user: User | None = Depends(get_current_user_optional), db: Session = Depends(get_session)):
room_obj = create_room_db(room=room, user=user, username=username, db=db)
2022-10-10 01:34:38 +02:00
return {'room': room_obj['room'].id_code, "member": getattr(room_obj['member'].anonymous, "reconnect_code", None)}
2022-09-18 22:43:04 +02:00
2022-10-10 01:34:38 +02:00
@router.get('/room/{room_id}', response_model=RoomInfo)
def get_room_route(room: Room = Depends(get_room), member: Member = Depends(get_member_dep), db: Session = Depends(get_session)):
return serialize_room(room, member, db)
@router.post('/room/{room_id}/parcours', response_model=ParcoursRead)
async def create_parcours(*, parcours: ParcoursCreate, room_id: str, member: Member = Depends(check_admin), m: RoomManager = Depends(get_manager), db: Session = Depends(get_session)):
parcours_obj = create_parcours_db(parcours, member.room_id, db)
if type(parcours_obj) == str:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail=parcours_obj)
await m.broadcast({"type": "add_parcours", "data": {"parcours": ParcoursReadShort(**parcours_obj.dict(exclude_unset=True)).dict()}}, room_id)
return parcours_obj
@router.get('/room/{room_id}/parcours/{parcours_id}', response_model=ParcoursRead)
async def get_parcours_route(*, parcours: Parcours = Depends(get_parcours), member: Member = Depends(get_member_dep), db: Session = Depends(get_session)):
if member.is_admin == False:
return {**parcours.dict(), "challenges": [Challenges(**{**chall.dict(), "challenger": member.id_code, "canCorrige": chall.data != []}) for chall in parcours.challenges if chall.challenger.id_code == member.id_code]}
if member.is_admin == True:
return {**parcours.dict(), "challenges": [Challenges(**{**chall.dict(), "challenger": member.id_code, "canCorrige": chall.data != []}) for chall in parcours.challenges]}
@router.put('/room/{room_id}/parcours/{parcours_id}', response_model=ParcoursRead, dependencies=[Depends(check_admin)])
async def update_parcours(*, room_id: str, parcours: ParcoursCreate, parcours_old: Parcours = Depends(get_parcours), m: RoomManager = Depends(get_manager), db: Session = Depends(get_session)):
parcours_obj = update_parcours_db(parcours, parcours_old, db)
if type(parcours_obj) == str:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail=parcours_obj)
short = ParcoursReadShort(
**parcours_obj.dict(exclude_unset=True), id_code=parcours_obj.id_code)
await m.broadcast({"type": "update_parcours", "data": {"parcours": short.dict()}}, room_id)
return parcours_obj
@router.delete('/room/{room_id}/parcours/{parcours_id}', dependencies=[Depends(check_admin)])
async def delete_parcours(parcours: Parcours = Depends(get_parcours), m: RoomManager = Depends(get_manager), db: Session = Depends(get_session)):
delete_parcours_db(parcours, db)
await m.broadcast({"type": "del_parcours", "data": {"parcours_id": parcours.id_code}}, parcours.room.id_code)
return "ok"
class Exos(BaseModel):
exercice: Exercice
quantity: int
@router.get('/room/{room_id}/challenge/{parcours_id}')
def challenge_route(parcours_id: str, exercices: List[Exos] = Depends(get_exercices), member: Member = Depends(get_member_dep), db: Session = Depends(get_session)):
correction = [parseGeneratorOut(generate_from_path(add_fast_api_root(
e['exercice'].exo_source), e['quantity'], "web")) for e in exercices]
sending = [[{**c, 'inputs': [stripKeyDict(i, "correction")
for i in c['inputs']]} for c in e] for e in correction]
tmpCorr = create_tmp_correction(correction, parcours_id, member, db)
return {'challenge': sending, "id_code": tmpCorr.id_code}
@router.post('/room/{room_id}/challenge/{parcours_id}/{correction_id}', response_model=ChallengeRead)
async def send_challenge(*, challenge: List[List[ParsedGeneratorOut]], correction: TmpCorrection = Depends(get_correction), time: int = Body(), db: Session = Depends(get_session), m: RoomManager = Depends(get_manager),):
parcours = correction.parcours
member = correction.member
data = corrige_challenge(challenge, correction)
if data is None:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail={"challenge_error":"Object does not correspond to correction"})
chall = create_challenge(**data, challenger=member,
parcours=parcours, time=time, db=db)
await m.broadcast({"type": "challenge", "data": Challenges(**{**chall.dict(), "challenger": member.id_code, "canCorrige": chall.data != []}).dict()}, parcours.id_code)
db.delete(correction)
db.commit()
return chall
@router.get('/room/{room_id}/challenge/{parcours_id}/{challenge_id}', response_model=ChallengeRead, dependencies=[Depends(get_member_dep)])
async def challenge_read(*, challenge: Challenge = Depends(get_challenge)):
return challenge
@router.put('/room/{room_id}/challenge/{parcours_id}/{challenge_id}', response_model=ChallengeRead, dependencies=[Depends(check_admin)])
async def corrige(*, correction: List[List[CorrigedGeneratorOut]], challenge: Challenge = Depends(get_challenge), db: Session = Depends(get_session), m: RoomManager = Depends(get_manager),):
parcours = challenge.parcours
member = challenge.challenger
data = change_correction(correction, challenge)
if data is None:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail={"correction_error": "Object does not correspond to challenge"})
challenge = change_challenge(challenge, data, db)
await m.broadcast({"type": "challenge_change", "data": Challenges(**{**challenge.dict(), "challenger": member.id_code, "canCorrige": challenge.data != []}).dict()}, parcours.id_code)
return challenge
2022-09-21 22:31:50 +02:00
2022-09-26 10:04:02 +02:00
2022-09-18 22:43:04 +02:00
@router.websocket('/ws/room/{room_id}')
2022-10-10 01:34:38 +02:00
async def room_ws(ws: WebSocket, room: Room | None = Depends(check_room), db: Session = Depends(get_session), m: RoomManager = Depends(get_manager)):
2022-09-18 22:43:04 +02:00
if room is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail='Room not found')
2022-10-10 01:34:38 +02:00
consumer = RoomConsumer(ws=ws, room=room, manager=m, db=db)
2022-09-18 22:43:04 +02:00
await consumer.run()