-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathaccount.go
135 lines (123 loc) · 3.38 KB
/
account.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
package main
import (
"bytes"
"context"
"encoding/gob"
"errors"
"time"
"google.golang.org/appengine/v2/datastore"
"github.com/google/go-github/v62/github"
"golang.org/x/oauth2"
)
type Account struct {
GitHubUserId int64 `datastore:",noindex"`
// The datastore API doesn't store maps, and the token contains one. We
// therefore store a gob-serialized version instead.
OAuthTokenSerialized []byte
OAuthToken oauth2.Token `datastore:"-,"`
TimezoneName string `datastore:",noindex"`
TimezoneLocation *time.Location `datastore:"-,"`
HasTimezoneSet bool `datastore:"-,"`
ExcludedRepoIds []int64 `datastore:",noindex"`
DigestEmailAddress string
Frequency string
WeeklyDay time.Weekday
}
func getAccount(c context.Context, githubUserId int64) (*Account, error) {
key := datastore.NewKey(c, "Account", "", githubUserId, nil)
account := new(Account)
err := datastore.Get(c, key, account)
if err != nil {
return nil, err
}
err = initAccount(account)
if err != nil {
return nil, err
}
return account, nil
}
func initAccount(account *Account) error {
r := bytes.NewBuffer(account.OAuthTokenSerialized)
err := gob.NewDecoder(r).Decode(&account.OAuthToken)
if err != nil {
return err
}
account.HasTimezoneSet = len(account.TimezoneName) > 0
if !account.HasTimezoneSet {
account.TimezoneName = "America/Los_Angeles"
}
if len(account.Frequency) == 0 {
account.Frequency = "daily"
}
account.TimezoneLocation, err = time.LoadLocation(account.TimezoneName)
if err != nil {
return err
}
return nil
}
func getAllAccounts(c context.Context) ([]Account, error) {
q := datastore.NewQuery("Account")
var accounts []Account
_, err := q.GetAll(c, &accounts)
if err != nil {
return nil, err
}
for i := range accounts {
err = initAccount(&accounts[i])
if err != nil {
return nil, err
}
}
return accounts, nil
}
func (account *Account) IsRepoIdExcluded(repoId int64) bool {
for i := range account.ExcludedRepoIds {
if account.ExcludedRepoIds[i] == repoId {
return true
}
}
return false
}
func (account *Account) Put(c context.Context) error {
w := new(bytes.Buffer)
err := gob.NewEncoder(w).Encode(&account.OAuthToken)
if err != nil {
return err
}
account.OAuthTokenSerialized = w.Bytes()
key := datastore.NewKey(c, "Account", "", int64(account.GitHubUserId), nil)
_, err = datastore.Put(c, key, account)
return err
}
func (account *Account) Delete(c context.Context) error {
key := datastore.NewKey(c, "Account", "", int64(account.GitHubUserId), nil)
err := datastore.Delete(c, key)
return err
}
func (account *Account) GetDigestEmailAddress(c context.Context, githubClient *github.Client) (string, error) {
if len(account.DigestEmailAddress) > 0 {
return account.DigestEmailAddress, nil
}
emails, _, err := githubClient.Users.ListEmails(c, nil)
if err != nil {
return "", err
}
// Prefer the primary, verified email
for _, email := range emails {
if email.Primary != nil && *email.Primary &&
email.Verified != nil && *email.Verified {
return *email.Email, nil
}
}
// Then the first verified email
for _, email := range emails {
if email.Verified != nil && *email.Verified {
return *email.Email, nil
}
}
// Then just the first email
for _, email := range emails {
return *email.Email, nil
}
return "", errors.New("No email addresses found in GitHub account")
}