Skip to content

Commit

Permalink
Merge pull request #52 from Tave100Shot/28-feat-컴파일러
Browse files Browse the repository at this point in the history
feat 컴파일러
  • Loading branch information
hyeonbinn authored Jan 24, 2024
2 parents 74fb6fb + 65fedc2 commit ccf8652
Show file tree
Hide file tree
Showing 10 changed files with 277 additions and 4 deletions.
9 changes: 6 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,13 @@ dependencies {
// redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'io.lettuce:lettuce-core'

// jsoup
implementation 'org.jsoup:jsoup:1.15.4'

// csv
implementation 'com.opencsv:opencsv:5.5.2'
implementation 'commons-io:commons-io:2.11.0'
}

tasks.named('bootBuildImage') {
Expand All @@ -83,5 +87,4 @@ tasks.named('test') {
// for queryDSL
clean {
delete file('src/main/generated')
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.api.TaveShot.domain.compiler.controller;

import com.api.TaveShot.domain.compiler.dto.ProblemDto;
import com.api.TaveShot.domain.compiler.service.ProblemService;
import com.api.TaveShot.global.success.SuccessResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/compile")
public class CompilerController {

private final ProblemService problemService;
//private final CompilerService compilerService;

@Operation(summary = "문제 정보 가져오기", description = "해당 문제 번호의 문제 정보들을 보여줍니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "문제 정보 가져오기 성공",
content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
schema = @Schema(implementation = ProblemDto.class)))
})
@GetMapping("/problems/{id}")
public SuccessResponse<ProblemDto> getProblem(@PathVariable String id) {
ProblemDto problemDto = problemService.getProblemById(id);
return new SuccessResponse<>(problemDto);
}

/*@Operation(summary = "코드 컴파일링 및 채점", description = "해당 문제 풀이에 대한 채점 결과를 보여줍니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "채점 성공",
content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
schema = @Schema(implementation = String.class)))
})
@PostMapping("/submit")
public SuccessResponse<String> submitCode(@RequestBody @Validated SubmissionRequestDto submissionRequestDto) {
String result = compilerService.submitCode(submissionRequestDto);
return new SuccessResponse<>(result);
}*/
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.api.TaveShot.domain.compiler.converter;

import com.api.TaveShot.domain.compiler.domain.BojProblem;
import com.api.TaveShot.domain.compiler.dto.ProblemDto;
import org.springframework.stereotype.Component;

import java.util.Optional;

public class ProblemConverter {

public static Optional<ProblemDto> convertToDto(BojProblem bojProblem) {
return Optional.ofNullable(bojProblem)
.map(bp -> ProblemDto.builder()
.id(bp.getId())
.title(bp.getTitle())
.description(bp.getDescription())
.inputDescription(bp.getInputDescription())
.outputDescription(bp.getOutputDescription())
.sampleInput(bp.getSampleInput())
.sampleOutput(bp.getSampleOutput())
.build());
}

public static Optional<BojProblem> convertToEntity(ProblemDto problemDto) {
return Optional.ofNullable(problemDto)
.map(pd -> BojProblem.builder()
.id(pd.getId())
.title(pd.getTitle())
.description(pd.getDescription())
.inputDescription(pd.getInputDescription())
.outputDescription(pd.getOutputDescription())
.sampleInput(pd.getSampleInput())
.sampleOutput(pd.getSampleOutput())
.build());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.api.TaveShot.domain.compiler.domain;

import jakarta.persistence.*;
import lombok.*;

@Entity
@Table(name = "bog_problems")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@AllArgsConstructor
@Builder
public class BojProblem {

@Id
@Column(name = "ID", columnDefinition = "TEXT")
private String id;

@Column(name = "Title", columnDefinition = "TEXT")
private String title;

@Lob
@Column(name = "Description")
private String description;

@Lob
@Column(name = "Input Description")
private String inputDescription;

@Column(name = "Output Description", columnDefinition = "TEXT")
private String outputDescription;

@Column(name = "Sample Input", columnDefinition = "TEXT")
private String sampleInput;

@Column(name = "Sample Output", columnDefinition = "TEXT")
private String sampleOutput;

}
42 changes: 42 additions & 0 deletions src/main/java/com/api/TaveShot/domain/compiler/dto/ProblemDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.api.TaveShot.domain.compiler.dto;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonRawValue;
import com.opencsv.bean.CsvBindByName;
import lombok.*;

@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class ProblemDto {

@JsonProperty("ID")
private String id;

@JsonProperty("Title")
private String title;

@JsonProperty("Description")
private String description;

@JsonProperty("Input Description")
private String inputDescription;

@JsonProperty("Output Description")
private String outputDescription;

@JsonProperty("Sample Input")
private String sampleInput;

@JsonProperty("Sample Output")
private String sampleOutput;

private String problemUrl;

public String getProblemUrl(){
this.problemUrl = "https://www.acmicpc.net/problem/" + this.id;
return this.problemUrl;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*package com.api.TaveShot.domain.compiler.dto;
import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class SubmissionRequestDto {
@NotEmpty
private String problemId;
@NotEmpty
private String language;
@NotEmpty
private String sourceCode;
}*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.api.TaveShot.domain.compiler.repository;

import com.api.TaveShot.domain.compiler.domain.BojProblem;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ProblemRepository extends JpaRepository<BojProblem, String> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*package com.api.TaveShot.domain.compiler.service;
import com.api.TaveShot.domain.compiler.dto.SubmissionRequestDto;
import com.api.TaveShot.global.exception.ApiException;
import com.api.TaveShot.global.exception.ErrorType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.Map;
@Service
public class CompilerService {
private static final String SUBMIT_CODE_URL = "http://43.202.52.177/submitCode";
private static final String RESULT_URL = "http://43.202.52.177/result/";
private static final int MAX_ATTEMPTS = 10;
private static final long SLEEP_TIME_MILLIS = 5000;
public String submitCode(SubmissionRequestDto submissionRequestDto) {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Map> submitResponse = restTemplate.postForEntity(SUBMIT_CODE_URL, submissionRequestDto, Map.class);
String submissionId = (String) submitResponse.getBody().get("submission_id");
String result = "결과 처리 중";
int attempts = 0;
while (result.equals("결과 처리 중") && attempts < MAX_ATTEMPTS) {
ResponseEntity<Map> resultResponse = restTemplate.getForEntity(RESULT_URL + submissionId, Map.class);
result = (String) resultResponse.getBody().get("result");
if (result.contains("정답이 준비되지 않아, 코드를 제출할 수 없습니다.")) {
throw new ApiException(ErrorType._SUBMIT_PAGE_NOT_FOUND);
}
try {
Thread.sleep(SLEEP_TIME_MILLIS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
attempts++;
}
return result;
}
}*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.api.TaveShot.domain.compiler.service;

import com.api.TaveShot.domain.compiler.converter.ProblemConverter;
import com.api.TaveShot.domain.compiler.domain.BojProblem;
import com.api.TaveShot.domain.compiler.dto.ProblemDto;
import com.api.TaveShot.domain.compiler.repository.ProblemRepository;
import com.api.TaveShot.global.exception.ApiException;
import com.api.TaveShot.global.exception.ErrorType;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Optional;


@Service
@RequiredArgsConstructor
public class ProblemService {

private final ProblemRepository problemRepository;

public ProblemDto getProblemById(String id) {
BojProblem bojProblem = problemRepository.findById(id)
.orElseThrow(() -> new ApiException(ErrorType._PROBLEM_NOT_FOUND));

return ProblemConverter.convertToDto(bojProblem).orElseThrow(() -> new ApiException(ErrorType._PROBLEM_CONVERSION_ERROR));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,14 @@ public enum ErrorType {
_GITHUB_REPO_NOT_FOUND(NOT_FOUND, "GITHUB_4040", "요청한 GitHub 리포지토리를 찾을 수 없습니다."),
_GITHUB_DESCRIPTION_NOT_FOUND(NOT_FOUND, "GITHUB_4041", "GitHub 리포지토리의 설명을 찾을 수 없습니다."),
_GITHUB_SERVER_ERROR(INTERNAL_SERVER_ERROR, "GITHUB_5000", "GitHub API 서버에서 오류가 발생했습니다."),
_GITHUB_API_ERROR(INTERNAL_SERVER_ERROR, "GITHUB_5001", "GitHub API 요청 중 일반 오류가 발생했습니다.");
_GITHUB_API_ERROR(INTERNAL_SERVER_ERROR, "GITHUB_5001", "GitHub API 요청 중 일반 오류가 발생했습니다."),


// ------------------------------------------ Compile ------------------------------------------
_PROBLEM_NOT_FOUND(NOT_FOUND, "PROBLEM_4040", "요청한 문제 번호를 찾을 수 없습니다."),
_SUBMIT_PAGE_NOT_FOUND(NOT_FOUND, "COMPILE_4040", "아직 정답이 준비 되지 않아 코드를 제출할 수 없습니다."),
_PROBLEM_CONVERSION_ERROR(INTERNAL_SERVER_ERROR, "PROBLEM_5002", "문제 정보 변환 중 오류가 발생했습니다.")

;

private final HttpStatus status;
Expand Down

0 comments on commit ccf8652

Please sign in to comment.