142 lines
5.2 KiB
Python
142 lines
5.2 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, Query
|
|
from sqlalchemy.orm import Session
|
|
from typing import List, Optional
|
|
from .. import crud, schemas, auth
|
|
from ..database import get_db
|
|
from ..models import User
|
|
|
|
router = APIRouter(prefix="/courses", tags=["courses"])
|
|
|
|
@router.get("/", response_model=schemas.SuccessResponse)
|
|
def get_courses(
|
|
skip: int = Query(0, ge=0),
|
|
limit: int = Query(100, ge=1, le=100),
|
|
level: Optional[str] = Query(None, pattern="^(beginner|intermediate|advanced)$"),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
# Get published courses for all users (including guests)
|
|
courses = crud.get_courses(db, skip=skip, limit=limit, level=level, published_only=True)
|
|
|
|
# Convert SQLAlchemy models to Pydantic models
|
|
course_responses = [schemas.CourseResponse.from_orm(course) for course in courses]
|
|
|
|
return schemas.SuccessResponse(
|
|
data={
|
|
"courses": course_responses,
|
|
"total": len(courses),
|
|
"skip": skip,
|
|
"limit": limit,
|
|
"level": level
|
|
}
|
|
)
|
|
|
|
@router.get("/{course_id}", response_model=schemas.SuccessResponse)
|
|
def get_course(
|
|
course_id: int,
|
|
db: Session = Depends(get_db),
|
|
current_user: Optional[User] = Depends(auth.get_optional_current_user)
|
|
):
|
|
course = crud.get_course_by_id(db, course_id=course_id)
|
|
if not course:
|
|
raise HTTPException(
|
|
status_code=404,
|
|
detail="Course not found"
|
|
)
|
|
|
|
# Check access based on status
|
|
course_status = getattr(course, 'status', 'draft')
|
|
author_id = getattr(course, 'author_id', None)
|
|
|
|
if course_status == 'published':
|
|
pass # Anyone can access published course
|
|
elif course_status == 'draft':
|
|
# Only author can access drafts
|
|
if current_user is None or author_id != current_user.id:
|
|
raise HTTPException(
|
|
status_code=403,
|
|
detail="Not authorized to access this draft"
|
|
)
|
|
else:
|
|
# Archived - author-only access
|
|
if current_user is None or author_id != current_user.id:
|
|
raise HTTPException(
|
|
status_code=403,
|
|
detail="Not authorized to access this course"
|
|
)
|
|
|
|
# Convert SQLAlchemy model to Pydantic model
|
|
course_response = schemas.CourseResponse.from_orm(course)
|
|
|
|
return schemas.SuccessResponse(data={"course": course_response})
|
|
|
|
@router.put("/{course_id}", response_model=schemas.SuccessResponse)
|
|
def update_course(
|
|
course_id: int,
|
|
course_update: schemas.CourseUpdate,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(auth.get_current_user)
|
|
):
|
|
course = crud.get_course_by_id(db, course_id)
|
|
if not course:
|
|
raise HTTPException(status_code=404, detail="Course not found")
|
|
|
|
if course.author_id != current_user.id:
|
|
raise HTTPException(status_code=403, detail="Not authorized to update this course")
|
|
|
|
updated_course = crud.update_course(db, course_id, course_update)
|
|
course_response = schemas.CourseResponse.from_orm(updated_course)
|
|
|
|
return schemas.SuccessResponse(data={"course": course_response})
|
|
|
|
@router.get("/{course_id}/structure", response_model=schemas.SuccessResponse)
|
|
def get_course_structure(
|
|
course_id: int,
|
|
db: Session = Depends(get_db),
|
|
current_user: Optional[User] = Depends(auth.get_optional_current_user)
|
|
):
|
|
course = crud.get_course_by_id(db, course_id=course_id, include_structure=True)
|
|
if not course:
|
|
raise HTTPException(status_code=404, detail="Course not found")
|
|
|
|
if course.status != 'published':
|
|
if current_user is None or course.author_id != current_user.id:
|
|
raise HTTPException(status_code=403, detail="Not authorized")
|
|
|
|
course_data = {
|
|
"id": course.id,
|
|
"title": course.title,
|
|
"description": course.description,
|
|
"level": course.level,
|
|
"duration": course.duration,
|
|
"status": course.status,
|
|
"modules": [
|
|
{
|
|
"id": module.id,
|
|
"title": module.title,
|
|
"description": module.description,
|
|
"duration": module.duration,
|
|
"order_index": module.order_index,
|
|
"lessons": [
|
|
{
|
|
"id": lesson.id,
|
|
"title": lesson.title,
|
|
"description": lesson.description,
|
|
"order_index": lesson.order_index,
|
|
"steps": [
|
|
{
|
|
"id": step.id,
|
|
"step_type": step.step_type,
|
|
"title": step.title,
|
|
"order_index": step.order_index
|
|
} for step in sorted(lesson.steps, key=lambda s: s.order_index)
|
|
] if lesson.steps else []
|
|
}
|
|
for lesson in sorted(module.lessons, key=lambda l: l.order_index)
|
|
] if module.lessons else []
|
|
}
|
|
for module in sorted(course.modules, key=lambda m: m.order_index)
|
|
] if course.modules else []
|
|
}
|
|
|
|
return schemas.SuccessResponse(data={"course": course_data})
|