diff --git a/front/components/LectureViews/DynamicCanva/DynamicCanva.tsx b/front/components/LectureViews/DynamicCanva/DynamicCanva.tsx
index f8e66ccf..e6b71fc7 100644
--- a/front/components/LectureViews/DynamicCanva/DynamicCanva.tsx
+++ b/front/components/LectureViews/DynamicCanva/DynamicCanva.tsx
@@ -12,7 +12,7 @@ import { styled } from "styled-components";
interface Editor {
content: string;
- element: any;
+ lecture: any;
//course: any;
}
@@ -31,11 +31,11 @@ function Canva(props: Editor) {
}),
ImageBlock.configure({
editable: isEditable,
- element: props.element,
+ lecture: props.lecture,
}),
VideoBlock.configure({
editable: true,
- element: props.element,
+ lecture: props.lecture,
}),
Youtube.configure({
controls: true,
diff --git a/front/components/LectureViews/Video/Video.tsx b/front/components/LectureViews/Video/Video.tsx
index 6def13b8..4dca7f8d 100644
--- a/front/components/LectureViews/Video/Video.tsx
+++ b/front/components/LectureViews/Video/Video.tsx
@@ -2,10 +2,10 @@ import { getBackendUrl } from "@services/config";
import React from "react";
import styled from "styled-components";
-function VideoLecture({ element, course }: { element: any; course: any }) {
+function VideoLecture({ lecture, course }: { lecture: any; course: any }) {
function getChapterName() {
let chapterName = "";
- let chapterId = element.chapter_id;
+ let chapterId = lecture.chapter_id;
course.chapters.forEach((chapter: any) => {
if (chapter.chapter_id === chapterId) {
chapterName = chapter.name;
@@ -18,10 +18,10 @@ function VideoLecture({ element, course }: { element: any; course: any }) {
Chapter : {getChapterName()}
- {element.name}
+ {lecture.name}
-
+
);
diff --git a/front/components/Modals/CourseEdit/NewChapter.tsx b/front/components/Modals/CourseEdit/NewChapter.tsx
index 79090cba..5a9bca70 100644
--- a/front/components/Modals/CourseEdit/NewChapter.tsx
+++ b/front/components/Modals/CourseEdit/NewChapter.tsx
@@ -16,7 +16,7 @@ function NewChapterModal({ submitChapter , closeModal }: any) {
const handleSubmit = async (e: any) => {
e.preventDefault();
console.log({ chapterName, chapterDescription });
- submitChapter({ name : chapterName, description : chapterDescription , elements : [] });
+ submitChapter({ name : chapterName, description : chapterDescription , lectures : [] });
};
return (
diff --git a/front/components/Modals/CourseEdit/NewElementModal/DynamicCanva.tsx b/front/components/Modals/CourseEdit/NewElementModal/DynamicCanva.tsx
deleted file mode 100644
index 5caf5577..00000000
--- a/front/components/Modals/CourseEdit/NewElementModal/DynamicCanva.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import React, { useState } from "react";
-
-function DynamicCanvaModal({ submitElement, chapterId }: any) {
- const [elementName, setElementName] = useState("");
- const [elementDescription, setElementDescription] = useState("");
-
- const handleElementNameChange = (e: any) => {
- setElementName(e.target.value);
- };
-
- const handleElementDescriptionChange = (e: any) => {
- setElementDescription(e.target.value);
- };
-
- const handleSubmit = async (e: any) => {
- e.preventDefault();
- console.log({ elementName, elementDescription, chapterId });
- submitElement({
- name: elementName,
- chapterId: chapterId,
- type: "dynamic",
- });
- };
- return (
-
- );
-}
-
-export default DynamicCanvaModal;
diff --git a/front/components/Modals/CourseEdit/NewElement.tsx b/front/components/Modals/CourseEdit/NewLecture.tsx
similarity index 56%
rename from front/components/Modals/CourseEdit/NewElement.tsx
rename to front/components/Modals/CourseEdit/NewLecture.tsx
index 19aead43..fcdae52d 100644
--- a/front/components/Modals/CourseEdit/NewElement.tsx
+++ b/front/components/Modals/CourseEdit/NewLecture.tsx
@@ -2,10 +2,10 @@ import React, { useState } from "react";
import { ArrowLeftIcon, Cross1Icon } from "@radix-ui/react-icons";
import Modal from "../Modal";
import styled from "styled-components";
-import DynamicCanvaModal from "./NewElementModal/DynamicCanva";
-import VideoModal from "./NewElementModal/Video";
+import DynamicCanvaModal from "./NewLectureModal/DynamicCanva";
+import VideoModal from "./NewLectureModal/Video";
-function NewElementModal({ closeModal, submitElement, submitFileElement, chapterId }: any) {
+function NewLectureModal({ closeModal, submitLecture, submitFileLecture, chapterId }: any) {
const [selectedView, setSelectedView] = useState("home");
return (
@@ -16,29 +16,29 @@ function NewElementModal({ closeModal, submitElement, submitFileElement, chapter
- Add New Element
+ Add New Lecture
{selectedView === "home" && (
-
- {setSelectedView("dynamic")}}>✨📄
- {setSelectedView("video")}}>📹
-
+
+ {setSelectedView("dynamic")}}>✨📄
+ {setSelectedView("video")}}>📹
+
)}
{selectedView === "dynamic" && (
-
+
)}
{selectedView === "video" && (
-
+
)}
);
}
-const ElementChooserWrapper = styled.div`
+const LectureChooserWrapper = styled.div`
display: flex;
flex-direction: row;
align-items: center;
@@ -46,7 +46,7 @@ const ElementChooserWrapper = styled.div`
gap: 20px;
`;
-const ElementButton = styled.button`
+const LectureButton = styled.button`
padding: 20px;
border-radius: 10px;
border: none;
@@ -58,4 +58,4 @@ const ElementButton = styled.button`
}
`;
-export default NewElementModal;
+export default NewLectureModal;
diff --git a/front/components/Modals/CourseEdit/NewLectureModal/DynamicCanva.tsx b/front/components/Modals/CourseEdit/NewLectureModal/DynamicCanva.tsx
new file mode 100644
index 00000000..b4ff2314
--- /dev/null
+++ b/front/components/Modals/CourseEdit/NewLectureModal/DynamicCanva.tsx
@@ -0,0 +1,36 @@
+import React, { useState } from "react";
+
+function DynamicCanvaModal({ submitLecture, chapterId }: any) {
+ const [lectureName, setLectureName] = useState("");
+ const [lectureDescription, setLectureDescription] = useState("");
+
+ const handleLectureNameChange = (e: any) => {
+ setLectureName(e.target.value);
+ };
+
+ const handleLectureDescriptionChange = (e: any) => {
+ setLectureDescription(e.target.value);
+ };
+
+ const handleSubmit = async (e: any) => {
+ e.preventDefault();
+ console.log({ lectureName, lectureDescription, chapterId });
+ submitLecture({
+ name: lectureName,
+ chapterId: chapterId,
+ type: "dynamic",
+ });
+ };
+ return (
+
+ );
+}
+
+export default DynamicCanvaModal;
diff --git a/front/components/Modals/CourseEdit/NewElementModal/Video.tsx b/front/components/Modals/CourseEdit/NewLectureModal/Video.tsx
similarity index 86%
rename from front/components/Modals/CourseEdit/NewElementModal/Video.tsx
rename to front/components/Modals/CourseEdit/NewLectureModal/Video.tsx
index fce8f192..058bd06e 100644
--- a/front/components/Modals/CourseEdit/NewElementModal/Video.tsx
+++ b/front/components/Modals/CourseEdit/NewLectureModal/Video.tsx
@@ -1,6 +1,6 @@
import React from "react";
-function VideoModal({ submitFileElement, chapterId }: any) {
+function VideoModal({ submitFileLecture, chapterId }: any) {
const [video, setVideo] = React.useState(null) as any;
const [name, setName] = React.useState("");
@@ -14,11 +14,11 @@ function VideoModal({ submitFileElement, chapterId }: any) {
const handleSubmit = async (e: any) => {
e.preventDefault();
- let status = await submitFileElement(video, "video", { name, type: "video" }, chapterId);
+ let status = await submitFileLecture(video, "video", { name, type: "video" }, chapterId);
};
/* TODO : implement some sort of progress bar for file uploads, it is not possible yet because i'm not using axios.
- and the actual upload isn't happening here anyway, it's in the submitFileElement function */
+ and the actual upload isn't happening here anyway, it's in the submitFileLecture function */
return (
diff --git a/front/services/courses/elements.ts b/front/services/courses/lectures.ts
similarity index 79%
rename from front/services/courses/elements.ts
rename to front/services/courses/lectures.ts
index cf4b2777..d5db065c 100644
--- a/front/services/courses/elements.ts
+++ b/front/services/courses/lectures.ts
@@ -1,6 +1,6 @@
import { getAPIUrl } from "../config";
-export async function createElement(data: any, chapter_id: any) {
+export async function createLecture(data: any, chapter_id: any) {
data.content = {};
console.log("data", data, chapter_id);
@@ -17,7 +17,7 @@ export async function createElement(data: any, chapter_id: any) {
body: JSON.stringify(data),
};
- const result: any = await fetch(`${getAPIUrl()}elements/?coursechapter_id=${chapter_id}`, requestOptions)
+ const result: any = await fetch(`${getAPIUrl()}lectures/?coursechapter_id=${chapter_id}`, requestOptions)
.then((result) => result.json())
.catch((error) => console.log("error", error));
@@ -26,7 +26,7 @@ export async function createElement(data: any, chapter_id: any) {
return result;
}
-export async function createFileElement(file: File, type: string, data: any, chapter_id: any) {
+export async function createFileLecture(file: File, type: string, data: any, chapter_id: any) {
const HeadersConfig = new Headers();
@@ -37,12 +37,12 @@ export async function createFileElement(file: File, type: string, data: any, cha
console.log("type" , type);
- let endpoint = `${getAPIUrl()}elements/video`;
+ let endpoint = `${getAPIUrl()}lectures/video`;
if (type === "video") {
formData.append("name", data.name);
formData.append("video_file", file);
- endpoint = `${getAPIUrl()}elements/video`;
+ endpoint = `${getAPIUrl()}lectures/video`;
}
console.log();
@@ -67,21 +67,21 @@ export async function createFileElement(file: File, type: string, data: any, cha
return result;
}
-export async function getElement(element_id: any) {
+export async function getLecture(lecture_id: any) {
const requestOptions: any = {
method: "GET",
redirect: "follow",
credentials: "include",
};
- const result: any = await fetch(`${getAPIUrl()}elements/${element_id}`, requestOptions)
+ const result: any = await fetch(`${getAPIUrl()}lectures/${lecture_id}`, requestOptions)
.then((result) => result.json())
.catch((error) => console.log("error", error));
return result;
}
-export async function updateElement(data: any, element_id: any) {
+export async function updateLecture(data: any, lecture_id: any) {
const HeadersConfig = new Headers({ "Content-Type": "application/json" });
const requestOptions: any = {
@@ -92,7 +92,7 @@ export async function updateElement(data: any, element_id: any) {
body: JSON.stringify(data),
};
- const result: any = await fetch(`${getAPIUrl()}elements/${element_id}`, requestOptions)
+ const result: any = await fetch(`${getAPIUrl()}lectures/${lecture_id}`, requestOptions)
.then((result) => result.json())
.catch((error) => console.log("error", error));
diff --git a/front/services/files/images.ts b/front/services/files/images.ts
index 9700755d..b9645dab 100644
--- a/front/services/files/images.ts
+++ b/front/services/files/images.ts
@@ -1,12 +1,12 @@
import { getAPIUrl } from "../config";
-export async function uploadNewImageFile(file: any, element_id: string) {
+export async function uploadNewImageFile(file: any, lecture_id: string) {
const HeadersConfig = new Headers();
// Send file thumbnail as form data
const formData = new FormData();
formData.append("file_object", file);
- formData.append("element_id", element_id);
+ formData.append("lecture_id", lecture_id);
const requestOptions: any = {
method: "POST",
diff --git a/front/services/files/video.ts b/front/services/files/video.ts
index 19210d7c..0baec936 100644
--- a/front/services/files/video.ts
+++ b/front/services/files/video.ts
@@ -1,12 +1,12 @@
import { getAPIUrl } from "../config";
-export async function uploadNewVideoFile(file: any, element_id: string) {
+export async function uploadNewVideoFile(file: any, lecture_id: string) {
const HeadersConfig = new Headers();
// Send file thumbnail as form data
const formData = new FormData();
formData.append("file_object", file);
- formData.append("element_id", element_id);
+ formData.append("lecture_id", lecture_id);
const requestOptions: any = {
method: "POST",
diff --git a/requirements.txt b/requirements.txt
index b0098a02..6881d583 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,6 +1,6 @@
-fastapi==0.78.0
+fastapi==0.89.1
pydantic>=1.8.0,<2.0.0
-uvicorn>=0.15.0,<0.16.0
+uvicorn==0.20.0
pymongo==4.1.1
python-multipart
python-jose
diff --git a/src/core/__init__.py b/src/core/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/src/core/config/__init__.py b/src/core/config/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/src/core/config/config.py b/src/core/config/config.py
new file mode 100644
index 00000000..99b429d5
--- /dev/null
+++ b/src/core/config/config.py
@@ -0,0 +1,11 @@
+from fastapi import FastAPI
+
+class Settings(FastAPI):
+ title="LearnHousse",
+ description="LearnHouse is a new open-source platform tailored for learning experiences.",
+ version="0.1.0",
+ root_path="/"
+ docs_url="/docs"
+
+async def get_settings() -> Settings:
+ return Settings()
\ No newline at end of file
diff --git a/src/core/events/__init__.py b/src/core/events/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/src/core/events/database.py b/src/core/events/database.py
new file mode 100644
index 00000000..22a6038c
--- /dev/null
+++ b/src/core/events/database.py
@@ -0,0 +1,18 @@
+import logging
+from fastapi import FastAPI
+import pymongo
+
+async def connect_to_db(app: FastAPI) :
+ logging.info("Connecting to database...")
+ try:
+ app.mongodb_client = pymongo.MongoClient("mongodb://learnhouse:learnhouse@mongo:27017/") # type: ignore
+ app.db = app.mongodb_client["learnhouse"] # type: ignore
+ logging.info("Connected to database!")
+ except Exception as e:
+ logging.error("Failed to connect to database!")
+ logging.error(e)
+
+async def close_database(app: FastAPI):
+ app.mongodb_client.close() # type: ignore
+ logging.info("LearnHouse has been shut down.")
+ return app
\ No newline at end of file
diff --git a/src/core/events/events.py b/src/core/events/events.py
new file mode 100644
index 00000000..daa8cc01
--- /dev/null
+++ b/src/core/events/events.py
@@ -0,0 +1,17 @@
+from typing import Callable
+from fastapi import FastAPI
+from src.core.events.database import close_database, connect_to_db
+
+
+def startup_app(app: FastAPI) -> Callable:
+ async def start_app() -> None:
+ # Connect to database
+ await connect_to_db(app)
+
+ return start_app
+
+
+def shutdown_app(app: FastAPI) -> Callable:
+ async def close_app() -> None:
+ await close_database(app)
+ return close_app
diff --git a/src/dependencies/auth.py b/src/dependencies/auth.py
index cae1b1be..b4f33a62 100644
--- a/src/dependencies/auth.py
+++ b/src/dependencies/auth.py
@@ -44,8 +44,8 @@ class TokenData(BaseModel):
#### Classes ####################################################
-async def authenticate_user(email: str, password: str):
- user = await security_get_user(email)
+async def authenticate_user(request: Request,email: str, password: str):
+ user = await security_get_user(request, email)
if not user:
return False
if not await security_verify_password(password, user.password):
@@ -63,28 +63,10 @@ def create_access_token(data: dict, expires_delta: timedelta | None = None):
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwt
-# DEPRECATED
-async def get_current_user_old(token: str = Depends(oauth2_scheme)):
- credentials_exception = HTTPException(
- status_code=status.HTTP_401_UNAUTHORIZED,
- detail="Could not validate credentials",
- headers={"WWW-Authenticate": "Bearer"},
- )
- try:
- payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
- username: str = payload.get("sub") # type: ignore
- if username is None:
- raise credentials_exception
- token_data = TokenData(username=username)
- except JWTError:
- raise credentials_exception
- user = await security_get_user(email=token_data.username) # type: ignore
- if user is None:
- raise credentials_exception
- return PublicUser(**user.dict())
-async def get_current_user(Authorize: AuthJWT = Depends()):
+
+async def get_current_user(request: Request, Authorize: AuthJWT = Depends()):
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
@@ -97,7 +79,7 @@ async def get_current_user(Authorize: AuthJWT = Depends()):
token_data = TokenData(username=username) # type: ignore
except JWTError:
raise credentials_exception
- user = await security_get_user(email=token_data.username) # type: ignore # treated as an email
+ user = await security_get_user(request, email=token_data.username) # type: ignore # treated as an email
if user is None:
raise credentials_exception
return PublicUser(**user.dict())
diff --git a/src/main.py b/src/main.py
index ffa2f84f..4d189a38 100644
--- a/src/main.py
+++ b/src/main.py
@@ -1,6 +1,6 @@
from fastapi import APIRouter
from src.routers import users, auth, houses, orgs, roles, files
-from src.routers.courses import chapters, collections, courses,elements
+from src.routers.courses import chapters, collections, courses,lectures
global_router = APIRouter(prefix="/api")
@@ -15,6 +15,6 @@ global_router.include_router(roles.router, prefix="/roles", tags=["roles"])
global_router.include_router(files.router, prefix="/files", tags=["files"])
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(lectures.router, prefix="/lectures", tags=["lectures"])
global_router.include_router(collections.router, prefix="/collections", tags=["collections"])
diff --git a/src/routers/auth.py b/src/routers/auth.py
index 691d5c97..d08ef3ff 100644
--- a/src/routers/auth.py
+++ b/src/routers/auth.py
@@ -1,5 +1,5 @@
from urllib.request import Request
-from fastapi import Depends, APIRouter, HTTPException, status
+from fastapi import Depends, APIRouter, HTTPException, status, Request
from fastapi.security import OAuth2PasswordRequestForm
from src.dependencies.auth import *
from src.services.users import *
@@ -11,11 +11,11 @@ router = APIRouter()
# DEPRECATED
@router.post("/token", response_model=Token)
-async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()):
+async def login_for_access_token(request: Request, form_data: OAuth2PasswordRequestForm = Depends()):
"""
OAuth2 compatible token login, get access token for future requests
"""
- user = await authenticate_user(form_data.username, form_data.password)
+ user = await authenticate_user(request, form_data.username, form_data.password)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
@@ -47,8 +47,8 @@ def refresh(Authorize: AuthJWT = Depends()):
return {"access_token": new_access_token}
@router.post('/login')
-async def login(Authorize: AuthJWT = Depends(), form_data: OAuth2PasswordRequestForm = Depends()):
- user = await authenticate_user(form_data.username, form_data.password)
+async def login(request: Request,Authorize: AuthJWT = Depends(), form_data: OAuth2PasswordRequestForm = Depends()):
+ user = await authenticate_user(request, form_data.username, form_data.password)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
diff --git a/src/routers/courses/chapters.py b/src/routers/courses/chapters.py
index 2bd25eaa..a00b7b83 100644
--- a/src/routers/courses/chapters.py
+++ b/src/routers/courses/chapters.py
@@ -1,4 +1,4 @@
-from fastapi import APIRouter, Depends, UploadFile, Form
+from fastapi import APIRouter, Depends, Request, UploadFile, Form
from src.services.courses.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
@@ -8,57 +8,57 @@ router = APIRouter()
@router.post("/")
-async def api_create_coursechapter(coursechapter_object: CourseChapter, course_id: str, current_user: PublicUser = Depends(get_current_user)):
+async def api_create_coursechapter(request: Request,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)
+ return await create_coursechapter(request, 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)):
+async def api_get_coursechapter(request: Request,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)
+ return await get_coursechapter(request, coursechapter_id, current_user=current_user)
@router.get("/meta/{course_id}")
-async def api_get_coursechapter_meta(course_id: str, current_user: PublicUser = Depends(get_current_user)):
+async def api_get_coursechapter_meta(request: Request,course_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Get coursechapter metadata
"""
- return await get_coursechapters_meta(course_id, current_user=current_user)
+ return await get_coursechapters_meta(request, 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)):
+async def api_update_coursechapter_meta(request: Request,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)
+ return await update_coursechapters_meta(request, 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):
+async def api_get_coursechapter_by(request: Request,course_id: str, page: int, limit: int):
"""
Get CourseChapters by page and limit
"""
- return await get_coursechapters(course_id, page, limit)
+ return await get_coursechapters(request, 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)):
+async def api_update_coursechapter(request: Request,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)
+ return await update_coursechapter(request, 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)):
+async def api_delete_coursechapter(request: Request,coursechapter_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Delete CourseChapters by ID
"""
- return await delete_coursechapter(coursechapter_id, current_user)
+ return await delete_coursechapter(request,coursechapter_id, current_user)
diff --git a/src/routers/courses/collections.py b/src/routers/courses/collections.py
index e2ce3dc5..284b7cad 100644
--- a/src/routers/courses/collections.py
+++ b/src/routers/courses/collections.py
@@ -1,4 +1,4 @@
-from fastapi import APIRouter, Depends
+from fastapi import APIRouter, Depends, Request
from src.dependencies.auth import get_current_user
from src.services.users import PublicUser, User
from src.services.courses.collections import Collection, create_collection, get_collection, get_collections, update_collection, delete_collection
@@ -8,41 +8,41 @@ router = APIRouter()
@router.post("/")
-async def api_create_collection(collection_object: Collection, current_user: PublicUser = Depends(get_current_user)):
+async def api_create_collection(request: Request,collection_object: Collection, current_user: PublicUser = Depends(get_current_user)):
"""
Create new Collection
"""
- return await create_collection(collection_object, current_user)
+ return await create_collection(request, collection_object, current_user)
@router.get("/{collection_id}")
-async def api_get_collection(collection_id: str, current_user: PublicUser = Depends(get_current_user)):
+async def api_get_collection(request: Request,collection_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Get single collection by ID
"""
- return await get_collection(collection_id, current_user)
+ return await get_collection(request, collection_id, current_user)
@router.get("/page/{page}/limit/{limit}")
-async def api_get_collections_by(page: int, limit: int, current_user: PublicUser = Depends(get_current_user)):
+async def api_get_collections_by(request: Request,page: int, limit: int, current_user: PublicUser = Depends(get_current_user)):
"""
Get collections by page and limit
"""
- return await get_collections(page, limit)
+ return await get_collections(request, page, limit)
@router.put("/{collection_id}")
-async def api_update_collection(collection_object: Collection, collection_id: str, current_user: PublicUser = Depends(get_current_user)):
+async def api_update_collection(request: Request,collection_object: Collection, collection_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Update collection by ID
"""
- return await update_collection(collection_object, collection_id, current_user)
+ return await update_collection(request, collection_object, collection_id, current_user)
@router.delete("/{collection_id}")
-async def api_delete_collection(collection_id: str, current_user: PublicUser = Depends(get_current_user)):
+async def api_delete_collection(request: Request,collection_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Delete collection by ID
"""
- return await delete_collection(collection_id, current_user)
+ return await delete_collection(request, collection_id, current_user)
diff --git a/src/routers/courses/courses.py b/src/routers/courses/courses.py
index 32ad4238..b3ddab1b 100644
--- a/src/routers/courses/courses.py
+++ b/src/routers/courses/courses.py
@@ -1,4 +1,4 @@
-from fastapi import APIRouter, Depends, UploadFile, Form
+from fastapi import APIRouter, Depends, UploadFile, Form, Request
from src.dependencies.auth import get_current_user
from src.services.courses.courses import Course, create_course, get_course, get_course_meta, get_courses, update_course, delete_course, update_course_thumbnail
@@ -9,59 +9,59 @@ router = APIRouter()
@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(request: Request,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
"""
course = Course(name=name, mini_description=mini_description, description=description,
org_id=org_id, public=public, thumbnail="", chapters=[], learnings=[])
- return await create_course(course, org_id, current_user, thumbnail)
+ return await create_course(request, course, org_id, current_user, thumbnail)
@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(request: Request,course_id: str, thumbnail: UploadFile | None = None, current_user: PublicUser = Depends(get_current_user)):
"""
Update new Course Thumbnail
"""
- return await update_course_thumbnail(course_id, current_user, thumbnail)
+ return await update_course_thumbnail(request, course_id, current_user, thumbnail)
@router.get("/{course_id}")
-async def api_get_course(course_id: str, current_user: PublicUser = Depends(get_current_user)):
+async def api_get_course(request: Request,course_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Get single Course by course_id
"""
- return await get_course(course_id, current_user=current_user)
+ return await get_course(request, course_id, current_user=current_user)
@router.get("/meta/{course_id}")
-async def api_get_course_meta(course_id: str, current_user: PublicUser = Depends(get_current_user)):
+async def api_get_course_meta(request: Request,course_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
- Get single Course Metadata (chapters, elements) by course_id
+ Get single Course Metadata (chapters, lectures) by course_id
"""
- return await get_course_meta(course_id, current_user=current_user)
+ return await get_course_meta(request, course_id, current_user=current_user)
@router.get("/{org_id}/page/{page}/limit/{limit}")
-async def api_get_course_by(page: int, limit: int, org_id: str):
+async def api_get_course_by(request: Request,page: int, limit: int, org_id: str):
"""
Get houses by page and limit
"""
- return await get_courses(page, limit, org_id)
+ return await get_courses(request,page, limit, org_id)
@router.put("/{course_id}")
-async def api_update_course(course_object: Course, course_id: str, current_user: PublicUser = Depends(get_current_user)):
+async def api_update_course(request: Request,course_object: Course, course_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Update Course by course_id
"""
- return await update_course(course_object, course_id, current_user)
+ return await update_course(request,course_object, course_id, current_user)
@router.delete("/{course_id}")
-async def api_delete_course(course_id: str, current_user: PublicUser = Depends(get_current_user)):
+async def api_delete_course(request: Request,course_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Delete Course by ID
"""
- return await delete_course(course_id, current_user)
+ return await delete_course(request, course_id, current_user)
diff --git a/src/routers/courses/elements.py b/src/routers/courses/elements.py
deleted file mode 100644
index 39226a4d..00000000
--- a/src/routers/courses/elements.py
+++ /dev/null
@@ -1,55 +0,0 @@
-from fastapi import APIRouter, Depends, UploadFile, Form
-from src.services.courses.elements.elements import *
-from src.dependencies.auth import get_current_user
-from src.services.courses.elements.video import create_video_element
-
-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)
-
-# Video Element
-
-@router.post("/video")
-async def api_create_video_element(name: str = Form() , coursechapter_id: str = Form(), current_user: PublicUser = Depends(get_current_user), video_file: UploadFile | None = None):
- """
- Create new Element
- """
- return await create_video_element(name, coursechapter_id, current_user, video_file)
diff --git a/src/routers/courses/lectures.py b/src/routers/courses/lectures.py
new file mode 100644
index 00000000..bf26a8e9
--- /dev/null
+++ b/src/routers/courses/lectures.py
@@ -0,0 +1,54 @@
+from fastapi import APIRouter, Depends, UploadFile, Form, Request
+from src.services.courses.lectures.lectures import *
+from src.dependencies.auth import get_current_user
+from src.services.courses.lectures.video import create_video_lecture
+
+router = APIRouter()
+
+
+@router.post("/")
+async def api_create_lecture(request: Request,lecture_object: Lecture, coursechapter_id: str, current_user: PublicUser = Depends(get_current_user)):
+ """
+ Create new lecture
+ """
+ return await create_lecture(request,lecture_object, coursechapter_id, current_user)
+
+
+@router.get("/{lecture_id}")
+async def api_get_lecture(request: Request,lecture_id: str, current_user: PublicUser = Depends(get_current_user)):
+ """
+ Get single lecture by lecture_id
+ """
+ return await get_lecture(request, lecture_id, current_user=current_user)
+
+
+@router.get("/coursechapter/{coursechapter_id}")
+async def api_get_lectures(request: Request,coursechapter_id: str, current_user: PublicUser = Depends(get_current_user)):
+ """
+ Get CourseChapter lectures
+ """
+ return await get_lectures(request,coursechapter_id, current_user)
+
+
+@router.put("/{lecture_id}")
+async def api_update_lecture(request: Request,lecture_object: Lecture, lecture_id: str, current_user: PublicUser = Depends(get_current_user)):
+ """
+ Update lecture by lecture_id
+ """
+ return await update_lecture(request,lecture_object, lecture_id, current_user)
+
+
+@router.delete("/{lecture_id}")
+async def api_delete_lecture(request: Request,lecture_id: str, current_user: PublicUser = Depends(get_current_user)):
+ """
+ Delete lecture by lecture_id
+ """
+ return await delete_lecture(request,lecture_id, current_user)
+
+# Video play
+@router.post("/video")
+async def api_create_video_lecture(request: Request,name: str = Form(), coursechapter_id: str = Form(), current_user: PublicUser = Depends(get_current_user), video_file: UploadFile | None = None):
+ """
+ Create new lecture
+ """
+ return await create_video_lecture(request,name, coursechapter_id, current_user, video_file)
diff --git a/src/routers/files.py b/src/routers/files.py
index a3169e63..d2cfb89d 100644
--- a/src/routers/files.py
+++ b/src/routers/files.py
@@ -1,4 +1,4 @@
-from fastapi import APIRouter, Depends, UploadFile, Form
+from fastapi import APIRouter, Depends, UploadFile, Form, Request
from src.dependencies.auth import get_current_user
from fastapi import HTTPException, status, UploadFile
@@ -10,32 +10,32 @@ router = APIRouter()
@router.post("/picture")
-async def api_create_picture_file(file_object: UploadFile, element_id: str = Form(), current_user: PublicUser = Depends(get_current_user)):
+async def api_create_picture_file(request: Request,file_object: UploadFile, lecture_id: str = Form(), current_user: PublicUser = Depends(get_current_user)):
"""
Create new picture file
"""
- return await create_picture_file(file_object, element_id)
+ return await create_picture_file(request,file_object, lecture_id)
@router.post("/video")
-async def api_create_video_file(file_object: UploadFile,element_id: str = Form(), current_user: PublicUser = Depends(get_current_user)):
+async def api_create_video_file(request: Request,file_object: UploadFile,lecture_id: str = Form(), current_user: PublicUser = Depends(get_current_user)):
"""
Create new video file
"""
- return await create_video_file(file_object, element_id)
+ return await create_video_file(request, file_object, lecture_id)
@router.get("/picture")
-async def api_get_picture_file(file_id: str, current_user: PublicUser = Depends(get_current_user)):
+async def api_get_picture_file(request: Request,file_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Get picture file
"""
- return await get_picture_file(file_id, current_user)
+ return await get_picture_file(request, file_id, current_user)
@router.get("/video")
-async def api_get_video_file(file_id: str, current_user: PublicUser = Depends(get_current_user)):
+async def api_get_video_file(request: Request,file_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Get video file
"""
- return await get_video_file(file_id, current_user)
+ return await get_video_file(request, file_id, current_user)
diff --git a/src/routers/houses.py b/src/routers/houses.py
index f1770ac8..164d5417 100644
--- a/src/routers/houses.py
+++ b/src/routers/houses.py
@@ -1,4 +1,4 @@
-from fastapi import APIRouter, Depends
+from fastapi import APIRouter, Depends, Request
from src.dependencies.auth import get_current_user
from src.services.houses import House, HouseInDB, create_house, get_house, get_houses, update_house, delete_house
@@ -9,41 +9,41 @@ router = APIRouter()
@router.post("/")
-async def api_create_house(house_object: House, current_user: PublicUser = Depends(get_current_user)):
+async def api_create_house(request: Request,house_object: House, current_user: PublicUser = Depends(get_current_user)):
"""
Create new house
"""
- return await create_house(house_object, current_user)
+ return await create_house(request, house_object, current_user)
@router.get("/{house_id}")
-async def api_get_house(house_id: str, current_user: PublicUser = Depends(get_current_user)):
+async def api_get_house(request: Request,house_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Get single House by house_id
"""
- return await get_house(house_id, current_user=current_user)
+ return await get_house(request, house_id, current_user=current_user)
@router.get("/page/{page}/limit/{limit}")
-async def api_get_house_by(page: int, limit: int):
+async def api_get_house_by(request: Request,page: int, limit: int):
"""
Get houses by page and limit
"""
- return await get_houses(page, limit)
+ return await get_houses(request, page, limit)
@router.put("/{house_id}")
-async def api_update_house(house_object: House, house_id: str, current_user: PublicUser = Depends(get_current_user)):
+async def api_update_house(request: Request,house_object: House, house_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Update House by house_id
"""
- return await update_house(house_object, house_id, current_user)
+ return await update_house(request, house_object, house_id, current_user)
@router.delete("/{house_id}")
-async def api_delete_house(house_id: str, current_user: PublicUser = Depends(get_current_user)):
+async def api_delete_house(request: Request,house_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Delete House by ID
"""
- return await delete_house(house_id, current_user)
+ return await delete_house(request, house_id, current_user)
diff --git a/src/routers/orgs.py b/src/routers/orgs.py
index 58fd8fdc..465a953b 100644
--- a/src/routers/orgs.py
+++ b/src/routers/orgs.py
@@ -1,6 +1,7 @@
-from fastapi import APIRouter, Depends
+
+from fastapi import APIRouter, Depends, Request
from src.dependencies.auth import get_current_user
-from src.services.orgs import Organization, create_org, delete_org, get_organization, get_organization_by_slug, get_orgs, get_orgs_by_user, update_org
+from src.services.orgs import Organization, create_org, delete_org, get_organization, get_organization_by_slug, get_orgs_by_user, update_org
from src.services.users import PublicUser, User
@@ -8,55 +9,49 @@ router = APIRouter()
@router.post("/")
-async def api_create_org(org_object: Organization, current_user: PublicUser = Depends(get_current_user)):
+async def api_create_org(request: Request, org_object: Organization, current_user: PublicUser = Depends(get_current_user)):
"""
Create new organization
"""
- return await create_org(org_object, current_user)
+ return await create_org(request, org_object, current_user)
@router.get("/{org_id}")
-async def api_get_org(org_id: str, current_user: PublicUser = Depends(get_current_user)):
+async def api_get_org(request: Request, org_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Get single Org by ID
"""
- return await get_organization(org_id)
+ return await get_organization(request, org_id)
+
@router.get("/slug/{org_slug}")
-async def api_get_org_by_slug(org_slug: str, current_user: User = Depends(get_current_user)):
+async def api_get_org_by_slug(request: Request, org_slug: str, current_user: User = Depends(get_current_user)):
"""
Get single Org by Slug
"""
- return await get_organization_by_slug(org_slug)
+ return await get_organization_by_slug(request, org_slug)
-@router.get("/page/{page}/limit/{limit}")
-async def api_get_org_by(page: int, limit: int):
- """
- Get orgs by page and limit
- """
- return await get_orgs(page, limit)
-
@router.get("/user/page/{page}/limit/{limit}")
-async def api_user_orgs(page: int, limit: int, current_user: PublicUser = Depends(get_current_user)):
+async def api_user_orgs(request: Request, page: int, limit: int, current_user: PublicUser = Depends(get_current_user)):
"""
Get orgs by page and limit by user
"""
- return await get_orgs_by_user(current_user.user_id, page, limit)
+ return await get_orgs_by_user(request, current_user.user_id, page, limit)
@router.put("/{org_id}")
-async def api_update_org(org_object: Organization, org_id: str, current_user: PublicUser = Depends(get_current_user)):
+async def api_update_org(request: Request, org_object: Organization, org_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Update Org by ID
"""
- return await update_org(org_object, org_id, current_user)
+ return await update_org(request, org_object, org_id, current_user)
@router.delete("/{org_id}")
-async def api_delete_org(org_id: str, current_user: PublicUser = Depends(get_current_user)):
+async def api_delete_org(request: Request, org_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Delete Org by ID
"""
- return await delete_org(org_id, current_user)
+ return await delete_org(request, org_id, current_user)
diff --git a/src/routers/roles.py b/src/routers/roles.py
index 9a1496d9..5efebe00 100644
--- a/src/routers/roles.py
+++ b/src/routers/roles.py
@@ -1,6 +1,5 @@
-from fastapi import APIRouter, Depends
+from fastapi import APIRouter, Depends, Request
from src.dependencies.auth import get_current_user
-
from src.services.roles import Role, create_role, delete_role, get_role, get_roles, update_role
from src.services.users import PublicUser, User
@@ -9,41 +8,41 @@ router = APIRouter()
@router.post("/")
-async def api_create_role(role_object: Role, current_user: PublicUser = Depends(get_current_user)):
+async def api_create_role(request: Request,role_object: Role, current_user: PublicUser = Depends(get_current_user)):
"""
Create new role
"""
- return await create_role(role_object, current_user)
+ return await create_role(request, role_object, current_user)
@router.get("/{role_id}")
-async def api_get_role(role_id: str):
+async def api_get_role(request: Request,role_id: str):
"""
Get single role by role_id
"""
- return await get_role(role_id)
+ return await get_role(request, role_id)
@router.get("/page/{page}/limit/{limit}")
-async def api_get_role_by(page: int, limit: int):
+async def api_get_role_by(request: Request,page: int, limit: int):
"""
Get roles by page and limit
"""
- return await get_roles(page, limit)
+ return await get_roles(request, page, limit)
@router.put("/{role_id}")
-async def api_update_role(role_object: Role, role_id: str, current_user: PublicUser = Depends(get_current_user)):
+async def api_update_role(request: Request,role_object: Role, role_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Update role by role_id
"""
- return await update_role(role_object, role_id, current_user)
+ return await update_role(request, role_object, role_id, current_user)
@router.delete("/{role_id}")
-async def api_delete_role(role_id: str, current_user: PublicUser = Depends(get_current_user)):
+async def api_delete_role(request: Request,role_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Delete role by ID
"""
- return await delete_role(role_id, current_user)
+ return await delete_role(request, role_id, current_user)
diff --git a/src/routers/users.py b/src/routers/users.py
index aea469a6..0ccc4818 100644
--- a/src/routers/users.py
+++ b/src/routers/users.py
@@ -9,13 +9,6 @@ from src.services.users import *
router = APIRouter()
-# DEPRECATED
-@router.get("/me")
-async def api_get_current_user_old(current_user: User = Depends(get_current_user)):
- """
- Get current user
- """
- return current_user.dict()
@router.get("/profile")
async def api_get_current_user(current_user: User = Depends(get_current_user)):
@@ -25,49 +18,49 @@ async def api_get_current_user(current_user: User = Depends(get_current_user)):
return current_user.dict()
@router.get("/profile_metadata")
-async def api_get_current_user_metadata(current_user: User = Depends(get_current_user)):
+async def api_get_current_user_metadata(request: Request,current_user: User = Depends(get_current_user)):
"""
Get current user
"""
- return await get_profile_metadata(current_user.dict())
+ return await get_profile_metadata(request , current_user.dict())
@router.get("/username/{username}")
-async def api_get_user_by_username(username: str):
+async def api_get_user_by_username(request: Request, username: str):
"""
Get single user by username
"""
- return await get_user(username)
+ return await get_user(request, username)
@router.get("/user_id/{user_id}")
-async def api_get_user_by_userid(user_id: str):
+async def api_get_user_by_userid(request: Request,user_id: str):
"""
Get single user by user_id
"""
- return await get_user_by_userid(user_id)
+ return await get_user_by_userid(request, user_id)
@router.post("/")
-async def api_create_user(user_object: UserWithPassword):
+async def api_create_user(request: Request,user_object: UserWithPassword):
"""
Create new user
"""
- return await create_user(user_object)
+ return await create_user(request, user_object)
@router.delete("/user_id/{user_id}")
-async def api_delete_user(user_id: str):
+async def api_delete_user(request: Request, user_id: str):
"""
Delete user by ID
"""
- return await delete_user(user_id)
+ return await delete_user(request, user_id)
@router.put("/user_id/{user_id}")
-async def api_update_user(user_object: UserWithPassword, user_id: str):
+async def api_update_user(request: Request, user_object: UserWithPassword, user_id: str):
"""
Update user by ID
"""
- return await update_user(user_id, user_object)
+ return await update_user(request, user_id, user_object)
diff --git a/src/services/courses/chapters.py b/src/services/courses/chapters.py
index 34829cc2..17391764 100644
--- a/src/services/courses/chapters.py
+++ b/src/services/courses/chapters.py
@@ -4,17 +4,16 @@ from typing import List
from uuid import uuid4
from pydantic import BaseModel
from src.services.courses.courses import Course, CourseInDB
-from src.services.courses.elements.elements import Element, ElementInDB
-from src.services.database import create_config_collection, check_database, create_database, learnhouseDB, learnhouseDB
+from src.services.courses.lectures.lectures import Lecture, LectureInDB
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
+from fastapi import HTTPException, status, Request, Response, BackgroundTasks, UploadFile, File
class CourseChapter(BaseModel):
name: str
description: str
- elements: list
+ lectures: list
class CourseChapterInDB(CourseChapter):
@@ -28,7 +27,7 @@ class CourseChapterInDB(CourseChapter):
class CourseChapterMetaData(BaseModel):
chapterOrder: List[str]
chapters: object
- elements: object
+ lectures: object
#### Classes ####################################################
@@ -37,15 +36,14 @@ class CourseChapterMetaData(BaseModel):
####################################################
-async def create_coursechapter(coursechapter_object: CourseChapter, course_id: str, current_user: PublicUser):
- await check_database()
- coursechapters = learnhouseDB["coursechapters"]
- courses = learnhouseDB["courses"]
+async def create_coursechapter(request: Request,coursechapter_object: CourseChapter, course_id: str, current_user: PublicUser):
+ coursechapters = request.app.db["coursechapters"]
+ courses = request.app.db["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)
+ hasRoleRights = await verify_user_rights_with_roles(request, "create", current_user.user_id, coursechapter_id)
if not hasRoleRights:
raise HTTPException(
@@ -65,16 +63,15 @@ async def create_coursechapter(coursechapter_object: CourseChapter, course_id: s
return coursechapter.dict()
-async def get_coursechapter(coursechapter_id: str, current_user: PublicUser):
- await check_database()
- coursechapters = learnhouseDB["coursechapters"]
+async def get_coursechapter(request: Request,coursechapter_id: str, current_user: PublicUser):
+ coursechapters = request.app.db["coursechapters"]
coursechapter = coursechapters.find_one(
{"coursechapter_id": coursechapter_id})
if coursechapter:
# verify course rights
- await verify_rights(coursechapter["course_id"], current_user, "read")
+ await verify_rights(request, coursechapter["course_id"], current_user, "read")
coursechapter = CourseChapter(**coursechapter)
return coursechapter
@@ -84,16 +81,15 @@ async def get_coursechapter(coursechapter_id: str, current_user: PublicUser):
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"]
+async def update_coursechapter(request: Request,coursechapter_object: CourseChapter, coursechapter_id: str, current_user: PublicUser):
+ coursechapters = request.app.db["coursechapters"]
coursechapter = coursechapters.find_one(
{"coursechapter_id": coursechapter_id})
if coursechapter:
# verify course rights
- await verify_rights(coursechapter["course_id"], current_user, "update")
+ await verify_rights(request, coursechapter["course_id"], current_user, "update")
creationDate = coursechapter["creationDate"]
# get today's date
@@ -112,18 +108,17 @@ async def update_coursechapter(coursechapter_object: CourseChapter, coursechapt
status_code=status.HTTP_409_CONFLICT, detail="Coursechapter does not exist")
-async def delete_coursechapter(coursechapter_id: str, current_user: PublicUser):
- await check_database()
+async def delete_coursechapter(request: Request,coursechapter_id: str, current_user: PublicUser):
- coursechapters = learnhouseDB["coursechapters"]
- courses = learnhouseDB["courses"]
+ coursechapters = request.app.db["coursechapters"]
+ courses = request.app.db["courses"]
coursechapter = coursechapters.find_one(
{"coursechapter_id": coursechapter_id})
if coursechapter:
# verify course rights
- await verify_rights(coursechapter["course_id"], current_user, "delete")
+ await verify_rights(request, coursechapter["course_id"], current_user, "delete")
isDeleted = coursechapters.delete_one(
{"coursechapter_id": coursechapter_id})
@@ -147,9 +142,8 @@ async def delete_coursechapter(coursechapter_id: str, current_user: PublicUser)
####################################################
-async def get_coursechapters(course_id: str, page: int = 1, limit: int = 10):
- await check_database()
- courses = learnhouseDB["coursechapters"]
+async def get_coursechapters(request: Request,course_id: str, page: int = 1, limit: int = 10):
+ courses = request.app.db["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(
@@ -158,11 +152,10 @@ 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"]
- elements = learnhouseDB["elements"]
+async def get_coursechapters_meta(request: Request,course_id: str, current_user: PublicUser):
+ coursechapters = request.app.db["coursechapters"]
+ courses = request.app.db["courses"]
+ lectures = request.app.db["lectures"]
coursechapters = coursechapters.find(
{"course_id": course_id}).sort("name", 1)
@@ -170,63 +163,61 @@ async def get_coursechapters_meta(course_id: str, current_user: PublicUser):
course = courses.find_one({"course_id": course_id})
course = Course(**course) # type: ignore
- # elements
- coursechapter_elementIds_global = []
+ # lectures
+ coursechapter_lectureIds_global = []
# chapters
chapters = {}
for coursechapter in coursechapters:
coursechapter = CourseChapterInDB(**coursechapter)
- coursechapter_elementIds = []
+ coursechapter_lectureIds = []
- for element in coursechapter.elements:
- coursechapter_elementIds.append(element)
- coursechapter_elementIds_global.append(element)
+ for lecture in coursechapter.lectures:
+ coursechapter_lectureIds.append(lecture)
+ coursechapter_lectureIds_global.append(lecture)
chapters[coursechapter.coursechapter_id] = {
- "id": coursechapter.coursechapter_id, "name": coursechapter.name, "elementIds": coursechapter_elementIds
+ "id": coursechapter.coursechapter_id, "name": coursechapter.name, "lectureIds": coursechapter_lectureIds
}
- # elements
- elements_list = {}
- for element in elements.find({"element_id": {"$in": coursechapter_elementIds_global}}):
- element = ElementInDB(**element)
- elements_list[element.element_id] = {
- "id": element.element_id, "name": element.name, "type": element.type, "content": element.content
+ # lectures
+ lectures_list = {}
+ for lecture in lectures.find({"lecture_id": {"$in": coursechapter_lectureIds_global}}):
+ lecture = LectureInDB(**lecture)
+ lectures_list[lecture.lecture_id] = {
+ "id": lecture.lecture_id, "name": lecture.name, "type": lecture.type, "content": lecture.content
}
final = {
"chapters": chapters,
"chapterOrder": course.chapters,
- "elements": elements_list
+ "lectures": lectures_list
}
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"]
+async def update_coursechapters_meta(request: Request,course_id: str, coursechapters_metadata: CourseChapterMetaData, current_user: PublicUser):
+ coursechapters = request.app.db["coursechapters"]
+ courses = request.app.db["courses"]
# update chapters in course
courseInDB = courses.update_one({"course_id": course_id}, {
"$set": {"chapters": coursechapters_metadata.chapterOrder}})
- # update elements in coursechapters
+ # update lectures in coursechapters
# TODO : performance/optimization improvement
for coursechapter in coursechapters_metadata.chapters.__dict__.items():
coursechapters.update_one({"coursechapter_id": coursechapter}, {
- "$set": {"elements": coursechapters_metadata.chapters[coursechapter]["elementIds"]}})
+ "$set": {"lectures": coursechapters_metadata.chapters[coursechapter]["lectureIds"]}}) # type: ignore
return {"detail": "coursechapters metadata updated"}
#### Security ####################################################
-async def verify_rights(course_id: str, current_user: PublicUser, action: str):
- await check_database()
- courses = learnhouseDB["courses"]
+async def verify_rights(request: Request,course_id: str, current_user: PublicUser, action: str):
+ courses = request.app.db["courses"]
course = courses.find_one({"course_id": course_id})
@@ -234,7 +225,7 @@ async def verify_rights(course_id: str, current_user: PublicUser, action: str):
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail=f"Course does not exist")
- hasRoleRights = await verify_user_rights_with_roles(action, current_user.user_id, course_id)
+ hasRoleRights = await verify_user_rights_with_roles(request, action, current_user.user_id, course_id)
isAuthor = current_user.user_id in course["authors"]
if not hasRoleRights and not isAuthor:
diff --git a/src/services/courses/collections.py b/src/services/courses/collections.py
index abb020f1..6c719819 100644
--- a/src/services/courses/collections.py
+++ b/src/services/courses/collections.py
@@ -3,7 +3,6 @@ from typing import List
from uuid import uuid4
from pydantic import BaseModel
from src.services.users import PublicUser, User
-from src.services.database import create_config_collection, check_database, create_database, learnhouseDB, learnhouseDB
from src.services.security import *
from fastapi import FastAPI, HTTPException, status, Request, Response, BackgroundTasks
from datetime import datetime
@@ -28,14 +27,13 @@ class CollectionInDB(Collection):
# CRUD
####################################################
-async def get_collection(collection_id: str, current_user: PublicUser):
- await check_database()
- collections = learnhouseDB["collections"]
+async def get_collection(request: Request,collection_id: str, current_user: PublicUser):
+ collections = request.app.db["collections"]
collection = collections.find_one({"collection_id": collection_id})
# verify collection rights
- await verify_collection_rights(collection_id, current_user, "read")
+ await verify_collection_rights(request, collection_id, current_user, "read")
if not collection:
raise HTTPException(
@@ -45,9 +43,8 @@ async def get_collection(collection_id: str, current_user: PublicUser):
return collection
-async def create_collection(collection_object: Collection, current_user: PublicUser):
- await check_database()
- collections = learnhouseDB["collections"]
+async def create_collection(request: Request,collection_object: Collection, current_user: PublicUser):
+ collections = request.app.db["collections"]
# find if collection already exists using name
isCollectionNameAvailable = collections.find_one(
@@ -75,13 +72,12 @@ async def create_collection(collection_object: Collection, current_user: PublicU
return collection.dict()
-async def update_collection(collection_object: Collection, collection_id: str, current_user: PublicUser):
- await check_database()
+async def update_collection(request: Request,collection_object: Collection, collection_id: str, current_user: PublicUser):
# verify collection rights
- await verify_collection_rights(collection_id, current_user, "update")
+ await verify_collection_rights(request, collection_id, current_user, "update")
- collections = learnhouseDB["collections"]
+ collections = request.app.db["collections"]
collection = collections.find_one({"collection_id": collection_id})
@@ -98,12 +94,11 @@ async def update_collection(collection_object: Collection, collection_id: str, c
return Collection(**updated_collection.dict())
-async def delete_collection(collection_id: str, current_user: PublicUser):
- await check_database()
+async def delete_collection(request: Request,collection_id: str, current_user: PublicUser):
- await verify_collection_rights(collection_id, current_user, "delete")
+ await verify_collection_rights(request, collection_id, current_user, "delete")
- collections = learnhouseDB["collections"]
+ collections = request.app.db["collections"]
collection = collections.find_one({"collection_id": collection_id})
@@ -124,10 +119,9 @@ async def delete_collection(collection_id: str, current_user: PublicUser):
####################################################
-async def get_collections(page: int = 1, limit: int = 10):
+async def get_collections(request: Request,page: int = 1, limit: int = 10):
## TODO : auth
- await check_database()
- collections = learnhouseDB["collections"]
+ collections = request.app.db["collections"]
# get all collections from database without ObjectId
all_collections = collections.find({}).sort(
@@ -141,7 +135,7 @@ async def get_collections(page: int = 1, limit: int = 10):
collection_courses = [course for course in collection.courses]
# add courses to collection
- courses = learnhouseDB["courses"]
+ courses = request.app.db["courses"]
collection.courses = []
collection.courses = courses.find(
{"course_id": {"$in": collection_courses}}, {'_id': 0})
@@ -153,9 +147,8 @@ async def get_collections(page: int = 1, limit: int = 10):
#### Security ####################################################
-async def verify_collection_rights(collection_id: str, current_user: PublicUser, action: str):
- await check_database()
- collections = learnhouseDB["collections"]
+async def verify_collection_rights(request: Request,collection_id: str, current_user: PublicUser, action: str):
+ collections = request.app.db["collections"]
collection = collections.find_one({"collection_id": collection_id})
@@ -163,7 +156,7 @@ async def verify_collection_rights(collection_id: str, current_user: PublicUser
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Collection does not exist")
- hasRoleRights = await verify_user_rights_with_roles(action, current_user.user_id, collection_id)
+ hasRoleRights = await verify_user_rights_with_roles(request, action, current_user.user_id, collection_id)
if not hasRoleRights:
raise HTTPException(
diff --git a/src/services/courses/courses.py b/src/services/courses/courses.py
index bfab213a..c27ef657 100644
--- a/src/services/courses/courses.py
+++ b/src/services/courses/courses.py
@@ -2,10 +2,9 @@ import json
from typing import List
from uuid import uuid4
from pydantic import BaseModel
-from src.services.courses.elements.elements import ElementInDB
+from src.services.courses.lectures.lectures import LectureInDB
from src.services.courses.thumbnails import upload_thumbnail
from src.services.users import PublicUser
-from src.services.database import check_database, learnhouseDB
from src.services.security import *
from fastapi import HTTPException, status, UploadFile
from datetime import datetime
@@ -36,7 +35,7 @@ class CourseInDB(Course):
class CourseChapter(BaseModel):
name: str
description: str
- elements: list
+ lectures: list
class CourseChapterInDB(CourseChapter):
@@ -54,14 +53,13 @@ class CourseChapterInDB(CourseChapter):
# CRUD
####################################################
-async def get_course(course_id: str, current_user: PublicUser):
- await check_database()
- courses = learnhouseDB["courses"]
+async def get_course(request: Request,course_id: str, current_user: PublicUser):
+ courses = request.app.db["courses"]
course = courses.find_one({"course_id": course_id})
# verify course rights
- await verify_rights(course_id, current_user, "read")
+ await verify_rights(request,course_id, current_user, "read")
if not course:
raise HTTPException(
@@ -71,15 +69,14 @@ async def get_course(course_id: str, current_user: PublicUser):
return course
-async def get_course_meta(course_id: str, current_user: PublicUser):
- await check_database()
- courses = learnhouseDB["courses"]
- coursechapters = learnhouseDB["coursechapters"]
+async def get_course_meta(request: Request,course_id: str, current_user: PublicUser):
+ courses = request.app.db["courses"]
+ coursechapters = request.app.db["coursechapters"]
course = courses.find_one({"course_id": course_id})
- elements = learnhouseDB["elements"]
+ lectures = request.app.db["lectures"]
# verify course rights
- await verify_rights(course_id, current_user, "read")
+ await verify_rights(request,course_id, current_user, "read")
if not course:
raise HTTPException(
@@ -88,52 +85,51 @@ async def get_course_meta(course_id: str, current_user: PublicUser):
coursechapters = coursechapters.find(
{"course_id": course_id}).sort("name", 1)
- # elements
- coursechapter_elementIds_global = []
+ # lectures
+ coursechapter_lectureIds_global = []
# chapters
chapters = {}
for coursechapter in coursechapters:
coursechapter = CourseChapterInDB(**coursechapter)
- coursechapter_elementIds = []
+ coursechapter_lectureIds = []
- for element in coursechapter.elements:
- coursechapter_elementIds.append(element)
- coursechapter_elementIds_global.append(element)
+ for lecture in coursechapter.lectures:
+ coursechapter_lectureIds.append(lecture)
+ coursechapter_lectureIds_global.append(lecture)
chapters[coursechapter.coursechapter_id] = {
- "id": coursechapter.coursechapter_id, "name": coursechapter.name, "elementIds": coursechapter_elementIds
+ "id": coursechapter.coursechapter_id, "name": coursechapter.name, "lectureIds": coursechapter_lectureIds
}
- # elements
- elements_list = {}
- for element in elements.find({"element_id": {"$in": coursechapter_elementIds_global}}):
- element = ElementInDB(**element)
- elements_list[element.element_id] = {
- "id": element.element_id, "name": element.name, "type": element.type, "content": element.content
+ # lectures
+ lectures_list = {}
+ for lecture in lectures.find({"lecture_id": {"$in": coursechapter_lectureIds_global}}):
+ lecture = LectureInDB(**lecture)
+ lectures_list[lecture.lecture_id] = {
+ "id": lecture.lecture_id, "name": lecture.name, "type": lecture.type, "content": lecture.content
}
- chapters_list_with_elements = []
+ chapters_list_with_lectures = []
for chapter in chapters:
- chapters_list_with_elements.append(
- {"id": chapters[chapter]["id"], "name": chapters[chapter]["name"], "elements": [elements_list[element] for element in chapters[chapter]["elementIds"]]})
+ chapters_list_with_lectures.append(
+ {"id": chapters[chapter]["id"], "name": chapters[chapter]["name"], "lectures": [lectures_list[lecture] for lecture in chapters[chapter]["lectureIds"]]})
course = Course(**course)
return {
"course": course,
- "chapters": chapters_list_with_elements,
+ "chapters": chapters_list_with_lectures,
}
-async def create_course(course_object: Course, org_id: str, current_user: PublicUser, thumbnail_file: UploadFile | None = None):
- await check_database()
- courses = learnhouseDB["courses"]
+async def create_course(request: Request,course_object: Course, org_id: str, current_user: PublicUser, thumbnail_file: UploadFile | None = None):
+ courses = request.app.db["courses"]
# generate course_id with uuid4
course_id = str(f"course_{uuid4()}")
# TODO(fix) : the implementation here is clearly not the best one (this entire function)
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(request, "create", current_user.user_id, course_id)
if not hasRoleRights:
raise HTTPException(
@@ -156,13 +152,12 @@ async def create_course(course_object: Course, org_id: str, current_user: Public
return course.dict()
-async def update_course_thumbnail(course_id: str, current_user: PublicUser, thumbnail_file: UploadFile | None = None):
- await check_database()
+async def update_course_thumbnail(request: Request,course_id: str, current_user: PublicUser, thumbnail_file: UploadFile | None = None):
# verify course rights
- await verify_rights(course_id, current_user, "update")
+ await verify_rights(request, course_id, current_user, "update")
- courses = learnhouseDB["courses"]
+ courses = request.app.db["courses"]
course = courses.find_one({"course_id": course_id})
# TODO(fix) : the implementation here is clearly not the best one
@@ -187,13 +182,12 @@ async def update_course_thumbnail(course_id: str, current_user: PublicUser, thum
status_code=status.HTTP_409_CONFLICT, detail="Course does not exist")
-async def update_course(course_object: Course, course_id: str, current_user: PublicUser):
- await check_database()
+async def update_course(request: Request,course_object: Course, course_id: str, current_user: PublicUser):
# verify course rights
- await verify_rights(course_id, current_user, "update")
+ await verify_rights(request, course_id, current_user, "update")
- courses = learnhouseDB["courses"]
+ courses = request.app.db["courses"]
course = courses.find_one({"course_id": course_id})
@@ -217,13 +211,12 @@ async def update_course(course_object: Course, course_id: str, current_user: Pub
status_code=status.HTTP_409_CONFLICT, detail="Course does not exist")
-async def delete_course(course_id: str, current_user: PublicUser):
- await check_database()
+async def delete_course(request: Request,course_id: str, current_user: PublicUser):
# verify course rights
- await verify_rights(course_id, current_user, "delete")
+ await verify_rights(request, course_id, current_user, "delete")
- courses = learnhouseDB["courses"]
+ courses = request.app.db["courses"]
course = courses.find_one({"course_id": course_id})
@@ -244,9 +237,8 @@ async def delete_course(course_id: str, current_user: PublicUser):
####################################################
-async def get_courses(page: int = 1, limit: int = 10, org_id: str | None = None):
- await check_database()
- courses = learnhouseDB["courses"]
+async def get_courses(request: Request,page: int = 1, limit: int = 10, org_id: str | None = None):
+ courses = request.app.db["courses"]
# TODO : Get only courses that user is admin/has roles of
# get all courses from database
all_courses = courses.find({"org_id": org_id}).sort(
@@ -258,9 +250,8 @@ async def get_courses(page: int = 1, limit: int = 10, org_id: str | None = None)
#### Security ####################################################
-async def verify_rights(course_id: str, current_user: PublicUser, action: str):
- await check_database()
- courses = learnhouseDB["courses"]
+async def verify_rights(request: Request,course_id: str, current_user: PublicUser, action: str):
+ courses = request.app.db["courses"]
course = courses.find_one({"course_id": course_id})
@@ -268,7 +259,7 @@ async def verify_rights(course_id: str, current_user: PublicUser, action: str):
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)
+ hasRoleRights = await verify_user_rights_with_roles(request, action, current_user.user_id, course_id)
isAuthor = current_user.user_id in course["authors"]
if not hasRoleRights and not isAuthor:
diff --git a/src/services/courses/elements/elements.py b/src/services/courses/elements/elements.py
deleted file mode 100644
index 58b24202..00000000
--- a/src/services/courses/elements/elements.py
+++ /dev/null
@@ -1,153 +0,0 @@
-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
- type: str
- content: object
-
-
-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"]
- coursechapters = learnhouseDB["coursechapters"]
-
- # 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())
-
- # update chapter
- coursechapters.update_one({"coursechapter_id": coursechapter_id}, {
- "$addToSet": {"elements": element_id}})
-
- 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
diff --git a/src/services/courses/lectures/lectures.py b/src/services/courses/lectures/lectures.py
new file mode 100644
index 00000000..ad43f8a8
--- /dev/null
+++ b/src/services/courses/lectures/lectures.py
@@ -0,0 +1,147 @@
+from pydantic import BaseModel
+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 Lecture(BaseModel):
+ name: str
+ type: str
+ content: object
+
+
+class LectureInDB(Lecture):
+ lecture_id: str
+ coursechapter_id: str
+ creationDate: str
+ updateDate: str
+
+#### Classes ####################################################
+
+
+####################################################
+# CRUD
+####################################################
+
+
+async def create_lecture(request: Request,lecture_object: Lecture, coursechapter_id: str, current_user: PublicUser):
+ lectures = request.app.db["lectures"]
+ coursechapters = request.app.db["coursechapters"]
+
+ # generate lecture_id
+ lecture_id = str(f"lecture_{uuid4()}")
+
+ hasRoleRights = await verify_user_rights_with_roles(request, "create", current_user.user_id, lecture_id)
+
+ if not hasRoleRights:
+ raise HTTPException(
+ status_code=status.HTTP_409_CONFLICT, detail="Roles : Insufficient rights to perform this action")
+
+ # create lecture
+ lecture = LectureInDB(**lecture_object.dict(), creationDate=str(
+ datetime.now()), coursechapter_id=coursechapter_id, updateDate=str(datetime.now()), lecture_id=lecture_id)
+ lectures.insert_one(lecture.dict())
+
+ # update chapter
+ coursechapters.update_one({"coursechapter_id": coursechapter_id}, {
+ "$addToSet": {"lectures": lecture_id}})
+
+ return lecture
+
+
+async def get_lecture(request: Request,lecture_id: str, current_user: PublicUser):
+ lectures = request.app.db["lectures"]
+
+ lecture = lectures.find_one({"lecture_id": lecture_id})
+
+ # verify course rights
+ hasRoleRights = await verify_user_rights_with_roles(request,"read", current_user.user_id, lecture_id)
+
+ if not hasRoleRights:
+ raise HTTPException(
+ status_code=status.HTTP_409_CONFLICT, detail="Roles : Insufficient rights to perform this action")
+
+ if not lecture:
+ raise HTTPException(
+ status_code=status.HTTP_409_CONFLICT, detail="Course does not exist")
+
+ lecture = LectureInDB(**lecture)
+ return lecture
+
+
+async def update_lecture(request: Request,lecture_object: Lecture, lecture_id: str, current_user: PublicUser):
+
+ # verify course rights
+ await verify_user_rights_with_roles(request, "update", current_user.user_id, lecture_id)
+
+ lectures = request.app.db["lectures"]
+
+ lecture = lectures.find_one({"lecture_id": lecture_id})
+
+ if lecture:
+ creationDate = lecture["creationDate"]
+
+ # get today's date
+ datetime_object = datetime.now()
+
+ updated_course = LectureInDB(
+ lecture_id=lecture_id, coursechapter_id=lecture["coursechapter_id"], creationDate=creationDate, updateDate=str(datetime_object), **lecture_object.dict())
+
+ lectures.update_one({"lecture_id": lecture_id}, {
+ "$set": updated_course.dict()})
+
+ return LectureInDB(**updated_course.dict())
+
+ else:
+ raise HTTPException(
+ status_code=status.HTTP_409_CONFLICT, detail="lecture does not exist")
+
+
+async def delete_lecture(request: Request,lecture_id: str, current_user: PublicUser):
+
+ # verify course rights
+ await verify_user_rights_with_roles(request,"delete", current_user.user_id, lecture_id)
+
+ lectures = request.app.db["lectures"]
+
+ lecture = lectures.find_one({"lecture_id": lecture_id})
+
+ if not lecture:
+ raise HTTPException(
+ status_code=status.HTTP_409_CONFLICT, detail="lecture does not exist")
+
+ isDeleted = lectures.delete_one({"lecture_id": lecture_id})
+
+ if isDeleted:
+ return {"detail": "lecture deleted"}
+ else:
+ raise HTTPException(
+ status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database")
+
+####################################################
+# Misc
+####################################################
+
+
+async def get_lectures(request: Request,coursechapter_id: str, current_user: PublicUser):
+ lectures = request.app.db["lectures"]
+
+ # verify course rights
+ await verify_user_rights_with_roles(request,"read", current_user.user_id, coursechapter_id)
+
+ lectures = lectures.find({"coursechapter_id": coursechapter_id})
+
+ if not lectures:
+ raise HTTPException(
+ status_code=status.HTTP_409_CONFLICT, detail="No lectures found")
+
+ lectures_list = []
+
+ for lecture in lectures:
+ lectures_list.append(Lecture(**lecture))
+
+ return lectures_list
diff --git a/src/services/courses/elements/uploads/videos.py b/src/services/courses/lectures/uploads/videos.py
similarity index 69%
rename from src/services/courses/elements/uploads/videos.py
rename to src/services/courses/lectures/uploads/videos.py
index 2ca74b6f..78106531 100644
--- a/src/services/courses/elements/uploads/videos.py
+++ b/src/services/courses/lectures/uploads/videos.py
@@ -1,14 +1,14 @@
import os
-async def upload_video(video_file, element_id):
+async def upload_video(video_file, lecture_id):
contents = video_file.file.read()
video_format = video_file.filename.split(".")[-1]
# create folder
- os.mkdir(f"content/uploads/video/{element_id}")
+ os.mkdir(f"content/uploads/video/{lecture_id}")
try:
- with open(f"content/uploads/video/{element_id}/video.{video_format}", 'wb') as f:
+ with open(f"content/uploads/video/{lecture_id}/video.{video_format}", 'wb') as f:
f.write(contents)
f.close()
diff --git a/src/services/courses/elements/video.py b/src/services/courses/lectures/video.py
similarity index 53%
rename from src/services/courses/elements/video.py
rename to src/services/courses/lectures/video.py
index ed096836..de1d9821 100644
--- a/src/services/courses/elements/video.py
+++ b/src/services/courses/lectures/video.py
@@ -1,21 +1,19 @@
from pydantic import BaseModel
-from src.services.database import check_database, learnhouseDB
from src.services.security import verify_user_rights_with_roles
-from src.services.courses.elements.uploads.videos import upload_video
+from src.services.courses.lectures.uploads.videos import upload_video
from src.services.users import PublicUser
-from src.services.courses.elements.elements import ElementInDB
-from fastapi import HTTPException, status, UploadFile
+from src.services.courses.lectures.lectures import LectureInDB
+from fastapi import HTTPException, status, UploadFile, Request
from uuid import uuid4
from datetime import datetime
-async def create_video_element(name: str, coursechapter_id: str, current_user: PublicUser, video_file: UploadFile | None = None):
- await check_database()
- elements = learnhouseDB["elements"]
- coursechapters = learnhouseDB["coursechapters"]
+async def create_video_lecture(request: Request,name: str, coursechapter_id: str, current_user: PublicUser, video_file: UploadFile | None = None):
+ lectures = request.app.db["lectures"]
+ coursechapters = request.app.db["coursechapters"]
- # generate element_id
- element_id = str(f"element_{uuid4()}")
+ # generate lecture_id
+ lecture_id = str(f"lecture_{uuid4()}")
# check if video_file is not None
if not video_file:
@@ -23,41 +21,41 @@ async def create_video_element(name: str, coursechapter_id: str, current_user:
status_code=status.HTTP_409_CONFLICT, detail="Video : No video file provided")
video_format = video_file.filename.split(".")[-1]
- element_object = ElementInDB(
- element_id=element_id,
+ lecture_object = LectureInDB(
+ lecture_id=lecture_id,
coursechapter_id=coursechapter_id,
name=name,
type="video",
content={
"video": {
"filename": "video."+video_format,
- "element_id": element_id,
+ "lecture_id": lecture_id,
}
},
creationDate=str(datetime.now()),
updateDate=str(datetime.now()),
)
- hasRoleRights = await verify_user_rights_with_roles("create", current_user.user_id, element_id)
+ hasRoleRights = await verify_user_rights_with_roles(request,"create", current_user.user_id, lecture_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())
- elements.insert_one(element.dict())
+ # create lecture
+ lecture = LectureInDB(**lecture_object.dict())
+ lectures.insert_one(lecture.dict())
# upload video
if video_file:
print("uploading video")
# get videofile format
- await upload_video(video_file, element_id)
+ await upload_video(video_file, lecture_id)
# todo : choose whether to update the chapter or not
# update chapter
coursechapters.update_one({"coursechapter_id": coursechapter_id}, {
- "$addToSet": {"elements": element_id}})
+ "$addToSet": {"lectures": lecture_id}})
- return element
+ return lecture
diff --git a/src/services/database.py b/src/services/database.py
deleted file mode 100644
index 4e92f092..00000000
--- a/src/services/database.py
+++ /dev/null
@@ -1,27 +0,0 @@
-import pymongo
-
-# MongoDB
-client = pymongo.MongoClient("mongodb://learnhouse:learnhouse@mongo:27017/") # type: ignore
-learnhouseDB = client["learnhouse"]
-
-
-async def create_database():
- learnhouseDB = client["learnhouse"]
-
-
-async def check_database():
- # Check if database learnhouse exists
-
- if "learnhouse" in client.list_database_names():
- return True
- else:
- await create_database()
-
-
-async def create_config_collection():
- # Create config collection if it doesn't exist
-
- learnhouseDB = client["learnhouse"]
- config = learnhouseDB["config"]
- config.insert_one({"name": "LearnHouse", "date": "2022"})
- return config.find_one()
diff --git a/src/services/files/pictures.py b/src/services/files/pictures.py
index 709d10a8..7bbf890b 100644
--- a/src/services/files/pictures.py
+++ b/src/services/files/pictures.py
@@ -1,7 +1,6 @@
from uuid import uuid4
from pydantic import BaseModel
-from src.services.database import check_database, learnhouseDB, learnhouseDB
-from fastapi import HTTPException, status, UploadFile
+from fastapi import HTTPException, status, UploadFile, Request
from fastapi.responses import StreamingResponse
import os
@@ -14,12 +13,11 @@ class PhotoFile(BaseModel):
file_name: str
file_size: int
file_type: str
- element_id: str
+ lecture_id: str
-async def create_picture_file(picture_file: UploadFile, element_id: str):
- await check_database()
- photos = learnhouseDB["files"]
+async def create_picture_file(request: Request,picture_file: UploadFile, lecture_id: str):
+ photos = request.app.db["files"]
# generate file_id
file_id = str(f"file_{uuid4()}")
@@ -51,15 +49,15 @@ async def create_picture_file(picture_file: UploadFile, element_id: str):
file_name=file_name,
file_size=file_size,
file_type=file_type,
- element_id=element_id
+ lecture_id=lecture_id
)
- # create folder for element
- if not os.path.exists(f"content/uploads/files/pictures/{element_id}"):
- os.mkdir(f"content/uploads/files/pictures/{element_id}")
+ # create folder for lecture
+ if not os.path.exists(f"content/uploads/files/pictures/{lecture_id}"):
+ os.mkdir(f"content/uploads/files/pictures/{lecture_id}")
# upload file to server
- with open(f"content/uploads/files/pictures/{element_id}/{file_id}.{file_format}", 'wb') as f:
+ with open(f"content/uploads/files/pictures/{lecture_id}/{file_id}.{file_format}", 'wb') as f:
f.write(file)
f.close()
@@ -73,9 +71,8 @@ async def create_picture_file(picture_file: UploadFile, element_id: str):
return uploadable_file
-async def get_picture_object(file_id: str):
- await check_database()
- photos = learnhouseDB["files"]
+async def get_picture_object(request: Request,file_id: str):
+ photos = request.app.db["files"]
photo_file = photos.find_one({"file_id": file_id})
@@ -88,9 +85,8 @@ async def get_picture_object(file_id: str):
status_code=status.HTTP_409_CONFLICT, detail="Photo file does not exist")
-async def get_picture_file(file_id: str, current_user: PublicUser):
- await check_database()
- photos = learnhouseDB["files"]
+async def get_picture_file(request: Request,file_id: str, current_user: PublicUser):
+ photos = request.app.db["files"]
photo_file = photos.find_one({"file_id": file_id})
@@ -106,9 +102,9 @@ async def get_picture_file(file_id: str, current_user: PublicUser):
# stream file
photo_file = PhotoFile(**photo_file)
file_format = photo_file.file_format
- element_id = photo_file.element_id
+ lecture_id = photo_file.lecture_id
file = open(
- f"content/uploads/files/pictures/{element_id}/{file_id}.{file_format}", 'rb')
+ f"content/uploads/files/pictures/{lecture_id}/{file_id}.{file_format}", 'rb')
return StreamingResponse(file, media_type=photo_file.file_type)
else:
diff --git a/src/services/files/videos.py b/src/services/files/videos.py
index df18caa3..dd194c1d 100644
--- a/src/services/files/videos.py
+++ b/src/services/files/videos.py
@@ -1,8 +1,7 @@
from uuid import uuid4
from pydantic import BaseModel
import os
-from src.services.database import check_database, learnhouseDB, learnhouseDB
-from fastapi import HTTPException, status, UploadFile
+from fastapi import HTTPException, status, UploadFile,Request
from fastapi.responses import StreamingResponse
from src.services.users import PublicUser
@@ -14,12 +13,11 @@ class VideoFile(BaseModel):
file_name: str
file_size: int
file_type: str
- element_id: str
+ lecture_id: str
-async def create_video_file(video_file: UploadFile, element_id: str):
- await check_database()
- files = learnhouseDB["files"]
+async def create_video_file(request: Request,video_file: UploadFile, lecture_id: str):
+ files = request.app.db["files"]
# generate file_id
file_id = str(f"file_{uuid4()}")
@@ -51,15 +49,15 @@ async def create_video_file(video_file: UploadFile, element_id: str):
file_name=file_name,
file_size=file_size,
file_type=file_type,
- element_id=element_id
+ lecture_id=lecture_id
)
- # create folder for element
- if not os.path.exists(f"content/uploads/files/videos/{element_id}"):
- os.mkdir(f"content/uploads/files/videos/{element_id}")
+ # create folder for lecture
+ if not os.path.exists(f"content/uploads/files/videos/{lecture_id}"):
+ os.mkdir(f"content/uploads/files/videos/{lecture_id}")
# upload file to server
- with open(f"content/uploads/files/videos/{element_id}/{file_id}.{file_format}", 'wb') as f:
+ with open(f"content/uploads/files/videos/{lecture_id}/{file_id}.{file_format}", 'wb') as f:
f.write(file)
f.close()
@@ -73,9 +71,8 @@ async def create_video_file(video_file: UploadFile, element_id: str):
return uploadable_file
-async def get_video_object(file_id: str, current_user: PublicUser):
- await check_database()
- photos = learnhouseDB["files"]
+async def get_video_object(request: Request,file_id: str, current_user: PublicUser):
+ photos = request.app.db["files"]
video_file = photos.find_one({"file_id": file_id})
@@ -88,9 +85,8 @@ async def get_video_object(file_id: str, current_user: PublicUser):
status_code=status.HTTP_409_CONFLICT, detail="Photo file does not exist")
-async def get_video_file(file_id: str, current_user: PublicUser):
- await check_database()
- photos = learnhouseDB["files"]
+async def get_video_file(request: Request,file_id: str, current_user: PublicUser):
+ photos = request.app.db["files"]
video_file = photos.find_one({"file_id": file_id})
@@ -106,11 +102,11 @@ async def get_video_file(file_id: str, current_user: PublicUser):
# stream file
video_file = VideoFile(**video_file)
file_format = video_file.file_format
- element_id = video_file.element_id
+ lecture_id = video_file.lecture_id
def iterfile(): #
#
- with open(f"content/uploads/files/videos/{element_id}/{file_id}.{file_format}", mode="rb") as file_like:
+ with open(f"content/uploads/files/videos/{lecture_id}/{file_id}.{file_format}", mode="rb") as file_like:
yield from file_like
return StreamingResponse(iterfile(), media_type=video_file.file_type)
diff --git a/src/services/houses.py b/src/services/houses.py
index 957ac35a..75ebd90d 100644
--- a/src/services/houses.py
+++ b/src/services/houses.py
@@ -3,7 +3,6 @@ from typing import List
from uuid import uuid4
from pydantic import BaseModel
from src.services.users import PublicUser, User
-from src.services.database import create_config_collection, check_database, create_database, learnhouseDB, learnhouseDB
from src.services.security import *
from fastapi import FastAPI, HTTPException, status, Request, Response, BackgroundTasks
from datetime import datetime
@@ -28,14 +27,13 @@ class HouseInDB(House):
# TODO : Add house photo upload and delete
-async def get_house(house_id: str, current_user: PublicUser):
- await check_database()
- houses = learnhouseDB["houses"]
+async def get_house(request: Request, house_id: str, current_user: PublicUser):
+ houses = request.app.db["houses"]
house = houses.find_one({"house_id": house_id})
# verify house rights
- await verify_house_rights(house_id, current_user, "read")
+ await verify_house_rights(request,house_id, current_user, "read")
if not house:
raise HTTPException(
@@ -45,9 +43,8 @@ async def get_house(house_id: str, current_user: PublicUser):
return house
-async def create_house(house_object: House, current_user: PublicUser):
- await check_database()
- houses = learnhouseDB["houses"]
+async def create_house(request: Request,house_object: House, current_user: PublicUser):
+ houses = request.app.db["houses"]
# find if house already exists using name
isHouseAvailable = houses.find_one({"name": house_object.name})
@@ -59,7 +56,7 @@ async def create_house(house_object: House, current_user: PublicUser):
# generate house_id with uuid4
house_id = str(f"house_{uuid4()}")
- hasRoleRights = await verify_user_rights_with_roles("create", current_user.user_id, house_id)
+ hasRoleRights = await verify_user_rights_with_roles(request, "create", current_user.user_id, house_id)
if not hasRoleRights:
raise HTTPException(
@@ -78,13 +75,12 @@ async def create_house(house_object: House, current_user: PublicUser):
return house.dict()
-async def update_house(house_object: House, house_id: str, current_user: PublicUser):
- await check_database()
+async def update_house(request: Request,house_object: House, house_id: str, current_user: PublicUser):
# verify house rights
- await verify_house_rights(house_id, current_user, "update")
+ await verify_house_rights(request,house_id, current_user, "update")
- houses = learnhouseDB["houses"]
+ houses = request.app.db["houses"]
house = houses.find_one({"house_id": house_id})
@@ -107,13 +103,12 @@ async def update_house(house_object: House, house_id: str, current_user: PublicU
-async def delete_house(house_id: str, current_user: PublicUser):
- await check_database()
+async def delete_house(request: Request,house_id: str, current_user: PublicUser):
# verify house rights
- await verify_house_rights(house_id, current_user, "delete")
+ await verify_house_rights(request,house_id, current_user, "delete")
- houses = learnhouseDB["houses"]
+ houses = request.app.db["houses"]
house = houses.find_one({"house_id": house_id})
@@ -130,9 +125,8 @@ async def delete_house(house_id: str, current_user: PublicUser):
status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database")
-async def get_houses(page: int = 1, limit: int = 10):
- await check_database()
- houses = learnhouseDB["houses"]
+async def get_houses(request: Request,page: int = 1, limit: int = 10):
+ houses = request.app.db["houses"]
# TODO : Get only houses that user is admin/has roles of
# get all houses from database
all_houses = houses.find().sort("name", 1).skip(10 * (page - 1)).limit(limit)
@@ -142,9 +136,8 @@ async def get_houses(page: int = 1, limit: int = 10):
#### Security ####################################################
-async def verify_house_rights(house_id: str, current_user: PublicUser, action: str):
- await check_database()
- houses = learnhouseDB["houses"]
+async def verify_house_rights(request: Request,house_id: str, current_user: PublicUser, action: str):
+ houses = request.app.db["houses"]
house = houses.find_one({"house_id": house_id})
@@ -152,7 +145,7 @@ async def verify_house_rights(house_id: str, current_user: PublicUser, action: s
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="House does not exist")
- hasRoleRights = await verify_user_rights_with_roles(action, current_user.user_id, house_id)
+ hasRoleRights = await verify_user_rights_with_roles(request,action, current_user.user_id, house_id)
isOwner = current_user.user_id in house["owners"]
if not hasRoleRights and not isOwner:
diff --git a/src/services/mocks/initial.py b/src/services/mocks/initial.py
index 4dcfe207..ba8744b7 100644
--- a/src/services/mocks/initial.py
+++ b/src/services/mocks/initial.py
@@ -1,14 +1,14 @@
+import requests
from datetime import datetime
from fileinput import filename
from pprint import pprint
from uuid import uuid4
-import requests
-from fastapi import File, UploadFile
+from fastapi import File, UploadFile, Request
from src.services.courses.chapters import CourseChapter, create_coursechapter
-from src.services.courses.elements.elements import Element, create_element
+from src.services.courses.lectures.lectures import Lecture, create_lecture
from src.services.courses.thumbnails import upload_thumbnail
from src.services.users import PublicUser, User, UserInDB, UserWithPassword
-from src.services.database import learnhouseDB
+
from src.services.orgs import OrganizationInDB, Organization, create_org
from src.services.roles import Permission, Elements, create_role
from src.services.users import create_user
@@ -17,7 +17,7 @@ from src.services.roles import Role
from faker import Faker
-async def create_initial_data():
+async def create_initial_data(request: Request):
fake = Faker(['en_US'])
fake_multilang = Faker(
['en_US', 'de_DE', 'ja_JP', 'es_ES', 'it_IT', 'pt_BR', 'ar_PS'])
@@ -25,7 +25,7 @@ async def create_initial_data():
# Create users
########################################
- database_users = learnhouseDB["users"]
+ database_users = request.app.db["users"]
database_users.delete_many({})
users = []
@@ -36,7 +36,7 @@ async def create_initial_data():
user_type="isOwner",
)
- admin_user = await create_user(admin_user)
+ admin_user = await create_user(request, admin_user)
for i in range(0, 20):
user = UserWithPassword(
@@ -49,10 +49,10 @@ async def create_initial_data():
users.append(user)
for user in users:
- await create_user(user)
+ await create_user(request, user)
# find admin user
- users = learnhouseDB["users"]
+ users = request.app.db["users"]
admin_user = users.find_one({"username": "admin"})
if admin_user:
@@ -64,7 +64,7 @@ async def create_initial_data():
# Create organizations
########################################
- database_orgs = learnhouseDB["organizations"]
+ database_orgs = request.app.db["organizations"]
database_orgs.delete_many({})
organizations = []
@@ -79,12 +79,12 @@ async def create_initial_data():
slug=slug,
)
organizations.append(org)
- await create_org(org, current_user)
+ await create_org(request, org, current_user)
# Create roles
########################################
- database_roles = learnhouseDB["roles"]
+ database_roles = request.app.db["roles"]
database_roles.delete_many({})
roles = []
@@ -104,24 +104,24 @@ async def create_initial_data():
collections=["*"],
organizations=["*"],
coursechapters=["*"],
- elements=["*"],
+ lectures=["*"],
),
linked_users=[admin_user.user_id],
)
roles.append(admin_role)
- await create_role(admin_role, current_user)
+ await create_role(request, admin_role, current_user)
# Generate Courses and CourseChapters
########################################
- database_courses = learnhouseDB["courses"]
- database_chapters = learnhouseDB["coursechapters"]
+ database_courses = request.app.db["courses"]
+ database_chapters = request.app.db["coursechapters"]
database_courses.delete_many({})
database_chapters.delete_many({})
courses = []
- orgs = learnhouseDB["organizations"]
+ orgs = request.app.db["organizations"]
if orgs.count_documents({}) > 0:
for org in orgs.find():
@@ -150,7 +150,7 @@ async def create_initial_data():
authors=[current_user.user_id],
)
- courses = learnhouseDB["courses"]
+ courses = request.app.db["courses"]
name_in_disk = f"test_mock{course_id}.jpeg"
image = requests.get(
@@ -168,16 +168,16 @@ async def create_initial_data():
coursechapter = CourseChapter(
name=fake_multilang.unique.sentence(),
description=fake_multilang.unique.text(),
- elements=[],
+ lectures=[],
)
- coursechapter = await create_coursechapter(coursechapter, course_id, current_user)
+ coursechapter = await create_coursechapter(request,coursechapter, course_id, current_user)
pprint(coursechapter)
if coursechapter:
- # create elements
+ # create lectures
for i in range(0, 5):
- element = Element(
+ lecture = Lecture(
name=fake_multilang.unique.sentence(),
type="dynamic",
content={},
)
- element = await create_element(element, coursechapter['coursechapter_id'], current_user)
+ lecture = await create_lecture(request,lecture, coursechapter['coursechapter_id'], current_user)
diff --git a/src/services/orgs.py b/src/services/orgs.py
index bb37d8dd..4c16e15a 100644
--- a/src/services/orgs.py
+++ b/src/services/orgs.py
@@ -3,7 +3,6 @@ from typing import List
from uuid import uuid4
from pydantic import BaseModel
from src.services.users import PublicUser, User
-from src.services.database import create_config_collection, check_database, create_database, learnhouseDB, learnhouseDB
from src.services.security import *
from fastapi import FastAPI, HTTPException, status, Request, Response, BackgroundTasks
from datetime import datetime
@@ -15,14 +14,15 @@ class Organization(BaseModel):
name: str
description: str
email: str
- slug :str
+ slug: str
class OrganizationInDB(Organization):
org_id: str
owners: List[str]
admins: List[str]
-
+
+
class PublicOrganization(Organization):
name: str
description: str
@@ -34,9 +34,8 @@ class PublicOrganization(Organization):
#### Classes ####################################################
-async def get_organization(org_id: str):
- await check_database()
- orgs = learnhouseDB["organizations"]
+async def get_organization(request: Request, org_id: str):
+ orgs = request.app.db["organizations"]
org = orgs.find_one({"org_id": org_id})
@@ -47,9 +46,9 @@ async def get_organization(org_id: str):
org = PublicOrganization(**org)
return org
-async def get_organization_by_slug(org_slug: str):
- await check_database()
- orgs = learnhouseDB["organizations"]
+
+async def get_organization_by_slug(request: Request, org_slug: str):
+ orgs = request.app.db["organizations"]
org = orgs.find_one({"slug": org_slug})
@@ -61,9 +60,8 @@ async def get_organization_by_slug(org_slug: str):
return org
-async def create_org(org_object: Organization, current_user: PublicUser):
- await check_database()
- orgs = learnhouseDB["organizations"]
+async def create_org(request: Request, org_object: Organization, current_user: PublicUser):
+ orgs = request.app.db["organizations"]
# find if org already exists using name
isOrgAvailable = orgs.find_one({"slug": org_object.slug})
@@ -88,13 +86,12 @@ async def create_org(org_object: Organization, current_user: PublicUser):
return org.dict()
-async def update_org(org_object: Organization, org_id: str, current_user: PublicUser):
- await check_database()
+async def update_org(request: Request, org_object: Organization, org_id: str, current_user: PublicUser):
# verify org rights
- await verify_org_rights(org_id, current_user,"update")
+ await verify_org_rights(request, org_id, current_user, "update")
- orgs = learnhouseDB["organizations"]
+ orgs = request.app.db["organizations"]
org = orgs.find_one({"org_id": org_id})
@@ -114,12 +111,11 @@ async def update_org(org_object: Organization, org_id: str, current_user: Public
return Organization(**updated_org.dict())
-async def delete_org(org_id: str, current_user: PublicUser):
- await check_database()
+async def delete_org(request: Request, org_id: str, current_user: PublicUser):
- await verify_org_rights(org_id, current_user,"delete")
+ await verify_org_rights(request, org_id, current_user, "delete")
- orgs = learnhouseDB["organizations"]
+ orgs = request.app.db["organizations"]
org = orgs.find_one({"org_id": org_id})
@@ -136,33 +132,21 @@ async def delete_org(org_id: str, current_user: PublicUser):
status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database")
-async def get_orgs(page: int = 1, limit: int = 10):
- ## TODO : Deprecated
- await check_database()
- orgs = learnhouseDB["organizations"]
+async def get_orgs_by_user(request: Request, user_id: str, page: int = 1, limit: int = 10):
+ orgs = request.app.db["organizations"]
- # get all orgs from database
- all_orgs = orgs.find().sort("name", 1).skip(10 * (page - 1)).limit(limit)
-
- return [json.loads(json.dumps(org, default=str)) for org in all_orgs]
-
-
-async def get_orgs_by_user(user_id: str, page: int = 1, limit: int = 10):
- await check_database()
- orgs = learnhouseDB["organizations"]
print(user_id)
- # find all orgs where user_id is in owners or admins arrays
- all_orgs = orgs.find({"$or": [{"owners": user_id}, {"admins": user_id}]}).sort("name", 1).skip(10 * (page - 1)).limit(limit)
-
+ # find all orgs where user_id is in owners or admins arrays
+ all_orgs = orgs.find({"$or": [{"owners": user_id}, {"admins": user_id}]}).sort(
+ "name", 1).skip(10 * (page - 1)).limit(limit)
+
return [json.loads(json.dumps(org, default=str)) for org in all_orgs]
-
#### Security ####################################################
-async def verify_org_rights(org_id: str, current_user: PublicUser, action: str,):
- await check_database()
- orgs = learnhouseDB["organizations"]
+async def verify_org_rights(request: Request, org_id: str, current_user: PublicUser, action: str,):
+ orgs = request.app.db["organizations"]
org = orgs.find_one({"org_id": org_id})
diff --git a/src/services/roles.py b/src/services/roles.py
index dcefb122..53642002 100644
--- a/src/services/roles.py
+++ b/src/services/roles.py
@@ -3,10 +3,9 @@ from typing import List
from uuid import uuid4
from pydantic import BaseModel
from src.services.users import PublicUser, User
-from src.services.database import check_database, learnhouseDB, learnhouseDB
from src.services.security import *
from src.services.houses import House
-from fastapi import HTTPException, status
+from fastapi import HTTPException, status, Request
from datetime import datetime
#### Classes ####################################################
@@ -26,7 +25,7 @@ class Elements(BaseModel):
collections: List[str]
organizations: List[str]
coursechapters: List[str]
- elements : List[str]
+ lectures : List[str]
class Role(BaseModel):
@@ -45,9 +44,8 @@ class RoleInDB(Role):
#### Classes ####################################################
-async def get_role(role_id: str):
- await check_database()
- roles = learnhouseDB["roles"]
+async def get_role(request: Request,role_id: str):
+ roles = request.app.db["roles"]
role = roles.find_one({"role_id": role_id})
@@ -59,9 +57,8 @@ async def get_role(role_id: str):
return role
-async def create_role(role_object: Role, current_user: PublicUser):
- await check_database()
- roles = learnhouseDB["roles"]
+async def create_role(request: Request,role_object: Role, current_user: PublicUser):
+ roles = request.app.db["roles"]
# find if house already exists using name
isRoleAvailable = roles.find_one({"name": role_object.name})
@@ -70,7 +67,7 @@ async def create_role(role_object: Role, current_user: PublicUser):
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Role name already exists")
- await verify_user_permissions_on_roles("create", current_user)
+ await verify_user_permissions_on_roles(request, "create", current_user)
# generate house_id with uuid4
role_id = str(f"role_{uuid4()}")
@@ -87,13 +84,12 @@ async def create_role(role_object: Role, current_user: PublicUser):
return role.dict()
-async def update_role(role_object: Role, role_id: str, current_user: PublicUser):
- await check_database()
+async def update_role(request: Request,role_object: Role, role_id: str, current_user: PublicUser):
# verify house rights
- await verify_user_permissions_on_roles("update", current_user)
+ await verify_user_permissions_on_roles(request, "update", current_user)
- roles = learnhouseDB["roles"]
+ roles = request.app.db["roles"]
role = roles.find_one({"role_id": role_id})
@@ -109,13 +105,12 @@ async def update_role(role_object: Role, role_id: str, current_user: PublicUser)
return RoleInDB(**updated_role.dict())
-async def delete_role(role_id: str, current_user: PublicUser):
- await check_database()
+async def delete_role(request: Request,role_id: str, current_user: PublicUser):
# verify house rights
- await verify_user_permissions_on_roles("delete", current_user)
+ await verify_user_permissions_on_roles(request, "delete", current_user)
- roles = learnhouseDB["roles"]
+ roles = request.app.db["roles"]
role = roles.find_one({"role_id": role_id})
@@ -132,9 +127,8 @@ async def delete_role(role_id: str, current_user: PublicUser):
status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database")
-async def get_roles(page: int = 1, limit: int = 10):
- await check_database()
- roles = learnhouseDB["roles"]
+async def get_roles(request: Request,page: int = 1, limit: int = 10):
+ roles = request.app.db["roles"]
# get all roles from database
all_roles = roles.find().sort("name", 1).skip(10 * (page - 1)).limit(limit)
@@ -144,9 +138,8 @@ async def get_roles(page: int = 1, limit: int = 10):
#### Security ####################################################
-async def verify_user_permissions_on_roles(action: str, current_user: PublicUser):
- await check_database()
- users = learnhouseDB["users"]
+async def verify_user_permissions_on_roles(request: Request,action: str, current_user: PublicUser):
+ users = request.app.db["users"]
user = users.find_one({"user_id": current_user.user_id})
diff --git a/src/services/security.py b/src/services/security.py
index a6998ff3..c9ae871b 100644
--- a/src/services/security.py
+++ b/src/services/security.py
@@ -1,10 +1,6 @@
-from fastapi import HTTPException, status
+from fastapi import HTTPException, status, Request
from passlib.context import CryptContext
-from jose import JWTError, jwt
-import logging
from passlib.hash import pbkdf2_sha256
-from src.services.database import check_database
-from src.services.database import check_database, learnhouseDB, learnhouseDB
### 🔒 JWT ##############################################################
@@ -31,12 +27,11 @@ async def security_verify_password(plain_password: str, hashed_password: str):
### 🔒 Roles checking ##############################################################
-async def verify_user_rights_with_roles(action: str, user_id: str, element_id: str):
+async def verify_user_rights_with_roles(request: Request,action: str, user_id: str, element_id: str):
"""
Check if the user has the right to perform the action on the element
"""
- await check_database()
- roles = learnhouseDB["roles"]
+ roles = request.app.db["roles"]
# find data where user_id is in linked_users or * is in linked_users
user_roles_cursor = roles.find({"$or": [{"linked_users": user_id}, {"linked_users": "*"}]})
@@ -77,8 +72,8 @@ async def check_element_type(element_id):
return "coursechapters"
elif element_id.startswith("collection_"):
return "collections"
- elif element_id.startswith("element_"):
- return "elements"
+ elif element_id.startswith("lecture_"):
+ return "lectures"
else:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Issue verifying element nature")
diff --git a/src/services/users.py b/src/services/users.py
index 1831931a..57f2829e 100644
--- a/src/services/users.py
+++ b/src/services/users.py
@@ -1,8 +1,7 @@
from uuid import uuid4
from pydantic import BaseModel
-from src.services.database import check_database, learnhouseDB, learnhouseDB
from src.services.security import *
-from fastapi import HTTPException, status
+from fastapi import HTTPException, status, Request
from datetime import datetime
#### Classes ####################################################
@@ -41,6 +40,8 @@ class UserProfileMetadata(BaseModel):
roles = list
# TODO : terrible, export role classes from one single source of truth
+
+
class Role(BaseModel):
name: str
description: str
@@ -53,9 +54,8 @@ class Role(BaseModel):
# TODO : avatar upload and update
-async def get_user(username: str):
- await check_database()
- users = learnhouseDB["users"]
+async def get_user(request: Request, username: str):
+ users = request.app.db["users"]
user = users.find_one({"username": username})
@@ -67,10 +67,9 @@ async def get_user(username: str):
return user
-async def get_profile_metadata(user):
- await check_database()
- users = learnhouseDB["users"]
- roles = learnhouseDB["roles"]
+async def get_profile_metadata(request: Request, user):
+ users = request.app.db["users"]
+ roles = request.app.db["roles"]
user = users.find_one({"user_id": user['user_id']})
@@ -92,9 +91,8 @@ async def get_profile_metadata(user):
}
-async def get_user_by_userid(user_id: str):
- await check_database()
- users = learnhouseDB["users"]
+async def get_user_by_userid(request: Request, user_id: str):
+ users = request.app.db["users"]
user = users.find_one({"user_id": user_id})
@@ -106,9 +104,8 @@ async def get_user_by_userid(user_id: str):
return user
-async def security_get_user(email: str):
- await check_database()
- users = learnhouseDB["users"]
+async def security_get_user(request: Request, email: str):
+ users = request.app.db["users"]
user = users.find_one({"email": email})
@@ -119,9 +116,8 @@ async def security_get_user(email: str):
return UserInDB(**user)
-async def get_userid_by_username(username: str):
- await check_database()
- users = learnhouseDB["users"]
+async def get_userid_by_username(request: Request, username: str):
+ users = request.app.db["users"]
user = users.find_one({"username": username})
@@ -132,9 +128,8 @@ async def get_userid_by_username(username: str):
return user["user_id"]
-async def update_user(user_id: str, user_object: UserWithPassword):
- await check_database()
- users = learnhouseDB["users"]
+async def update_user(request: Request, user_id: str, user_object: UserWithPassword):
+ users = request.app.db["users"]
isUserExists = users.find_one({"user_id": user_id})
isUsernameAvailable = users.find_one({"username": user_object.username})
@@ -155,9 +150,8 @@ async def update_user(user_id: str, user_object: UserWithPassword):
return User(**user_object.dict())
-async def delete_user(user_id: str):
- await check_database()
- users = learnhouseDB["users"]
+async def delete_user(request: Request, user_id: str):
+ users = request.app.db["users"]
isUserAvailable = users.find_one({"user_id": user_id})
@@ -170,9 +164,8 @@ async def delete_user(user_id: str):
return {"detail": "User deleted"}
-async def create_user(user_object: UserWithPassword):
- await check_database()
- users = learnhouseDB["users"]
+async def create_user(request: Request, user_object: UserWithPassword):
+ users = request.app.db["users"]
isUserAvailable = users.find_one({"username": user_object.username})