mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-18 20:09:25 +00:00
feat : init elements
This commit is contained in:
parent
b1ed0185f9
commit
6a2bea4293
8 changed files with 269 additions and 60 deletions
0
src/dependencies/__init__.py
Normal file
0
src/dependencies/__init__.py
Normal file
|
|
@ -1,6 +1,6 @@
|
|||
from fastapi import APIRouter
|
||||
from src.routers import users, auth, houses, orgs, roles
|
||||
from src.routers.courses import chapters, collections, courses
|
||||
from src.routers.courses import chapters, collections, courses,elements
|
||||
|
||||
|
||||
global_router = APIRouter(prefix="/api")
|
||||
|
|
@ -14,5 +14,6 @@ global_router.include_router(orgs.router, prefix="/orgs", tags=["orgs"])
|
|||
global_router.include_router(roles.router, prefix="/roles", tags=["roles"])
|
||||
global_router.include_router(courses.router, prefix="/courses", tags=["courses"])
|
||||
global_router.include_router(chapters.router, prefix="/chapters", tags=["chapters"])
|
||||
global_router.include_router(elements.router, prefix="/elements", tags=["elements"])
|
||||
global_router.include_router(collections.router, prefix="/collections", tags=["collections"])
|
||||
|
||||
|
|
|
|||
45
src/routers/courses/elements.py
Normal file
45
src/routers/courses/elements.py
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
from fastapi import APIRouter, Depends, UploadFile, Form
|
||||
from src.services.courses.elements import *
|
||||
from src.dependencies.auth import get_current_user
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.post("/")
|
||||
async def api_create_element(element_object: Element, coursechapter_id: str, current_user: PublicUser = Depends(get_current_user)):
|
||||
"""
|
||||
Create new Element
|
||||
"""
|
||||
return await create_element(element_object, coursechapter_id, current_user)
|
||||
|
||||
|
||||
@router.get("/{element_id}")
|
||||
async def api_get_element(element_id: str, current_user: PublicUser = Depends(get_current_user)):
|
||||
"""
|
||||
Get single Element by element_id
|
||||
"""
|
||||
return await get_element(element_id, current_user=current_user)
|
||||
|
||||
@router.get("/coursechapter/{coursechapter_id}")
|
||||
async def api_get_elements(coursechapter_id: str, current_user: PublicUser = Depends(get_current_user)):
|
||||
"""
|
||||
Get CourseChapter Elements
|
||||
"""
|
||||
return await get_elements(coursechapter_id, current_user)
|
||||
|
||||
@router.put("/{element_id}")
|
||||
async def api_update_element(element_object: Element, element_id: str, current_user: PublicUser = Depends(get_current_user)):
|
||||
"""
|
||||
Update Element by element_id
|
||||
"""
|
||||
return await update_element(element_object, element_id, current_user)
|
||||
|
||||
|
||||
@router.delete("/{element_id}")
|
||||
async def api_delete_element(element_id: str, current_user: PublicUser = Depends(get_current_user)):
|
||||
"""
|
||||
Delete Element by element_id
|
||||
"""
|
||||
return await delete_element(element_id, current_user)
|
||||
|
||||
|
||||
|
|
@ -32,7 +32,11 @@ class CourseChapterMetaData(BaseModel):
|
|||
chapterOrder: List[str]
|
||||
chapters: List
|
||||
|
||||
# CoursesChapters
|
||||
#### Classes ####################################################
|
||||
|
||||
####################################################
|
||||
# CRUD
|
||||
####################################################
|
||||
|
||||
|
||||
async def create_coursechapter(coursechapter_object: CourseChapter, course_id: str, current_user: PublicUser):
|
||||
|
|
@ -82,55 +86,6 @@ async def get_coursechapter(coursechapter_id: str, current_user: PublicUser):
|
|||
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) # type: ignore
|
||||
|
||||
# chapters
|
||||
chapters = {}
|
||||
for coursechapter in coursechapters:
|
||||
coursechapter = CourseChapterInDB(**coursechapter)
|
||||
coursechapter_elementIds = []
|
||||
|
||||
for element in coursechapter.elements:
|
||||
coursechapter_elementIds.append(element.element_id)
|
||||
|
||||
chapters[coursechapter.coursechapter_id] = {
|
||||
"id": coursechapter.coursechapter_id, "name": coursechapter.name, "elementIds": coursechapter_elementIds
|
||||
}
|
||||
|
||||
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) # type: ignore
|
||||
|
||||
# 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"]
|
||||
|
|
@ -189,6 +144,10 @@ async def delete_coursechapter(coursechapter_id: str, current_user: PublicUser)
|
|||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT, detail="Course does not exist")
|
||||
|
||||
####################################################
|
||||
# Misc
|
||||
####################################################
|
||||
|
||||
|
||||
async def get_coursechapters(course_id: str, page: int = 1, limit: int = 10):
|
||||
await check_database()
|
||||
|
|
@ -201,6 +160,54 @@ async def get_coursechapters(course_id: str, page: int = 1, limit: int = 10):
|
|||
return [json.loads(json.dumps(coursechapter, default=str)) for coursechapter in all_coursechapters]
|
||||
|
||||
|
||||
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) # type: ignore
|
||||
|
||||
# chapters
|
||||
chapters = {}
|
||||
for coursechapter in coursechapters:
|
||||
coursechapter = CourseChapterInDB(**coursechapter)
|
||||
coursechapter_elementIds = []
|
||||
|
||||
for element in coursechapter.elements:
|
||||
coursechapter_elementIds.append(element.element_id)
|
||||
|
||||
chapters[coursechapter.coursechapter_id] = {
|
||||
"id": coursechapter.coursechapter_id, "name": coursechapter.name, "elementIds": coursechapter_elementIds
|
||||
}
|
||||
|
||||
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) # type: ignore
|
||||
|
||||
# update chapters in course
|
||||
courseInDB = courses.update_one({"course_id": course_id}, {
|
||||
"$set": {"chapters": coursechapters_metadata.chapterOrder}})
|
||||
|
||||
# TODO : update chapters in coursechapters
|
||||
|
||||
return {courseInDB}
|
||||
|
||||
#### Security ####################################################
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@ class CollectionInDB(Collection):
|
|||
|
||||
#### Classes ####################################################
|
||||
|
||||
####################################################
|
||||
# CRUD
|
||||
####################################################
|
||||
|
||||
async def get_collection(collection_id: str, current_user: PublicUser):
|
||||
await check_database()
|
||||
|
|
@ -112,6 +115,9 @@ async def delete_collection(collection_id: str, current_user: PublicUser):
|
|||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database")
|
||||
|
||||
####################################################
|
||||
# Misc
|
||||
####################################################
|
||||
|
||||
async def get_collections(page: int = 1, limit: int = 10):
|
||||
## TODO : auth
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from uuid import uuid4
|
|||
from pydantic import BaseModel
|
||||
from src.services.uploads import upload_thumbnail
|
||||
from src.services.users import PublicUser, User
|
||||
from src.services.database import create_config_collection, check_database, create_database, learnhouseDB, learnhouseDB
|
||||
from src.services.database import create_config_collection, check_database, create_database, learnhouseDB
|
||||
from src.services.security import *
|
||||
from fastapi import FastAPI, HTTPException, status, Request, Response, BackgroundTasks, UploadFile, File
|
||||
from datetime import datetime
|
||||
|
|
@ -30,17 +30,14 @@ class CourseInDB(Course):
|
|||
updateDate: str
|
||||
authors: List[str]
|
||||
|
||||
#####
|
||||
|
||||
|
||||
|
||||
|
||||
#### Classes ####################################################
|
||||
|
||||
# TODO : Add courses photo & cover upload and delete
|
||||
|
||||
|
||||
# Courses
|
||||
####################################################
|
||||
# CRUD
|
||||
####################################################
|
||||
|
||||
async def get_course(course_id: str, current_user: PublicUser):
|
||||
await check_database()
|
||||
|
|
@ -59,7 +56,7 @@ async def get_course(course_id: str, current_user: PublicUser):
|
|||
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()
|
||||
courses = learnhouseDB["courses"]
|
||||
|
||||
|
|
@ -174,6 +171,10 @@ async def delete_course(course_id: str, current_user: PublicUser):
|
|||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database")
|
||||
|
||||
####################################################
|
||||
# Misc
|
||||
####################################################
|
||||
|
||||
|
||||
async def get_courses(page: int = 1, limit: int = 10, org_id: str | None = None):
|
||||
await check_database()
|
||||
|
|
@ -186,7 +187,6 @@ async def get_courses(page: int = 1, limit: int = 10, org_id: str | None = None)
|
|||
return [json.loads(json.dumps(course, default=str)) for course in all_courses]
|
||||
|
||||
|
||||
|
||||
#### Security ####################################################
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,148 @@
|
|||
from pydantic import BaseModel
|
||||
from src.services.database import create_config_collection, check_database, create_database, learnhouseDB
|
||||
from src.services.security import verify_user_rights_with_roles
|
||||
from src.services.users import PublicUser, User
|
||||
from fastapi import FastAPI, HTTPException, status, Request, Response, BackgroundTasks, UploadFile, File
|
||||
from uuid import uuid4
|
||||
from datetime import datetime
|
||||
|
||||
#### Classes ####################################################
|
||||
|
||||
class Element(BaseModel):
|
||||
name: str
|
||||
element_type: str
|
||||
content: str
|
||||
|
||||
|
||||
|
||||
class ElementInDB(Element):
|
||||
element_id: str
|
||||
coursechapter_id: str
|
||||
creationDate: str
|
||||
updateDate: str
|
||||
|
||||
#### Classes ####################################################
|
||||
|
||||
|
||||
####################################################
|
||||
# CRUD
|
||||
####################################################
|
||||
|
||||
|
||||
async def create_element(element_object: Element, coursechapter_id : str , current_user: PublicUser):
|
||||
await check_database()
|
||||
elements = learnhouseDB["elements"]
|
||||
|
||||
# generate element_id
|
||||
element_id = str(f"element_{uuid4()}")
|
||||
|
||||
hasRoleRights = await verify_user_rights_with_roles("create", current_user.user_id, element_id)
|
||||
|
||||
if not hasRoleRights:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT, detail="Roles : Insufficient rights to perform this action")
|
||||
|
||||
# create element
|
||||
element = ElementInDB(**element_object.dict(), creationDate=str(
|
||||
datetime.now()), coursechapter_id=coursechapter_id, updateDate=str(datetime.now()), element_id=element_id)
|
||||
elements.insert_one(element.dict())
|
||||
|
||||
return element
|
||||
|
||||
|
||||
async def get_element(element_id: str, current_user: PublicUser):
|
||||
await check_database()
|
||||
elements = learnhouseDB["elements"]
|
||||
|
||||
element = elements.find_one({"element_id": element_id})
|
||||
|
||||
# verify course rights
|
||||
hasRoleRights = await verify_user_rights_with_roles("read", current_user.user_id, element_id)
|
||||
|
||||
if not hasRoleRights:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT, detail="Roles : Insufficient rights to perform this action")
|
||||
|
||||
if not element:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT, detail="Course does not exist")
|
||||
|
||||
element = ElementInDB(**element)
|
||||
return element
|
||||
|
||||
|
||||
async def update_element(element_object: Element, element_id: str, current_user: PublicUser):
|
||||
await check_database()
|
||||
|
||||
# verify course rights
|
||||
await verify_user_rights_with_roles("update", current_user.user_id, element_id)
|
||||
|
||||
elements = learnhouseDB["elements"]
|
||||
|
||||
element = elements.find_one({"element_id": element_id})
|
||||
|
||||
if element:
|
||||
creationDate = element["creationDate"]
|
||||
|
||||
# get today's date
|
||||
datetime_object = datetime.now()
|
||||
|
||||
updated_course = ElementInDB(
|
||||
element_id=element_id,coursechapter_id=element["coursechapter_id"] ,creationDate=creationDate, updateDate=str(datetime_object), **element_object.dict())
|
||||
|
||||
elements.update_one({"element_id": element_id}, {
|
||||
"$set": updated_course.dict()})
|
||||
|
||||
return ElementInDB(**updated_course.dict())
|
||||
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT, detail="Element does not exist")
|
||||
|
||||
|
||||
async def delete_element(element_id: str, current_user: PublicUser):
|
||||
await check_database()
|
||||
|
||||
# verify course rights
|
||||
await verify_user_rights_with_roles("delete", current_user.user_id, element_id)
|
||||
|
||||
elements = learnhouseDB["elements"]
|
||||
|
||||
element = elements.find_one({"element_id": element_id})
|
||||
|
||||
if not element:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT, detail="Element does not exist")
|
||||
|
||||
isDeleted = elements.delete_one({"element_id": element_id})
|
||||
|
||||
if isDeleted:
|
||||
return {"detail": "Element deleted"}
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database")
|
||||
|
||||
####################################################
|
||||
# Misc
|
||||
####################################################
|
||||
|
||||
|
||||
async def get_elements(coursechapter_id: str, current_user: PublicUser):
|
||||
await check_database()
|
||||
elements = learnhouseDB["elements"]
|
||||
|
||||
# verify course rights
|
||||
await verify_user_rights_with_roles("read", current_user.user_id, coursechapter_id)
|
||||
|
||||
elements = elements.find({"coursechapter_id": coursechapter_id})
|
||||
|
||||
if not elements:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT, detail="No elements found")
|
||||
|
||||
elements_list = []
|
||||
|
||||
for element in elements:
|
||||
elements_list.append(Element(**element))
|
||||
|
||||
return elements_list
|
||||
|
|
@ -77,6 +77,8 @@ async def check_element_type(element_id):
|
|||
return "coursechapters"
|
||||
elif element_id.startswith("collection_"):
|
||||
return "collections"
|
||||
elif element_id.startswith("element_"):
|
||||
return "elements"
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT, detail="Issue verifying element nature")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue