[READ-ONLY] Mirror of https://github.com/shuuji3/github-contribution-recorder. 馃摴 A tool to record GitHub activities (commits, issues, PRs, comments) into a local SQLite database.
2.3 kB
80 lines
1import { execSync } from 'child_process'
2import { config } from './config.ts'
3
4function isMyActivity(data: any, username: string): boolean {
5 const users = [data.author, data.committer, data.user, data.merged_by, data.assignee]
6 for (const user of users) {
7 if (user && user.login === username) return true
8 }
9 return false
10}
11
12function isAfterDate(dateString: string, sinceDate: string): boolean {
13 if (!sinceDate) return true
14 const date = new Date(dateString)
15 const since = new Date(sinceDate)
16 return date >= since
17}
18
19export function fetch(
20 username: string,
21 owner: string,
22 repo: string,
23 endpoint: string,
24 filter: (item: any) => boolean = () => true
25) {
26 const userConfig = config.users[username]
27 if (!userConfig) {
28 console.error(`User configuration not found for: ${username}`)
29 return []
30 }
31 try {
32 const separator = endpoint.includes('?') ? '&' : '?'
33 const items = JSON.parse(
34 execSync(`gh api repos/${owner}/${repo}/${endpoint}${separator}per_page=100`, {
35 encoding: 'utf8',
36 })
37 )
38 return items.filter((item: any) => {
39 const date = item.created_at || (item.commit && item.commit.author && item.commit.author.date)
40 return (
41 filter(item) &&
42 isMyActivity(item, username) &&
43 (date ? isAfterDate(date, userConfig.sinceDate) : true)
44 )
45 })
46 } catch (e) {
47 console.error(`Error fetching from repos/${owner}/${repo}/${endpoint}: ${e}`)
48 return []
49 }
50}
51
52export function getRepos(username: string) {
53 const userConfig = config.users[username]
54 if (!userConfig) {
55 console.error(`User configuration not found for: ${username}`)
56 return []
57 }
58 let repos: any[] = []
59 let page = 1
60 while (true) {
61 const perPage = 100
62 const output = execSync(`gh api user/repos?sort=updated&per_page=${perPage}&page=${page}`, {
63 encoding: 'utf8',
64 })
65 const pageRepos = JSON.parse(output)
66 if (pageRepos.length === 0) break
67 repos = repos.concat(pageRepos)
68 if (userConfig.maxRepos !== 0 && repos.length >= userConfig.maxRepos) {
69 repos = repos.slice(0, userConfig.maxRepos)
70 break
71 }
72 if (pageRepos.length < perPage) break
73 page++
74 }
75 const result = []
76 for (const repo of repos) {
77 result.push({ id: repo.node_id, fullName: repo.full_name })
78 }
79 return result
80}