Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

백준 제출 시 solution-id반환하게 설정 #501 #503

Merged
merged 2 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading