working on the homage page

This commit is contained in:
Brad Rydzewski 2015-10-15 15:40:27 -07:00
parent 8fbd3d5fa7
commit f84c8bc411
11 changed files with 106 additions and 171 deletions

View file

@ -34,6 +34,47 @@ func ShowIndex(c *gin.Context) {
}) })
} }
// func ShowIndex(c *gin.Context) {
// db := context.Database(c)
// remote := context.Remote(c)
// user := session.User(c)
// if user == nil {
// c.Redirect(http.StatusSeeOther, "/login")
// return
// }
// var err error
// var repos []*model.RepoLite
// // get the repository list from the cache
// reposv, ok := c.Get("repos")
// if ok {
// repos = reposv.([]*model.RepoLite)
// } else {
// println("GETTING REMOTE REPOS")
// repos, err = remote.Repos(user)
// if err != nil {
// log.Errorf("Failure to get remote repositories for %s. %s.",
// user.Login, err)
// } else {
// c.Set("repos", repos)
// }
// }
// // for each repository in the remote system we get
// // the intersection of those repostiories in Drone
// repos_, err := model.GetRepoListOf(db, repos)
// if err != nil {
// log.Errorf("Failure to get repository list for %s. %s.",
// user.Login, err)
// }
// c.HTML(200, "repos.html", gin.H{
// "User": user,
// "Repos": repos_,
// })
// }
func ShowLogin(c *gin.Context) { func ShowLogin(c *gin.Context) {
c.HTML(200, "login.html", gin.H{"Error": c.Query("error")}) c.HTML(200, "login.html", gin.H{"Error": c.Query("error")})
} }

View file

