Skip to content
Open
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
48 changes: 32 additions & 16 deletions src/main/java/com/example/capd/User/domain/Contest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,53 @@
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

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

@Entity
@Entity(name = "contest")
@Getter
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
//테스트용
@Builder
@AllArgsConstructor
public class Contest {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(length = 200)
private String title;

//참여할게요 매핑
@OneToMany(mappedBy = "contest")
private List<Participation> participations = new ArrayList<>();
@Column(length = 200)
private String host;

@Column(length = 200)
private String targetParticipants;

@Column(length = 40)
private String receptionPeriod;

@Column(length = 40)
private String decisionPeriod;

@Column(length = 200)
private String compatitionArea;

@Column(length = 200)
private String award;
@Column(length = 300)
private String homepage;

//유저 매핑
// @ManyToOne
// @JoinColumn(name = "user_id")
// private User user;
@Column(length = 20)
private String howToApply;

// 팀 매핑
@OneToMany(mappedBy = "contest")
private List<Team> teams = new ArrayList<>();
@Column(length = 20)
private String fee;

@Column(length = 400)
private String image;

@Column(length = 2000)
private String detailText;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.example.capd.contest.controller;

import com.example.capd.contest.controller.dto.ContestResponse;
import com.example.capd.contest.service.ContestService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping("/contests")
public class ContestController {
private final ContestService contestService;

@GetMapping
public ResponseEntity<List<ContestResponse>> findAllContest() {
final List<ContestResponse> contestResponses = contestService.findAllContest();
return ResponseEntity.ok(contestResponses);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.example.capd.contest.controller.dto;

public record ContestResponse(
Long id,
String title,
String host,
String targetParticipants,
String receptionPeriod,
String decisionPeriod,
String compatitionArea,
String award,
String homepage,
String howToApply,
String fee,
String image,
String detailText
){}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.example.capd.contest.repository;

import com.example.capd.User.domain.Contest;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Map;

@Repository
public interface ContestRepository extends JpaRepository<Contest, Long> {

@Query(value = "select * from capstone_crawling.contest", nativeQuery = true)
List<Map<String, Object>> fetchDataFromDatabase();

Contest findByTitle(String title);
}
38 changes: 38 additions & 0 deletions src/main/java/com/example/capd/contest/service/ContestService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.example.capd.contest.service;

import com.example.capd.User.domain.Contest;
import com.example.capd.contest.controller.dto.ContestResponse;
import com.example.capd.contest.repository.ContestRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Transactional
@RequiredArgsConstructor
public class ContestService {
private final ContestRepository contestRepository;

@Transactional(readOnly = true)
public List<ContestResponse> findAllContest() {
final List<Contest> contests = contestRepository.findAll();

return contests.stream()
.map(contest -> new ContestResponse(
contest.getId(),
contest.getTitle(),
contest.getHost(),
contest.getTargetParticipants(),
contest.getReceptionPeriod(),
contest.getDecisionPeriod(),
contest.getCompatitionArea(),
contest.getAward(),
contest.getHomepage(),
contest.getHowToApply(),
contest.getFee(),
contest.getImage(),
contest.getDetailText())).toList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.example.capd.contest.service;

import com.example.capd.User.domain.Contest;
import com.example.capd.contest.repository.ContestRepository;
import lombok.RequiredArgsConstructor;
import org.apache.tomcat.util.json.JSONParser;
import org.apache.tomcat.util.json.ParseException;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.io.FileReader;
import java.io.IOException;
import java.util.List;

@Service
@RequiredArgsConstructor
public class CrawlingScriptService {

private final ContestRepository contestRepository;
private final List<String> filePath =
List.of("contestkorea__contest_data.json",
"wevity_contest_data.json",
"thinkgood_contest_data.json");

@Scheduled(fixedRate = 30000)
public void executeCrawlingScript() {
try {
String pythonScriptPath = "C:/IntelliJ/crawlingpracticeCopy/src/main/java/crawlingpractice/example/crawlingpractice/contestkorea_crawling.py";

ProcessBuilder processBuilder = new ProcessBuilder("python", pythonScriptPath);
processBuilder.redirectErrorStream(true);
Process process = processBuilder.start();

int exitCode = process.waitFor();
System.out.println("파이썬 스크립트 실행 종료, 종료 코드: " + exitCode);

filePath.forEach(this::readContestkorea);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}

private void readContestkorea(final String siteName) {
try (FileReader reader = new FileReader(siteName)) {
JSONParser parser = new JSONParser(reader);
JSONArray jsonArray = (JSONArray) parser.parse();

for (Object json : jsonArray) {
JSONObject jsonObj = (JSONObject) json;
String contestTitle = (String) jsonObj.get(siteName);

Contest existingContest = contestRepository.findByTitle(contestTitle);
if (existingContest != null) {
continue;
}

final Contest contest = Contest.builder()
.title((String) jsonObj.get("contest_title"))
.host((String) jsonObj.get("contest_host"))
.targetParticipants((String) jsonObj.get("contest_target_participants"))
.receptionPeriod((String) jsonObj.get("contest_reception_period"))
.decisionPeriod((String) jsonObj.get("contest_decision_period"))
.compatitionArea((String) jsonObj.get("contest_compatition_area"))
.award((String) jsonObj.get("contest_award"))
.homepage((String) jsonObj.get("contest_homepage"))
.howToApply((String) jsonObj.get("contest_how_to_apply"))
.fee((String) jsonObj.get("contest_fee"))
.image((String) jsonObj.get("contest_image"))
.detailText((String) jsonObj.get("contest_detail_text"))
.build();

contestRepository.save(contest);
}
} catch (IOException | ParseException e) {
e.printStackTrace();
}
}
}