@@ -38,32 +38,44 @@ export class APIService {
38
38
return data ;
39
39
}
40
40
41
-
42
- async getGithubStreak ( username : string ) : Promise < { streak : number ; longest : number ; } | null > {
43
- const cache = await this . cacheManager . get < string > ( `streak:${ username } ` ) ;
41
+ async getGithubUserRegistration ( username : string ) : Promise < UserReg | null > {
42
+ const cache = await this . cacheManager . get < string > ( `user_reg:${ username } ` ) ;
44
43
45
44
if ( cache ) return JSON . parse ( cache ) ;
46
45
47
- const date = new Date ( ) ;
48
- const timezoneOffset = date . getTimezoneOffset ( ) ;
49
- const now = date . getTime ( ) - timezoneOffset * 60000 ;
46
+ const response = await axios . post (
47
+ 'https://api.github.com/graphql' ,
48
+ {
49
+ query : "query GetUserCreatedAt($username: String!) { user(login: $username) { createdAt } }" ,
50
+ variables : {
51
+ username : username
52
+ }
53
+ } ,
54
+ {
55
+ headers : { Authorization : `Bearer ${ process . env . GITHUB } ` } ,
56
+ validateStatus : ( ) => true
57
+ }
58
+ ) ;
50
59
51
- const nowISO = new Date ( now ) . toISOString ( ) ;
60
+ if ( response . status !== 200 ) return null ;
52
61
53
- const from = new Date ( now ) ;
54
- from . setFullYear ( from . getFullYear ( ) - 1 ) ;
55
- const fromISO = from . toISOString ( ) ;
62
+ const data : UserReg = response . data ;
56
63
64
+ await this . cacheManager . set ( `user_reg:${ username } ` , JSON . stringify ( data ) , 1000 * 60 * 60 ) ;
65
+ return data ;
66
+ }
67
+
68
+ async getGithubStreakYear ( username : string , from : string , to : string ) {
57
69
const response = await axios . post (
58
70
'https://api.github.com/graphql' ,
59
71
{
60
- query : " query GetUserContributions($username: String!, $from: DateTime!, $to: DateTime!)" +
61
- " { user(login: $username) { contributionsCollection(from: $from, to: $to)" +
72
+ query : ` query GetUserContributions($username: String!, $from: DateTime!${ ! ! to ? " , $to: DateTime!" : "" } )` +
73
+ ` { user(login: $username) { contributionsCollection(from: $from${ ! ! to ? " , to: $to" : "" } )` +
62
74
"{ contributionCalendar { weeks { contributionDays { date contributionCount } } } } } }" ,
63
75
variables : {
64
76
username : username ,
65
- from : fromISO ,
66
- to : nowISO
77
+ from : from ,
78
+ to : to
67
79
}
68
80
} ,
69
81
{
@@ -72,18 +84,49 @@ export class APIService {
72
84
}
73
85
) ;
74
86
if ( response . status !== 200 || ! response . data . data . user ) return null ;
87
+ const data : GithubStreak = response . data ;
75
88
76
- const data = response . data as GithubStreak ;
77
- const days = data . data . user . contributionsCollection . contributionCalendar . weeks . flatMap ( week =>
89
+ return data . data . user . contributionsCollection . contributionCalendar . weeks . flatMap ( week =>
78
90
week . contributionDays . map ( val => val . contributionCount )
79
91
) ;
92
+ }
93
+
94
+
95
+ async getGithubStreak ( username : string ) : Promise < { streak : number ; longest : number ; total_contributions : number ; } | null > {
96
+ const cache = await this . cacheManager . get < string > ( `streak:${ username } ` ) ;
97
+
98
+ if ( cache ) return JSON . parse ( cache ) ;
99
+
100
+ const date = new Date ( ) ;
101
+ const timezoneOffset = date . getTimezoneOffset ( ) ;
102
+ const now = date . getTime ( ) - timezoneOffset * 60000 ;
103
+ const nowISO = new Date ( now ) . toISOString ( ) ;
104
+
105
+ const currentYearStart = `${ date . getFullYear ( ) } -01-01T00:00:00Z` ;
106
+
107
+ let days = await this . getGithubStreakYear ( username , currentYearStart , nowISO ) ;
108
+ if ( ! days ) return null ;
109
+
110
+ const regTime = new Date ( ( await this . getGithubUserRegistration ( username ) ) . data . user . createdAt ) ;
111
+
112
+ for ( let year = date . getFullYear ( ) - 1 ; year >= regTime . getFullYear ( ) ; year -- ) {
113
+ try {
114
+ const days_last = await this . getGithubStreakYear ( username , `${ year } -01-01T00:00:00Z` , undefined ) ;
115
+ days = [ ...days_last , ...days ] ;
116
+ } catch ( e ) {
117
+ console . error ( e ) ;
118
+ break ;
119
+ }
120
+ }
80
121
81
122
let streak_start = - 1 ;
82
123
let streak_end = - 1 ;
83
124
let longest_streak = 0 ;
125
+ let total_contributions = 0 ;
84
126
85
127
for ( let i = 0 ; i < days . length ; i ++ ) {
86
128
const day = days [ i ] ;
129
+ total_contributions += day ;
87
130
88
131
if ( day !== 0 ) {
89
132
if ( streak_start === - 1 ) {
@@ -102,10 +145,11 @@ export class APIService {
102
145
const streak_days = streak_end - streak_start ;
103
146
const result = {
104
147
streak : streak_days ,
105
- longest : longest_streak
148
+ longest : longest_streak ,
149
+ total_contributions
106
150
}
107
151
108
- await this . cacheManager . set ( `streak:${ username } ` , JSON . stringify ( result ) , 1000 * 60 * 60 ) ;
152
+ await this . cacheManager . set ( `streak:${ username } ` , JSON . stringify ( result ) , 1000 * 60 * 60 * 3 ) ;
109
153
return result ;
110
154
}
111
155
0 commit comments