Skip to content

Commit 8d0ce15

Browse files
streak now counting all activity period
1 parent c16cafc commit 8d0ce15

File tree

3 files changed

+73
-19
lines changed

3 files changed

+73
-19
lines changed

src/apis/apis.service.ts

Lines changed: 62 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -38,32 +38,44 @@ export class APIService {
3838
return data;
3939
}
4040

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}`);
4443

4544
if (cache) return JSON.parse(cache);
4645

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+
);
5059

51-
const nowISO = new Date(now).toISOString();
60+
if (response.status !== 200) return null;
5261

53-
const from = new Date(now);
54-
from.setFullYear(from.getFullYear() - 1);
55-
const fromISO = from.toISOString();
62+
const data: UserReg = response.data;
5663

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) {
5769
const response = await axios.post(
5870
'https://api.github.com/graphql',
5971
{
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" : ""})` +
6274
"{ contributionCalendar { weeks { contributionDays { date contributionCount } } } } } }",
6375
variables: {
6476
username: username,
65-
from: fromISO,
66-
to: nowISO
77+
from: from,
78+
to: to
6779
}
6880
},
6981
{
@@ -72,18 +84,49 @@ export class APIService {
7284
}
7385
);
7486
if (response.status !== 200 || !response.data.data.user) return null;
87+
const data: GithubStreak = response.data;
7588

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 =>
7890
week.contributionDays.map(val => val.contributionCount)
7991
);
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+
}
80121

81122
let streak_start = -1;
82123
let streak_end = -1;
83124
let longest_streak = 0;
125+
let total_contributions = 0;
84126

85127
for (let i = 0; i < days.length; i++) {
86128
const day = days[i];
129+
total_contributions += day;
87130

88131
if (day !== 0) {
89132
if (streak_start === -1) {
@@ -102,10 +145,11 @@ export class APIService {
102145
const streak_days = streak_end - streak_start;
103146
const result = {
104147
streak: streak_days,
105-
longest: longest_streak
148+
longest: longest_streak,
149+
total_contributions
106150
}
107151

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);
109153
return result;
110154
}
111155

src/apis/types.d.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,12 @@ interface ActivityResponse {
103103
start_time: Date
104104
}[]
105105
}
106+
107+
108+
interface UserReg {
109+
data: {
110+
user: {
111+
createdAt: Date
112+
}
113+
}
114+
}

src/widget/widget.service.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ export class WidgetService {
7676
top_repos: top_repos,
7777
streak: streak ? {
7878
current: streak.streak,
79-
longest: streak.longest
79+
longest: streak.longest,
80+
total_contributions: streak.total_contributions
8081
} : null,
8182
},
8283
wakatime: {

0 commit comments

Comments
 (0)