This repository has been archived by the owner on Oct 12, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 24
/
models.go
159 lines (133 loc) · 3.95 KB
/
models.go
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package gql
import (
"time"
"github.com/Ullaakut/disgo"
)
const (
// Request 100 users per query when listing stargazers.
listPagination = 100
// Request 20 users per query when fetching contribution data.
contribPagination = 20
// ISO8601 time format used by the GitHub API.
iso8601Format = "2006-01-02T15:04:05Z"
// Request to list users. Low cost in terms of rate limiting.
fetchUsersRequest = `{"query" : "{
rateLimit {
limit
remaining
}
repository(owner: \"$repoOwner\", name: \"$repoName\") {
stargazers(first: $pagination) {
edges {
cursor
}
nodes {
login
}
}
}
}"}`
// Request to fetch user contributions. Expensive in terms of rate limiting.
// Fetching more than 20 users at a time is pretty much a guaranteed timeout.
fetchContributionsRequest = `{"query" : "{
rateLimit {
remaining
}
repository(owner: \"$repoOwner\", name: \"$repoName\") {
stargazers(first: $pagination) {
edges {
cursor
}
nodes {
login
createdAt
contributionsCollection(from: \"$dateFrom\", to: \"$dateTo\") {
restrictedContributionsCount
totalIssueContributions
totalCommitContributions
totalRepositoryContributions
totalPullRequestContributions
totalPullRequestReviewContributions
contributionCalendar {
totalContributions
}
}
}
}
}
}"}`
)
// User represents a github user who starred a repository. It is
// public because this model is the output of the Fetch methods of
// this package.
type User struct {
Login string `json:"login"`
CreatedAt string `json:"createdAt"`
Contributions contributions `json:"contributionsCollection"`
YearlyContributions map[int]int
}
// DaysOld returns the amount of days since this user created their
// GitHub account.
func (u User) DaysOld() float64 {
creationDate, err := time.Parse(iso8601Format, u.CreatedAt)
if err != nil {
disgo.Errorln("Unexpected date time format from GraphQL API:", err)
}
return time.Since(creationDate).Hours() / 24
}
type listStargazersResponse struct {
response `json:"data"`
ErrorMessage string `json:"message"`
Errors []gqlError `json:"errors"`
}
type gqlError struct {
Extensions gqlErrorExtension `json:"extensions"`
Message string `json:"message"`
}
type gqlErrorExtension struct {
Name string `json:"name"`
ArgumentName string `json:"argumentName"`
}
type response struct {
Repository repository `json:"repository"`
RateLimit rateLimit `json:"ratelimit"`
}
type rateLimit struct {
Limit int `json:"limit"`
Cost int `json:"cost"`
Remaining int `json:"remaining"`
ResetAt string `json:"resetAt"`
}
type repository struct {
Stargazers stargazers `json:"stargazers"`
}
type stargazers struct {
Users []User `json:"nodes"`
Meta metaData `json:"edges"`
}
type metaData []meta
// cursor returns the last cursor, or none if the metadata is empty.
// The cursor is used for pagination purposes, it represents the ID
// of the last fetched node, and lets the API know that we want to
// offset our query by the position of that node.
func (m metaData) cursor() string {
if len(m) == 0 {
return ""
}
return m[len(m)-1].Cursor
}
type meta struct {
Cursor string `json:"cursor"`
}
type contributions struct {
PrivateContributions int `json:"restrictedContributionsCount"`
TotalIssueContributions int `json:"totalIssueContributions"`
TotalCommitContributions int `json:"totalCommitContributions"`
TotalRepositoryContributions int `json:"totalRepositoryContributions"`
TotalPullRequestContributions int `json:"totalPullRequestContributions"`
TotalPullRequestReviewContributions int `json:"totalPullRequestReviewContributions"`
ContributionCalendar contributionCalendar `json:"contributionCalendar"`
}
type contributionCalendar struct {
TotalContributions int `json:"totalContributions"`
}