mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-18 20:09:25 +00:00
fix: refactor course chapters
This commit is contained in:
parent
318bb221aa
commit
40496f7ced
6 changed files with 321 additions and 209 deletions
|
|
@ -7,10 +7,10 @@ export const initialData = {
|
||||||
"element-5": { id: "element-5", content: "Fifth element" },
|
"element-5": { id: "element-5", content: "Fifth element" },
|
||||||
},
|
},
|
||||||
chapters: {
|
chapters: {
|
||||||
"chapter-1": { id: "chapter-1", title: "Chapter 1", elementIds: ["element-1", "element-2", "element-3", ] },
|
"chapter-1": { id: "chapter-1", title: "Chapter 1", elementIds: ["element-1", "element-2", "element-3"] },
|
||||||
"chapter-2": { id: "chapter-2", title: "Chapter 2", elementIds: ["element-4"] },
|
"chapter-2": { id: "chapter-2", title: "Chapter 2", elementIds: ["element-4"] },
|
||||||
"chapter-3": { id: "chapter-3", title: "Chapter 3", elementIds: ["element-5"] },
|
"chapter-3": { id: "chapter-3", title: "Chapter 3", elementIds: ["element-5"] },
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
chapterOrder: ["chapter-1", "chapter-2", "chapter-3"],
|
chapterOrder: ["chapter-1", "chapter-2", "chapter-3"],
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from fastapi import APIRouter
|
from fastapi import APIRouter
|
||||||
from src.routers import collections, courses, users, auth, houses, orgs, roles
|
from src.routers import chapters, collections, courses, users, auth, houses, orgs, roles
|
||||||
|
|
||||||
|
|
||||||
global_router = APIRouter(prefix="/api")
|
global_router = APIRouter(prefix="/api")
|
||||||
|
|
@ -12,5 +12,6 @@ global_router.include_router(houses.router, prefix="/houses", tags=["houses"])
|
||||||
global_router.include_router(orgs.router, prefix="/orgs", tags=["orgs"])
|
global_router.include_router(orgs.router, prefix="/orgs", tags=["orgs"])
|
||||||
global_router.include_router(roles.router, prefix="/roles", tags=["roles"])
|
global_router.include_router(roles.router, prefix="/roles", tags=["roles"])
|
||||||
global_router.include_router(courses.router, prefix="/courses", tags=["courses"])
|
global_router.include_router(courses.router, prefix="/courses", tags=["courses"])
|
||||||
|
global_router.include_router(chapters.router, prefix="/chapters", tags=["chapters"])
|
||||||
global_router.include_router(collections.router, prefix="/collections", tags=["collections"])
|
global_router.include_router(collections.router, prefix="/collections", tags=["collections"])
|
||||||
|
|
||||||
|
|
|
||||||
64
src/routers/chapters.py
Normal file
64
src/routers/chapters.py
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
from fastapi import APIRouter, Depends, UploadFile, Form
|
||||||
|
|
||||||
|
from src.services.chapters import CourseChapter, CourseChapterMetaData, create_coursechapter, delete_coursechapter, get_coursechapter, get_coursechapters, get_coursechapters_meta, update_coursechapter, update_coursechapters_meta
|
||||||
|
from src.services.users import PublicUser
|
||||||
|
from src.services.auth import get_current_user
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/")
|
||||||
|
async def api_create_coursechapter(coursechapter_object: CourseChapter, course_id: str, current_user: PublicUser = Depends(get_current_user)):
|
||||||
|
"""
|
||||||
|
Create new CourseChapter
|
||||||
|
"""
|
||||||
|
return await create_coursechapter(coursechapter_object, course_id, current_user)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/{coursechapter_id}")
|
||||||
|
async def api_get_coursechapter(coursechapter_id: str, current_user: PublicUser = Depends(get_current_user)):
|
||||||
|
"""
|
||||||
|
Get single CourseChapter by coursechapter_id
|
||||||
|
"""
|
||||||
|
return await get_coursechapter(coursechapter_id, current_user=current_user)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/meta/{course_id}")
|
||||||
|
async def api_get_coursechapter(course_id: str, current_user: PublicUser = Depends(get_current_user)):
|
||||||
|
"""
|
||||||
|
Get coursechapter metadata
|
||||||
|
"""
|
||||||
|
return await get_coursechapters_meta(course_id, current_user=current_user)
|
||||||
|
|
||||||
|
|
||||||
|
@router.put("/meta/{course_id}")
|
||||||
|
async def api_update_coursechapter_meta(course_id: str, coursechapters_metadata: CourseChapterMetaData, current_user: PublicUser = Depends(get_current_user)):
|
||||||
|
"""
|
||||||
|
Update coursechapter metadata
|
||||||
|
"""
|
||||||
|
return await update_coursechapters_meta(course_id, coursechapters_metadata, current_user=current_user)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/{course_id}/page/{page}/limit/{limit}")
|
||||||
|
async def api_get_coursechapter_by(course_id: str, page: int, limit: int):
|
||||||
|
"""
|
||||||
|
Get CourseChapters by page and limit
|
||||||
|
"""
|
||||||
|
return await get_coursechapters(course_id, page, limit)
|
||||||
|
|
||||||
|
|
||||||
|
@router.put("/{coursechapter_id}")
|
||||||
|
async def api_update_coursechapter(coursechapter_object: CourseChapter, coursechapter_id: str, current_user: PublicUser = Depends(get_current_user)):
|
||||||
|
"""
|
||||||
|
Update CourseChapters by course_id
|
||||||
|
"""
|
||||||
|
return await update_coursechapter(coursechapter_object, coursechapter_id, current_user)
|
||||||
|
|
||||||
|
|
||||||
|
@router.delete("/{coursechapter_id}")
|
||||||
|
async def api_delete_coursechapter(coursechapter_id: str, current_user: PublicUser = Depends(get_current_user)):
|
||||||
|
"""
|
||||||
|
Delete CourseChapters by ID
|
||||||
|
"""
|
||||||
|
|
||||||
|
return await delete_coursechapter(coursechapter_id, current_user)
|
||||||
|
|
@ -1,23 +1,25 @@
|
||||||
from fastapi import APIRouter, Depends, File, UploadFile, Form
|
from fastapi import APIRouter, Depends, UploadFile, Form
|
||||||
from src.services.auth import get_current_user
|
from src.services.auth import get_current_user
|
||||||
|
|
||||||
from src.services.courses import Course, CourseChapter, create_course, create_coursechapter, delete_coursechapter, get_course, get_coursechapter, get_coursechapters, get_courses, update_course, delete_course, update_course_thumbnail, update_coursechapter
|
from src.services.courses import Course, create_course, get_course, get_courses, update_course, delete_course, update_course_thumbnail
|
||||||
from src.services.users import PublicUser, User
|
from src.services.users import PublicUser
|
||||||
|
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
@router.post("/")
|
@router.post("/")
|
||||||
async def api_create_course(org_id :str , name : str = Form(), mini_description : str = Form() , description :str = Form(), public : bool = Form(), current_user: PublicUser = Depends(get_current_user) , thumbnail: UploadFile | None = None):
|
async def api_create_course(org_id: str, name: str = Form(), mini_description: str = Form(), description: str = Form(), public: bool = Form(), current_user: PublicUser = Depends(get_current_user), thumbnail: UploadFile | None = None):
|
||||||
"""
|
"""
|
||||||
Create new Course
|
Create new Course
|
||||||
"""
|
"""
|
||||||
course = Course(name=name, mini_description=mini_description, description=description, org_id=org_id, public=public , thumbnail="" , chapters=[], learnings=[])
|
course = Course(name=name, mini_description=mini_description, description=description,
|
||||||
return await create_course(course, org_id , current_user, thumbnail)
|
org_id=org_id, public=public, thumbnail="", chapters=[], learnings=[])
|
||||||
|
return await create_course(course, org_id, current_user, thumbnail)
|
||||||
|
|
||||||
|
|
||||||
@router.put("/thumbnail/{course_id}")
|
@router.put("/thumbnail/{course_id}")
|
||||||
async def api_create_course_thumbnail(course_id : str, thumbnail: UploadFile | None = None, current_user: PublicUser = Depends(get_current_user)):
|
async def api_create_course_thumbnail(course_id: str, thumbnail: UploadFile | None = None, current_user: PublicUser = Depends(get_current_user)):
|
||||||
"""
|
"""
|
||||||
Update new Course Thumbnail
|
Update new Course Thumbnail
|
||||||
"""
|
"""
|
||||||
|
|
@ -29,7 +31,7 @@ async def api_get_course(course_id: str, current_user: PublicUser = Depends(get
|
||||||
"""
|
"""
|
||||||
Get single Course by course_id
|
Get single Course by course_id
|
||||||
"""
|
"""
|
||||||
return await get_course(course_id,current_user=current_user)
|
return await get_course(course_id, current_user=current_user)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/{org_id}/page/{page}/limit/{limit}")
|
@router.get("/{org_id}/page/{page}/limit/{limit}")
|
||||||
|
|
@ -54,47 +56,4 @@ async def api_delete_course(course_id: str, current_user: PublicUser = Depends(g
|
||||||
Delete Course by ID
|
Delete Course by ID
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return await delete_course(course_id, current_user)
|
return await delete_course(course_id, current_user)
|
||||||
|
|
||||||
# CoursesChapters
|
|
||||||
|
|
||||||
|
|
||||||
@router.post("/chapters/")
|
|
||||||
async def api_create_coursechapter(coursechapter_object: CourseChapter, course_id: str, current_user: PublicUser = Depends(get_current_user)):
|
|
||||||
"""
|
|
||||||
Create new CourseChapter
|
|
||||||
"""
|
|
||||||
return await create_coursechapter(coursechapter_object, course_id, current_user)
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/chapters/{coursechapter_id}")
|
|
||||||
async def api_get_coursechapter(coursechapter_id: str, current_user: PublicUser = Depends(get_current_user)):
|
|
||||||
"""
|
|
||||||
Get single CourseChapter by coursechapter_id
|
|
||||||
"""
|
|
||||||
return await get_coursechapter(coursechapter_id, current_user=current_user)
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/chapters/{course_id}/page/{page}/limit/{limit}")
|
|
||||||
async def api_get_coursechapter_by(course_id: str, page: int, limit: int):
|
|
||||||
"""
|
|
||||||
Get CourseChapters by page and limit
|
|
||||||
"""
|
|
||||||
return await get_coursechapters(course_id, page, limit)
|
|
||||||
|
|
||||||
|
|
||||||
@router.put("/chapters/{coursechapter_id}")
|
|
||||||
async def api_update_coursechapter(coursechapter_object: CourseChapter, coursechapter_id: str, current_user: PublicUser = Depends(get_current_user)):
|
|
||||||
"""
|
|
||||||
Update CourseChapters by course_id
|
|
||||||
"""
|
|
||||||
return await update_coursechapter(coursechapter_object, coursechapter_id, current_user)
|
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/chapters/{coursechapter_id}")
|
|
||||||
async def api_delete_coursechapter(coursechapter_id: str, current_user: PublicUser = Depends(get_current_user)):
|
|
||||||
"""
|
|
||||||
Delete CourseChapters by ID
|
|
||||||
"""
|
|
||||||
|
|
||||||
return await delete_coursechapter(coursechapter_id, current_user)
|
|
||||||
220
src/services/chapters.py
Normal file
220
src/services/chapters.py
Normal file
|
|
@ -0,0 +1,220 @@
|
||||||
|
from cmath import log
|
||||||
|
from datetime import datetime
|
||||||
|
import json
|
||||||
|
from typing import List
|
||||||
|
from uuid import uuid4
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from src.services.courses import Course, CourseInDB
|
||||||
|
from src.services.database import create_config_collection, check_database, create_database, learnhouseDB, learnhouseDB
|
||||||
|
from src.services.security import verify_user_rights_with_roles
|
||||||
|
from src.services.users import PublicUser
|
||||||
|
from fastapi import FastAPI, HTTPException, status, Request, Response, BackgroundTasks, UploadFile, File
|
||||||
|
|
||||||
|
|
||||||
|
class CourseElement(BaseModel):
|
||||||
|
element_id: str
|
||||||
|
content: str
|
||||||
|
content_type: str
|
||||||
|
|
||||||
|
|
||||||
|
class CourseChapter(BaseModel):
|
||||||
|
name: str
|
||||||
|
description: str
|
||||||
|
elements: List[CourseElement]
|
||||||
|
|
||||||
|
|
||||||
|
class CourseChapterInDB(CourseChapter):
|
||||||
|
coursechapter_id: str
|
||||||
|
course_id: str
|
||||||
|
creationDate: str
|
||||||
|
updateDate: str
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Frontend
|
||||||
|
class CourseChapterMetaData(BaseModel):
|
||||||
|
chapterOrder: List[str]
|
||||||
|
chapters: List
|
||||||
|
|
||||||
|
# CoursesChapters
|
||||||
|
|
||||||
|
|
||||||
|
async def create_coursechapter(coursechapter_object: CourseChapter, course_id: str, current_user: PublicUser):
|
||||||
|
await check_database()
|
||||||
|
coursechapters = learnhouseDB["coursechapters"]
|
||||||
|
courses = learnhouseDB["courses"]
|
||||||
|
|
||||||
|
# generate coursechapter_id with uuid4
|
||||||
|
coursechapter_id = str(f"coursechapter_{uuid4()}")
|
||||||
|
|
||||||
|
hasRoleRights = await verify_user_rights_with_roles("create", current_user.user_id, coursechapter_id)
|
||||||
|
|
||||||
|
if not hasRoleRights:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_409_CONFLICT, detail="Roles : Insufficient rights to perform this action")
|
||||||
|
|
||||||
|
coursechapter = CourseChapterInDB(coursechapter_id=coursechapter_id, creationDate=str(
|
||||||
|
datetime.now()), updateDate=str(datetime.now()), course_id=course_id, **coursechapter_object.dict())
|
||||||
|
|
||||||
|
coursechapter_in_db = coursechapters.insert_one(coursechapter.dict())
|
||||||
|
courses.update_one({"course_id": course_id}, {
|
||||||
|
"$addToSet": {"chapters": coursechapter_id}})
|
||||||
|
|
||||||
|
if not coursechapter_in_db:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database")
|
||||||
|
|
||||||
|
return coursechapter.dict()
|
||||||
|
|
||||||
|
|
||||||
|
async def get_coursechapter(coursechapter_id: str, current_user: PublicUser):
|
||||||
|
await check_database()
|
||||||
|
coursechapters = learnhouseDB["coursechapters"]
|
||||||
|
|
||||||
|
coursechapter = coursechapters.find_one(
|
||||||
|
{"coursechapter_id": coursechapter_id})
|
||||||
|
|
||||||
|
if coursechapter:
|
||||||
|
# verify course rights
|
||||||
|
await verify_rights(coursechapter["course_id"], current_user, "read")
|
||||||
|
coursechapter = CourseChapter(**coursechapter)
|
||||||
|
|
||||||
|
return coursechapter
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_409_CONFLICT, detail="CourseChapter does not exist")
|
||||||
|
|
||||||
|
|
||||||
|
async def get_coursechapters_meta(course_id: str, current_user: PublicUser):
|
||||||
|
await check_database()
|
||||||
|
coursechapters = learnhouseDB["coursechapters"]
|
||||||
|
courses = learnhouseDB["courses"]
|
||||||
|
|
||||||
|
coursechapters = coursechapters.find(
|
||||||
|
{"course_id": course_id}).sort("name", 1)
|
||||||
|
|
||||||
|
course = courses.find_one({"course_id": course_id})
|
||||||
|
course = Course(**course)
|
||||||
|
|
||||||
|
|
||||||
|
# chapters
|
||||||
|
chapters = [json.loads(json.dumps(chapter, default=str))
|
||||||
|
for chapter in coursechapters]
|
||||||
|
|
||||||
|
final = {
|
||||||
|
"chapters": chapters,
|
||||||
|
"chapterOrder": course.chapters
|
||||||
|
}
|
||||||
|
|
||||||
|
return final
|
||||||
|
|
||||||
|
|
||||||
|
async def update_coursechapters_meta(course_id: str, coursechapters_metadata: CourseChapterMetaData, current_user: PublicUser):
|
||||||
|
await check_database()
|
||||||
|
coursechapters = learnhouseDB["coursechapters"]
|
||||||
|
courses = learnhouseDB["courses"]
|
||||||
|
|
||||||
|
course = courses.find_one({"course_id": course_id})
|
||||||
|
course = Course(**course)
|
||||||
|
|
||||||
|
# update chapters in course
|
||||||
|
courseInDB = courses.update_one({"course_id": course_id}, {
|
||||||
|
"$set": {"chapters": coursechapters_metadata.chapterOrder}})
|
||||||
|
|
||||||
|
# TODO : update chapters in coursechapters
|
||||||
|
|
||||||
|
|
||||||
|
return {courseInDB}
|
||||||
|
|
||||||
|
|
||||||
|
async def update_coursechapter(coursechapter_object: CourseChapter, coursechapter_id: str, current_user: PublicUser):
|
||||||
|
await check_database()
|
||||||
|
coursechapters = learnhouseDB["coursechapters"]
|
||||||
|
|
||||||
|
coursechapter = coursechapters.find_one(
|
||||||
|
{"coursechapter_id": coursechapter_id})
|
||||||
|
|
||||||
|
if coursechapter:
|
||||||
|
# verify course rights
|
||||||
|
await verify_rights(coursechapter["course_id"], current_user, "update")
|
||||||
|
creationDate = coursechapter["creationDate"]
|
||||||
|
|
||||||
|
# get today's date
|
||||||
|
datetime_object = datetime.now()
|
||||||
|
|
||||||
|
updated_coursechapter = CourseChapterInDB(
|
||||||
|
coursechapter_id=coursechapter_id, creationDate=creationDate, course_id=coursechapter["course_id"], updateDate=str(datetime_object), **coursechapter_object.dict())
|
||||||
|
|
||||||
|
coursechapters.update_one({"coursechapter_id": coursechapter_id}, {
|
||||||
|
"$set": updated_coursechapter.dict()})
|
||||||
|
|
||||||
|
return CourseChapterInDB(**updated_coursechapter.dict())
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_409_CONFLICT, detail="Coursechapter does not exist")
|
||||||
|
|
||||||
|
|
||||||
|
async def delete_coursechapter(coursechapter_id: str, current_user: PublicUser):
|
||||||
|
await check_database()
|
||||||
|
|
||||||
|
coursechapters = learnhouseDB["coursechapters"]
|
||||||
|
|
||||||
|
coursechapter = coursechapters.find_one(
|
||||||
|
{"coursechapter_id": coursechapter_id})
|
||||||
|
|
||||||
|
if coursechapter:
|
||||||
|
# verify course rights
|
||||||
|
await verify_rights(coursechapter["course_id"], current_user, "delete")
|
||||||
|
|
||||||
|
isDeleted = coursechapters.delete_one(
|
||||||
|
{"coursechapter_id": coursechapter_id})
|
||||||
|
|
||||||
|
# TODO : delete coursechapter from course using $pull https://www.mongodb.com/docs/v4.2/reference/operator/update/pull/
|
||||||
|
|
||||||
|
if isDeleted:
|
||||||
|
return {"detail": "coursechapter deleted"}
|
||||||
|
else:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database")
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_409_CONFLICT, detail="Course does not exist")
|
||||||
|
|
||||||
|
|
||||||
|
async def get_coursechapters(course_id: str, page: int = 1, limit: int = 10):
|
||||||
|
await check_database()
|
||||||
|
courses = learnhouseDB["coursechapters"]
|
||||||
|
# TODO : Get only courses that user is admin/has roles of
|
||||||
|
# get all courses from database
|
||||||
|
all_coursechapters = courses.find({"course_id": course_id}).sort(
|
||||||
|
"name", 1).skip(10 * (page - 1)).limit(limit)
|
||||||
|
|
||||||
|
return [json.loads(json.dumps(coursechapter, default=str)) for coursechapter in all_coursechapters]
|
||||||
|
|
||||||
|
|
||||||
|
#### Security ####################################################
|
||||||
|
|
||||||
|
|
||||||
|
async def verify_rights(course_id: str, current_user: PublicUser, action: str):
|
||||||
|
await check_database()
|
||||||
|
courses = learnhouseDB["courses"]
|
||||||
|
|
||||||
|
course = courses.find_one({"course_id": course_id})
|
||||||
|
|
||||||
|
if not course:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_409_CONFLICT, detail=f"Course/CourseChapter does not exist")
|
||||||
|
|
||||||
|
hasRoleRights = await verify_user_rights_with_roles(action, current_user.user_id, course_id)
|
||||||
|
isAuthor = current_user.user_id in course["authors"]
|
||||||
|
|
||||||
|
if not hasRoleRights and not isAuthor:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_403_FORBIDDEN, detail="Roles/Ownership : Insufficient rights to perform this action")
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
#### Security ####################################################
|
||||||
|
|
@ -18,7 +18,7 @@ class Course(BaseModel):
|
||||||
mini_description: str
|
mini_description: str
|
||||||
description: str
|
description: str
|
||||||
learnings: List[str]
|
learnings: List[str]
|
||||||
thumbnail : str
|
thumbnail: str
|
||||||
public: bool
|
public: bool
|
||||||
chapters: List[str]
|
chapters: List[str]
|
||||||
org_id: str
|
org_id: str
|
||||||
|
|
@ -33,23 +33,6 @@ class CourseInDB(Course):
|
||||||
#####
|
#####
|
||||||
|
|
||||||
|
|
||||||
class CourseElement(BaseModel):
|
|
||||||
element_id: str
|
|
||||||
content: str
|
|
||||||
content_type: str
|
|
||||||
|
|
||||||
|
|
||||||
class CourseChapter(BaseModel):
|
|
||||||
name: str
|
|
||||||
description: str
|
|
||||||
elements: List[CourseElement]
|
|
||||||
|
|
||||||
|
|
||||||
class CourseChapterInDB(CourseChapter):
|
|
||||||
coursechapter_id: str
|
|
||||||
course_id: str
|
|
||||||
creationDate: str
|
|
||||||
updateDate: str
|
|
||||||
|
|
||||||
|
|
||||||
#### Classes ####################################################
|
#### Classes ####################################################
|
||||||
|
|
@ -59,7 +42,7 @@ class CourseChapterInDB(CourseChapter):
|
||||||
|
|
||||||
# Courses
|
# Courses
|
||||||
|
|
||||||
async def get_course(course_id: str , current_user: PublicUser):
|
async def get_course(course_id: str, current_user: PublicUser):
|
||||||
await check_database()
|
await check_database()
|
||||||
courses = learnhouseDB["courses"]
|
courses = learnhouseDB["courses"]
|
||||||
|
|
||||||
|
|
@ -76,27 +59,26 @@ async def get_course(course_id: str , current_user: PublicUser):
|
||||||
return course
|
return course
|
||||||
|
|
||||||
|
|
||||||
async def create_course(course_object: Course, org_id : str , current_user: PublicUser, thumbnail_file: UploadFile | None = None):
|
async def create_course(course_object: Course, org_id: str, current_user: PublicUser, thumbnail_file: UploadFile | None = None):
|
||||||
await check_database()
|
await check_database()
|
||||||
courses = learnhouseDB["courses"]
|
courses = learnhouseDB["courses"]
|
||||||
|
|
||||||
# generate course_id with uuid4
|
# generate course_id with uuid4
|
||||||
course_id = str(f"course_{uuid4()}")
|
course_id = str(f"course_{uuid4()}")
|
||||||
|
|
||||||
# TODO(fix) : the implementation here is clearly not the best one (this entire function)
|
# TODO(fix) : the implementation here is clearly not the best one (this entire function)
|
||||||
course_object.org_id = org_id
|
course_object.org_id = org_id
|
||||||
hasRoleRights = await verify_user_rights_with_roles("create", current_user.user_id, course_id)
|
hasRoleRights = await verify_user_rights_with_roles("create", current_user.user_id, course_id)
|
||||||
|
|
||||||
|
|
||||||
if not hasRoleRights:
|
if not hasRoleRights:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_409_CONFLICT, detail="Roles : Insufficient rights to perform this action")
|
status_code=status.HTTP_409_CONFLICT, detail="Roles : Insufficient rights to perform this action")
|
||||||
|
|
||||||
if thumbnail_file:
|
if thumbnail_file:
|
||||||
name_in_disk = f"{course_id}_thumbnail_{uuid4()}.{thumbnail_file.filename.split('.')[-1]}"
|
name_in_disk = f"{course_id}_thumbnail_{uuid4()}.{thumbnail_file.filename.split('.')[-1]}"
|
||||||
await upload_thumbnail(thumbnail_file, name_in_disk)
|
await upload_thumbnail(thumbnail_file, name_in_disk)
|
||||||
course_object.thumbnail = name_in_disk
|
course_object.thumbnail = name_in_disk
|
||||||
|
|
||||||
course = CourseInDB(course_id=course_id, authors=[
|
course = CourseInDB(course_id=course_id, authors=[
|
||||||
current_user.user_id], creationDate=str(datetime.now()), updateDate=str(datetime.now()), **course_object.dict())
|
current_user.user_id], creationDate=str(datetime.now()), updateDate=str(datetime.now()), **course_object.dict())
|
||||||
|
|
||||||
|
|
@ -108,12 +90,13 @@ async def create_course(course_object: Course, org_id : str , current_user: Pu
|
||||||
|
|
||||||
return course.dict()
|
return course.dict()
|
||||||
|
|
||||||
async def update_course_thumbnail(course_id: str , current_user: PublicUser, thumbnail_file: UploadFile | None = None):
|
|
||||||
|
async def update_course_thumbnail(course_id: str, current_user: PublicUser, thumbnail_file: UploadFile | None = None):
|
||||||
await check_database()
|
await check_database()
|
||||||
|
|
||||||
# verify course rights
|
# verify course rights
|
||||||
await verify_rights(course_id, current_user, "update")
|
await verify_rights(course_id, current_user, "update")
|
||||||
|
|
||||||
courses = learnhouseDB["courses"]
|
courses = learnhouseDB["courses"]
|
||||||
|
|
||||||
course = courses.find_one({"course_id": course_id})
|
course = courses.find_one({"course_id": course_id})
|
||||||
|
|
@ -121,19 +104,18 @@ async def update_course_thumbnail(course_id: str , current_user: PublicUser, thu
|
||||||
if course:
|
if course:
|
||||||
creationDate = course["creationDate"]
|
creationDate = course["creationDate"]
|
||||||
authors = course["authors"]
|
authors = course["authors"]
|
||||||
if thumbnail_file:
|
if thumbnail_file:
|
||||||
name_in_disk = f"{course_id}_thumbnail_{uuid4()}.{thumbnail_file.filename.split('.')[-1]}"
|
name_in_disk = f"{course_id}_thumbnail_{uuid4()}.{thumbnail_file.filename.split('.')[-1]}"
|
||||||
course = Course(**course).copy(update={"thumbnail": name_in_disk})
|
course = Course(**course).copy(update={"thumbnail": name_in_disk})
|
||||||
await upload_thumbnail( thumbnail_file, name_in_disk)
|
await upload_thumbnail(thumbnail_file, name_in_disk)
|
||||||
|
|
||||||
|
updated_course = CourseInDB(course_id=course_id, creationDate=creationDate,
|
||||||
updated_course = CourseInDB(course_id=course_id, creationDate=creationDate, authors=authors, updateDate=str(datetime.now()) , **course.dict())
|
authors=authors, updateDate=str(datetime.now()), **course.dict())
|
||||||
|
|
||||||
courses.update_one({"course_id": course_id}, {
|
courses.update_one({"course_id": course_id}, {
|
||||||
"$set": updated_course.dict()})
|
"$set": updated_course.dict()})
|
||||||
|
|
||||||
return CourseInDB(**updated_course.dict())
|
return CourseInDB(**updated_course.dict())
|
||||||
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
|
@ -145,7 +127,7 @@ async def update_course(course_object: Course, course_id: str, current_user: Pub
|
||||||
|
|
||||||
# verify course rights
|
# verify course rights
|
||||||
await verify_rights(course_id, current_user, "update")
|
await verify_rights(course_id, current_user, "update")
|
||||||
|
|
||||||
courses = learnhouseDB["courses"]
|
courses = learnhouseDB["courses"]
|
||||||
|
|
||||||
course = courses.find_one({"course_id": course_id})
|
course = courses.find_one({"course_id": course_id})
|
||||||
|
|
@ -156,12 +138,12 @@ async def update_course(course_object: Course, course_id: str, current_user: Pub
|
||||||
|
|
||||||
# get today's date
|
# get today's date
|
||||||
datetime_object = datetime.now()
|
datetime_object = datetime.now()
|
||||||
|
|
||||||
updated_course = CourseInDB(
|
updated_course = CourseInDB(
|
||||||
course_id=course_id, creationDate=creationDate, authors=authors, updateDate=str(datetime_object), **course_object.dict())
|
course_id=course_id, creationDate=creationDate, authors=authors, updateDate=str(datetime_object), **course_object.dict())
|
||||||
|
|
||||||
courses.update_one({"course_id": course_id}, {
|
courses.update_one({"course_id": course_id}, {
|
||||||
"$set": updated_course.dict()})
|
"$set": updated_course.dict()})
|
||||||
|
|
||||||
return CourseInDB(**updated_course.dict())
|
return CourseInDB(**updated_course.dict())
|
||||||
|
|
||||||
|
|
@ -169,8 +151,6 @@ async def update_course(course_object: Course, course_id: str, current_user: Pub
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_409_CONFLICT, detail="Course does not exist")
|
status_code=status.HTTP_409_CONFLICT, detail="Course does not exist")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def delete_course(course_id: str, current_user: PublicUser):
|
async def delete_course(course_id: str, current_user: PublicUser):
|
||||||
await check_database()
|
await check_database()
|
||||||
|
|
@ -195,129 +175,17 @@ async def delete_course(course_id: str, current_user: PublicUser):
|
||||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database")
|
status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database")
|
||||||
|
|
||||||
|
|
||||||
async def get_courses(page: int = 1, limit: int = 10 , org_id : str | None = None):
|
async def get_courses(page: int = 1, limit: int = 10, org_id: str | None = None):
|
||||||
await check_database()
|
await check_database()
|
||||||
courses = learnhouseDB["courses"]
|
courses = learnhouseDB["courses"]
|
||||||
# TODO : Get only courses that user is admin/has roles of
|
# TODO : Get only courses that user is admin/has roles of
|
||||||
# get all courses from database
|
# get all courses from database
|
||||||
all_courses = courses.find({"org_id": org_id}).sort("name", 1).skip(10 * (page - 1)).limit(limit)
|
all_courses = courses.find({"org_id": org_id}).sort(
|
||||||
|
"name", 1).skip(10 * (page - 1)).limit(limit)
|
||||||
|
|
||||||
return [json.loads(json.dumps(course, default=str)) for course in all_courses]
|
return [json.loads(json.dumps(course, default=str)) for course in all_courses]
|
||||||
|
|
||||||
# CoursesChapters
|
|
||||||
|
|
||||||
async def create_coursechapter(coursechapter_object: CourseChapter, course_id: str, current_user: PublicUser):
|
|
||||||
await check_database()
|
|
||||||
coursechapters = learnhouseDB["coursechapters"]
|
|
||||||
|
|
||||||
# generate coursechapter_id with uuid4
|
|
||||||
coursechapter_id = str(f"coursechapter_{uuid4()}")
|
|
||||||
|
|
||||||
hasRoleRights = await verify_user_rights_with_roles("create", current_user.user_id, coursechapter_id)
|
|
||||||
|
|
||||||
if not hasRoleRights:
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_409_CONFLICT, detail="Roles : Insufficient rights to perform this action")
|
|
||||||
|
|
||||||
coursechapter = CourseChapterInDB(coursechapter_id=coursechapter_id, creationDate=str(
|
|
||||||
datetime.now()), updateDate=str(datetime.now()), course_id=course_id, **coursechapter_object.dict())
|
|
||||||
|
|
||||||
coursechapter_in_db = coursechapters.insert_one(coursechapter.dict())
|
|
||||||
|
|
||||||
if not coursechapter_in_db:
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database")
|
|
||||||
|
|
||||||
return coursechapter.dict()
|
|
||||||
|
|
||||||
|
|
||||||
async def get_coursechapter(coursechapter_id: str, current_user: PublicUser):
|
|
||||||
await check_database()
|
|
||||||
coursechapters = learnhouseDB["coursechapters"]
|
|
||||||
|
|
||||||
coursechapter = coursechapters.find_one(
|
|
||||||
{"coursechapter_id": coursechapter_id})
|
|
||||||
|
|
||||||
if coursechapter:
|
|
||||||
# verify course rights
|
|
||||||
await verify_rights(coursechapter["course_id"], current_user, "read")
|
|
||||||
coursechapter = CourseChapter(**coursechapter)
|
|
||||||
|
|
||||||
return coursechapter
|
|
||||||
|
|
||||||
else:
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_409_CONFLICT, detail="CourseChapter does not exist")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def update_coursechapter(coursechapter_object: CourseChapter, coursechapter_id: str, current_user: PublicUser):
|
|
||||||
await check_database()
|
|
||||||
coursechapters = learnhouseDB["coursechapters"]
|
|
||||||
|
|
||||||
coursechapter = coursechapters.find_one(
|
|
||||||
{"coursechapter_id": coursechapter_id})
|
|
||||||
|
|
||||||
if coursechapter:
|
|
||||||
# verify course rights
|
|
||||||
await verify_rights(coursechapter["course_id"], current_user, "update")
|
|
||||||
creationDate = coursechapter["creationDate"]
|
|
||||||
|
|
||||||
# get today's date
|
|
||||||
datetime_object = datetime.now()
|
|
||||||
|
|
||||||
updated_coursechapter = CourseChapterInDB(
|
|
||||||
coursechapter_id=coursechapter_id, creationDate=creationDate, course_id=coursechapter["course_id"], updateDate=str(datetime_object), **coursechapter_object.dict())
|
|
||||||
|
|
||||||
coursechapters.update_one({"coursechapter_id": coursechapter_id}, {
|
|
||||||
"$set": updated_coursechapter.dict()})
|
|
||||||
|
|
||||||
return CourseChapterInDB(**updated_coursechapter.dict())
|
|
||||||
|
|
||||||
else:
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_409_CONFLICT, detail="Coursechapter does not exist")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def delete_coursechapter(coursechapter_id: str, current_user: PublicUser):
|
|
||||||
await check_database()
|
|
||||||
|
|
||||||
coursechapters = learnhouseDB["coursechapters"]
|
|
||||||
|
|
||||||
coursechapter = coursechapters.find_one(
|
|
||||||
{"coursechapter_id": coursechapter_id})
|
|
||||||
|
|
||||||
if coursechapter:
|
|
||||||
# verify course rights
|
|
||||||
await verify_rights(coursechapter["course_id"], current_user, "delete")
|
|
||||||
|
|
||||||
isDeleted = coursechapters.delete_one(
|
|
||||||
{"coursechapter_id": coursechapter_id})
|
|
||||||
|
|
||||||
if isDeleted:
|
|
||||||
return {"detail": "coursechapter deleted"}
|
|
||||||
else:
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database")
|
|
||||||
|
|
||||||
else:
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_409_CONFLICT, detail="Course does not exist")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def get_coursechapters(course_id: str, page: int = 1, limit: int = 10):
|
|
||||||
await check_database()
|
|
||||||
courses = learnhouseDB["coursechapters"]
|
|
||||||
# TODO : Get only courses that user is admin/has roles of
|
|
||||||
# get all courses from database
|
|
||||||
all_coursechapters = courses.find({"course_id": course_id}).sort(
|
|
||||||
"name", 1).skip(10 * (page - 1)).limit(limit)
|
|
||||||
|
|
||||||
return [json.loads(json.dumps(coursechapter, default=str)) for coursechapter in all_coursechapters]
|
|
||||||
|
|
||||||
#### Security ####################################################
|
#### Security ####################################################
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue