Final Plans
File Preview on Backend
- Have working file submissions
- Endpoint to send assignment data to frontend
- Endpoint to send file previews copies of the assignments to frontend
- Only allow leaders and file submitters to access file previews from each class
- Utilize the JWT token to assess user id
File Preview on Frontend
- Receive and properly display file submission data from backend (including displaying file previews)
- Provide JWT token for authentication
Work on File Submissions
We have decided to work on file previews for our assignment objects, and my job will be to work on the backend endpoints to facilitate that. Our wireframe above indicates the rough idea for my end of the project. Currently, we do not have a specific backend role for teachers/leaders for organizations in our project. Instead, we have lists of leaders in each Class Period which we can iterate through to determine leadership roles in organizations.
@GetMapping("/preview")
public ResponseEntity<String> getFilePreview(@CookieValue("jwt") String jwtToken, @PathVariable long id) {
if (jwtToken.isEmpty()) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
// getting user data
String userEmail = tokenUtil.getUsernameFromToken(jwtToken);
Person existingPerson = personRepository.findByEmail(userEmail);
if (existingPerson == null) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
Assignment assignment = repository.findById(id); //find the assignment
boolean isLeader = false;
List<AssignmentSubmission> allSubmissionsOut = new ArrayList<>();
loop1: for (AssignmentSubmission sub : assignment.getSubmissions()) //get all the submissions
{
// Person user = sub.getSubmitter(); //get the submitter for each submission to the assignment
// if (user.getEmail() == userEmail) //if the user is the same as the one in the JWT token
// {
List<ClassPeriod> classesInAssignment = classService.getClassPeriodsByAssignment(assignment);
for (ClassPeriod classP : classesInAssignment) //go through all class periods in the assignment
{
Collection<Person> lead = classP.getLeaders(); //get the leaders of the class period
for (Person leaderOfClassPeriod : lead)
{
if (existingPerson.equals(leaderOfClassPeriod)) //if the user from the JWT token is a leader then grant access
{
isLeader = true; //after this, send a link describing each submission to the assignment
allSubmissionsOut.addAll(assignment.getSubmissions());
break loop1;
}
}
}
// }
}
if (isLeader)
{
String submissionData = "";
for (AssignmentSubmission eachSub : allSubmissionsOut) {
submissionData += "Submission ID: " + eachSub.getId() +
"\nSubmitter: " + eachSub.getSubmitter().getName() +
"\nFile Path: " + eachSub.getFilePath() +
"\nTime Submitted: " + eachSub.getTimeSubmitted() +
"\nSubmission Number: " + eachSub.getSubmissionNumber() + "\n";
}
return ResponseEntity.ok(submissionData);
}
else
{
return new ResponseEntity<>("Existing user is not a leader for the assignment", HttpStatus.BAD_REQUEST);
}
}
My existing code essentially fetches assignment data if the leader is determined to be a leader in the class period. This currently does not give a file preview, but a plan would be to add a method that would fetch a selected user’s file submission to an assignment.
Relation of Parts of Project
JWT Token
- We parse the JWT token to determine which user is requesting to view other assignment submissions and determine leaders.
Class structure
- Assignment -> AssignmentSubmission -> ClassPeriod -> leaders
Final Accomplishments
File Previews Work
- The backend enabled both leaders of a Class Period and submitters to view their file submissions. For submitters aka students it only allows them to view their own submissions. For leaders it allows all of the file submissions for the Class Period. This was finalized in this commit: https://github.com/John-sCC/jcc_backend/commit/6325f0a675a7dc49c0fc95f9a1706c70a1c367a0
Learning Moment: Comparing Person objects using
equals
did not work, so I used emails of each object (which are unique) to compare the Persons instead: https://github.com/John-sCC/jcc_backend/commit/b0c362631c35a29bd5a6c270b0a17e9ae2b0a44f - The backend also sent files not Blob objects to the frontend. Previously it would send the file in essentially gibberish. Allowing for specific file types to be sent fixed this issue: https://github.com/John-sCC/jcc_backend/commit/d27ec0f75bce71c436214bd0485814802dcf03de
- The frontend wound into some issues with properly receiving the data, which was solved here without CSS (Drew’s work later): https://github.com/John-sCC/jcc_frontend/commit/aa5e28369aa0427e2037ad7d5414a6b7ab16beb8 Learning Moment: Any time I had to do error handling in the backend, I added a basic error message that was not very informative and stuck a 400 error on it. While this technically worked, when I was testing I spent a long time trying to figure out why I was receiving random 400 errors, which were actually just due to assignments not existing or submissions not existing. This has shown me the benefit of descriptive error handlers: https://github.com/John-sCC/jcc_frontend/commit/aa5e28369aa0427e2037ad7d5414a6b7ab16beb8 (Line 137)
File Upload Handling
String contentType;
String filename = file.getName().toLowerCase();
if (filename.endsWith(".pdf")) {
contentType = MediaType.APPLICATION_PDF_VALUE;
} else if (filename.endsWith(".jpg") || filename.endsWith(".jpeg")) {
contentType = MediaType.IMAGE_JPEG_VALUE;
} else if (filename.endsWith(".png")) {
contentType = MediaType.IMAGE_PNG_VALUE;
} else if (filename.endsWith(".docx")) {
contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
} else {
// If the file type is unknown, set it as octet-stream
contentType = MediaType.APPLICATION_OCTET_STREAM_VALUE;
}
headers.setContentType(MediaType.parseMediaType(contentType));
headers.setContentDispositionFormData("inline", file.getName());