169 lines
5.6 KiB
Python
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 |