99import org .springframework .stereotype .Service ;
1010import org .springframework .web .reactive .function .client .WebClient ;
1111
12+ import java .time .LocalDate ;
13+ import java .time .LocalDateTime ;
14+ import java .time .format .DateTimeFormatter ;
15+ import java .util .ArrayList ;
16+ import java .util .Collections ;
17+ import java .util .List ;
1218import java .util .Map ;
1319
1420
@@ -23,14 +29,11 @@ public class TotalCommitService {
2329
2430 private final WebClient webClient = WebClient .builder ()
2531 .baseUrl (BASE_URL )
26- .defaultHeader (HttpHeaders .CONTENT_TYPE , MediaType .APPLICATION_JSON_VALUE )
32+ .defaultHeader (HttpHeaders .CONTENT_TYPE , MediaType .APPLICATION_JSON_VALUE )
2733 .build ();
2834
35+ // ๊ธฐ์กด ๋ฉ์๋
2936 public TotalCommitResponseDto getTotalCommitCount (String username ) {
30- // String query = String.format("""
31- // {"query": "query { user(login: \\\"%s\\\") { contributionsCollection { totalCommitContributions restrictedContributionsCount } } }"}
32- // """, username);
33- // GraphQL ์ฟผ๋ฆฌ๋ฅผ Map์ผ๋ก ๊ตฌ์ฑ
3437 Map <String , String > requestBody = Map .of (
3538 "query" , String .format (
3639 "query { user(login: \" %s\" ) { contributionsCollection { totalCommitContributions restrictedContributionsCount } } }" ,
@@ -45,11 +48,110 @@ public TotalCommitResponseDto getTotalCommitCount(String username) {
4548 .bodyToMono (TotalCommitGraphQLResponse .class )
4649 .block ();
4750
48- TotalCommitGraphQLResponse .ContributionsCollection contributions = response .getData ().getUser ().getContributionsCollection ();
51+ TotalCommitGraphQLResponse .ContributionsCollection contributions =
52+ response .getData ().getUser ().getContributionsCollection ();
4953
5054 return new TotalCommitResponseDto (
5155 contributions .getTotalCommitContributions (),
5256 contributions .getRestrictedContributionsCount ()
5357 );
5458 }
59+
60+ // ์์ฆ๋ณ ์ปค๋ฐ ๋ถ์
61+ public TotalCommitResponseDto getSeasonCommits (String username , LocalDateTime since , LocalDateTime until ) {
62+ String query = String .format ("""
63+ query {
64+ user(login: "%s") {
65+ contributionsCollection(from: "%s", to: "%s") {
66+ totalCommitContributions
67+ restrictedContributionsCount
68+ contributionCalendar {
69+ totalContributions
70+ weeks {
71+ contributionDays {
72+ contributionCount
73+ date
74+ }
75+ }
76+ }
77+ }
78+ }
79+ }
80+ """ , username , since .format (DateTimeFormatter .ISO_DATE_TIME ), until .format (DateTimeFormatter .ISO_DATE_TIME ));
81+
82+ Map <String , String > requestBody = Map .of ("query" , query );
83+
84+ TotalCommitGraphQLResponse response = webClient .post ()
85+ .header ("Authorization" , "bearer " + PAT )
86+ .bodyValue (requestBody )
87+ .retrieve ()
88+ .bodyToMono (TotalCommitGraphQLResponse .class )
89+ .block ();
90+
91+ if (response == null || response .getData () == null || response .getData ().getUser () == null ) {
92+ throw new RuntimeException ("Failed to fetch GitHub data" );
93+ }
94+
95+ TotalCommitGraphQLResponse .ContributionsCollection contributions =
96+ response .getData ().getUser ().getContributionsCollection ();
97+
98+ List <LocalDate > commitDates = extractCommitDates (contributions .getContributionCalendar ());
99+ StreakResult streaks = calculateStreaks (commitDates );
100+
101+ return new TotalCommitResponseDto (
102+ contributions .getTotalCommitContributions (),
103+ contributions .getRestrictedContributionsCount (),
104+ streaks .currentStreak ,
105+ streaks .maxStreak
106+ );
107+ }
108+
109+ private List <LocalDate > extractCommitDates (TotalCommitGraphQLResponse .ContributionCalendar calendar ) {
110+ List <LocalDate > dates = new ArrayList <>();
111+ calendar .getWeeks ().forEach (week ->
112+ week .getContributionDays ().forEach (day -> {
113+ if (day .getContributionCount () > 0 ) {
114+ dates .add (LocalDate .parse (day .getDate ()));
115+ }
116+ })
117+ );
118+ return dates ;
119+ }
120+
121+ @ RequiredArgsConstructor
122+ private static class StreakResult {
123+ final int currentStreak ;
124+ final int maxStreak ;
125+ }
126+
127+ private StreakResult calculateStreaks (List <LocalDate > commitDates ) {
128+ if (commitDates .isEmpty ()) {
129+ return new StreakResult (0 , 0 );
130+ }
131+
132+ Collections .sort (commitDates );
133+ int currentStreak = 0 ;
134+ int maxStreak = 0 ;
135+ int tempStreak = 0 ;
136+ LocalDate previousDate = null ;
137+
138+ for (LocalDate date : commitDates ) {
139+ if (previousDate == null || date .minusDays (1 ).equals (previousDate )) {
140+ tempStreak ++;
141+ } else {
142+ tempStreak = 1 ;
143+ }
144+ maxStreak = Math .max (maxStreak , tempStreak );
145+ previousDate = date ;
146+ }
147+
148+ // ํ์ฌ ์คํธ๋ฆญ ๊ณ์ฐ (๋ง์ง๋ง ์ปค๋ฐ์ด ์ค๋ ๋๋ ์ด์ ์ธ ๊ฒฝ์ฐ)
149+ LocalDate today = LocalDate .now ();
150+ LocalDate lastCommitDate = commitDates .get (commitDates .size () - 1 );
151+ if (lastCommitDate .equals (today ) || lastCommitDate .equals (today .minusDays (1 ))) {
152+ currentStreak = tempStreak ;
153+ }
154+
155+ return new StreakResult (currentStreak , maxStreak );
156+ }
55157}
0 commit comments