@@ -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) | |||