169 lines
5.6 KiB
Python

from typing import Any, List, Optional
from fastapi import APIRouter, Depends, HTTPException, Path
from sqlalchemy.orm import Session
from app import crud, models, schemas
from app.api.v1.deps import get_db, get_current_active_user, get_teacher_user
router = APIRouter()
@router.get("/", response_model=List[schemas.Question])
def read_questions(
db: Session = Depends(get_db),
skip: int = 0,
limit: int = 100,
exam_id: Optional[int] = None,
current_user: models.User = Depends(get_current_active_user),
) -> Any:
"""
Retrieve questions.
"""
if exam_id:
questions = crud.question.get_by_exam_id(db, exam_id=exam_id)
else:
questions = crud.question.get_multi(db, skip=skip, limit=limit)
return questions
@router.post("/", response_model=schemas.Question)
def create_question(
*,
db: Session = Depends(get_db),
question_in: schemas.QuestionCreate,
current_user: models.User = Depends(get_teacher_user),
) -> Any:
"""
Create new question.
"""
# Check if the exam exists
exam = crud.exam.get(db=db, id=question_in.exam_id)
if not exam:
raise HTTPException(
status_code=404,
detail=f"Exam with ID {question_in.exam_id} not found",
)
# Check if the user is a teacher of this course or an admin
is_admin = any(role.name == "admin" for role in db.query(models.Role).all() if role.id == current_user.role_id)
if not is_admin:
course = db.query(models.Course).filter(models.Course.id == exam.course_id).first()
teacher = db.query(models.Teacher).filter(models.Teacher.user_id == current_user.id).first()
if not teacher or not course or teacher.id != course.teacher_id:
raise HTTPException(
status_code=403,
detail="You don't have permission to create a question for this exam",
)
question = crud.question.create(db=db, obj_in=question_in)
return question
@router.get("/{question_id}", response_model=schemas.QuestionWithOptions)
def read_question(
*,
db: Session = Depends(get_db),
question_id: int = Path(..., title="The ID of the question to get"),
current_user: models.User = Depends(get_current_active_user),
) -> Any:
"""
Get question by ID with options.
"""
question = crud.question.get(db=db, id=question_id)
if not question:
raise HTTPException(
status_code=404,
detail="Question not found",
)
# Get options for this question
options = crud.question_option.get_by_question_id(db=db, question_id=question_id)
# Create a combined response
result = schemas.QuestionWithOptions.from_orm(question)
result.options = options
return result
@router.put("/{question_id}", response_model=schemas.Question)
def update_question(
*,
db: Session = Depends(get_db),
question_id: int = Path(..., title="The ID of the question to update"),
question_in: schemas.QuestionUpdate,
current_user: models.User = Depends(get_teacher_user),
) -> Any:
"""
Update a question.
"""
question = crud.question.get(db=db, id=question_id)
if not question:
raise HTTPException(
status_code=404,
detail="Question not found",
)
# Check if the user is a teacher of this course or an admin
is_admin = any(role.name == "admin" for role in db.query(models.Role).all() if role.id == current_user.role_id)
if not is_admin:
exam = db.query(models.Exam).filter(models.Exam.id == question.exam_id).first()
if not exam:
raise HTTPException(
status_code=404,
detail="Exam not found",
)
course = db.query(models.Course).filter(models.Course.id == exam.course_id).first()
teacher = db.query(models.Teacher).filter(models.Teacher.user_id == current_user.id).first()
if not teacher or not course or teacher.id != course.teacher_id:
raise HTTPException(
status_code=403,
detail="You don't have permission to update this question",
)
question = crud.question.update(db=db, db_obj=question, obj_in=question_in)
return question
@router.delete("/{question_id}", response_model=schemas.Question)
def delete_question(
*,
db: Session = Depends(get_db),
question_id: int = Path(..., title="The ID of the question to delete"),
current_user: models.User = Depends(get_teacher_user),
) -> Any:
"""
Delete a question.
"""
question = crud.question.get(db=db, id=question_id)
if not question:
raise HTTPException(
status_code=404,
detail="Question not found",
)
# Check if the user is a teacher of this course or an admin
is_admin = any(role.name == "admin" for role in db.query(models.Role).all() if role.id == current_user.role_id)
if not is_admin:
exam = db.query(models.Exam).filter(models.Exam.id == question.exam_id).first()
if not exam:
raise HTTPException(
status_code=404,
detail="Exam not found",
)
course = db.query(models.Course).filter(models.Course.id == exam.course_id).first()
teacher = db.query(models.Teacher).filter(models.Teacher.user_id == current_user.id).first()
if not teacher or not course or teacher.id != course.teacher_id:
raise HTTPException(
status_code=403,
detail="You don't have permission to delete this question",
)
question = crud.question.remove(db=db, id=question_id)
return question