@ -110,11 +110,6 @@ func PostRepo(c *gin.Context) {
c.AbortWithError(500, err) c.AbortWithError(500, err)
return return
} }
err = model.CreateStar(tx, user, r)
if err != nil {
c.AbortWithError(500, err)
return
}
tx.Commit() tx.Commit()
c.JSON(200, r) c.JSON(200, r)
@ -163,27 +158,11 @@ func PatchRepo(c *gin.Context) {
return return
} }
// if the user is authenticated we should
// check to see if they've starred the repository
repo.IsStarred, _ = model.GetStar(db, user, repo)
c.IndentedJSON(http.StatusOK, repo) c.IndentedJSON(http.StatusOK, repo)
} }
func GetRepo(c *gin.Context) { func GetRepo(c *gin.Context) {
db := context.Database(c) c.IndentedJSON(http.StatusOK, session.Repo(c))
repo := session.Repo(c)
user := session.User(c)
if user == nil {
c.IndentedJSON(http.StatusOK, repo)
return
}
// if the user is authenticated we should
// check to see if they've starred the repository
repo.IsStarred, _ = model.GetStar(db, user, repo)
c.IndentedJSON(http.StatusOK, repo)
} }
func GetRepoKey(c *gin.Context) { func GetRepoKey(c *gin.Context) {
@ -254,29 +233,3 @@ func PostSecure(c *gin.Context) {
func PostReactivate(c *gin.Context) { func PostReactivate(c *gin.Context) {
} }
func PostStar(c *gin.Context) {
db := context.Database(c)
repo := session.Repo(c)
user := session.User(c)
err := model.CreateStar(db, user, repo)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
} else {
c.Writer.WriteHeader(http.StatusOK)
}
}
func DeleteStar(c *gin.Context) {
db := context.Database(c)
repo := session.Repo(c)
user := session.User(c)
err := model.DeleteStar(db, user, repo)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
} else {
c.Writer.WriteHeader(http.StatusOK)
}
}

View file

@ -28,13 +28,33 @@ func GetFeed(c *gin.Context) {
func GetRepos(c *gin.Context) { func GetRepos(c *gin.Context) {
user := session.User(c) user := session.User(c)
remote := context.Remote(c)
db := context.Database(c) db := context.Database(c)
repos, err := model.GetRepoList(db, user) var repos []*model.RepoLite
// get the repository list from the cache
reposv, ok := c.Get("repos")
if ok {
repos = reposv.([]*model.RepoLite)
} else {
var err error
repos, err = remote.Repos(user)
if err != nil {
c.AbortWithStatus(http.StatusInternalServerError)
return
}
}
// for each repository in the remote system we get
// the intersection of those repostiories in Drone
repos_, err := model.GetRepoListOf(db, repos)
if err != nil { if err != nil {
c.AbortWithStatus(http.StatusInternalServerError) c.AbortWithStatus(http.StatusInternalServerError)
return return
} }
c.IndentedJSON(http.StatusOK, repos)
c.Set("repos", repos)
c.IndentedJSON(http.StatusOK, repos_)
} }
func GetRemoteRepos(c *gin.Context) { func GetRemoteRepos(c *gin.Context) {

View file

@ -60,15 +60,16 @@ func GetRepoList(db meddler.DB, user *User) ([]*Repo, error) {
return repos, err return repos, err
} }
func GetRepoListOf(db meddler.DB, listof []string) ([]*Repo, error) { func GetRepoListOf(db meddler.DB, listof []*RepoLite) ([]*Repo, error) {
var repos = []*Repo{} var repos = []*Repo{}
var qs = make([]string, len(listof), len(listof)) var size = len(listof)
var in = make([]interface{}, len(listof), len(listof)) var qs = make([]string, size, size)
var in = make([]interface{}, size, size)
for i, repo := range listof { for i, repo := range listof {
qs[i] = "?" qs[i] = "?"
in[i] = repo in[i] = repo.FullName
} }
var stmt = "SELECT * FROM repos WHERE repo_id IN (" + strings.Join(qs, ",") + ")" var stmt = "SELECT * FROM repos WHERE repo_full_name IN (" + strings.Join(qs, ",") + ")"
var err = meddler.QueryAll(db, &repos, database.Rebind(stmt), in...) var err = meddler.QueryAll(db, &repos, database.Rebind(stmt), in...)
return repos, err return repos, err
} }

View file

@ -1,44 +0,0 @@
package model
import (
"github.com/drone/drone/shared/database"
"github.com/russross/meddler"
)
type Star struct {
ID int64 `meddler:"star_id,pk"`
RepoID int64 `meddler:"star_repo_id"`
UserID int64 `meddler:"star_user_id"`
}
func GetStar(db meddler.DB, user *User, repo *Repo) (bool, error) {
var star = new(Star)
err := meddler.QueryRow(db, star, database.Rebind(starQuery), user.ID, repo.ID)
return (err == nil), err
}
func CreateStar(db meddler.DB, user *User, repo *Repo) error {
var star = &Star{UserID: user.ID, RepoID: repo.ID}
return meddler.Insert(db, starTable, star)
}
func DeleteStar(db meddler.DB, user *User, repo *Repo) error {
var _, err = db.Exec(database.Rebind(starDeleteStmt), user.ID, repo.ID)
return err
}
const starTable = "stars"
const starQuery = `
SELECT *
FROM stars
WHERE star_user_id=?
AND star_repo_id=?
LIMIT 1
`
const starDeleteStmt = `
DELETE FROM stars
WHERE star_user_id=?
AND star_repo_id=?
`

View file

@ -1,59 +0,0 @@
package model
import (
"testing"
"github.com/drone/drone/shared/database"
"github.com/franela/goblin"
)
func TestStarstore(t *testing.T) {
db := database.Open("sqlite3", ":memory:")
defer db.Close()
g := goblin.Goblin(t)
g.Describe("Stars", func() {
// before each test be sure to purge the package
// table data from the database.
g.BeforeEach(func() {
db.Exec("DELETE FROM stars")
})
g.It("Should Add a Star", func() {
user := User{ID: 1}
repo := Repo{ID: 2}
err := CreateStar(db, &user, &repo)
g.Assert(err == nil).IsTrue()
})
g.It("Should Get Starred", func() {
user := User{ID: 1}
repo := Repo{ID: 2}
CreateStar(db, &user, &repo)
ok, err := GetStar(db, &user, &repo)
g.Assert(err == nil).IsTrue()
g.Assert(ok).IsTrue()
})
g.It("Should Not Get Starred", func() {
user := User{ID: 1}
repo := Repo{ID: 2}
ok, err := GetStar(db, &user, &repo)
g.Assert(err != nil).IsTrue()
g.Assert(ok).IsFalse()
})
g.It("Should Del a Star", func() {
user := User{ID: 1}
repo := Repo{ID: 2}
CreateStar(db, &user, &repo)
_, err1 := GetStar(db, &user, &repo)
err2 := DeleteStar(db, &user, &repo)
_, err3 := GetStar(db, &user, &repo)
g.Assert(err1 == nil).IsTrue()
g.Assert(err2 == nil).IsTrue()
g.Assert(err3 == nil).IsFalse()
})
})
}

View file

@ -28,7 +28,7 @@ func Load(middleware ...gin.HandlerFunc) http.Handler {
e.Use(cache.Perms) e.Use(cache.Perms)
e.Use(token.Refresh) e.Use(token.Refresh)
e.GET("/", controller.ShowIndex) e.GET("/", cache.Repos, controller.ShowIndex)
e.GET("/login", controller.ShowLogin) e.GET("/login", controller.ShowLogin)
e.GET("/logout", controller.GetLogout) e.GET("/logout", controller.GetLogout)
@ -60,8 +60,8 @@ func Load(middleware ...gin.HandlerFunc) http.Handler {
{ {
user.Use(session.MustUser()) user.Use(session.MustUser())
user.GET("", controller.GetSelf) user.GET("", controller.GetSelf)
user.GET("/builds", controller.GetFeed) // user.GET("/builds", controller.GetFeed)
user.GET("/repos", controller.GetRepos) user.GET("/repos", cache.Repos, controller.GetRepos)
user.GET("/repos/remote", cache.Repos, controller.GetRemoteRepos) user.GET("/repos/remote", cache.Repos, controller.GetRemoteRepos)
user.POST("/token", controller.PostToken) user.POST("/token", controller.PostToken)
} }
@ -101,8 +101,6 @@ func Load(middleware ...gin.HandlerFunc) http.Handler {
repo.GET("/logs/:number/:job", controller.GetBuildLogs) repo.GET("/logs/:number/:job", controller.GetBuildLogs)
// requires authenticated user // requires authenticated user
repo.POST("/starred", session.MustUser(), controller.PostStar)
repo.DELETE("/starred", session.MustUser(), controller.DeleteStar)
repo.POST("/encrypt", session.MustUser(), controller.PostSecure) repo.POST("/encrypt", session.MustUser(), controller.PostSecure)
// requires push permissions // requires push permissions

View file

@ -45,3 +45,13 @@
padding-right:0px; padding-right:0px;
padding-left:0px; padding-left:0px;
width:45px; width:45px;
.repo-search
color: #747C84;
border: none;
background-color: #eff1f5;
border-radius: 0px;
padding: 9px 15px;
width: 100%;
margin-bottom: 45px;
border-radius: 2px;

View file

@ -291,6 +291,8 @@ body.login div.alert { position: fixed; top: 0px; left: 0px; right: 0px; line-he
.repo-row .card-header { background: #FFF; border-bottom: none; padding-right: 0px; padding-left: 0px; width: 45px; } .repo-row .card-header { background: #FFF; border-bottom: none; padding-right: 0px; padding-left: 0px; width: 45px; }
.repo-search { color: #747C84; border: none; background-color: #eff1f5; border-radius: 0px; padding: 9px 15px; width: 100%; margin-bottom: 45px; border-radius: 2px; }
.toc { list-style-type: none; padding: 0px; margin: 0px; padding-bottom: 40px; } .toc { list-style-type: none; padding: 0px; margin: 0px; padding-bottom: 40px; }
.toc h2 { font-size: 21px; font-weight: normal; margin-bottom: 20px; color: #2b303b; } .toc h2 { font-size: 21px; font-weight: normal; margin-bottom: 20px; color: #2b303b; }

View file

@ -50,6 +50,7 @@ html
block scripts block scripts
script[type="text/javascript"][src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"] script[type="text/javascript"][src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"]
script[type="text/javascript"][src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"] script[type="text/javascript"][src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"]
script[type="text/javascript"][src="https://cdnjs.cloudflare.com/ajax/libs/jquery-searcher/0.2.0/jquery.searcher.min.js"]
script[type="text/javascript"][src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/js/bootstrap.min.js"] script[type="text/javascript"][src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/js/bootstrap.min.js"]
script[type="text/javascript"][src="https://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.11.1/typeahead.bundle.min.js"] script[type="text/javascript"][src="https://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.11.1/typeahead.bundle.min.js"]
script[text="text/javascript"][src="https://cdnjs.cloudflare.com/ajax/libs/stickyfill/1.1.2/stickyfill.js"] script[text="text/javascript"][src="https://cdnjs.cloudflare.com/ajax/libs/stickyfill/1.1.2/stickyfill.js"]

View file

@ -14,10 +14,22 @@ block content
| Your repository list is empty. | Your repository list is empty.
div.row.repo-row div.row.repo-row
each $repo in Repos input.repo-search[type="search"][placeholder="Filter..."]
div.col-sm-4 div.repo-list
a.card[href="/"+$repo.FullName] each $repo in Repos
div.card-header div.col-sm-4
img.avatar[src=$repo.Avatar] a.card[href="/"+$repo.FullName]
div.card-block div.card-header
h3.login #{$repo.Name} img.avatar[src=$repo.Avatar]
div.card-block
h3.login #{$repo.Name}
block append scripts
if len(Repos) != 0
script
$(window).load(function(){
$(".repo-list").searcher({
itemSelector: ".col-sm-4",
textSelector: ".login",
inputSelector: ".repo-search"
});
});