Add option to control which repositories are included in the digest.

This commit is contained in:
Mihai Parparita 2014-08-31 15:22:19 -07:00
parent 7852b128df
commit 1cb55cfe6a
5 changed files with 70 additions and 24 deletions

View file

@ -19,6 +19,7 @@ type Account struct {
OAuthToken oauth.Token `datastore:"-,"`
TimezoneName string `datastore:",noindex"`
TimezoneLocation *time.Location `datastore:"-,"`
ExcludedRepoIds []int `datastore:",noindex"`
}
func getAccount(c appengine.Context, githubUserId int) (*Account, error) {
@ -66,6 +67,15 @@ func getAllAccountGithubUserIds(c appengine.Context) ([]int, error) {
return result, nil
}
func (account *Account) IsRepoIdExcluded(repoId int) bool {
for i := range account.ExcludedRepoIds {
if account.ExcludedRepoIds[i] == repoId {
return true
}
}
return false
}
func (account *Account) put(c appengine.Context) error {
w := new(bytes.Buffer)
err := gob.NewEncoder(w).Encode(&account.OAuthToken)

View file

@ -133,7 +133,7 @@ func newDigest(c appengine.Context, githubClient *github.Client, account *Accoun
return nil, err
}
repos, err := getRepos(c, githubClient, user)
repos, err := getRepos(c, githubClient, account, user)
if err != nil {
return nil, err
}
@ -151,7 +151,7 @@ func newDigest(c appengine.Context, githubClient *github.Client, account *Accoun
// Only look at repos that may have activity in the digest interval.
var intervalRepos []*Repo
for _, repo := range repos.AllRepos {
if repo.Vintage.Before(digestEndTime) && repo.PushedAt != nil &&
if repo.IncludeInDigest && repo.Vintage.Before(digestEndTime) && repo.PushedAt != nil &&
repo.PushedAt.After(digestStartTime) {
intervalRepos = append(intervalRepos, repo)
}

View file

@ -49,8 +49,8 @@ func init() {
router.HandleFunc("/digest/send", sendDigestHandler).Name("send-digest").Methods("POST")
router.HandleFunc("/digest/cron", digestCronHandler)
router.HandleFunc("/account/settings", settingsHandler).Name("settings")
router.HandleFunc("/account/set-timezone", setTimezoneHandler).Name("set-timezone").Methods("POST")
router.HandleFunc("/account/settings", settingsHandler).Name("settings").Methods("GET")
router.HandleFunc("/account/settings", saveSettingsHandler).Name("save-settings").Methods("POST")
router.HandleFunc("/admin/digest", digestAdminHandler)
http.Handle("/", router)
@ -374,7 +374,7 @@ func settingsHandler(w http.ResponseWriter, r *http.Request) {
return
}
repos, err := getRepos(c, githubClient, user)
repos, err := getRepos(c, githubClient, account, user)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@ -391,7 +391,7 @@ func settingsHandler(w http.ResponseWriter, r *http.Request) {
}
}
func setTimezoneHandler(w http.ResponseWriter, r *http.Request) {
func saveSettingsHandler(w http.ResponseWriter, r *http.Request) {
session, _ := sessionStore.Get(r, sessionConfig.CookieName)
userId := session.Values[sessionConfig.UserIdKey].(int)
c := appengine.NewContext(r)
@ -400,6 +400,21 @@ func setTimezoneHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
oauthTransport := githubOAuthTransport(c)
oauthTransport.Token = &account.OAuthToken
githubClient := github.NewClient(oauthTransport.Client())
user, _, err := githubClient.Users.Get("")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
repos, err := getRepos(c, githubClient, account, user)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
timezoneName := r.FormValue("timezone_name")
_, err = time.LoadLocation(timezoneName)
@ -407,16 +422,25 @@ func setTimezoneHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
account.TimezoneName = timezoneName
account.ExcludedRepoIds = make([]int, 0)
for _, repo := range repos.AllRepos {
repoId := *repo.ID
_, included := r.Form[fmt.Sprintf("repo-%d", repoId)]
if !included {
account.ExcludedRepoIds = append(account.ExcludedRepoIds, repoId)
}
}
err = account.put(c)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
indexUrl, _ := router.Get("index").URL()
http.Redirect(w, r, indexUrl.String(), http.StatusFound)
settingsUrl, _ := router.Get("settings").URL()
http.Redirect(w, r, settingsUrl.String(), http.StatusFound)
}
func digestAdminHandler(w http.ResponseWriter, r *http.Request) {

View file

@ -159,11 +159,16 @@ type Repos struct {
type Repo struct {
*github.Repository
Vintage time.Time
Vintage time.Time
IncludeInDigest bool
}
func newRepo(githubRepo *github.Repository) *Repo {
return &Repo{githubRepo, githubRepo.CreatedAt.UTC()}
func newRepo(githubRepo *github.Repository, account *Account) *Repo {
return &Repo{
Repository: githubRepo,
Vintage: githubRepo.CreatedAt.UTC(),
IncludeInDigest: !account.IsRepoIdExcluded(*githubRepo.ID),
}
}
func (repo *Repo) TypeAsOcticonName() string {
@ -200,7 +205,7 @@ type OrgRepos struct {
Repos []*Repo
}
func getRepos(c appengine.Context, githubClient *github.Client, user *github.User) (*Repos, error) {
func getRepos(c appengine.Context, githubClient *github.Client, account *Account, user *github.User) (*Repos, error) {
// The username parameter must be left blank so that we can get all of the
// repositories the user has access to, not just ones that they own.
clientUserRepos, _, err := githubClient.Repositories.List("", nil)
@ -215,7 +220,7 @@ func getRepos(c appengine.Context, githubClient *github.Client, user *github.Use
for i := range clientUserRepos {
ownerID := *clientUserRepos[i].Owner.ID
if ownerID == *user.ID {
repos.UserRepos = append(repos.UserRepos, newRepo(&clientUserRepos[i]))
repos.UserRepos = append(repos.UserRepos, newRepo(&clientUserRepos[i], account))
} else {
var userRepos *UserRepos
for j := range repos.OtherUserRepos {
@ -231,7 +236,7 @@ func getRepos(c appengine.Context, githubClient *github.Client, user *github.Use
}
repos.OtherUserRepos = append(repos.OtherUserRepos, userRepos)
}
userRepos.Repos = append(userRepos.Repos, newRepo(&clientUserRepos[i]))
userRepos.Repos = append(userRepos.Repos, newRepo(&clientUserRepos[i], account))
}
}
@ -251,7 +256,7 @@ func getRepos(c appengine.Context, githubClient *github.Client, user *github.Use
orgRepos := make([]*Repo, 0, len(clientOrgRepos))
allRepoCount += len(clientOrgRepos)
for j := range clientOrgRepos {
orgRepos = append(orgRepos, newRepo(&clientOrgRepos[j]))
orgRepos = append(orgRepos, newRepo(&clientOrgRepos[j], account))
}
repos.OrgRepos = append(repos.OrgRepos, &OrgRepos{org, orgRepos})
}

View file

@ -2,16 +2,22 @@
{{define "repo"}}
<li class="repo {{.TypeAsClassName}}">
<span class="glyph octicon octicon-{{.TypeAsOcticonName}}"></span>
<a href="{{.HTMLURL}}">{{.FullName}}</a>
<span class="vintage">{{.DisplayVintage}}</span>
<label>
<input type="checkbox" name="repo-{{.ID}}" value="include" {{if .IncludeInDigest}}checked{{end}}>
<span class="glyph octicon octicon-{{.TypeAsOcticonName}}"></span>
<a href="{{.HTMLURL}}">{{.FullName}}</a>
<span class="vintage">{{.DisplayVintage}}</span>
</label>
</li>
{{end}}
{{define "body"}}
<form method="POST" action="{{routeUrl "save-settings"}}">
<p>
<form method="POST" action="{{routeUrl "set-timezone"}}">
<label>
Timezone for digest day boundaries:
<select name="timezone_name">
{{$accountTimezoneName := .Account.TimezoneName}}
{{range .Timezones}}
@ -22,13 +28,11 @@
{{end}}
{{end}}
</select>
<input type="submit" value="Set Timezone">
</form>
</label>
</p>
<p>
You have {{len .Repos.AllRepos}} repositories:
You have {{len .Repos.AllRepos}} repositories. Select which you would like to include in your digest:
</p>
<div class="repos">
@ -71,5 +75,8 @@
</div>
{{end}}
<input type="submit" value="Save Settings">
</form>
{{end}}