From 1bc22d7007efa85cf34053f74b57464f94346133 Mon Sep 17 00:00:00 2001 From: JunSang Date: Thu, 16 May 2024 23:14:18 +0900 Subject: [PATCH 1/2] =?UTF-8?q?[#27]=20Feat:=20ProblemRequestdDto,=20Probl?= =?UTF-8?q?emResponseDto=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sajang/devracebackend/domain/Problem.java | 17 +++++++++- .../dto/problem/ProblemRequestDto.java | 34 +++++++++++++++++++ .../dto/problem/ProblemResponseDto.java | 33 ++++++++++++++++++ .../service/impl/UserServiceImpl.java | 1 - 4 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/sajang/devracebackend/dto/problem/ProblemRequestDto.java create mode 100644 src/main/java/com/sajang/devracebackend/dto/problem/ProblemResponseDto.java diff --git a/src/main/java/com/sajang/devracebackend/domain/Problem.java b/src/main/java/com/sajang/devracebackend/domain/Problem.java index 70aba58..b7710b8 100644 --- a/src/main/java/com/sajang/devracebackend/domain/Problem.java +++ b/src/main/java/com/sajang/devracebackend/domain/Problem.java @@ -2,6 +2,7 @@ import com.sajang.devracebackend.domain.common.BaseEntity; import jakarta.persistence.*; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -20,7 +21,7 @@ public class Problem extends BaseEntity implements Serializable { private Long id; @Column(name = "number", unique = true) - private Integer number; + private Integer number; //백준 문제번호 private String title; @@ -45,4 +46,18 @@ public class Problem extends BaseEntity implements Serializable { @Column(name = "sample_output") private String sampleOutput; // 예제 출력 + + @Builder + public Problem(Long id, Integer number, String title, String content, String imageUrl, String problemInput, String problemOutput, String problemLimit, String sampleInput, String sampleOutput) { + this.id = id; + this.number = number; + this.title = title; + this.content = content; + this.imageUrl = imageUrl; + this.problemInput = problemInput; + this.problemOutput = problemOutput; + this.problemLimit = problemLimit; + this.sampleInput = sampleInput; + this.sampleOutput = sampleOutput; + } } \ No newline at end of file diff --git a/src/main/java/com/sajang/devracebackend/dto/problem/ProblemRequestDto.java b/src/main/java/com/sajang/devracebackend/dto/problem/ProblemRequestDto.java new file mode 100644 index 0000000..069764e --- /dev/null +++ b/src/main/java/com/sajang/devracebackend/dto/problem/ProblemRequestDto.java @@ -0,0 +1,34 @@ +package com.sajang.devracebackend.dto.problem; + + +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class ProblemRequestDto { + private Integer number; + private String title; + private String content; + private String imageUrl; + private String problemInput; + private String problemOutput; + private String problemLimit; + private String sampleInput; + private String sampleOutput; + + @Builder + public ProblemRequestDto(String imageUrl, String title,Integer number, String content, String problemInput, String problemOutput, String problemLimit, String sampleInput, String sampleOutput){ + this.imageUrl = imageUrl; + this.title = title; + this.number = number; + this.content =content; + this.problemInput = problemInput; + this.problemOutput = problemOutput; + this.problemLimit = problemLimit; + this.sampleInput = sampleInput; + this.sampleOutput = sampleOutput; + + } +} diff --git a/src/main/java/com/sajang/devracebackend/dto/problem/ProblemResponseDto.java b/src/main/java/com/sajang/devracebackend/dto/problem/ProblemResponseDto.java new file mode 100644 index 0000000..6ed3220 --- /dev/null +++ b/src/main/java/com/sajang/devracebackend/dto/problem/ProblemResponseDto.java @@ -0,0 +1,33 @@ +package com.sajang.devracebackend.dto.problem; + +import com.sajang.devracebackend.domain.Problem; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class ProblemResponseDto { + private Integer number; + private String title; + private String content; + private String imageUrl; + private String problemInput; + private String problemOutput; + private String problemLimit; + private String sampleInput; + private String sampleOutput; + + @Builder + public ProblemResponseDto(Problem problem){ + this.number = problem.getNumber(); + this.imageUrl = problem.getImageUrl(); + this.title = problem.getTitle(); + this.content = problem.getContent(); + this.problemInput = problem.getProblemInput(); + this.problemOutput = problem.getProblemOutput(); + this.problemLimit = problem.getProblemLimit(); + this.sampleInput = problem.getSampleInput(); + this.sampleOutput = problem.getSampleOutput(); + } +} diff --git a/src/main/java/com/sajang/devracebackend/service/impl/UserServiceImpl.java b/src/main/java/com/sajang/devracebackend/service/impl/UserServiceImpl.java index 7c4ee3e..3d915c7 100644 --- a/src/main/java/com/sajang/devracebackend/service/impl/UserServiceImpl.java +++ b/src/main/java/com/sajang/devracebackend/service/impl/UserServiceImpl.java @@ -17,7 +17,6 @@ public class UserServiceImpl implements UserService { private final UserRepository userRepository; - @Transactional @Override public SolvedResponseDto checkUserSolvedCount(String bojId){ From 32acb856a7314f84c5ff6fd732ae6e80701844f1 Mon Sep 17 00:00:00 2001 From: JunSang Date: Fri, 17 May 2024 06:37:53 +0900 Subject: [PATCH 2/2] =?UTF-8?q?[#27]=20Feat:=20Service=EC=97=90=20?= =?UTF-8?q?=ED=81=AC=EB=A1=A4=EB=A7=81=20=EB=A1=9C=EC=A7=81=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 + .../dto/problem/ProblemDto.java | 58 +++++++++++++++++ .../dto/problem/ProblemRequestDto.java | 34 ---------- .../dto/problem/ProblemResponseDto.java | 33 ---------- .../service/ProblemService.java | 3 + .../service/impl/ProblemServiceImpl.java | 63 +++++++++++++++++++ src/main/resources/application.properties | 2 +- 7 files changed, 127 insertions(+), 68 deletions(-) create mode 100644 src/main/java/com/sajang/devracebackend/dto/problem/ProblemDto.java delete mode 100644 src/main/java/com/sajang/devracebackend/dto/problem/ProblemRequestDto.java delete mode 100644 src/main/java/com/sajang/devracebackend/dto/problem/ProblemResponseDto.java diff --git a/build.gradle b/build.gradle index b458e47..aa3fcdf 100644 --- a/build.gradle +++ b/build.gradle @@ -38,6 +38,8 @@ dependencies { testImplementation 'org.springframework.security:spring-security-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' implementation 'org.springframework.boot:spring-boot-starter-webflux' + implementation 'org.jsoup:jsoup:1.15.3' + implementation group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1' // Swagger API implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2") diff --git a/src/main/java/com/sajang/devracebackend/dto/problem/ProblemDto.java b/src/main/java/com/sajang/devracebackend/dto/problem/ProblemDto.java new file mode 100644 index 0000000..19f476f --- /dev/null +++ b/src/main/java/com/sajang/devracebackend/dto/problem/ProblemDto.java @@ -0,0 +1,58 @@ +package com.sajang.devracebackend.dto.problem; + +import com.sajang.devracebackend.domain.Problem; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class ProblemDto { + + private String title; + private String content; + private String imageUrl; + private String problemInput; + private String problemOutput; + private String problemLimit; + private String sampleInput; + private String sampleOutput; + private Integer number; + + @Builder + public ProblemDto(String imageUrl, String title, Integer number,String content, String problemInput, String problemOutput, String problemLimit, String sampleInput, String sampleOutput){ + this.imageUrl = imageUrl; + this.title = title; + this.number = number; + this.content =content; + this.problemInput = problemInput; + this.problemOutput = problemOutput; + this.problemLimit = problemLimit; + this.sampleInput = sampleInput; + this.sampleOutput = sampleOutput; + } + public Problem toEntity(){ + return Problem.builder() + .imageUrl(imageUrl) + .title(title) + .number(number) + .content(content) + .problemInput(problemInput) + .problemOutput(problemOutput) + .problemLimit(problemLimit) + .sampleInput(sampleInput) + .sampleOutput(sampleOutput) + .build(); + } + public ProblemDto(Problem problem){ + this.number = problem.getNumber(); + this.imageUrl = problem.getImageUrl(); + this.title = problem.getTitle(); + this.content = problem.getContent(); + this.problemInput = problem.getProblemInput(); + this.problemOutput = problem.getProblemOutput(); + this.problemLimit = problem.getProblemLimit(); + this.sampleInput = problem.getSampleInput(); + this.sampleOutput = problem.getSampleOutput(); + } +} diff --git a/src/main/java/com/sajang/devracebackend/dto/problem/ProblemRequestDto.java b/src/main/java/com/sajang/devracebackend/dto/problem/ProblemRequestDto.java deleted file mode 100644 index 069764e..0000000 --- a/src/main/java/com/sajang/devracebackend/dto/problem/ProblemRequestDto.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.sajang.devracebackend.dto.problem; - - -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor -public class ProblemRequestDto { - private Integer number; - private String title; - private String content; - private String imageUrl; - private String problemInput; - private String problemOutput; - private String problemLimit; - private String sampleInput; - private String sampleOutput; - - @Builder - public ProblemRequestDto(String imageUrl, String title,Integer number, String content, String problemInput, String problemOutput, String problemLimit, String sampleInput, String sampleOutput){ - this.imageUrl = imageUrl; - this.title = title; - this.number = number; - this.content =content; - this.problemInput = problemInput; - this.problemOutput = problemOutput; - this.problemLimit = problemLimit; - this.sampleInput = sampleInput; - this.sampleOutput = sampleOutput; - - } -} diff --git a/src/main/java/com/sajang/devracebackend/dto/problem/ProblemResponseDto.java b/src/main/java/com/sajang/devracebackend/dto/problem/ProblemResponseDto.java deleted file mode 100644 index 6ed3220..0000000 --- a/src/main/java/com/sajang/devracebackend/dto/problem/ProblemResponseDto.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.sajang.devracebackend.dto.problem; - -import com.sajang.devracebackend.domain.Problem; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor -public class ProblemResponseDto { - private Integer number; - private String title; - private String content; - private String imageUrl; - private String problemInput; - private String problemOutput; - private String problemLimit; - private String sampleInput; - private String sampleOutput; - - @Builder - public ProblemResponseDto(Problem problem){ - this.number = problem.getNumber(); - this.imageUrl = problem.getImageUrl(); - this.title = problem.getTitle(); - this.content = problem.getContent(); - this.problemInput = problem.getProblemInput(); - this.problemOutput = problem.getProblemOutput(); - this.problemLimit = problem.getProblemLimit(); - this.sampleInput = problem.getSampleInput(); - this.sampleOutput = problem.getSampleOutput(); - } -} diff --git a/src/main/java/com/sajang/devracebackend/service/ProblemService.java b/src/main/java/com/sajang/devracebackend/service/ProblemService.java index 8abfcfe..9ebb2ff 100644 --- a/src/main/java/com/sajang/devracebackend/service/ProblemService.java +++ b/src/main/java/com/sajang/devracebackend/service/ProblemService.java @@ -1,4 +1,7 @@ package com.sajang.devracebackend.service; +import com.sajang.devracebackend.dto.problem.ProblemDto; + public interface ProblemService { + //ProblemDto crawlProblem(Integer problemNumber); } diff --git a/src/main/java/com/sajang/devracebackend/service/impl/ProblemServiceImpl.java b/src/main/java/com/sajang/devracebackend/service/impl/ProblemServiceImpl.java index a360dbb..beab3fa 100644 --- a/src/main/java/com/sajang/devracebackend/service/impl/ProblemServiceImpl.java +++ b/src/main/java/com/sajang/devracebackend/service/impl/ProblemServiceImpl.java @@ -1,13 +1,76 @@ package com.sajang.devracebackend.service.impl; +import com.sajang.devracebackend.domain.Problem; +import com.sajang.devracebackend.dto.problem.ProblemDto; import com.sajang.devracebackend.repository.ProblemRepository; import com.sajang.devracebackend.service.ProblemService; import lombok.RequiredArgsConstructor; +import org.json.simple.JSONObject; import org.springframework.stereotype.Service; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; + +import org.jsoup.select.Elements; +import org.springframework.transaction.annotation.Transactional; + +import java.io.IOException; @Service @RequiredArgsConstructor public class ProblemServiceImpl implements ProblemService { private final ProblemRepository problemRepository; + + @Transactional + //@Override + public ProblemDto crawlProblem(Integer problemNumber) throws IOException{ + String Url = "https://www.acmicpc.net/problem/" + problemNumber; + Document doc = Jsoup.connect(Url).get(); + + //#problem-body에 접근 + Elements contents = doc.select("#problem-body"); //body에 접근 + Elements contentHead = doc.select(".page-header h1"); //문제 title 추출을 위한 page-header에 접근 + Elements sampleDataElement = doc.getElementsByClass("col-md-6"); //예제 문제쪽 요소에 따로 접근 + + int Amount = sampleDataElement.size(); //예제 문제 개수 추출 + + JSONObject sampleInputJson = new JSONObject(); + JSONObject sampleOutputJson = new JSONObject(); + for(int i =1;i<=Amount/2;i++){ + sampleInputJson.put("sampleInput"+i,contents.select(".col-md-6 #sample-input-"+i).text()); //예제객체 담기 + sampleOutputJson.put("sampleOutput"+i,contents.select(".col-md-6 #sample-output-"+i).text()); //예제객체 담기 + } + + String sampleInput = sampleInputJson.toString(); //Json -> String + String sampleOutput = sampleOutputJson.toString(); //Json -> String + + String problemTitle = contentHead.select("#problem_title").text(); //title 은 따로 접근. body가 아닌 header 부분 + ProblemDto data = ProblemDto.builder() //Builder를 이용해 ProblemDto 값으로 저장 + .imageUrl(contents.select("p img").attr("abs:src")) + .number(problemNumber) + .title(problemTitle) + .content(contents.select("#problem_description").toString()) + .problemInput(contents.select("#problem_input").toString()) + .problemOutput(contents.select("#problem_output").toString()) + .problemLimit(contents.select("#problem_limit").toString()) + .sampleInput(sampleInput) + .sampleOutput(sampleOutput) + .build(); + + ProblemDto problemDto = new ProblemDto( + data.getImageUrl(), + data.getTitle(), + data.getNumber(), + data.getContent(), + data.getProblemInput(), + data.getProblemOutput(), + data.getProblemLimit(), + data.getSampleInput(), + data.getSampleOutput() + ); + + Problem problemEntity = problemRepository.save(problemDto.toEntity()); + + return new ProblemDto(problemEntity); + } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index abee673..1cfddaf 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -8,4 +8,4 @@ spring.mvc.pathmatch.matching-strategy=ant_path_matcher spring.servlet.multipart.maxFileSize=30MB spring.servlet.multipart.maxRequestSize=30MB -spring.profiles.active=local,swagger,mongodb,oauth \ No newline at end of file +spring.profiles.active=local,swagger,mongodb,oauth,bucket \ No newline at end of file