feat: refactor imageBlock

This commit is contained in:
swve 2023-03-23 22:03:05 +01:00
parent 7ca481960c
commit 3715157722
10 changed files with 87 additions and 138 deletions

View file

@ -10,7 +10,7 @@ export default Node.create({
addAttributes() { addAttributes() {
return { return {
fileObject: { blockObject: {
default: null, default: null,
}, },
}; };

View file

@ -8,7 +8,7 @@ import { uploadNewVideoFile } from "../../../../services/files/video";
function VideoBlockComponents(props: any) { function VideoBlockComponents(props: any) {
const [video, setVideo] = React.useState(null); const [video, setVideo] = React.useState(null);
const [isLoading, setIsLoading] = React.useState(false); const [isLoading, setIsLoading] = React.useState(false);
const [fileObject, setfileObject] = React.useState(props.node.attrs.fileObject); const [blockObject, setblockObject] = React.useState(props.node.attrs.fileObject);
const handleVideoChange = (event: React.ChangeEvent<any>) => { const handleVideoChange = (event: React.ChangeEvent<any>) => {
setVideo(event.target.files[0]); setVideo(event.target.files[0]);
@ -19,15 +19,15 @@ function VideoBlockComponents(props: any) {
setIsLoading(true); setIsLoading(true);
let object = await uploadNewVideoFile(video, props.extension.options.lecture.lecture_id); let object = await uploadNewVideoFile(video, props.extension.options.lecture.lecture_id);
setIsLoading(false); setIsLoading(false);
setfileObject(object); setblockObject(object);
props.updateAttributes({ props.updateAttributes({
fileObject: object, blockObject: object,
}); });
}; };
return ( return (
<NodeViewWrapper className="block-video"> <NodeViewWrapper className="block-video">
{!fileObject && ( {!blockObject && (
<BlockVideoWrapper contentEditable={props.extension.options.editable}> <BlockVideoWrapper contentEditable={props.extension.options.editable}>
<div> <div>
<Video color="#e1e0e0" size={50} /> <Video color="#e1e0e0" size={50} />
@ -38,12 +38,12 @@ function VideoBlockComponents(props: any) {
<button onClick={handleSubmit}>Submit</button> <button onClick={handleSubmit}>Submit</button>
</BlockVideoWrapper> </BlockVideoWrapper>
)} )}
{fileObject && ( {blockObject && (
<BlockVideo> <BlockVideo>
<video <video
controls controls
src={`${getBackendUrl()}content/uploads/files/videos/${props.extension.options.lecture.lecture_id}/${fileObject.file_id}.${ src={`${getBackendUrl()}content/uploads/files/lectures/${props.extension.options.lecture.lecture_id}/blocks/videoBlock/${blockObject.block_id}/${blockObject.block_data.file_id}.${
fileObject.file_format blockObject.block_data.file_format
}`} }`}
></video> ></video>
</BlockVideo> </BlockVideo>

View file

@ -1,10 +1,10 @@
from fastapi import APIRouter, Depends, UploadFile, Form, Request from fastapi import APIRouter, Depends, UploadFile, Form, Request
from src.dependencies.auth import get_current_user from src.dependencies.auth import get_current_user
from fastapi import HTTPException, status, UploadFile from fastapi import HTTPException, status, UploadFile
from src.services.blocks.imageBlock.images import create_image_file, get_image_file from src.services.blocks.block_types.imageBlock.images import create_image_file, get_image_file
from src.services.blocks.videoBlock.videos import create_video_file, get_video_file from src.services.blocks.block_types.videoBlock.videoBlock import create_video_block, get_video_block
from src.services.blocks.pdfBlock.documents import create_document_file, get_document_file from src.services.blocks.block_types.pdfBlock.documents import create_document_file, get_document_file
from src.services.blocks.quizBlock.quizBlock import create_quiz_block, get_quiz_block_answers, get_quiz_block_options, quizBlock from src.services.blocks.block_types.quizBlock.quizBlock import create_quiz_block, get_quiz_block_answers, get_quiz_block_options, quizBlock
from src.services.users.users import PublicUser from src.services.users.users import PublicUser
router = APIRouter() router = APIRouter()
@ -25,19 +25,21 @@ async def api_get_image_file_block(request: Request, file_id: str, current_user:
""" """
return await get_image_file(request, file_id, current_user) return await get_image_file(request, file_id, current_user)
@router.post("/video") @router.post("/video")
async def api_create_video_file_block(request: Request, file_object: UploadFile, lecture_id: str = Form(), current_user: PublicUser = Depends(get_current_user)): async def api_create_video_file_block(request: Request, file_object: UploadFile, lecture_id: str = Form(), current_user: PublicUser = Depends(get_current_user)):
""" """
Create new video file Create new video file
""" """
return await create_video_file(request, file_object, lecture_id) return await create_video_block(request, file_object, lecture_id)
@router.get("/video") @router.get("/video")
async def api_get_video_file_block(request: Request, file_id: str, current_user: PublicUser = Depends(get_current_user)): async def api_get_video_file_block(request: Request, file_id: str, current_user: PublicUser = Depends(get_current_user)):
""" """
Get video file Get video file
""" """
return await get_video_file(request, file_id, current_user) return await get_video_block(request, file_id, current_user)
@router.post("/document") @router.post("/document")

View file

@ -30,11 +30,17 @@ class quizBlock(BaseModel):
async def create_quiz_block(request: Request, quizBlock: quizBlock, lecture_id: str, user: PublicUser): async def create_quiz_block(request: Request, quizBlock: quizBlock, lecture_id: str, user: PublicUser):
blocks = request.app.db["blocks"] blocks = request.app.db["blocks"]
lectures = request.app.db["lectures"]
# Get org_id from lecture
lecture = await lectures.find_one({"lecture_id": lecture_id}, {"_id": 0, "org_id": 1})
org_id = lecture["org_id"]
block_id = str(f"block_{uuid4()}") block_id = str(f"block_{uuid4()}")
# create block # create block
block = Block(block_id=block_id, lecture_id=lecture_id, block = Block(block_id=block_id, lecture_id=lecture_id,
block_type="quizBlock", block_data=quizBlock) block_type="quizBlock", block_data=quizBlock, org_id=org_id)
# insert block # insert block
await blocks.insert_one(block.dict()) await blocks.insert_one(block.dict())

View file

@ -0,0 +1,46 @@
from uuid import uuid4
from pydantic import BaseModel
import os
from fastapi import HTTPException, status, UploadFile, Request
from fastapi.responses import StreamingResponse
from src.services.blocks.schemas.blocks import Block
from src.services.blocks.utils.upload_files import upload_file_and_return_file_object
from src.services.users.users import PublicUser
async def create_video_block(request: Request, video_file: UploadFile, lecture_id: str):
blocks = request.app.db["blocks"]
lecture = request.app.db["lectures"]
block_type = "videoBlock"
# get org_id from lecture
lecture = await lecture.find_one({"lecture_id": lecture_id}, {"_id": 0, "org_id": 1})
org_id = lecture["org_id"]
# get block id
block_id = str(f"block_{uuid4()}")
block_data = await upload_file_and_return_file_object(request, video_file, lecture_id, block_id, ["mp4", "webm", "ogg"], block_type)
# create block
block = Block(block_id=block_id, lecture_id=lecture_id,
block_type=block_type, block_data=block_data, org_id=org_id)
# insert block
await blocks.insert_one(block.dict())
return block
async def get_video_block(request: Request, file_id: str, current_user: PublicUser):
photos = request.app.db["blocks"]
video_block = await photos.find_one({"block_id": file_id})
if video_block:
return Block(**video_block)
else:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Photo file does not exist")

View file

@ -8,5 +8,6 @@ from pydantic import BaseModel
class Block(BaseModel): class Block(BaseModel):
block_id: str block_id: str
lecture_id: str lecture_id: str
org_id: str
block_type: Literal["quizBlock", "videoBlock", "pdfBlock"] block_type: Literal["quizBlock", "videoBlock", "pdfBlock"]
block_data: Any block_data: Any

View file

@ -1,18 +1,26 @@
import os import os
import uuid import uuid
from fastapi import Request, UploadFile from fastapi import HTTPException, Request, UploadFile, status
from src.services.blocks.schemas.files import BlockFile from src.services.blocks.schemas.files import BlockFile
from src.services.users.schemas.users import PublicUser from src.services.users.schemas.users import PublicUser
async def upload_file_and_return_file_object(request: Request, file: UploadFile, current_user: PublicUser, lecture_id: str, block_id: str): async def upload_file_and_return_file_object(request: Request, file: UploadFile, lecture_id: str, block_id: str, list_of_allowed_file_formats: list, type_of_block: str):
# get file id # get file id
file_id = str(uuid.uuid4()) file_id = str(uuid.uuid4())
# get file format # get file format
file_format = file.filename.split(".")[-1] file_format = file.filename.split(".")[-1]
# validate file format
if file_format not in list_of_allowed_file_formats:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="File format not supported")
# create file
file_binary = await file.read()
# get file size # get file size
file_size = len(await file.read()) file_size = len(await file.read())
@ -33,14 +41,15 @@ async def upload_file_and_return_file_object(request: Request, file: UploadFile,
) )
# create folder for lecture # create folder for lecture
if not os.path.exists(f"content/uploads/files/lectures/{lecture_id}/blocks/{block_id}"): if not os.path.exists(f"content/uploads/files/lectures/{lecture_id}/blocks/{type_of_block}/{block_id}"):
os.mkdir(f"content/uploads/files/lectures/{lecture_id}/blocks/{block_id}") # create folder for lecture
os.makedirs(f"content/uploads/files/lectures/{lecture_id}/blocks/{type_of_block}/{block_id}")
# upload file to server # upload file to server
with open(f"content/uploads/files/lectures/{lecture_id}/blocks/{block_id}/{file_id}.{file_format}", 'wb') as f: with open(f"content/uploads/files/lectures/{lecture_id}/blocks/{type_of_block}/{block_id}/{file_id}.{file_format}", 'wb') as f:
f.write(await file.read()) f.write(file_binary)
f.close() f.close()
# TODO: do some error handling here # TODO: do some error handling here
return uploadable_file return uploadable_file

View file

@ -1,115 +0,0 @@
from uuid import uuid4
from pydantic import BaseModel
import os
from fastapi import HTTPException, status, UploadFile,Request
from fastapi.responses import StreamingResponse
from src.services.users.users import PublicUser
class VideoFile(BaseModel):
file_id: str
file_format: str
file_name: str
file_size: int
file_type: str
lecture_id: str
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()}")
# get file format
file_format = video_file.filename.split(".")[-1]
# validate file format
if file_format not in ["mp4", "webm", "ogg"]:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Video file format not supported")
# create file
file = await video_file.read()
# get file size
file_size = len(file)
# get file type
file_type = video_file.content_type
# get file name
file_name = video_file.filename
# create file object
uploadable_file = VideoFile(
file_id=file_id,
file_format=file_format,
file_name=file_name,
file_size=file_size,
file_type=file_type,
lecture_id=lecture_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/{lecture_id}/{file_id}.{file_format}", 'wb') as f:
f.write(file)
f.close()
# insert file object into database
video_file_in_db = await files.insert_one(uploadable_file.dict())
if not video_file_in_db:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Video file could not be created")
return uploadable_file
async def get_video_object(request: Request,file_id: str, current_user: PublicUser):
photos = request.app.db["files"]
video_file = await photos.find_one({"file_id": file_id})
if video_file:
video_file = VideoFile(**video_file)
return video_file
else:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Photo file does not exist")
async def get_video_file(request: Request,file_id: str, current_user: PublicUser):
photos = request.app.db["files"]
video_file = await photos.find_one({"file_id": file_id})
# TODO : check if user has access to file
if video_file:
# check media type
if video_file.format not in ["mp4", "webm", "ogg"]:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Video file format not supported")
# stream file
video_file = VideoFile(**video_file)
file_format = video_file.file_format
lecture_id = video_file.lecture_id
def iterfile(): #
#
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)
else:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Video file does not exist")