diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..9a874b5 Binary files /dev/null and b/.DS_Store differ diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 0000000..7b0d367 Binary files /dev/null and b/src/.DS_Store differ diff --git a/src/main/.DS_Store b/src/main/.DS_Store new file mode 100644 index 0000000..55c1fcb Binary files /dev/null and b/src/main/.DS_Store differ diff --git a/src/main/java/.DS_Store b/src/main/java/.DS_Store new file mode 100644 index 0000000..db39f98 Binary files /dev/null and b/src/main/java/.DS_Store differ diff --git a/src/main/java/cmf/.DS_Store b/src/main/java/cmf/.DS_Store new file mode 100644 index 0000000..4a1c4db Binary files /dev/null and b/src/main/java/cmf/.DS_Store differ diff --git a/src/main/java/cmf/commitField/.DS_Store b/src/main/java/cmf/commitField/.DS_Store new file mode 100644 index 0000000..23d2133 Binary files /dev/null and b/src/main/java/cmf/commitField/.DS_Store differ diff --git a/src/main/java/cmf/commitField/domain/.DS_Store b/src/main/java/cmf/commitField/domain/.DS_Store new file mode 100644 index 0000000..f943dc4 Binary files /dev/null and b/src/main/java/cmf/commitField/domain/.DS_Store differ diff --git a/src/main/java/cmf/commitField/domain/commit/sinceCommit/controller/SinceCommitController.java b/src/main/java/cmf/commitField/domain/commit/sinceCommit/controller/SinceCommitController.java new file mode 100644 index 0000000..b5fae86 --- /dev/null +++ b/src/main/java/cmf/commitField/domain/commit/sinceCommit/controller/SinceCommitController.java @@ -0,0 +1,95 @@ +package cmf.commitField.domain.commit.sinceCommit.controller; + +import cmf.commitField.domain.commit.sinceCommit.dto.SinceCommitResponseDto; +import cmf.commitField.domain.commit.sinceCommit.service.SinceCommitService; +import lombok.RequiredArgsConstructor; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.time.LocalDateTime; +import java.time.temporal.TemporalAdjusters; +import java.util.List; + +@RestController +@RequiredArgsConstructor +public class SinceCommitController { + private final SinceCommitService sinceCommitService; + + @GetMapping("/api/github/commits-since") + public ResponseEntity> getCommits( + @RequestParam String owner, + @RequestParam String repo, + @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime since, + @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime until + ) { + List sinceCommits = sinceCommitService.getSinceCommits(owner, repo, since, until); + + return ResponseEntity.ok(sinceCommits); + } + + // 시즌 별 커밋 수 불러오기 + + // 봄 시즌 + @GetMapping("/api/github/commits-spring") + public ResponseEntity> getSpringSeasonCommits( + @RequestParam String owner, + @RequestParam String repo + ) { + int currentYear = LocalDateTime.now().getYear(); + LocalDateTime since = LocalDateTime.of(2024, 3, 1, 0, 0); + LocalDateTime until = LocalDateTime.of(2024, 5, 31, 23, 59, 59); + + List sinceCommits = sinceCommitService.getSinceCommits(owner, repo, since, until); + + return ResponseEntity.ok(sinceCommits); + } + + // 여름 시즌 + @GetMapping("/api/github/commits-summer") + public ResponseEntity> getSummerSeasonCommits( + @RequestParam String owner, + @RequestParam String repo + ) { + int currentYear = LocalDateTime.now().getYear(); + LocalDateTime since = LocalDateTime.of(currentYear, 6, 1, 0, 0); + LocalDateTime until = LocalDateTime.of(currentYear, 8, 31, 23, 59, 59); + + List sinceCommits = sinceCommitService.getSinceCommits(owner, repo, since, until); + + return ResponseEntity.ok(sinceCommits); + } + + // 가을 시즌 + @GetMapping("/api/github/commits-fall") + public ResponseEntity> getFallSeasonCommits( + @RequestParam String owner, + @RequestParam String repo + ) { + int currentYear = LocalDateTime.now().getYear(); + LocalDateTime since = LocalDateTime.of(currentYear, 9, 1, 0, 0); + LocalDateTime until = LocalDateTime.of(currentYear, 11, 30, 23, 59, 59); + + List sinceCommits = sinceCommitService.getSinceCommits(owner, repo, since, until); + + return ResponseEntity.ok(sinceCommits); + } + + // 겨울 시즌 + @GetMapping("/api/github/commits-winter") + public ResponseEntity> getWinterSeasonCommits( + @RequestParam String owner, + @RequestParam String repo + ) { + int currentYear = LocalDateTime.now().getYear(); + LocalDateTime since = LocalDateTime.of(currentYear, 12, 1, 0, 0); + LocalDateTime until = LocalDateTime.of(currentYear + 1, 2, 1, 23, 59, 59) + .with(TemporalAdjusters.lastDayOfMonth()); // 윤년 고려 + + List sinceCommits = sinceCommitService.getSinceCommits(owner, repo, since, until); + + return ResponseEntity.ok(sinceCommits); + } +} diff --git a/src/main/java/cmf/commitField/domain/commit/sinceCommit/dto/SinceCommitResponseDto.java b/src/main/java/cmf/commitField/domain/commit/sinceCommit/dto/SinceCommitResponseDto.java new file mode 100644 index 0000000..90cbb31 --- /dev/null +++ b/src/main/java/cmf/commitField/domain/commit/sinceCommit/dto/SinceCommitResponseDto.java @@ -0,0 +1,37 @@ +package cmf.commitField.domain.commit.sinceCommit.dto; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class SinceCommitResponseDto { + private String sha; + private Commit commit; + private Author author; + private String html_url; + + + @Getter + @NoArgsConstructor + public static class Commit { + private CommitAuthor author; // 원래 코드 작성자 + private String message; + + @Getter + @NoArgsConstructor + public static class CommitAuthor { + private String name; // 커밋한 사람의 깃허브 이름 + private String email; + private String date; + } + } + + @Getter + @NoArgsConstructor + public static class Author { + private String login; // 커밋한 사람의 깃허브 id + private String avatar_url; + private String html_url; // 사용자의 깃허브 주소 + } +} diff --git a/src/main/java/cmf/commitField/domain/commit/sinceCommit/service/SinceCommitService.java b/src/main/java/cmf/commitField/domain/commit/sinceCommit/service/SinceCommitService.java new file mode 100644 index 0000000..f4c985f --- /dev/null +++ b/src/main/java/cmf/commitField/domain/commit/sinceCommit/service/SinceCommitService.java @@ -0,0 +1,64 @@ +package cmf.commitField.domain.commit.sinceCommit.service; + +import cmf.commitField.domain.commit.sinceCommit.dto.SinceCommitResponseDto; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Service; +import org.springframework.web.reactive.function.client.WebClient; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + +@Slf4j +@Service +public class SinceCommitService { + private static final String BASE_URL = "https://api.github.com"; + // ?since=2024-01-01T00:00:00Z&until=2025-02-1T23:59:59Z + + @Value("${github.token}") + private String PAT; + + private final WebClient webClient = WebClient.builder() + .baseUrl(BASE_URL) + .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .build(); + + public List getSinceCommits(String owner, String repo, LocalDateTime since, LocalDateTime until) { + try { + return webClient.get() + .uri(uriBuilder -> uriBuilder + .path("/repos/{owner}/{repo}/commits") + .queryParam("since", since.format(DateTimeFormatter.ISO_DATE_TIME)) + .queryParam("until", until.format(DateTimeFormatter.ISO_DATE_TIME)) + .build(owner, repo)) + .header("Authorization", "bearer " + PAT) + .retrieve() + .bodyToMono(new ParameterizedTypeReference>() {}) + .block(); + } catch (Exception e) { + log.error("GitHub API 호출 중 오류 발생: {}", e.getMessage()); + throw new RuntimeException("GitHub API 호출 중 오류가 발생했습니다.", e); + } + } +} + /* + ParameterizedTypeReference를 사용하는 주요 이유 + 1. 제네릭 타입 정보 보존 + 2. 복잡한 타입 구조 처리 가능 + 3. 타입 안전성 보장 + 4. 런타임에 올바른 타입으로 역직렬화 가능 + + ParameterizedTypeReference를 사용하지 않으면 + // 잘못된 예시 + List commits = webClient.get() + .retrieve() + .bodyToMono(List.class) + .block(); + + // 런타임 에러 발생 가능 + GitHubCommitResponse commit = commits.get(0); // ClassCastException 발생 위험 + */ \ No newline at end of file diff --git a/src/main/java/cmf/commitField/domain/totalCommit/config/WebConfig.java b/src/main/java/cmf/commitField/domain/commit/totalCommit/config/WebConfig.java similarity index 90% rename from src/main/java/cmf/commitField/domain/totalCommit/config/WebConfig.java rename to src/main/java/cmf/commitField/domain/commit/totalCommit/config/WebConfig.java index 5210512..26654db 100644 --- a/src/main/java/cmf/commitField/domain/totalCommit/config/WebConfig.java +++ b/src/main/java/cmf/commitField/domain/commit/totalCommit/config/WebConfig.java @@ -1,4 +1,4 @@ -package cmf.commitField.domain.totalCommit.config; +package cmf.commitField.domain.commit.totalCommit.config; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; diff --git a/src/main/java/cmf/commitField/domain/totalCommit/controller/TotalCommitController.java b/src/main/java/cmf/commitField/domain/commit/totalCommit/controller/TotalCommitController.java similarity index 72% rename from src/main/java/cmf/commitField/domain/totalCommit/controller/TotalCommitController.java rename to src/main/java/cmf/commitField/domain/commit/totalCommit/controller/TotalCommitController.java index 51d1757..ecac86b 100644 --- a/src/main/java/cmf/commitField/domain/totalCommit/controller/TotalCommitController.java +++ b/src/main/java/cmf/commitField/domain/commit/totalCommit/controller/TotalCommitController.java @@ -1,7 +1,7 @@ -package cmf.commitField.domain.totalCommit.controller; +package cmf.commitField.domain.commit.totalCommit.controller; -import cmf.commitField.domain.totalCommit.dto.TotalCommitResponseDto; -import cmf.commitField.domain.totalCommit.service.TotalCommitService; +import cmf.commitField.domain.commit.totalCommit.dto.TotalCommitResponseDto; +import cmf.commitField.domain.commit.totalCommit.service.TotalCommitService; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; diff --git a/src/main/java/cmf/commitField/domain/totalCommit/dto/TotalCommitGraphQLResponse.java b/src/main/java/cmf/commitField/domain/commit/totalCommit/dto/TotalCommitGraphQLResponse.java similarity index 93% rename from src/main/java/cmf/commitField/domain/totalCommit/dto/TotalCommitGraphQLResponse.java rename to src/main/java/cmf/commitField/domain/commit/totalCommit/dto/TotalCommitGraphQLResponse.java index 6f27b7c..6d45eeb 100644 --- a/src/main/java/cmf/commitField/domain/totalCommit/dto/TotalCommitGraphQLResponse.java +++ b/src/main/java/cmf/commitField/domain/commit/totalCommit/dto/TotalCommitGraphQLResponse.java @@ -1,4 +1,4 @@ -package cmf.commitField.domain.totalCommit.dto; +package cmf.commitField.domain.commit.totalCommit.dto; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/src/main/java/cmf/commitField/domain/totalCommit/dto/TotalCommitResponseDto.java b/src/main/java/cmf/commitField/domain/commit/totalCommit/dto/TotalCommitResponseDto.java similarity index 82% rename from src/main/java/cmf/commitField/domain/totalCommit/dto/TotalCommitResponseDto.java rename to src/main/java/cmf/commitField/domain/commit/totalCommit/dto/TotalCommitResponseDto.java index e18b023..b71a44e 100644 --- a/src/main/java/cmf/commitField/domain/totalCommit/dto/TotalCommitResponseDto.java +++ b/src/main/java/cmf/commitField/domain/commit/totalCommit/dto/TotalCommitResponseDto.java @@ -1,4 +1,4 @@ -package cmf.commitField.domain.totalCommit.dto; +package cmf.commitField.domain.commit.totalCommit.dto; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/src/main/java/cmf/commitField/domain/totalCommit/service/TotalCommitService.java b/src/main/java/cmf/commitField/domain/commit/totalCommit/service/TotalCommitService.java similarity index 90% rename from src/main/java/cmf/commitField/domain/totalCommit/service/TotalCommitService.java rename to src/main/java/cmf/commitField/domain/commit/totalCommit/service/TotalCommitService.java index 44f4374..e37bfcd 100644 --- a/src/main/java/cmf/commitField/domain/totalCommit/service/TotalCommitService.java +++ b/src/main/java/cmf/commitField/domain/commit/totalCommit/service/TotalCommitService.java @@ -1,7 +1,7 @@ -package cmf.commitField.domain.totalCommit.service; +package cmf.commitField.domain.commit.totalCommit.service; -import cmf.commitField.domain.totalCommit.dto.TotalCommitGraphQLResponse; -import cmf.commitField.domain.totalCommit.dto.TotalCommitResponseDto; +import cmf.commitField.domain.commit.totalCommit.dto.TotalCommitGraphQLResponse; +import cmf.commitField.domain.commit.totalCommit.dto.TotalCommitResponseDto; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders;