Skip to content
This repository has been archived by the owner on Apr 27, 2024. It is now read-only.

Commit

Permalink
Merge pull request #194 from WisdomWorks/dev-stef
Browse files Browse the repository at this point in the history
feat[dev-stef]: create file exercise and submit api
  • Loading branch information
TungPhan2808 authored Apr 7, 2024
2 parents dbed144 + 1bf97e4 commit 3e6eb76
Show file tree
Hide file tree
Showing 15 changed files with 259 additions and 43 deletions.
47 changes: 38 additions & 9 deletions src/main/java/com/example/codeE/controller/ExerciseController.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,12 @@
import com.example.codeE.request.exercise.CreatePermissionExerciseRequest;
import com.example.codeE.request.exercise.ExerciseResponse;
import com.example.codeE.request.exercise.GetDetailExerciseRequest;
import com.example.codeE.request.exercise.code.CodeDetailResponse;
import com.example.codeE.request.exercise.code.CodeRunRequest;
import com.example.codeE.request.exercise.code.CreateCodeExerciseRequest;
import com.example.codeE.request.exercise.code.RunCodeExerciseResponse;
import com.example.codeE.request.exercise.code.SubmitCodeExerciseRequest;
import com.example.codeE.request.exercise.code.UpdateCodeExerciseRequest;
import com.example.codeE.request.exercise.code.*;
import com.example.codeE.request.exercise.essay.CreateEssayExerciseRequest;
import com.example.codeE.request.exercise.essay.CreateEssaySubmissionRequest;
import com.example.codeE.request.exercise.essay.UpdateEssayExerciseRequest;
import com.example.codeE.request.exercise.file.CreateFileExerciseRequest;
import com.example.codeE.request.exercise.file.CreateFileSubmissionRequest;
import com.example.codeE.request.exercise.quiz.CreateQuizExerciseRequest;
import com.example.codeE.request.exercise.quiz.CreateQuizSubmissionRequest;
import com.example.codeE.request.exercise.quiz.UpdateQuizExerciseRequest;
Expand All @@ -24,15 +21,18 @@
import com.example.codeE.service.exercise.problem.CodeExerciseTestcaseService;
import com.example.codeE.service.exercise.submission.CodeSubmissionService;
import com.example.codeE.service.exercise.submission.EssaySubmissionService;
import com.example.codeE.service.exercise.submission.FileSubmissionService;
import com.example.codeE.service.judge.JudgeService;
import com.mongodb.client.MongoDatabase;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.time.ZoneId;
import java.util.ArrayList;
Expand All @@ -47,7 +47,10 @@ public class ExerciseController {
private CodeExerciseService codeExerciseService;
@Autowired
private ExerciseService exerciseService;

@Autowired
private FileExerciseService fileExerciseService;
@Autowired
private FileSubmissionService fileSubmissionService;
@Autowired
private QuizExerciseService quizExerciseService;
@Autowired
Expand Down Expand Up @@ -128,6 +131,15 @@ public ResponseEntity<?> createEssayExercise(@Valid @RequestBody CreateEssayExer
return ResponseEntity.status(HttpStatus.CREATED).body(essaySave);
}

@PostMapping
@RequestMapping(value = "file", method = RequestMethod.POST)
public ResponseEntity<?> createFileExercise(@Valid @RequestBody CreateFileExerciseRequest request){
FileExercise fileExercise = new FileExercise(request);
var fileSave = this.fileExerciseService.createFileExercise(fileExercise);
this.exerciseService.saveFileExercise(fileSave);
return ResponseEntity.status(HttpStatus.CREATED).body(fileSave);
}

@GetMapping
@RequestMapping(value = "", method = RequestMethod.GET)
public ResponseEntity<?> getAllExerciseByCourseId(@RequestParam String courseId) {
Expand All @@ -141,6 +153,7 @@ public ResponseEntity<?> getExerciseById(@PathVariable String exerciseId){
Exercise exercise = this.exerciseService.getExerciseById(exerciseId);
return ResponseEntity.status(HttpStatus.OK).body(exercise);
}

@PostMapping
@RequestMapping(value = "detail", method = RequestMethod.POST)
public ResponseEntity<?> getExerciseDetail(@RequestBody GetDetailExerciseRequest request){
Expand All @@ -157,6 +170,7 @@ public ResponseEntity<?> getExerciseDetail(@RequestBody GetDetailExerciseRequest
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(Map.of("message","Something went wrong, type must be quiz/essay/code"));
}
}

@PostMapping
@RequestMapping(value = "code/submit", method = RequestMethod.POST)
public ResponseEntity<?> submitCodeExercise(@Valid @RequestBody SubmitCodeExerciseRequest request){
Expand Down Expand Up @@ -245,6 +259,17 @@ public ResponseEntity<?> submitQuizExercise(@Valid @RequestBody CreateQuizSubmis
public ResponseEntity<?> submitEssayExercise(@Valid @RequestBody CreateEssaySubmissionRequest essaySubmission){
return ResponseEntity.status(HttpStatus.OK).body(this.essaySubmissionService.createSubmission(essaySubmission));
}

@PostMapping
@RequestMapping(value = "file/submit", method = RequestMethod.POST, consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
public ResponseEntity<?> submitFileExercise(@Valid @ModelAttribute CreateFileSubmissionRequest request, @RequestPart(required = false) MultipartFile file){
if (file == null){
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(Map.of("message", "Please upload your file"));
}
FileSubmission result = this.fileSubmissionService.createSubmission(request, file);
return ResponseEntity.status(HttpStatus.OK).body(result);
}

@GetMapping
@RequestMapping(value = "preview/{exerciseId}", method = RequestMethod.GET)
public ResponseEntity<?> getPreviewExercise(@PathVariable String exerciseId, @RequestParam String studentId){
Expand All @@ -270,9 +295,9 @@ public ResponseEntity<?> deleteExerciseById(@Valid @PathVariable String exercise
return ResponseEntity.status(HttpStatus.OK).body(Map.of("message", "Delete success"));
}

@PutMapping
@PutMapping
@RequestMapping(value = "code", method = RequestMethod.PUT)
public ResponseEntity<?> updateCodeExercise(@RequestBody UpdateCodeExerciseRequest request) {
public ResponseEntity<?> updateCodeExercise(@RequestBody UpdateCodeExerciseRequest request) {
CodeExercise updatedExercise = this.codeExerciseService.updateCodeExercise(request.getExerciseId(), request);

List<TestCase> testCases = request.getTestCases();
Expand All @@ -298,12 +323,14 @@ public ResponseEntity<?> updateQuizExercise(@RequestBody UpdateQuizExerciseReque
QuizExercise updatedExercise = this.quizExerciseService.updateQuizExercise(request.getExerciseId(), request);
return ResponseEntity.status(HttpStatus.OK).body(updatedExercise);
}

@PutMapping
@RequestMapping(value = "essay", method = RequestMethod.PUT)
public ResponseEntity<?> updateEssayExercise(@RequestBody UpdateEssayExerciseRequest request){
EssayExercise updatedExercise = this.essayExerciseService.updateEssayExercise(request.getExerciseId(), request);
return ResponseEntity.status(HttpStatus.OK).body(updatedExercise);
}

@PostMapping
@RequestMapping(value = "view", method = RequestMethod.POST)
public ResponseEntity<?> addPermissionExercise(@RequestBody CreatePermissionExerciseRequest request){
Expand Down Expand Up @@ -344,11 +371,13 @@ public ResponseEntity<?> getStudentSubmission(@PathVariable String submissionId,
ResponseEntity.status(HttpStatus.BAD_REQUEST).body(Map.of("message", "Something went wrong, type must be quiz/essay/code"));
};
}

@GetMapping
@RequestMapping(value = "all-submission/user/{userId}", method = RequestMethod.GET)
public ResponseEntity<?> getAllStudentSubmission(@PathVariable String userId, @RequestParam String courseId){
return ResponseEntity.status(HttpStatus.OK).body(this.exerciseService.getAllStudentSubmission(courseId, userId));
}

@GetMapping
@RequestMapping(value = "submit/user/{userId}", method = RequestMethod.GET)
public ResponseEntity<?> getExerciseByUserId(@RequestParam String exerciseId, @PathVariable String userId, @RequestParam String type) {
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/com/example/codeE/model/exercise/Exercise.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import jakarta.persistence.PrePersist;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import jdk.jfr.Description;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand Down Expand Up @@ -77,7 +76,7 @@ public class Exercise {

@Field
@NotNull(message = "Exercise type is required")
@Pattern(regexp = "^(quiz|essay|code|file)$", message = "Exercise type should be quiz, essay, or code")
@Pattern(regexp = "^(quiz|essay|code|file)$", message = "Exercise type should be quiz, essay, code or file.")
private String type;

@Field
Expand Down
19 changes: 13 additions & 6 deletions src/main/java/com/example/codeE/model/exercise/FileExercise.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
package com.example.codeE.model.exercise;

import com.example.codeE.model.exercise.common.QuizQuestion;
import com.example.codeE.request.exercise.file.CreateFileExerciseRequest;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

import java.util.Date;
import java.util.List;
import java.util.ArrayList;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Document(collection = "FileExercise")
public class FileExercise extends Exercise{
public FileExercise(String topicId, String exerciseName, String key, Date startTime, Date endTime, int durationTime, int reAttempt, String type, String exerciseDescription, boolean isShowAll, List<String> publicGroupIds) {
super(topicId, exerciseName, key, startTime, endTime, durationTime, reAttempt, type, exerciseDescription, isShowAll, publicGroupIds);
@Field
@NotNull(message = "Exercise's question is required")
private String question;

public FileExercise(CreateFileExerciseRequest request){
super(request.getTopicId(), request.getExerciseName(), request.getKey(), request.getStartTime(), request.getEndTime(), request.getDurationTime(), request.getReAttempt(), "file",request.getExerciseDescription(), false,
new ArrayList<String>());
this.question = request.getQuestion();
}
}
24 changes: 24 additions & 0 deletions src/main/java/com/example/codeE/model/exercise/FileSubmission.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.example.codeE.model.exercise;

import com.example.codeE.request.exercise.file.CreateFileSubmissionRequest;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Document(collection = "FileSubmission")
public class FileSubmission extends Submission {
@Field
private String fileUrl;

public FileSubmission(CreateFileSubmissionRequest request, float score) {
super(request.getStudentId(), request.getExerciseId(), score, true, "");
this.fileUrl = request.getUrl();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.codeE.repository;

import com.example.codeE.model.exercise.FileExercise;
import org.springframework.data.mongodb.repository.MongoRepository;

public interface FileExerciseRepository extends MongoRepository<FileExercise, String> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.codeE.repository;

import com.example.codeE.model.exercise.FileSubmission;
import org.springframework.data.mongodb.repository.MongoRepository;

public interface FileSubmissionRepository extends MongoRepository<FileSubmission, String> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.example.codeE.request.exercise.file;

import com.example.codeE.validator.id.ExistingId;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.Date;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ExistingId(targetClasses = {CreateFileExerciseRequest.class})
public class CreateFileExerciseRequest {
@NotNull(message = "Topic ID is required")
private String topicId;
@NotNull(message = "Exercise's name is required")
private String exerciseName;
@NotNull(message = "Exercise's key is required")
private String key;
@NotNull(message = "Start time is required")
private Date startTime;
@NotNull(message = "End time is required")
private Date endTime;
@NotNull(message = "Duration time is required")
private int durationTime;
private int reAttempt;
private String exerciseDescription;
@NotNull(message = "Question is required")
private String question;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.example.codeE.request.exercise.file;

import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class CreateFileSubmissionRequest {
@NotNull(message = "Student Id is required")
private String studentId;
@NotNull(message = "Exercise Id is required")
private String exerciseId;
private String url;
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package com.example.codeE.service.exercise;

import com.example.codeE.helper.LoggerHelper;
import com.example.codeE.model.exercise.CodeExercise;
import com.example.codeE.model.exercise.EssayExercise;
import com.example.codeE.model.exercise.Exercise;
import com.example.codeE.model.exercise.QuizExercise;
import com.example.codeE.model.exercise.*;
import com.example.codeE.model.topic.Topic;
import com.example.codeE.repository.*;
import com.example.codeE.request.exercise.AllStudentSubmissionResponse;
Expand Down Expand Up @@ -63,6 +60,11 @@ public Exercise saveCodeExercise(CodeExercise exercise) {
return this.exerciseRepository.save(exercise);
}

@Override
public Exercise saveFileExercise(FileExercise exercise) {
return this.exerciseRepository.save(exercise);
}

@Override
public ExerciseStudentResponse getPreviewExercise(String exerciseId, String studentId) {
var exercise = this.exerciseRepository.findById(exerciseId).orElseThrow(() -> new NoSuchElementException("No exercise found with ID: " + exerciseId));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package com.example.codeE.service.exercise;

import com.example.codeE.model.exercise.CodeExercise;
import com.example.codeE.model.exercise.EssayExercise;
import com.example.codeE.model.exercise.Exercise;
import com.example.codeE.model.exercise.QuizExercise;
import com.example.codeE.model.exercise.*;
import com.example.codeE.request.exercise.AllStudentSubmissionResponse;
import com.example.codeE.request.exercise.CreatePermissionExerciseRequest;
import com.example.codeE.request.exercise.ExerciseResponse;
Expand All @@ -15,6 +12,7 @@ public interface ExerciseService {
Exercise saveQuizExercise(QuizExercise exercise);
Exercise saveEsayExercise(EssayExercise exercise);
Exercise saveCodeExercise(CodeExercise exercise);
Exercise saveFileExercise(FileExercise exercise);
ExerciseStudentResponse getPreviewExercise(String exerciseId, String studentId);
List<ExerciseResponse> getExercisesByCourseId(String courseId);
Exercise getExerciseById(String exerciseId);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.example.codeE.service.exercise;

import com.example.codeE.helper.LoggerHelper;
import com.example.codeE.model.exercise.FileExercise;
import com.example.codeE.repository.FileExerciseRepository;
import com.example.codeE.repository.GroupRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.NoSuchElementException;

@Service
public class FileExerciseImpl implements FileExerciseService{
@Autowired
private FileExerciseRepository fileExerciseRepository;

@Autowired
private GroupRepository groupRepository;

@Override
public FileExercise createFileExercise(FileExercise fileExercise) {
try{
for(String groupId : fileExercise.getPublicGroupIds()){
this.groupRepository.findById(groupId).orElseThrow(() -> new NoSuchElementException("No Group found with ID: " + groupId));
}
if (fileExercise.getReAttempt() <= 0){
fileExercise.setReAttempt(1);
}
return this.fileExerciseRepository.save(fileExercise);
}catch (Exception e){
LoggerHelper.logError(e.getMessage());
throw new RuntimeException("Can not save file exercise");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.example.codeE.service.exercise;
import com.example.codeE.model.exercise.FileExercise;
public interface FileExerciseService {
FileExercise createFileExercise(FileExercise request);
}
Loading

0 comments on commit 3e6eb76

Please sign in to comment.