mirror of
https://github.com/samsonjs/retrogit.git
synced 2026-04-27 15:07:43 +00:00
Add setting for which email address the digest will be sent to.
This commit is contained in:
parent
1cb55cfe6a
commit
69fcc91dc7
4 changed files with 90 additions and 25 deletions
|
|
@ -3,12 +3,14 @@ package githop
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"appengine"
|
"appengine"
|
||||||
"appengine/datastore"
|
"appengine/datastore"
|
||||||
|
|
||||||
"code.google.com/p/goauth2/oauth"
|
"code.google.com/p/goauth2/oauth"
|
||||||
|
"github.com/google/go-github/github"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Account struct {
|
type Account struct {
|
||||||
|
|
@ -20,6 +22,7 @@ type Account struct {
|
||||||
TimezoneName string `datastore:",noindex"`
|
TimezoneName string `datastore:",noindex"`
|
||||||
TimezoneLocation *time.Location `datastore:"-,"`
|
TimezoneLocation *time.Location `datastore:"-,"`
|
||||||
ExcludedRepoIds []int `datastore:",noindex"`
|
ExcludedRepoIds []int `datastore:",noindex"`
|
||||||
|
DigestEmailAddress string
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAccount(c appengine.Context, githubUserId int) (*Account, error) {
|
func getAccount(c appengine.Context, githubUserId int) (*Account, error) {
|
||||||
|
|
@ -76,7 +79,7 @@ func (account *Account) IsRepoIdExcluded(repoId int) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (account *Account) put(c appengine.Context) error {
|
func (account *Account) Put(c appengine.Context) error {
|
||||||
w := new(bytes.Buffer)
|
w := new(bytes.Buffer)
|
||||||
err := gob.NewEncoder(w).Encode(&account.OAuthToken)
|
err := gob.NewEncoder(w).Encode(&account.OAuthToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -87,3 +90,31 @@ func (account *Account) put(c appengine.Context) error {
|
||||||
_, err = datastore.Put(c, key, account)
|
_, err = datastore.Put(c, key, account)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (account *Account) GetDigestEmailAddress(githubClient *github.Client) (string, error) {
|
||||||
|
if len(account.DigestEmailAddress) > 0 {
|
||||||
|
return account.DigestEmailAddress, nil
|
||||||
|
}
|
||||||
|
emails, _, err := githubClient.Users.ListEmails(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")
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package githop
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
@ -293,25 +292,14 @@ func sendDigestForAccount(account *Account, c appengine.Context) (bool, error) {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
emails, _, err := githubClient.Users.ListEmails(nil)
|
emailAddress, err := account.GetDigestEmailAddress(githubClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
var primaryVerified *string
|
|
||||||
for _, email := range emails {
|
|
||||||
if email.Primary != nil && *email.Primary &&
|
|
||||||
email.Verified != nil && *email.Verified {
|
|
||||||
primaryVerified = email.Email
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if primaryVerified == nil {
|
|
||||||
return false, errors.New("No verified email addresses found in GitHub account")
|
|
||||||
}
|
|
||||||
|
|
||||||
digestMessage := &mail.Message{
|
digestMessage := &mail.Message{
|
||||||
Sender: "GitHop <mihai.parparita@gmail.com>",
|
Sender: "GitHop <mihai.parparita@gmail.com>",
|
||||||
To: []string{*primaryVerified},
|
To: []string{emailAddress},
|
||||||
Subject: "GitHop Digest",
|
Subject: "GitHop Digest",
|
||||||
HTMLBody: digestHtml.String(),
|
HTMLBody: digestHtml.String(),
|
||||||
}
|
}
|
||||||
|
|
@ -341,7 +329,7 @@ func githubOAuthCallbackHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
GitHubUserId: *user.ID,
|
GitHubUserId: *user.ID,
|
||||||
OAuthToken: *token,
|
OAuthToken: *token,
|
||||||
}
|
}
|
||||||
err = account.put(c)
|
err = account.Put(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
|
|
@ -380,11 +368,28 @@ func settingsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emails, _, err := githubClient.Users.ListEmails(nil)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
emailAddresses := make([]string, len(emails))
|
||||||
|
for i := range emails {
|
||||||
|
emailAddresses[i] = *emails[i].Email
|
||||||
|
}
|
||||||
|
accountEmailAddress, err := account.GetDigestEmailAddress(githubClient)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var data = map[string]interface{}{
|
var data = map[string]interface{}{
|
||||||
"Account": account,
|
"Account": account,
|
||||||
"User": user,
|
"User": user,
|
||||||
"Timezones": timezones,
|
"Timezones": timezones,
|
||||||
"Repos": repos,
|
"Repos": repos,
|
||||||
|
"EmailAddresses": emailAddresses,
|
||||||
|
"AccountEmailAddress": accountEmailAddress,
|
||||||
}
|
}
|
||||||
if err := templates["settings"].Execute(w, data); err != nil {
|
if err := templates["settings"].Execute(w, data); err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
|
@ -433,7 +438,9 @@ func saveSettingsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = account.put(c)
|
account.DigestEmailAddress = r.FormValue("email_address")
|
||||||
|
|
||||||
|
err = account.Put(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,15 @@ a {
|
||||||
display: inline;
|
display: inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.setting {
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting .explanation {
|
||||||
|
color: #999;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.repos h2 {
|
.repos h2 {
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
|
||||||
|
|
@ -15,21 +15,39 @@
|
||||||
|
|
||||||
<form method="POST" action="{{routeUrl "save-settings"}}">
|
<form method="POST" action="{{routeUrl "save-settings"}}">
|
||||||
|
|
||||||
<p>
|
<div class="setting">
|
||||||
<label>
|
<label>
|
||||||
Timezone for digest day boundaries:
|
Timezone:
|
||||||
<select name="timezone_name">
|
<select name="timezone_name">
|
||||||
{{$accountTimezoneName := .Account.TimezoneName}}
|
{{$accountTimezoneName := .Account.TimezoneName}}
|
||||||
{{range .Timezones}}
|
{{range .Timezones}}
|
||||||
{{if .LocationName}}
|
{{if .LocationName}}
|
||||||
<option value={{.LocationName}} {{if eq .LocationName $accountTimezoneName}}selected{{end}}>{{.LocationName}} (GMT {{.DisplayUTCOffset}})</option>
|
<option value="{{.LocationName}}" {{if eq .LocationName $accountTimezoneName}}selected{{end}}>{{.LocationName}} (GMT {{.DisplayUTCOffset}})</option>
|
||||||
{{else}}
|
{{else}}
|
||||||
<option disabled></option>
|
<option disabled></option>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
</select>
|
</select>
|
||||||
|
<div class="explanation">
|
||||||
|
Used for determining day boundaries and timestamps in emails.
|
||||||
|
</div>
|
||||||
</label>
|
</label>
|
||||||
</p>
|
</div>
|
||||||
|
|
||||||
|
<div class="setting">
|
||||||
|
<label>
|
||||||
|
Email address:
|
||||||
|
<select name="email_address">
|
||||||
|
{{$accountEmailAddress := .AccountEmailAddress}}
|
||||||
|
{{range .EmailAddresses}}
|
||||||
|
<option value="{{.}}" {{if eq . $accountEmailAddress}}selected{{end}}>{{.}}</option>
|
||||||
|
{{end}}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<div class="explanation">
|
||||||
|
Where your digest will be sent to.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
You have {{len .Repos.AllRepos}} repositories. Select which you would like to include in your digest:
|
You have {{len .Repos.AllRepos}} repositories. Select which you would like to include in your digest:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue