Skip to content

Feat: 사용자와 레포지토리 정보를 받아 시즌 별 커밋 불러오기 #54

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

Merged
merged 2 commits into from
Feb 24, 2025
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
Binary file added .DS_Store
Binary file not shown.
Binary file added src/.DS_Store
Binary file not shown.
Binary file added src/main/.DS_Store
Binary file not shown.
Binary file added src/main/java/.DS_Store
Binary file not shown.
Binary file added src/main/java/cmf/.DS_Store
Binary file not shown.
Binary file added src/main/java/cmf/commitField/.DS_Store
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -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<List<SinceCommitResponseDto>> 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<SinceCommitResponseDto> sinceCommits = sinceCommitService.getSinceCommits(owner, repo, since, until);

return ResponseEntity.ok(sinceCommits);
}

// 시즌 별 커밋 수 불러오기

// 봄 시즌
@GetMapping("/api/github/commits-spring")
public ResponseEntity<List<SinceCommitResponseDto>> 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<SinceCommitResponseDto> sinceCommits = sinceCommitService.getSinceCommits(owner, repo, since, until);

return ResponseEntity.ok(sinceCommits);
}

// 여름 시즌
@GetMapping("/api/github/commits-summer")
public ResponseEntity<List<SinceCommitResponseDto>> 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<SinceCommitResponseDto> sinceCommits = sinceCommitService.getSinceCommits(owner, repo, since, until);

return ResponseEntity.ok(sinceCommits);
}

// 가을 시즌
@GetMapping("/api/github/commits-fall")
public ResponseEntity<List<SinceCommitResponseDto>> 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<SinceCommitResponseDto> sinceCommits = sinceCommitService.getSinceCommits(owner, repo, since, until);

return ResponseEntity.ok(sinceCommits);
}

// 겨울 시즌
@GetMapping("/api/github/commits-winter")
public ResponseEntity<List<SinceCommitResponseDto>> 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<SinceCommitResponseDto> sinceCommits = sinceCommitService.getSinceCommits(owner, repo, since, until);

return ResponseEntity.ok(sinceCommits);
}
}
Original file line number Diff line number Diff line change
@@ -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; // 사용자의 깃허브 주소
}
}
Original file line number Diff line number Diff line change
@@ -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<SinceCommitResponseDto> 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<List<SinceCommitResponseDto>>() {})
.block();
} catch (Exception e) {
log.error("GitHub API 호출 중 오류 발생: {}", e.getMessage());
throw new RuntimeException("GitHub API 호출 중 오류가 발생했습니다.", e);
}
}
}
/*
ParameterizedTypeReference를 사용하는 주요 이유
1. 제네릭 타입 정보 보존
2. 복잡한 타입 구조 처리 가능
3. 타입 안전성 보장
4. 런타임에 올바른 타입으로 역직렬화 가능

ParameterizedTypeReference를 사용하지 않으면
// 잘못된 예시
List<GitHubCommitResponse> commits = webClient.get()
.retrieve()
.bodyToMono(List.class)
.block();

// 런타임 에러 발생 가능
GitHubCommitResponse commit = commits.get(0); // ClassCastException 발생 위험
*/
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package cmf.commitField.domain.totalCommit.dto;
package cmf.commitField.domain.commit.totalCommit.dto;

import lombok.Getter;
import lombok.NoArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package cmf.commitField.domain.totalCommit.dto;
package cmf.commitField.domain.commit.totalCommit.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down