| @@ -12,11 +12,8 @@ import ( | |||
| "github.com/gogits/binding" | |||
| "github.com/gogits/gogs/models" | |||
| "github.com/gogits/gogs/modules/base" | |||
| "github.com/gogits/gogs/modules/log" | |||
| "github.com/martini-contrib/render" | |||
| "github.com/martini-contrib/sessions" | |||
| ) | |||
| type CreateRepoForm struct { | |||
| @@ -61,62 +58,3 @@ type DeleteRepoForm struct { | |||
| UserName string `form:"userName" binding:"Required"` | |||
| RepoId int64 `form:"repoId" binding:"Required"` | |||
| } | |||
| func RepoAssignment(redirect bool) martini.Handler { | |||
| return func(params martini.Params, r render.Render, data base.TmplData, session sessions.Session) { | |||
| // assign false first | |||
| data["IsRepositoryValid"] = false | |||
| var ( | |||
| user *models.User | |||
| err error | |||
| ) | |||
| // get repository owner | |||
| isOwner := (data["SignedUserName"] == params["username"]) | |||
| if !isOwner { | |||
| user, err = models.GetUserByName(params["username"]) | |||
| if err != nil { | |||
| if redirect { | |||
| r.Redirect("/") | |||
| return | |||
| } | |||
| //data["ErrorMsg"] = err | |||
| //log.Error("repo.Single: %v", err) | |||
| //r.HTML(200, "base/error", data) | |||
| return | |||
| } | |||
| } else { | |||
| user = SignedInUser(session) | |||
| } | |||
| if user == nil { | |||
| if redirect { | |||
| r.Redirect("/") | |||
| return | |||
| } | |||
| //data["ErrorMsg"] = "invliad user account for single repository" | |||
| //log.Error("repo.Single: %v", err) | |||
| //r.HTML(200, "base/error", data) | |||
| return | |||
| } | |||
| data["IsRepositoryOwner"] = isOwner | |||
| // get repository | |||
| repo, err := models.GetRepositoryByName(user, params["reponame"]) | |||
| if err != nil { | |||
| if redirect { | |||
| r.Redirect("/") | |||
| return | |||
| } | |||
| //data["ErrorMsg"] = err | |||
| //log.Error("repo.Single: %v", err) | |||
| //r.HTML(200, "base/error", data) | |||
| return | |||
| } | |||
| data["Repository"] = repo | |||
| data["Owner"] = user | |||
| data["Title"] = user.Name + "/" + repo.Name | |||
| data["RepositoryLink"] = data["Title"] | |||
| data["IsRepositoryValid"] = true | |||
| } | |||
| } | |||
| @@ -21,6 +21,7 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{ | |||
| }, | |||
| "str2html": Str2html, | |||
| "TimeSince": TimeSince, | |||
| "FileSize": FileSize, | |||
| "Subtract": Subtract, | |||
| "ActionIcon": ActionIcon, | |||
| "ActionDesc": ActionDesc, | |||
| @@ -8,6 +8,7 @@ import ( | |||
| "crypto/md5" | |||
| "encoding/hex" | |||
| "fmt" | |||
| "math" | |||
| "strings" | |||
| "time" | |||
| ) | |||
| @@ -80,6 +81,51 @@ func TimeSince(then time.Time) string { | |||
| return then.String() | |||
| } | |||
| const ( | |||
| Byte = 1 | |||
| KByte = Byte * 1024 | |||
| MByte = KByte * 1024 | |||
| GByte = MByte * 1024 | |||
| TByte = GByte * 1024 | |||
| PByte = TByte * 1024 | |||
| EByte = PByte * 1024 | |||
| ) | |||
| var bytesSizeTable = map[string]uint64{ | |||
| "b": Byte, | |||
| "kb": KByte, | |||
| "mb": MByte, | |||
| "gb": GByte, | |||
| "tb": TByte, | |||
| "pb": PByte, | |||
| "eb": EByte, | |||
| } | |||
| func logn(n, b float64) float64 { | |||
| return math.Log(n) / math.Log(b) | |||
| } | |||
| func humanateBytes(s uint64, base float64, sizes []string) string { | |||
| if s < 10 { | |||
| return fmt.Sprintf("%dB", s) | |||
| } | |||
| e := math.Floor(logn(float64(s), base)) | |||
| suffix := sizes[int(e)] | |||
| val := float64(s) / math.Pow(base, math.Floor(e)) | |||
| f := "%.0f" | |||
| if val < 10 { | |||
| f = "%.1f" | |||
| } | |||
| return fmt.Sprintf(f+"%s", val, suffix) | |||
| } | |||
| // FileSize calculates the file size and generate user-friendly string. | |||
| func FileSize(s int64) string { | |||
| sizes := []string{"B", "KB", "MB", "GB", "TB", "PB", "EB"} | |||
| return humanateBytes(uint64(s), 1024, sizes) | |||
| } | |||
| // Subtract deals with subtraction of all types of number. | |||
| func Subtract(left interface{}, right interface{}) interface{} { | |||
| var rleft, rright int64 | |||
| @@ -29,6 +29,13 @@ type Context struct { | |||
| Render render.Render | |||
| User *models.User | |||
| IsSigned bool | |||
| Repo struct { | |||
| IsValid bool | |||
| IsOwner bool | |||
| Repository *models.Repository | |||
| Owner *models.User | |||
| } | |||
| } | |||
| // Query querys form parameter. | |||
| @@ -0,0 +1,78 @@ | |||
| // Copyright 2014 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package middleware | |||
| import ( | |||
| "github.com/codegangsta/martini" | |||
| "github.com/gogits/gogs/models" | |||
| ) | |||
| func RepoAssignment(redirect bool) martini.Handler { | |||
| return func(ctx *Context, params martini.Params) { | |||
| // assign false first | |||
| ctx.Data["IsRepositoryValid"] = false | |||
| var ( | |||
| user *models.User | |||
| err error | |||
| ) | |||
| // get repository owner | |||
| ctx.Repo.IsOwner = ctx.IsSigned && ctx.User.LowerName == params["username"] | |||
| ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner | |||
| if !ctx.Repo.IsOwner { | |||
| user, err = models.GetUserByName(params["username"]) | |||
| if err != nil { | |||
| if redirect { | |||
| ctx.Render.Redirect("/") | |||
| return | |||
| } | |||
| //data["ErrorMsg"] = err | |||
| //log.Error("repo.Single: %v", err) | |||
| //r.HTML(200, "base/error", data) | |||
| return | |||
| } | |||
| } else { | |||
| user = ctx.User | |||
| } | |||
| if user == nil { | |||
| if redirect { | |||
| ctx.Render.Redirect("/") | |||
| return | |||
| } | |||
| //data["ErrorMsg"] = "invliad user account for single repository" | |||
| //log.Error("repo.Single: %v", err) | |||
| //r.HTML(200, "base/error", data) | |||
| return | |||
| } | |||
| ctx.Repo.Owner = user | |||
| // get repository | |||
| repo, err := models.GetRepositoryByName(user, params["reponame"]) | |||
| if err != nil { | |||
| if redirect { | |||
| ctx.Render.Redirect("/") | |||
| return | |||
| } | |||
| //data["ErrorMsg"] = err | |||
| //log.Error("repo.Single: %v", err) | |||
| //r.HTML(200, "base/error", data) | |||
| return | |||
| } | |||
| ctx.Repo.IsValid = true | |||
| ctx.Repo.Repository = repo | |||
| ctx.Data["IsRepositoryValid"] = true | |||
| ctx.Data["Repository"] = repo | |||
| ctx.Data["Owner"] = user | |||
| ctx.Data["Title"] = user.Name + "/" + repo.Name | |||
| ctx.Data["RepositoryLink"] = ctx.Data["Title"] | |||
| } | |||
| } | |||
| @@ -551,6 +551,38 @@ html, body { | |||
| border-top: none; | |||
| } | |||
| .repo-list li { | |||
| padding: 15px 0; | |||
| border-top: 1px solid #ddd; | |||
| } | |||
| .repo-list li:first-child { | |||
| border-top: none; | |||
| } | |||
| .repo-list h4 { | |||
| font-weight: bold; | |||
| font-size: 24px; | |||
| } | |||
| .repo-list .meta { | |||
| margin: 15px 0 0; | |||
| font-size: 14px; | |||
| } | |||
| .repo-list .desc { | |||
| font-size: 15px; | |||
| } | |||
| .repo-list .meta .fa { | |||
| margin: 0 0 0 20px; | |||
| } | |||
| .repo-list .meta, | |||
| .repo-list .info { | |||
| color: #999; | |||
| } | |||
| #wrapper { | |||
| min-height: 100%; | |||
| height: auto !important; | |||
| @@ -67,20 +67,3 @@ func Delete(ctx *middleware.Context, form auth.DeleteRepoForm) { | |||
| ctx.Render.Redirect("/", 302) | |||
| } | |||
| func List(ctx *middleware.Context) { | |||
| if ctx.User != nil { | |||
| ctx.Render.Redirect("/") | |||
| return | |||
| } | |||
| ctx.Data["Title"] = "Repositories" | |||
| repos, err := models.GetRepositories(ctx.User) | |||
| if err != nil { | |||
| ctx.Handle(200, "repo.List", err) | |||
| return | |||
| } | |||
| ctx.Data["Repos"] = repos | |||
| ctx.Render.HTML(200, "repo/list", ctx.Data) | |||
| } | |||
| @@ -10,12 +10,14 @@ import ( | |||
| ) | |||
| func Single(ctx *middleware.Context, params martini.Params) { | |||
| if !ctx.Data["IsRepositoryValid"].(bool) { | |||
| if !ctx.Repo.IsValid { | |||
| return | |||
| } | |||
| if params["branchname"] == "" { | |||
| params["branchname"] = "master" | |||
| } | |||
| treename := params["_1"] | |||
| files, err := models.GetReposFiles(params["username"], params["reponame"], | |||
| params["branchname"], treename) | |||
| @@ -41,16 +43,20 @@ func Single(ctx *middleware.Context, params martini.Params) { | |||
| ctx.Data["Treenames"] = treenames | |||
| ctx.Data["IsRepoToolbarSource"] = true | |||
| ctx.Data["Files"] = files | |||
| ctx.Render.HTML(200, "repo/single", ctx.Data) | |||
| } | |||
| func Setting(ctx *middleware.Context) { | |||
| if !ctx.Data["IsRepositoryValid"].(bool) { | |||
| if !ctx.Repo.IsValid { | |||
| return | |||
| } | |||
| ctx.Data["Title"] = ctx.Data["Title"].(string) + " - settings" | |||
| var title string | |||
| if t, ok := ctx.Data["Title"].(string); ok { | |||
| title = t | |||
| } | |||
| ctx.Data["Title"] = title + " - settings" | |||
| ctx.Data["IsRepoToolbarSetting"] = true | |||
| ctx.Render.HTML(200, "repo/setting", ctx.Data) | |||
| } | |||
| @@ -60,7 +60,12 @@ func Profile(ctx *middleware.Context, params martini.Params) { | |||
| } | |||
| ctx.Data["Feeds"] = feeds | |||
| default: | |||
| repos, err := models.GetRepositories(user) | |||
| if err != nil { | |||
| ctx.Handle(200, "user.Profile", err) | |||
| return | |||
| } | |||
| ctx.Data["Repos"] = repos | |||
| } | |||
| ctx.Render.HTML(200, "user/profile", ctx.Data) | |||
| @@ -47,7 +47,7 @@ | |||
| {{if .IsDir}} | |||
| <a href="/{{$username}}/{{$reponame}}/tree/{{$branchname}}/{{.Path}}">{{.Name}}</a> | |||
| {{else}} | |||
| <a href="#">{{.Name}} - {{.Size}}</a> | |||
| <a href="#">{{.Name}} - {{FileSize .Size}}</a> | |||
| {{end}}</td> | |||
| <td class="date"><time datetime="{{.Created}}" data-title="true" title="{{.Created}}">{{TimeSince .Created}}</time></td> | |||
| <td class="text">{{.Message}}</td> | |||
| @@ -4,9 +4,9 @@ | |||
| <div class="container"> | |||
| <ul class="nav nav-pills pull-right"> | |||
| <li class="active"><a href="/">Feed</a></li> | |||
| <li><a href="/issues/">Issues</a></li> | |||
| <li><a href="/pulls/">Pull Requests</a></li> | |||
| <li><a href="/stars/">Stars</a></li> | |||
| <li><a href="/issues">Issues</a></li> | |||
| <li><a href="/pulls">Pull Requests</a></li> | |||
| <li><a href="/stars">Stars</a></li> | |||
| </ul> | |||
| <h3>News Feed</h3> | |||
| </div> | |||
| @@ -29,7 +29,7 @@ | |||
| <div id="gogs-feed-right" class="col-md-4"> | |||
| <div class="panel panel-default repo-panel"> | |||
| <div class="panel-heading">Your Repositories | |||
| <a class="btn btn-success pull-right btn-sm" href="/repo/create/"><i class="fa fa-plus-square"></i>New Repo</a> | |||
| <a class="btn btn-success pull-right btn-sm" href="/repo/create"><i class="fa fa-plus-square"></i>New Repo</a> | |||
| </div> | |||
| <div class="panel-body"> | |||
| <ul class="list-group">{{range .MyRepos}} | |||
| @@ -44,7 +44,21 @@ | |||
| </ul> | |||
| </div> | |||
| {{else}} | |||
| <div class="tab-pane active">repo</div> | |||
| {{$owner := .Owner}} | |||
| <div class="tab-pane active"> | |||
| <ul class="list-unstyled repo-list"> | |||
| {{range .Repos}} | |||
| <li> | |||
| <div class="meta pull-right"><i class="fa fa-star"></i> {{.NumStars}} <i class="fa fa-code-fork"></i> {{.NumForks}}</div> | |||
| <h4> | |||
| <a href="/{{$owner.Name}}/{{.LowerName}}">{{.LowerName}}</a> | |||
| </h4> | |||
| <p class="desc">{{.Description}}</p> | |||
| <div class="info">Last updated {{.Updated|TimeSince}}</div> | |||
| </li> | |||
| {{end}} | |||
| </ul> | |||
| </div> | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| @@ -66,14 +66,13 @@ func runWeb(*cli.Context) { | |||
| m.Any("/repo/create", middleware.SignInRequire(true), binding.BindIgnErr(auth.CreateRepoForm{}), repo.Create) | |||
| m.Any("/repo/delete", middleware.SignInRequire(true), binding.Bind(auth.DeleteRepoForm{}), repo.Delete) | |||
| m.Any("/repo/list", middleware.SignInRequire(false), repo.List) | |||
| m.Get("/:username/:reponame/settings", middleware.SignInRequire(false), auth.RepoAssignment(true), repo.Setting) | |||
| m.Get("/:username/:reponame/settings", middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Setting) | |||
| m.Get("/:username/:reponame/tree/:branchname/**", | |||
| middleware.SignInRequire(false), auth.RepoAssignment(true), repo.Single) | |||
| middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Single) | |||
| m.Get("/:username/:reponame/tree/:branchname", | |||
| middleware.SignInRequire(false), auth.RepoAssignment(true), repo.Single) | |||
| m.Get("/:username/:reponame", middleware.SignInRequire(false), auth.RepoAssignment(true), repo.Single) | |||
| middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Single) | |||
| m.Get("/:username/:reponame", middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Single) | |||
| //m.Get("/:username/:reponame", repo.Repo) | |||