-
Notifications
You must be signed in to change notification settings - Fork 1
Files
/
+server.ts
73 lines (58 loc) ยท 1.72 KB
/
+server.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import { json } from '@sveltejs/kit'
import { parseHTML } from 'linkedom'
import type { RouteParams } from './$types.js'
type Contribution = {
count: number
month: string
day: number
level: number
} | null
export async function GET({ params, setHeaders }) {
setHeaders({
'Acces-Control-Allow-Origin': '*',
'Cache-Control': `public, s-maxage=${60 * 60 * 24 * 365}`,
})
const html = await getContributions(params)
return json(parseContributions(html))
}
async function getContributions({ user, year }: RouteParams) {
const api = `https://github.com/users/${user}/contributions?from=${year}-12-01&to=${year}-12-31`
const response = await fetch(api)
if (!response.ok) {
throw new Error(`Failed to fetch: ${response.status}`)
}
return await response.text()
}
function parseContributions(html: string) {
const { document } = parseHTML(html)
const days = document.querySelectorAll<Element>('tool-tip')
const contributions: Contribution[][] = [
[], // Sundays
[], // Mondays
[], // Tuesdays
[], // Wednesdays
[], // Thursdays
[], // Fridays
[], // Saturdays
]
for (const [_, day] of days.entries()) {
const data = day.innerHTML.split(' ')
const forDayRaw = day.getAttribute('for')
if (!forDayRaw) continue
const forDay = forDayRaw.replace('contribution-day-component-', '')
const [weekday, week] = forDay.split('-').map(Number)
if (data.length > 1) {
const td = document.getElementById(forDayRaw)
if (!td) continue
const level = td.dataset.level || '0'
const contribution = {
count: data[0] === 'No' ? 0 : +data[0],
month: data[3],
day: +data[4].replace(/(st|nd|rd|th)/, ''),
level: +level,
}
contributions[weekday][week] = contribution
}
}
return contributions
}