@@ -77,87 +77,114 @@ export class APIService {
77
77
const cache = await this . cacheManager . get < string > (
78
78
`streak:${ username } `
79
79
) ;
80
-
81
80
if ( cache ) return JSON . parse ( cache ) ;
82
81
83
- const date = new Date ( ) ;
84
- const timezoneOffset = date . getTimezoneOffset ( ) ;
85
- const now = date . getTime ( ) - timezoneOffset * 60000 ;
82
+ const today = new Date ( ) ;
83
+ const timezoneOffset = today . getTimezoneOffset ( ) ;
84
+ today . setMinutes ( today . getMinutes ( ) - timezoneOffset ) ;
85
+
86
+ const headers = { Authorization : `Bearer ${ process . env . GITHUB } ` } ;
87
+ const allDays : { date : string ; count : number } [ ] = [ ] ;
88
+
89
+ for ( let i = 0 ; i < 5 ; i ++ ) {
90
+ const from = new Date ( today ) ;
91
+ from . setFullYear ( today . getFullYear ( ) - i - 1 ) ;
92
+ const to = new Date ( today ) ;
93
+ to . setFullYear ( today . getFullYear ( ) - i ) ;
94
+
95
+ const response = await instance . post (
96
+ 'https://api.github.com/graphql' ,
97
+ {
98
+ query : `
99
+ query GetUserContributions($username: String!, $from: DateTime!, $to: DateTime!) {
100
+ user(login: $username) {
101
+ contributionsCollection(from: $from, to: $to) {
102
+ contributionCalendar {
103
+ weeks {
104
+ contributionDays {
105
+ date
106
+ contributionCount
107
+ }
108
+ }
109
+ }
110
+ }
111
+ }
112
+ }
113
+ ` ,
114
+ variables : {
115
+ username,
116
+ from : from . toISOString ( ) ,
117
+ to : to . toISOString ( )
118
+ }
119
+ } ,
120
+ {
121
+ headers,
122
+ validateStatus : ( ) => true
123
+ }
124
+ ) ;
86
125
87
- const nowISO = new Date ( now ) . toISOString ( ) ;
126
+ if (
127
+ response . status !== 200 ||
128
+ ! response . data . data ?. user ?. contributionsCollection
129
+ ) {
130
+ return null ;
131
+ }
88
132
89
- const from = new Date ( now ) ;
90
- from . setFullYear ( from . getFullYear ( ) - 1 ) ;
91
- const fromISO = from . toISOString ( ) ;
133
+ const weeks =
134
+ response . data . data . user . contributionsCollection
135
+ . contributionCalendar . weeks ;
92
136
93
- const response = await instance . post (
94
- 'https://api.github.com/graphql' ,
95
- {
96
- query :
97
- 'query GetUserContributions($username: String!, $from: DateTime!, $to: DateTime!)' +
98
- '{ user(login: $username) { contributionsCollection(from: $from, to: $to)' +
99
- '{ contributionCalendar { weeks { contributionDays { date contributionCount } } } } } }' ,
100
- variables : {
101
- username : username ,
102
- from : fromISO ,
103
- to : nowISO
104
- }
105
- } ,
106
- {
107
- headers : { Authorization : `Bearer ${ process . env . GITHUB } ` } ,
108
- validateStatus : ( ) => true
109
- }
137
+ const days = weeks . flatMap ( ( week : any ) =>
138
+ week . contributionDays . map ( ( day : any ) => ( {
139
+ date : day . date ,
140
+ count : day . contributionCount
141
+ } ) )
142
+ ) ;
143
+
144
+ allDays . push ( ...days ) ;
145
+ }
146
+
147
+ allDays . sort (
148
+ ( a , b ) =>
149
+ new Date ( a . date ) . getTime ( ) - new Date ( b . date ) . getTime ( )
110
150
) ;
111
- if ( response . status !== 200 || ! response . data . data . user )
112
- return null ;
113
151
114
- const data = response . data as GithubStreak ;
115
- const days =
116
- data . data . user . contributionsCollection . contributionCalendar . weeks . flatMap (
117
- ( week ) =>
118
- week . contributionDays . map (
119
- ( val ) => val . contributionCount
120
- )
121
- ) ;
152
+ let currentStreak = 0 ;
153
+ let longestStreak = 0 ;
154
+ let totalContributions = 0 ;
122
155
123
- let streak_start = - 1 ;
124
- let streak_end = - 1 ;
125
- let longest_streak = 0 ;
126
- let total_contributions = 0 ;
156
+ for ( const day of allDays ) {
157
+ totalContributions += day . count ;
127
158
128
- for ( let i = 0 ; i < days . length ; i ++ ) {
129
- const day = days [ i ] ;
130
- total_contributions += day ;
159
+ if ( day . count > 0 ) {
160
+ currentStreak ++ ;
161
+ longestStreak = Math . max ( longestStreak , currentStreak ) ;
162
+ } else {
163
+ currentStreak = 0 ;
164
+ }
165
+ }
131
166
132
- if ( day !== 0 ) {
133
- if ( streak_start === - 1 ) {
134
- streak_start = i ;
135
- streak_end = i ;
136
- }
137
- streak_end = i ;
138
- longest_streak = Math . max (
139
- longest_streak ,
140
- streak_end - streak_start
141
- ) ;
167
+ let streak = 0 ;
168
+ for ( let i = allDays . length - 1 ; i >= 0 ; i -- ) {
169
+ if ( allDays [ i ] . count > 0 ) {
170
+ streak ++ ;
142
171
} else {
143
- if ( i !== days . length - 1 ) {
144
- streak_start = - 1 ;
145
- streak_end = - 1 ;
146
- }
172
+ break ;
147
173
}
148
174
}
149
- const streak_days = streak_end - streak_start ;
175
+
150
176
const result = {
151
- streak : streak_days ,
152
- longest : longest_streak ,
153
- total_contributions
177
+ streak,
178
+ longest : longestStreak ,
179
+ total_contributions : totalContributions
154
180
} ;
155
181
156
182
await this . cacheManager . set (
157
183
`streak:${ username } ` ,
158
184
JSON . stringify ( result ) ,
159
- 1000 * 60 * 60
185
+ 1000 * 60 * 60 * 12
160
186
) ;
187
+
161
188
return result ;
162
189
} catch ( e ) {
163
190
console . error ( e ) ;
0 commit comments