mirror of
https://github.com/samsonjs/retrogit.git
synced 2026-03-25 09:25:49 +00:00
Stop looking up repos for all users on the admin page.
Takes too long to load. Move repos instead into a per-user page. Also adds basic redacting of repo information.
This commit is contained in:
parent
439d60913b
commit
6b8e347a72
6 changed files with 119 additions and 23 deletions
43
app/admin.go
43
app/admin.go
|
|
@ -14,8 +14,6 @@ type AdminUserData struct {
|
|||
Account *Account
|
||||
User *github.User
|
||||
EmailAddress string
|
||||
Repos *Repos
|
||||
ReposError error
|
||||
}
|
||||
|
||||
// sort.Interface implementation for sorting AdminUserDatas
|
||||
|
|
@ -48,34 +46,25 @@ func usersAdminHandler(w http.ResponseWriter, r *http.Request) *AppError {
|
|||
emailAddress = err.Error()
|
||||
}
|
||||
|
||||
repos, reposErr := getRepos(c, githubClient, account, user)
|
||||
ch <- &AdminUserData{
|
||||
Account: account,
|
||||
User: user,
|
||||
EmailAddress: emailAddress,
|
||||
Repos: repos,
|
||||
ReposError: reposErr,
|
||||
}
|
||||
}(&accounts[i])
|
||||
}
|
||||
|
||||
users := make([]*AdminUserData, 0)
|
||||
totalRepos := 0
|
||||
for _ = range accounts {
|
||||
select {
|
||||
case r := <-ch:
|
||||
users = append(users, r)
|
||||
if r.Repos != nil {
|
||||
totalRepos += len(r.Repos.AllRepos)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Sort(AdminUserDataByGitHubUserId(users))
|
||||
|
||||
var data = map[string]interface{}{
|
||||
"Users": users,
|
||||
"TotalUsers": len(users),
|
||||
"TotalRepos": totalRepos,
|
||||
"Users": users,
|
||||
}
|
||||
return templates["users-admin"].Render(w, data)
|
||||
}
|
||||
|
|
@ -109,6 +98,36 @@ func digestAdminHandler(w http.ResponseWriter, r *http.Request) *AppError {
|
|||
return templates["digest-admin"].Render(w, data)
|
||||
}
|
||||
|
||||
func reposAdminHandler(w http.ResponseWriter, r *http.Request) *AppError {
|
||||
userId, err := strconv.Atoi(r.FormValue("user_id"))
|
||||
if err != nil {
|
||||
return BadRequest(err, "Malformed user_id value")
|
||||
}
|
||||
c := appengine.NewContext(r)
|
||||
account, err := getAccount(c, userId)
|
||||
if account == nil {
|
||||
return BadRequest(err, "user_id does not point to an account")
|
||||
}
|
||||
if err != nil {
|
||||
return InternalError(err, "Could not look up account")
|
||||
}
|
||||
|
||||
oauthTransport := githubOAuthTransport(c)
|
||||
oauthTransport.Token = &account.OAuthToken
|
||||
githubClient := github.NewClient(oauthTransport.Client())
|
||||
|
||||
user, _, err := githubClient.Users.Get("")
|
||||
repos, reposErr := getRepos(c, githubClient, account, user)
|
||||
|
||||
repos.Redact()
|
||||
var data = map[string]interface{}{
|
||||
"User": user,
|
||||
"Repos": repos,
|
||||
"ReposError": reposErr,
|
||||
}
|
||||
return templates["repos-admin"].Render(w, data)
|
||||
}
|
||||
|
||||
func deleteAccountAdminHandler(w http.ResponseWriter, r *http.Request) *AppError {
|
||||
userId, err := strconv.Atoi(r.FormValue("user_id"))
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -316,6 +316,5 @@ func (digest *Digest) Redact() {
|
|||
commit.Message = "Redacted redacted redacted"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
23
app/repos.go
23
app/repos.go
|
|
@ -167,6 +167,29 @@ type Repos struct {
|
|||
OldestVintage time.Time
|
||||
}
|
||||
|
||||
func (repos *Repos) Redact() {
|
||||
for _, repo := range repos.UserRepos {
|
||||
*repo.HTMLURL = "https://redacted"
|
||||
*repo.FullName = "redacted/redacted"
|
||||
}
|
||||
for _, otherUserRepos := range repos.OtherUserRepos {
|
||||
*otherUserRepos.User.Login = "redacted"
|
||||
*otherUserRepos.User.AvatarURL = "https://redacted"
|
||||
for _, repo := range otherUserRepos.Repos {
|
||||
*repo.HTMLURL = "https://redacted"
|
||||
*repo.FullName = "redacted/redacted"
|
||||
}
|
||||
}
|
||||
for _, orgRepos := range repos.OrgRepos {
|
||||
*orgRepos.Org.Login = "redacted"
|
||||
*orgRepos.Org.AvatarURL = "https://redacted"
|
||||
for _, repo := range orgRepos.Repos {
|
||||
*repo.HTMLURL = "https://redacted"
|
||||
*repo.FullName = "redacted/redacted"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type Repo struct {
|
||||
*github.Repository
|
||||
Vintage time.Time
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ func init() {
|
|||
|
||||
router.Handle("/admin/users", AppHandler(usersAdminHandler)).Name("users-admin")
|
||||
router.Handle("/admin/digest", AppHandler(digestAdminHandler)).Name("digest-admin")
|
||||
router.Handle("/admin/repos", AppHandler(reposAdminHandler)).Name("repos-admin")
|
||||
router.Handle("/admin/delete-account", AppHandler(deleteAccountAdminHandler)).Name("delete-account-admin")
|
||||
http.Handle("/", router)
|
||||
}
|
||||
|
|
|
|||
58
app/templates/repos-admin.html
Normal file
58
app/templates/repos-admin.html
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
{{define "title"}}Repos Admin{{end}}
|
||||
|
||||
{{define "repo"}}
|
||||
<li class="repo {{.TypeAsClassName}}">
|
||||
<span class="glyph octicon octicon-{{.TypeAsOcticonName}}"></span>
|
||||
<a href="{{.HTMLURL}}">{{.FullName}}</a>
|
||||
<span class="vintage">{{.DisplayVintage}}</span>
|
||||
</li>
|
||||
{{end}}
|
||||
|
||||
{{define "body"}}
|
||||
|
||||
{{if .ReposError}}
|
||||
{{.ReposError}}
|
||||
{{else}}
|
||||
{{len .Repos.AllRepos}} from {{len .Repos.OtherUserRepos}} other users and {{len .Repos.OrgRepos}} organizations
|
||||
|
||||
<div class="repos">
|
||||
<h2>
|
||||
<a href="https://github.com/{{.User.Login}}">
|
||||
<img src="{{.User.AvatarURL}}" class="avatar">{{.User.Login}}</a>
|
||||
</h2>
|
||||
<ul>
|
||||
{{range .Repos.UserRepos}}
|
||||
{{template "repo" .}}
|
||||
{{end}}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{{range .Repos.OtherUserRepos}}
|
||||
<div class="repos">
|
||||
<h2>
|
||||
<a href="https://github.com/{{.User.Login}}">{{.User.Login}}</a>
|
||||
</h2>
|
||||
<ul>
|
||||
{{range .Repos}}
|
||||
{{template "repo" .}}
|
||||
{{end}}
|
||||
</ul>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
{{range .Repos.OrgRepos}}
|
||||
<div class="repos">
|
||||
<h2>
|
||||
<a href="https://github.com/{{.Org.Login}}">{{.Org.Login}}</a>
|
||||
</h2>
|
||||
<ul>
|
||||
{{range .Repos}}
|
||||
{{template "repo" .}}
|
||||
{{end}}
|
||||
</ul>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
{{end}}
|
||||
|
||||
{{end}}
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
<link rel="stylesheet" href="/static/admin.css">
|
||||
|
||||
<div class="blurb">
|
||||
{{.TotalUsers}} users with {{.TotalRepos}} repositories.
|
||||
{{len .Users}} users.
|
||||
</div>
|
||||
|
||||
<table id="users-table">
|
||||
|
|
@ -15,14 +15,15 @@
|
|||
<th>Username</th>
|
||||
<th>Email</th>
|
||||
<th>Frequency</th>
|
||||
<th>Repositories</th>
|
||||
<th>Digest</th>
|
||||
<th>Repos</th>
|
||||
<th>Account</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range .Users}}
|
||||
<tr>
|
||||
<td><a href="{{routeUrl "digest-admin"}}?user_id={{.Account.GitHubUserId}}">{{.Account.GitHubUserId}}</a></td>
|
||||
<td>{{.Account.GitHubUserId}}</td>
|
||||
<td>
|
||||
{{if .User}}
|
||||
{{template "user" .User}}
|
||||
|
|
@ -32,13 +33,8 @@
|
|||
</td>
|
||||
<td>{{.EmailAddress}}</td>
|
||||
<td>{{.Account.Frequency}}</td>
|
||||
<td>
|
||||
{{if .ReposError}}
|
||||
{{.ReposError}}
|
||||
{{else}}
|
||||
{{len .Repos.AllRepos}} from {{len .Repos.OtherUserRepos}} other users and {{len .Repos.OrgRepos}} organizations
|
||||
{{end}}
|
||||
</td>
|
||||
<td><a href="{{routeUrl "digest-admin"}}?user_id={{.Account.GitHubUserId}}">View</a></td>
|
||||
<td><a href="{{routeUrl "repos-admin"}}?user_id={{.Account.GitHubUserId}}">View</a></td>
|
||||
<td>
|
||||
<form method="POST" action="{{routeUrl "delete-account-admin"}}" onsubmit="return confirm('Really delete?')">
|
||||
<input type="hidden" name="user_id" value="{{.Account.GitHubUserId}}">
|
||||
|
|
|
|||
Loading…
Reference in a new issue