feat : init elements

This commit is contained in:
swve 2022-11-06 16:11:46 +01:00
parent b1ed0185f9
commit 6a2bea4293
8 changed files with 269 additions and 60 deletions

View file

View file

@ -1,6 +1,6 @@
from fastapi import APIRouter from fastapi import APIRouter
from src.routers import users, auth, houses, orgs, roles 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") 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(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(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"]) global_router.include_router(collections.router, prefix="/collections", tags=["collections"])

View 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)

View file

@ -32,7 +32,11 @@ class CourseChapterMetaData(BaseModel):
chapterOrder: List[str] chapterOrder: List[str]
chapters: List chapters: List
# CoursesChapters #### Classes ####################################################
####################################################
# CRUD
####################################################
async def create_coursechapter(coursechapter_object: CourseChapter, course_id: str, current_user: PublicUser): 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") 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): async def update_coursechapter(coursechapter_object: CourseChapter, coursechapter_id: str, current_user: PublicUser):
await check_database() await check_database()
coursechapters = learnhouseDB["coursechapters"] coursechapters = learnhouseDB["coursechapters"]
@ -189,6 +144,10 @@ async def delete_coursechapter(coursechapter_id: str, current_user: PublicUser)
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")
####################################################
# Misc
####################################################
async def get_coursechapters(course_id: str, page: int = 1, limit: int = 10): async def get_coursechapters(course_id: str, page: int = 1, limit: int = 10):
await check_database() 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] 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 #################################################### #### Security ####################################################

View file

@ -23,6 +23,9 @@ class CollectionInDB(Collection):
#### Classes #################################################### #### Classes ####################################################
####################################################
# CRUD
####################################################
async def get_collection(collection_id: str, current_user: PublicUser): async def get_collection(collection_id: str, current_user: PublicUser):
await check_database() await check_database()
@ -112,6 +115,9 @@ async def delete_collection(collection_id: str, current_user: PublicUser):
raise HTTPException( raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database") status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database")
####################################################
# Misc
####################################################
async def get_collections(page: int = 1, limit: int = 10): async def get_collections(page: int = 1, limit: int = 10):
## TODO : auth ## TODO : auth

View file

@ -5,7 +5,7 @@ from uuid import uuid4
from pydantic import BaseModel from pydantic import BaseModel
from src.services.uploads import upload_thumbnail from src.services.uploads import upload_thumbnail
from src.services.users import PublicUser, User 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 src.services.security import *
from fastapi import FastAPI, HTTPException, status, Request, Response, BackgroundTasks, UploadFile, File from fastapi import FastAPI, HTTPException, status, Request, Response, BackgroundTasks, UploadFile, File
from datetime import datetime from datetime import datetime
@ -30,17 +30,14 @@ class CourseInDB(Course):
updateDate: str updateDate: str
authors: List[str] authors: List[str]
#####
#### Classes #################################################### #### Classes ####################################################
# TODO : Add courses photo & cover upload and delete # TODO : Add courses photo & cover upload and delete
# Courses ####################################################
# CRUD
####################################################
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()
@ -59,7 +56,7 @@ 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"]
@ -174,6 +171,10 @@ async def delete_course(course_id: str, current_user: PublicUser):
raise HTTPException( raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database") 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): async def get_courses(page: int = 1, limit: int = 10, org_id: str | None = None):
await check_database() 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] return [json.loads(json.dumps(course, default=str)) for course in all_courses]
#### Security #################################################### #### Security ####################################################

View file

@ -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

View file

@ -77,6 +77,8 @@ async def check_element_type(element_id):
return "coursechapters" return "coursechapters"
elif element_id.startswith("collection_"): elif element_id.startswith("collection_"):
return "collections" return "collections"
elif element_id.startswith("element_"):
return "elements"
else: else:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Issue verifying element nature") status_code=status.HTTP_409_CONFLICT, detail="Issue verifying element nature")