Skip to content

Commit

Permalink
Merge pull request #503 from SWM-NM/dev
Browse files Browse the repository at this point in the history
백준 제출 시 solution-id반환하게 설정 #501
  • Loading branch information
miiiinju1 authored Oct 24, 2023
2 parents be8e56e + b8147a9 commit 1c01939
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import swm_nm.morandi.domain.codeSubmit.dto.BaekjoonUserDto;
import swm_nm.morandi.domain.codeSubmit.dto.SolutionIdDto;
import swm_nm.morandi.domain.codeSubmit.dto.SubmitCodeDto;
import swm_nm.morandi.domain.codeSubmit.service.BaekjoonSubmitService;

Expand All @@ -21,7 +22,7 @@ public class CodeSubmitController {

@PostMapping("/baekjoon")
@Operation(summary = "문제 번호, 언어이름, 소스코드를 백준에 제출하는 컨트롤러 ", description = "사용자가 테스트 중 코드를 제출하는 경우 백준에 제출하는 컨트롤러입니다.")
public ResponseEntity<String> submit(@RequestBody @Valid SubmitCodeDto submitCodeDto) {
public ResponseEntity<SolutionIdDto> submit(@RequestBody @Valid SubmitCodeDto submitCodeDto) {
return submitService.submit(submitCodeDto);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package swm_nm.morandi.domain.codeSubmit.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

@Setter
@Getter
@AllArgsConstructor
public class SolutionIdDto {
public String solutionId;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
Expand All @@ -13,8 +14,8 @@
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import swm_nm.morandi.domain.codeSubmit.constants.CodeVisuabilityConstants;
import swm_nm.morandi.domain.codeSubmit.constants.SubmitConstants;
import swm_nm.morandi.domain.codeSubmit.dto.BaekjoonUserDto;
import swm_nm.morandi.domain.codeSubmit.dto.SolutionIdDto;
import swm_nm.morandi.domain.member.entity.Member;
import swm_nm.morandi.domain.member.repository.MemberRepository;
import swm_nm.morandi.global.exception.MorandiException;
Expand Down Expand Up @@ -86,15 +87,16 @@ private void updateMemberInfo(Member member, String bojId){

}

public ResponseEntity<String> submit(SubmitCodeDto submitCodeDto) {
public ResponseEntity<SolutionIdDto> submit(SubmitCodeDto submitCodeDto) {
validateBojProblemId(submitCodeDto.getBojProblemId());

Long memberId = SecurityUtils.getCurrentMemberId();
String cookie = getCookieFromRedis(generateKey(memberId));
String CSRFKey = getCSRFKey(cookie, submitCodeDto.getBojProblemId());
String submitResult = sendSubmitRequest(cookie, CSRFKey, submitCodeDto);

return processSubmitResult(submitResult);
String acmicpcUrl = String.format("https://www.acmicpc.net/submit/%s", submitCodeDto.getBojProblemId());
HttpHeaders headers = createHeaders(cookie);
return processSubmitResult(submitResult,acmicpcUrl,headers);
}
private void validateBojProblemId(String bojProblemId) {
try {
Expand Down Expand Up @@ -168,10 +170,48 @@ private MultiValueMap<String, String> createParameters(SubmitCodeDto submitCodeD
parameters.add("csrf_key", CSRFKey);
return parameters;
}
private ResponseEntity<String> processSubmitResult(String submitResult) {
if (submitResult.contains("status")) {
return new ResponseEntity<>(HttpStatus.OK);
private ResponseEntity<SolutionIdDto> processSubmitResult(String location,String acmicpcUrl,HttpHeaders headers){

if (location.contains("status")) {
if (!location.startsWith("http"))
location = URI.create(acmicpcUrl).resolve(location).toString();
ResponseEntity<String> redirectedResponse = restTemplate.exchange(location, HttpMethod.GET, new HttpEntity<>(headers), String.class);

// HTML에서 solution-id를 추출합니다.
SolutionIdDto solutionId = extractSolutionIdFromHtml(redirectedResponse.getBody());

if (solutionId.getSolutionId() != null) {
System.out.println("Extracted Solution ID: " + solutionId);
return ResponseEntity.status(redirectedResponse.getStatusCode()).body(solutionId);

} else {
throw new MorandiException(SubmitErrorCode.CANT_FIND_SOLUTION_ID);
}


}
throw new MorandiException(SubmitErrorCode.BAEKJOON_LOGIN_ERROR);
}
private SolutionIdDto extractSolutionIdFromHtml(String html) {
// HTML을 파싱합니다.
Document doc = Jsoup.parse(html);

// 테이블을 선택합니다.
Element table = doc.getElementById("status-table");

// 첫 번째 행을 선택합니다.
Element firstRow = table.select("tbody tr").first();

// 첫 번째 행에서 solution-id를 추출합니다.
Element solutionIdElement = firstRow.select("td").first(); // 첫 번째 열에 있는 것이 solution-id 입니다.

if (solutionIdElement != null) {
String solutionId = solutionIdElement.text();

return new SolutionIdDto(solutionId);

} else {
throw new MorandiException(SubmitErrorCode.CANT_FIND_SOLUTION_ID);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ public enum SubmitErrorCode implements ErrorCode {
COOKIE_NOT_EXIST(HttpStatus.BAD_REQUEST,"쿠키가 존재하지 않습니다. 익스텐션을 실행해 주세요"),
BAEKJOON_INVALID_ID(HttpStatus.BAD_REQUEST,"초기에 등록한 백준 ID로 로그인 해주세요"),
BAEKJOON_UNKNOWN_ERROR(HttpStatus.INTERNAL_SERVER_ERROR,"알 수 없는 오류가 발생했습니다"),
INVALID_BOJPROBLEM_NUMBER(HttpStatus.BAD_REQUEST,"유효하지 않은 문제 번호입니다");
INVALID_BOJPROBLEM_NUMBER(HttpStatus.BAD_REQUEST,"유효하지 않은 문제 번호입니다"),
CANT_FIND_SOLUTION_ID(HttpStatus.BAD_REQUEST,"Solution ID를 찾을 수 없습니다");

//TODO
//크롬익스텐션에서 fetch요청 시 forbidden오면 저장된 쿠키 null로 변경하고, 다시 로그인하라는 메시지 띄우기
Expand Down

0 comments on commit 1c01939

Please sign in to comment.