import math from fastapi import APIRouter, Depends, HTTPException, UploadFile, File from sqlalchemy.orm import Session from models import User from utils import deps from datetime import datetime, timedelta from cruds import crud_assignment_upload, crud_assignment from schemas import ( AssignmentUpload, AssignmentUploadCreate, AssignmentUploadUpdate, AssignmentUploadwithName, ) import os from fastapi.responses import FileResponse from hashlib import sha1 import aiofiles import shutil from typing import Any, Optional, List, Dict # noqa from core.config import settings router = APIRouter() assignment_upload_ROUTE: str = "assignmentUpload" @router.get("/") async def get_assignments( db: Session = Depends(deps.get_db), *, current_user: User = Depends(deps.get_current_active_user), ): pass @router.get("/{assignmentid}", response_model=AssignmentUpload) async def get_assignment_upload( db: Session = Depends(deps.get_db), *, assignmentid: int, current_user: User = Depends(deps.get_current_active_user), ): assignmentUpload = crud_assignment_upload.get_by_assignment_id( db=db, assignmentId=assignmentid, studentId=current_user.id ) if assignmentUpload: return assignmentUpload raise HTTPException(status_code=404, detail="Error ID: 147") @router.get( "/{assignmentid}/getUploadsAsTeacher", response_model=List[AssignmentUploadwithName] ) async def get_assignment_upload_as_teacher( db: Session = Depends(deps.get_db), *, assignmentid: int, current_user: User = Depends(deps.get_current_active_teacher_or_above), ): if current_user.assignments: for assignment in current_user.assignments: if assignment.id == assignmentid: assignmentUpload = ( crud_assignment_upload.get_all_by_assignment_id_as_teacher( db=db, assignmentId=assignmentid ) ) if assignmentUpload: return assignmentUpload raise HTTPException( status_code=404, detail="Error ID: 148", # could not populate answer ) @router.get("/{assignmentid}/exists") async def check_existence( db: Session = Depends(deps.get_db), current_user: User = Depends(deps.get_current_active_user), *, assignmentid: int, ): assignmentUpload = crud_assignment_upload.get_by_assignment_id( db=db, assignmentId=assignmentid, studentId=current_user.id ) if not assignmentUpload: return {"exists": False} else: return {"exists": True} @router.post("/{assignmentid}/upload") async def post_files( db: Session = Depends(deps.get_db), files: List[UploadFile] = File(...), current_user=Depends(deps.get_current_active_user), *, assignmentid: int, ): hashedAssignmentId = sha1( str(assignmentid).encode(encoding="UTF-8", errors="strict") ) hashedUserId = sha1(str(current_user.id).encode(encoding="UTF-8", errors="strict")) FILE_ASSIGNMENT_PATH = os.path.join( assignment_upload_ROUTE, hashedUserId.hexdigest(), hashedAssignmentId.hexdigest(), ) FILE_PATH = os.path.join( settings.UPLOAD_DIR_ROOT, FILE_ASSIGNMENT_PATH, ) if os.path.exists(FILE_PATH): shutil.rmtree(FILE_PATH) if not os.path.exists(FILE_PATH): os.makedirs(FILE_PATH) fileIndex = 0 assignmentFiles = [] for file in files: fileName, fileExtension = os.path.splitext(file.filename) hashedFileName = sha1( (fileName + str(fileIndex)).encode(encoding="UTF-8", errors="strict") ) fileIndex = fileIndex + 1 filename = f"{FILE_PATH}/{hashedFileName.hexdigest()}{fileExtension}" async with aiofiles.open(filename, mode="wb") as f: content = await file.read() await f.write(content) assignmentFiles.append( { "path": f"{FILE_ASSIGNMENT_PATH}/{hashedFileName.hexdigest()}{fileExtension}", "name": file.filename, } ) assignmentUpload = crud_assignment_upload.get_by_assignment_id( db=db, assignmentId=assignmentid, studentId=current_user.id ) if assignmentUpload: db_obj = assignmentUpload obj_in = AssignmentUploadUpdate( files=assignmentFiles, submission_date=datetime.utcnow(), marks_obtained=None, ) assignmentUploadX = crud_assignment_upload.update( db=db, db_obj=db_obj, obj_in=obj_in ) else: obj_in = AssignmentUploadCreate( files=assignmentFiles, assignment_id=assignmentid, student_id=current_user.id, submission_date=datetime.utcnow(), marks_obtained=None, ) assignmentUploadX = crud_assignment_upload.create(db=db, obj_in=obj_in) return assignmentUploadX @router.delete("/{assignmentid}/files") async def post_files( db: Session = Depends(deps.get_db), current_user=Depends(deps.get_current_active_user), *, assignmentid: int, ): hashedAssignmentId = sha1( str(assignmentid).encode(encoding="UTF-8", errors="strict") ) hashedUserId = sha1(str(current_user.id).encode(encoding="UTF-8", errors="strict")) FILE_ASSIGNMENT_PATH = os.path.join( assignment_upload_ROUTE, hashedUserId.hexdigest(), hashedAssignmentId.hexdigest(), ) FILE_PATH = os.path.join( settings.UPLOAD_DIR_ROOT, FILE_ASSIGNMENT_PATH, ) if os.path.exists(FILE_PATH): shutil.rmtree(FILE_PATH) assignmentUpload = crud_assignment_upload.get_by_assignment_id( db=db, assignmentId=assignmentid, studentId=current_user.id ) if assignmentUpload: crud_assignment_upload.remove(db=db, id=assignmentUpload.id) return {"message": "Success"} raise HTTPException(status_code=404, detail="Error ID: 149") @router.post("/{assignmentuploadid}/mark") async def post_files( db: Session = Depends(deps.get_db), current_user=Depends(deps.get_current_active_teacher_or_above), *, assignmentuploadid: int, marks_obtained: int, ): assignmentUpload = crud_assignment_upload.get(db=db, id=assignmentuploadid) if assignmentUpload: obj_in = AssignmentUploadUpdate(marks_obtained=marks_obtained) db_obj = assignmentUpload updated = crud_assignment_upload.update(db=db, db_obj=db_obj, obj_in=obj_in) return updated raise HTTPException(status_code=404, detail="Error ID: 150")