From 76cd448e7925997b60a54e8d9431ffd0826cc24e Mon Sep 17 00:00:00 2001 From: Unknown Date: Sat, 22 Mar 2014 06:20:00 -0400 Subject: Add admin delete user --- gogs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gogs.go') diff --git a/gogs.go b/gogs.go index 41df79280a..8ec4fd42f1 100644 --- a/gogs.go +++ b/gogs.go @@ -20,7 +20,7 @@ import ( // Test that go1.2 tag above is included in builds. main.go refers to this definition. const go12tag = true -const APP_VER = "0.1.5.0321" +const APP_VER = "0.1.5.0322" func init() { base.AppVer = APP_VER -- cgit v1.2.3 From fd1831052c3a79492643b89512282fc66f34dd8d Mon Sep 17 00:00:00 2001 From: Unknown Date: Sat, 22 Mar 2014 09:21:57 -0400 Subject: Update session --- .gopmfile | 1 - README.md | 2 +- conf/app.ini | 25 ++++++------- gogs.go | 2 +- modules/base/conf.go | 16 +++++--- modules/base/tool.go | 84 +++++++++++++++++++++++++++++++++++++++++- routers/admin/admin.go | 12 +++++- templates/admin/config.tmpl | 19 ++++++++++ templates/admin/dashboard.tmpl | 1 + 9 files changed, 135 insertions(+), 27 deletions(-) (limited to 'gogs.go') diff --git a/.gopmfile b/.gopmfile index 5b690a06a7..6e6b59c620 100644 --- a/.gopmfile +++ b/.gopmfile @@ -4,7 +4,6 @@ path=github.com/gogits/gogs [deps] github.com/codegangsta/cli= github.com/codegangsta/martini= -github.com/martini-contrib/sessions= github.com/Unknwon/com= github.com/Unknwon/cae= github.com/Unknwon/goconfig= diff --git a/README.md b/README.md index a9ab7fe498..35044927ff 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ There are two ways to install Gogs: ## Acknowledgments - Logo is inspired by [martini](https://github.com/martini-contrib). -- Mail service is based on [WeTalk](https://github.com/beego/wetalk). +- Mail Service is based on [WeTalk](https://github.com/beego/wetalk). - System Monitor Status is based on [GoBlog](https://github.com/fuxiaohei/goblog). ## Contributors diff --git a/conf/app.ini b/conf/app.ini index cf2ae31d83..30d6c7d483 100644 --- a/conf/app.ini +++ b/conf/app.ini @@ -75,28 +75,25 @@ HOST = [session] ; Either "memory", "file", "redis" or "mysql", default is "memory" PROVIDER = file -; provider config +; Provider config options ; memory: not have any config yet -; file: session file path -; e.g. tmp/sessions -; redis: config like redis server addr,poolSize,password -; e.g. 127.0.0.1:6379,100,astaxie -; mysql: go-sql-driver/mysql dsn config string -; e.g. root:password@/session_table +; file: session file path, e.g. data/sessions +; redis: config like redis server addr, poolSize, password, e.g. 127.0.0.1:6379,100,astaxie +; mysql: go-sql-driver/mysql dsn config string, e.g. root:password@/session_table PROVIDER_CONFIG = data/sessions -; session cookie name +; Session cookie name COOKIE_NAME = i_like_gogits -; if you use session in https only, default is false +; If you use session in https only, default is false COOKIE_SECURE = false -; enable set cookie, default is true +; Enable set cookie, default is true ENABLE_SET_COOKIE = true -; session gc time interval, default is 86400 +; Session GC time interval, default is 86400 GC_INTERVAL_TIME = 86400 -; session life time, default is 86400 +; Session life time, default is 86400 SESSION_LIFE_TIME = 86400 -; session id hash func, default is sha1 +; Session id hash func, default is sha1 SESSION_ID_HASHFUNC = sha1 -; session hash key, default is use random string +; Session hash key, default is use random string SESSION_ID_HASHKEY = [picture] diff --git a/gogs.go b/gogs.go index 8ec4fd42f1..a609032093 100644 --- a/gogs.go +++ b/gogs.go @@ -20,7 +20,7 @@ import ( // Test that go1.2 tag above is included in builds. main.go refers to this definition. const go12tag = true -const APP_VER = "0.1.5.0322" +const APP_VER = "0.1.5.0322.2" func init() { base.AppVer = APP_VER diff --git a/modules/base/conf.go b/modules/base/conf.go index d5e27d043b..7c8ed93654 100644 --- a/modules/base/conf.go +++ b/modules/base/conf.go @@ -41,19 +41,19 @@ var ( Cfg *goconfig.ConfigFile MailService *Mailer + LogMode string + LogConfig string + Cache cache.Cache CacheAdapter string CacheConfig string - PictureService string - PictureRootPath string - - LogMode string - LogConfig string - SessionProvider string SessionConfig *session.Config SessionManager *session.Manager + + PictureService string + PictureRootPath string ) var Service struct { @@ -182,6 +182,10 @@ func newSessionService() { SessionConfig.SessionIDHashFunc = Cfg.MustValue("session", "SESSION_ID_HASHFUNC", "sha1") SessionConfig.SessionIDHashKey = Cfg.MustValue("session", "SESSION_ID_HASHKEY") + if SessionProvider == "file" { + os.MkdirAll(path.Dir(SessionConfig.ProviderConfig), os.ModePerm) + } + var err error SessionManager, err = session.NewManager(SessionProvider, *SessionConfig) if err != nil { diff --git a/modules/base/tool.go b/modules/base/tool.go index 8fabb8c531..4f368aa58c 100644 --- a/modules/base/tool.go +++ b/modules/base/tool.go @@ -111,6 +111,85 @@ const ( Year = 12 * Month ) +func computeTimeDiff(diff int64) (int64, string) { + diffStr := "" + switch { + case diff <= 0: + diff = 0 + diffStr = "now" + case diff < 2: + diff = 0 + diffStr = "1 second" + case diff < 1*Minute: + diffStr = fmt.Sprintf("%d seconds", diff) + diff = 0 + + case diff < 2*Minute: + diff -= 1 * Minute + diffStr = "1 minute" + case diff < 1*Hour: + diffStr = fmt.Sprintf("%d minutes", diff/Minute) + diff -= diff / Minute * Minute + + case diff < 2*Hour: + diff -= 1 * Hour + diffStr = "1 hour" + case diff < 1*Day: + diffStr = fmt.Sprintf("%d hours", diff/Hour) + diff -= diff / Hour * Hour + + case diff < 2*Day: + diff -= 1 * Day + diffStr = "1 day" + case diff < 1*Week: + diffStr = fmt.Sprintf("%d days", diff/Day) + diff -= diff / Day * Day + + case diff < 2*Week: + diff -= 1 * Week + diffStr = "1 week" + case diff < 1*Month: + diffStr = fmt.Sprintf("%d weeks", diff/Week) + diff -= diff / Week * Week + + case diff < 2*Month: + diff -= 1 * Month + diffStr = "1 month" + case diff < 1*Year: + diffStr = fmt.Sprintf("%d months", diff/Month) + diff -= diff / Month * Month + + case diff < 2*Year: + diff -= 1 * Year + diffStr = "1 year" + default: + diffStr = fmt.Sprintf("%d years", diff/Year) + diff = 0 + } + return diff, diffStr +} + +// TimeSincePro calculates the time interval and generate full user-friendly string. +func TimeSincePro(then time.Time) string { + now := time.Now() + diff := now.Unix() - then.Unix() + + if then.After(now) { + return "future" + } + + var timeStr, diffStr string + for { + if diff == 0 { + break + } + + diff, diffStr = computeTimeDiff(diff) + timeStr += ", " + diffStr + } + return strings.TrimPrefix(timeStr, ", ") +} + // TimeSince calculates the time interval and generate user-friendly string. func TimeSince(then time.Time) string { now := time.Now() @@ -123,7 +202,6 @@ func TimeSince(then time.Time) string { } switch { - case diff <= 0: return "now" case diff <= 2: @@ -156,8 +234,10 @@ func TimeSince(then time.Time) string { case diff < 1*Year: return fmt.Sprintf("%d months %s", diff/Month, lbl) - case diff < 18*Month: + case diff < 2*Year: return fmt.Sprintf("1 year %s", lbl) + default: + return fmt.Sprintf("%d years %s", diff/Year, lbl) } return then.String() } diff --git a/routers/admin/admin.go b/routers/admin/admin.go index 57a46d1dfe..c0f39f7159 100644 --- a/routers/admin/admin.go +++ b/routers/admin/admin.go @@ -17,7 +17,10 @@ import ( "github.com/gogits/gogs/modules/middleware" ) +var startTime = time.Now() + var sysStatus struct { + Uptime string NumGoroutine int // General statistics. @@ -58,6 +61,8 @@ var sysStatus struct { } func updateSystemStatus() { + sysStatus.Uptime = base.TimeSincePro(startTime) + m := new(runtime.MemStats) runtime.ReadMemStats(m) sysStatus.NumGoroutine = runtime.NumGoroutine() @@ -88,8 +93,8 @@ func updateSystemStatus() { sysStatus.NextGC = base.FileSize(int64(m.NextGC)) sysStatus.LastGC = fmt.Sprintf("%.1fs", float64(time.Now().UnixNano()-int64(m.LastGC))/1000/1000/1000) - sysStatus.PauseTotalNs = fmt.Sprintf("%.1fs", float64(m.PauseTotalNs/1000/1000/1000)) - sysStatus.PauseNs = fmt.Sprintf("%.3fs", float64(m.PauseNs[(m.NumGC+255)%256]/1000/1000/1000)) + sysStatus.PauseTotalNs = fmt.Sprintf("%.1fs", float64(m.PauseTotalNs)/1000/1000/1000) + sysStatus.PauseNs = fmt.Sprintf("%.3fs", float64(m.PauseNs[(m.NumGC+255)%256])/1000/1000/1000) sysStatus.NumGC = m.NumGC } @@ -151,6 +156,9 @@ func Config(ctx *middleware.Context) { ctx.Data["CacheAdapter"] = base.CacheAdapter ctx.Data["CacheConfig"] = base.CacheConfig + ctx.Data["SessionProvider"] = base.SessionProvider + ctx.Data["SessionConfig"] = base.SessionConfig + ctx.Data["PictureService"] = base.PictureService ctx.Data["PictureRootPath"] = base.PictureRootPath diff --git a/templates/admin/config.tmpl b/templates/admin/config.tmpl index e3f69ee6ea..048740e617 100644 --- a/templates/admin/config.tmpl +++ b/templates/admin/config.tmpl @@ -77,6 +77,25 @@ +
+
+ Session Configuration +
+ +
+
Session Provider: {{.SessionProvider}}
+
Cookie Name: {{.SessionConfig.CookieName}}
+
Enable Set Cookie:
+
GC Interval Time: {{.SessionConfig.GcIntervalTime}} seconds
+
Session Life Time: {{.SessionConfig.SessionLifeTime}} seconds
+
HTTPS Only:
+
Cookie Life Time: {{.SessionConfig.CookieLifeTime}} seconds
+
Session ID Hash Function: {{.SessionConfig.SessionIDHashFunc}}
+
Session ID Hash Key: {{.SessionConfig.SessionIDHashKey}}
+
Provider Config: {{.SessionConfig.ProviderConfig}}
+
+
+
Picture Configuration diff --git a/templates/admin/dashboard.tmpl b/templates/admin/dashboard.tmpl index 0bebf8318f..2a5a161e03 100644 --- a/templates/admin/dashboard.tmpl +++ b/templates/admin/dashboard.tmpl @@ -19,6 +19,7 @@
+
Server Uptime: {{.SysStatus.Uptime}}
Current Goroutines: {{.SysStatus.NumGoroutine}}

Current Memory Usage: {{.SysStatus.MemAllocated}}
-- cgit v1.2.3 From 61e29226015fad6451281035948c3d8d1364880c Mon Sep 17 00:00:00 2001 From: Unknown Date: Sat, 22 Mar 2014 13:50:50 -0400 Subject: Working on issues --- gogs.go | 2 +- models/action.go | 1 - models/issue.go | 123 +++++++++++++++++++- models/models.go | 2 +- routers/repo/issue.go | 30 +++++ routers/repo/repo.go | 294 +++++++++++++++++++++++++++++++++++++++++++++++ routers/repo/single.go | 301 ------------------------------------------------- 7 files changed, 443 insertions(+), 310 deletions(-) create mode 100644 routers/repo/issue.go delete mode 100644 routers/repo/single.go (limited to 'gogs.go') diff --git a/gogs.go b/gogs.go index a609032093..2bb80a6644 100644 --- a/gogs.go +++ b/gogs.go @@ -20,7 +20,7 @@ import ( // Test that go1.2 tag above is included in builds. main.go refers to this definition. const go12tag = true -const APP_VER = "0.1.5.0322.2" +const APP_VER = "0.1.6.0323.1" func init() { base.AppVer = APP_VER diff --git a/models/action.go b/models/action.go index 4e1107f891..a996e16aa8 100644 --- a/models/action.go +++ b/models/action.go @@ -88,7 +88,6 @@ func CommitRepoAction(userId int64, userName string, return err } repo.IsBare = false - repo.Updated = time.Now() if err = UpdateRepository(repo); err != nil { return err } diff --git a/models/issue.go b/models/issue.go index c669d201f6..0b6ca4c323 100644 --- a/models/issue.go +++ b/models/issue.go @@ -4,16 +4,127 @@ package models +import ( + "strings" + "time" + + "github.com/gogits/gogs/modules/base" +) + +// Issue represents an issue or pull request of repository. type Issue struct { - Id int64 - RepoId int64 `xorm:"index"` - PosterId int64 + Id int64 + Index int64 // Index in one repository. + Name string + RepoId int64 `xorm:"index"` + PosterId int64 + MilestoneId int64 + AssigneeId int64 + IsPull bool // Indicates whether is a pull request or not. + IsClosed bool + Labels string + Mentions string + Content string + NumComments int + Created time.Time `xorm:"created"` + Updated time.Time `xorm:"updated"` +} + +// CreateIssue creates new issue for repository. +func CreateIssue(userId, repoId, milestoneId, assigneeId int64, name, labels, mentions, content string, isPull bool) error { + count, err := GetIssueCount(repoId) + if err != nil { + return err + } + + _, err = orm.Insert(&Issue{ + Index: count + 1, + Name: name, + RepoId: repoId, + PosterId: userId, + MilestoneId: milestoneId, + AssigneeId: assigneeId, + IsPull: isPull, + Labels: labels, + Mentions: mentions, + Content: content, + }) + return err } -type PullRequest struct { - Id int64 +// GetIssueCount returns count of issues in the repository. +func GetIssueCount(repoId int64) (int64, error) { + return orm.Count(&Issue{RepoId: repoId}) } +// GetIssues returns a list of issues by given conditions. +func GetIssues(userId, repoId, posterId, milestoneId int64, page int, isClosed, isMention bool, labels, sortType string) ([]Issue, error) { + sess := orm.Limit(20, (page-1)*20).Where("repo_id=?", repoId).And("is_closed=?", isClosed) + if userId > 0 { + sess = sess.And("assignee_id=?", userId) + } else if posterId > 0 { + sess = sess.And("poster_id=?", posterId) + } else if isMention { + sess = sess.And("mentions like '%$" + base.ToStr(userId) + "|%'") + } + + if milestoneId > 0 { + sess = sess.And("milestone_id=?", milestoneId) + } + + if len(labels) > 0 { + for _, label := range strings.Split(labels, ",") { + sess = sess.And("mentions like '%$" + label + "|%'") + } + } + + switch sortType { + case "oldest": + sess = sess.Asc("created") + case "recentupdate": + sess = sess.Desc("updated") + case "leastupdate": + sess = sess.Asc("updated") + case "mostcomment": + sess = sess.Desc("num_comments") + case "leastcomment": + sess = sess.Asc("num_comments") + default: + sess = sess.Desc("created") + } + + var issues []Issue + err := sess.Find(&issues) + return issues, err +} + +// Label represents a list of labels of repository for issues. +type Label struct { + Id int64 + RepoId int64 `xorm:"index"` + Names string + Colors string +} + +// Milestone represents a milestone of repository. +type Milestone struct { + Id int64 + Name string + RepoId int64 `xorm:"index"` + IsClosed bool + Content string + NumIssues int + DueDate time.Time + Created time.Time `xorm:"created"` +} + +// Comment represents a comment in commit and issue page. type Comment struct { - Id int64 + Id int64 + PosterId int64 + IssueId int64 + CommitId int64 + Line int + Content string + Created time.Time `xorm:"created"` } diff --git a/models/models.go b/models/models.go index 8713ff2896..fb749c5d8a 100644 --- a/models/models.go +++ b/models/models.go @@ -72,7 +72,7 @@ func setEngine() { func NewEngine() { setEngine() if err := orm.Sync(new(User), new(PublicKey), new(Repository), new(Watch), - new(Action), new(Access)); err != nil { + new(Action), new(Access), new(Issue)); err != nil { fmt.Printf("sync database struct error: %v\n", err) os.Exit(2) } diff --git a/routers/repo/issue.go b/routers/repo/issue.go new file mode 100644 index 0000000000..c6af8ca0bc --- /dev/null +++ b/routers/repo/issue.go @@ -0,0 +1,30 @@ +// 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 repo + +import ( + "github.com/codegangsta/martini" + + "github.com/gogits/gogs/models" + "github.com/gogits/gogs/modules/base" + "github.com/gogits/gogs/modules/middleware" +) + +func Issues(ctx *middleware.Context, params martini.Params) { + ctx.Data["IsRepoToolbarIssues"] = true + + milestoneId, _ := base.StrTo(params["milestone"]).Int() + page, _ := base.StrTo(params["page"]).Int() + + var err error + ctx.Data["Issues"], err = models.GetIssues(0, ctx.Repo.Repository.Id, 0, + int64(milestoneId), page, params["state"] == "closed", false, params["labels"], params["sortType"]) + if err != nil { + ctx.Handle(200, "issue.Issues: %v", err) + return + } + + ctx.HTML(200, "repo/issues") +} diff --git a/routers/repo/repo.go b/routers/repo/repo.go index c83a6df522..ff0fa85dde 100644 --- a/routers/repo/repo.go +++ b/routers/repo/repo.go @@ -5,8 +5,17 @@ package repo import ( + "path" + "strings" + + "github.com/codegangsta/martini" + + "github.com/gogits/git" + "github.com/gogits/webdav" + "github.com/gogits/gogs/models" "github.com/gogits/gogs/modules/auth" + "github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/middleware" ) @@ -61,3 +70,288 @@ func SettingPost(ctx *middleware.Context) { log.Trace("%s Repository deleted: %s/%s", ctx.Req.RequestURI, ctx.User.LowerName, ctx.Repo.Repository.LowerName) ctx.Redirect("/", 302) } + +func Branches(ctx *middleware.Context, params martini.Params) { + if !ctx.Repo.IsValid { + return + } + + brs, err := models.GetBranches(params["username"], params["reponame"]) + if err != nil { + ctx.Handle(200, "repo.Branches", err) + return + } else if len(brs) == 0 { + ctx.Error(404) + return + } + + ctx.Data["Username"] = params["username"] + ctx.Data["Reponame"] = params["reponame"] + + ctx.Data["Branchname"] = brs[0] + ctx.Data["Branches"] = brs + ctx.Data["IsRepoToolbarBranches"] = true + + ctx.HTML(200, "repo/branches") +} + +func Single(ctx *middleware.Context, params martini.Params) { + if !ctx.Repo.IsValid { + return + } + + if len(params["branchname"]) == 0 { + params["branchname"] = "master" + } + + // Get tree path + treename := params["_1"] + + if len(treename) > 0 && treename[len(treename)-1] == '/' { + ctx.Redirect("/"+ctx.Repo.Owner.LowerName+"/"+ + ctx.Repo.Repository.Name+"/src/"+params["branchname"]+"/"+treename[:len(treename)-1], 302) + return + } + + ctx.Data["IsRepoToolbarSource"] = true + + // Branches. + brs, err := models.GetBranches(params["username"], params["reponame"]) + if err != nil { + log.Error("repo.Single(GetBranches): %v", err) + ctx.Error(404) + return + } else if ctx.Repo.Repository.IsBare { + ctx.Data["IsBareRepo"] = true + ctx.HTML(200, "repo/single") + return + } + + ctx.Data["Branches"] = brs + + repoFile, err := models.GetTargetFile(params["username"], params["reponame"], + params["branchname"], params["commitid"], treename) + + if err != nil && err != models.ErrRepoFileNotExist { + log.Error("repo.Single(GetTargetFile): %v", err) + ctx.Error(404) + return + } + + branchLink := "/" + ctx.Repo.Owner.LowerName + "/" + ctx.Repo.Repository.Name + "/src/" + params["branchname"] + + if len(treename) != 0 && repoFile == nil { + ctx.Error(404) + return + } + + if repoFile != nil && repoFile.IsFile() { + if repoFile.Size > 1024*1024 || repoFile.Filemode != git.FileModeBlob { + ctx.Data["FileIsLarge"] = true + } else if blob, err := repoFile.LookupBlob(); err != nil { + log.Error("repo.Single(repoFile.LookupBlob): %v", err) + ctx.Error(404) + } else { + ctx.Data["IsFile"] = true + ctx.Data["FileName"] = repoFile.Name + ext := path.Ext(repoFile.Name) + if len(ext) > 0 { + ext = ext[1:] + } + ctx.Data["FileExt"] = ext + + readmeExist := base.IsMarkdownFile(repoFile.Name) || base.IsReadmeFile(repoFile.Name) + ctx.Data["ReadmeExist"] = readmeExist + if readmeExist { + ctx.Data["FileContent"] = string(base.RenderMarkdown(blob.Contents(), "")) + } else { + ctx.Data["FileContent"] = string(blob.Contents()) + } + } + + } else { + // Directory and file list. + files, err := models.GetReposFiles(params["username"], params["reponame"], + params["branchname"], params["commitid"], treename) + if err != nil { + log.Error("repo.Single(GetReposFiles): %v", err) + ctx.Error(404) + return + } + + ctx.Data["Files"] = files + + var readmeFile *models.RepoFile + + for _, f := range files { + if !f.IsFile() || !base.IsReadmeFile(f.Name) { + continue + } else { + readmeFile = f + break + } + } + + if readmeFile != nil { + ctx.Data["ReadmeExist"] = true + // if file large than 1M not show it + if readmeFile.Size > 1024*1024 || readmeFile.Filemode != git.FileModeBlob { + ctx.Data["FileIsLarge"] = true + } else if blob, err := readmeFile.LookupBlob(); err != nil { + log.Error("repo.Single(readmeFile.LookupBlob): %v", err) + ctx.Error(404) + return + } else { + // current repo branch link + + ctx.Data["FileName"] = readmeFile.Name + ctx.Data["FileContent"] = string(base.RenderMarkdown(blob.Contents(), branchLink)) + } + } + } + + ctx.Data["Username"] = params["username"] + ctx.Data["Reponame"] = params["reponame"] + ctx.Data["Branchname"] = params["branchname"] + + var treenames []string + Paths := make([]string, 0) + + if len(treename) > 0 { + treenames = strings.Split(treename, "/") + for i, _ := range treenames { + Paths = append(Paths, strings.Join(treenames[0:i+1], "/")) + } + + ctx.Data["HasParentPath"] = true + if len(Paths)-2 >= 0 { + ctx.Data["ParentPath"] = "/" + Paths[len(Paths)-2] + } + } + + // Get latest commit according username and repo name + commit, err := models.GetCommit(params["username"], params["reponame"], + params["branchname"], params["commitid"]) + if err != nil { + log.Error("repo.Single(GetCommit): %v", err) + ctx.Error(404) + return + } + ctx.Data["LastCommit"] = commit + + ctx.Data["Paths"] = Paths + ctx.Data["Treenames"] = treenames + ctx.Data["BranchLink"] = branchLink + ctx.HTML(200, "repo/single") +} + +func Http(ctx *middleware.Context, params martini.Params) { + /*if !ctx.Repo.IsValid { + return + }*/ + + // TODO: access check + + username := params["username"] + reponame := params["reponame"] + if strings.HasSuffix(reponame, ".git") { + reponame = reponame[:len(reponame)-4] + } + + prefix := path.Join("/", username, params["reponame"]) + server := &webdav.Server{ + Fs: webdav.Dir(models.RepoPath(username, reponame)), + TrimPrefix: prefix, + Listings: true, + } + + server.ServeHTTP(ctx.ResponseWriter, ctx.Req) +} + +func Setting(ctx *middleware.Context, params martini.Params) { + if !ctx.Repo.IsOwner { + ctx.Error(404) + return + } + + ctx.Data["IsRepoToolbarSetting"] = true + + if ctx.Repo.Repository.IsBare { + ctx.Data["IsBareRepo"] = true + ctx.HTML(200, "repo/setting") + return + } + + var title string + if t, ok := ctx.Data["Title"].(string); ok { + title = t + } + + if len(params["branchname"]) == 0 { + params["branchname"] = "master" + } + + ctx.Data["Branchname"] = params["branchname"] + ctx.Data["Title"] = title + " - settings" + ctx.HTML(200, "repo/setting") +} + +func Commits(ctx *middleware.Context, params martini.Params) { + brs, err := models.GetBranches(params["username"], params["reponame"]) + if err != nil { + ctx.Handle(200, "repo.Commits", err) + return + } else if len(brs) == 0 { + ctx.Error(404) + return + } + + ctx.Data["IsRepoToolbarCommits"] = true + commits, err := models.GetCommits(params["username"], + params["reponame"], params["branchname"]) + if err != nil { + ctx.Error(404) + return + } + ctx.Data["Username"] = params["username"] + ctx.Data["Reponame"] = params["reponame"] + ctx.Data["CommitCount"] = commits.Len() + ctx.Data["Commits"] = commits + ctx.HTML(200, "repo/commits") +} + +func Pulls(ctx *middleware.Context) { + ctx.Data["IsRepoToolbarPulls"] = true + ctx.HTML(200, "repo/pulls") +} + +func Action(ctx *middleware.Context, params martini.Params) { + var err error + switch params["action"] { + case "watch": + err = models.WatchRepo(ctx.User.Id, ctx.Repo.Repository.Id, true) + case "unwatch": + err = models.WatchRepo(ctx.User.Id, ctx.Repo.Repository.Id, false) + case "desc": + if !ctx.Repo.IsOwner { + ctx.Error(404) + return + } + + ctx.Repo.Repository.Description = ctx.Query("desc") + ctx.Repo.Repository.Website = ctx.Query("site") + err = models.UpdateRepository(ctx.Repo.Repository) + } + + if err != nil { + log.Error("repo.Action(%s): %v", params["action"], err) + ctx.JSON(200, map[string]interface{}{ + "ok": false, + "err": err.Error(), + }) + return + } + ctx.JSON(200, map[string]interface{}{ + "ok": true, + }) +} diff --git a/routers/repo/single.go b/routers/repo/single.go deleted file mode 100644 index 5906e64fb9..0000000000 --- a/routers/repo/single.go +++ /dev/null @@ -1,301 +0,0 @@ -// 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 repo - -import ( - "path" - "strings" - - "github.com/codegangsta/martini" - - "github.com/gogits/git" - "github.com/gogits/webdav" - - "github.com/gogits/gogs/models" - "github.com/gogits/gogs/modules/base" - "github.com/gogits/gogs/modules/log" - "github.com/gogits/gogs/modules/middleware" -) - -func Branches(ctx *middleware.Context, params martini.Params) { - if !ctx.Repo.IsValid { - return - } - - brs, err := models.GetBranches(params["username"], params["reponame"]) - if err != nil { - ctx.Handle(200, "repo.Branches", err) - return - } else if len(brs) == 0 { - ctx.Error(404) - return - } - - ctx.Data["Username"] = params["username"] - ctx.Data["Reponame"] = params["reponame"] - - ctx.Data["Branchname"] = brs[0] - ctx.Data["Branches"] = brs - ctx.Data["IsRepoToolbarBranches"] = true - - ctx.HTML(200, "repo/branches") -} - -func Single(ctx *middleware.Context, params martini.Params) { - if !ctx.Repo.IsValid { - return - } - - if len(params["branchname"]) == 0 { - params["branchname"] = "master" - } - - // Get tree path - treename := params["_1"] - - if len(treename) > 0 && treename[len(treename)-1] == '/' { - ctx.Redirect("/"+ctx.Repo.Owner.LowerName+"/"+ - ctx.Repo.Repository.Name+"/src/"+params["branchname"]+"/"+treename[:len(treename)-1], 302) - return - } - - ctx.Data["IsRepoToolbarSource"] = true - - // Branches. - brs, err := models.GetBranches(params["username"], params["reponame"]) - if err != nil { - log.Error("repo.Single(GetBranches): %v", err) - ctx.Error(404) - return - } else if ctx.Repo.Repository.IsBare { - ctx.Data["IsBareRepo"] = true - ctx.HTML(200, "repo/single") - return - } - - ctx.Data["Branches"] = brs - - repoFile, err := models.GetTargetFile(params["username"], params["reponame"], - params["branchname"], params["commitid"], treename) - - if err != nil && err != models.ErrRepoFileNotExist { - log.Error("repo.Single(GetTargetFile): %v", err) - ctx.Error(404) - return - } - - branchLink := "/" + ctx.Repo.Owner.LowerName + "/" + ctx.Repo.Repository.Name + "/src/" + params["branchname"] - - if len(treename) != 0 && repoFile == nil { - ctx.Error(404) - return - } - - if repoFile != nil && repoFile.IsFile() { - if repoFile.Size > 1024*1024 || repoFile.Filemode != git.FileModeBlob { - ctx.Data["FileIsLarge"] = true - } else if blob, err := repoFile.LookupBlob(); err != nil { - log.Error("repo.Single(repoFile.LookupBlob): %v", err) - ctx.Error(404) - } else { - ctx.Data["IsFile"] = true - ctx.Data["FileName"] = repoFile.Name - ext := path.Ext(repoFile.Name) - if len(ext) > 0 { - ext = ext[1:] - } - ctx.Data["FileExt"] = ext - - readmeExist := base.IsMarkdownFile(repoFile.Name) || base.IsReadmeFile(repoFile.Name) - ctx.Data["ReadmeExist"] = readmeExist - if readmeExist { - ctx.Data["FileContent"] = string(base.RenderMarkdown(blob.Contents(), "")) - } else { - ctx.Data["FileContent"] = string(blob.Contents()) - } - } - - } else { - // Directory and file list. - files, err := models.GetReposFiles(params["username"], params["reponame"], - params["branchname"], params["commitid"], treename) - if err != nil { - log.Error("repo.Single(GetReposFiles): %v", err) - ctx.Error(404) - return - } - - ctx.Data["Files"] = files - - var readmeFile *models.RepoFile - - for _, f := range files { - if !f.IsFile() || !base.IsReadmeFile(f.Name) { - continue - } else { - readmeFile = f - break - } - } - - if readmeFile != nil { - ctx.Data["ReadmeExist"] = true - // if file large than 1M not show it - if readmeFile.Size > 1024*1024 || readmeFile.Filemode != git.FileModeBlob { - ctx.Data["FileIsLarge"] = true - } else if blob, err := readmeFile.LookupBlob(); err != nil { - log.Error("repo.Single(readmeFile.LookupBlob): %v", err) - ctx.Error(404) - return - } else { - // current repo branch link - - ctx.Data["FileName"] = readmeFile.Name - ctx.Data["FileContent"] = string(base.RenderMarkdown(blob.Contents(), branchLink)) - } - } - } - - ctx.Data["Username"] = params["username"] - ctx.Data["Reponame"] = params["reponame"] - ctx.Data["Branchname"] = params["branchname"] - - var treenames []string - Paths := make([]string, 0) - - if len(treename) > 0 { - treenames = strings.Split(treename, "/") - for i, _ := range treenames { - Paths = append(Paths, strings.Join(treenames[0:i+1], "/")) - } - - ctx.Data["HasParentPath"] = true - if len(Paths)-2 >= 0 { - ctx.Data["ParentPath"] = "/" + Paths[len(Paths)-2] - } - } - - // Get latest commit according username and repo name - commit, err := models.GetCommit(params["username"], params["reponame"], - params["branchname"], params["commitid"]) - if err != nil { - log.Error("repo.Single(GetCommit): %v", err) - ctx.Error(404) - return - } - ctx.Data["LastCommit"] = commit - - ctx.Data["Paths"] = Paths - ctx.Data["Treenames"] = treenames - ctx.Data["BranchLink"] = branchLink - ctx.HTML(200, "repo/single") -} - -func Http(ctx *middleware.Context, params martini.Params) { - /*if !ctx.Repo.IsValid { - return - }*/ - - // TODO: access check - - username := params["username"] - reponame := params["reponame"] - if strings.HasSuffix(reponame, ".git") { - reponame = reponame[:len(reponame)-4] - } - - prefix := path.Join("/", username, params["reponame"]) - server := &webdav.Server{ - Fs: webdav.Dir(models.RepoPath(username, reponame)), - TrimPrefix: prefix, - Listings: true, - } - - server.ServeHTTP(ctx.ResponseWriter, ctx.Req) -} - -func Setting(ctx *middleware.Context, params martini.Params) { - if !ctx.Repo.IsOwner { - ctx.Error(404) - return - } - - ctx.Data["IsRepoToolbarSetting"] = true - - if ctx.Repo.Repository.IsBare { - ctx.Data["IsBareRepo"] = true - ctx.HTML(200, "repo/setting") - return - } - - var title string - if t, ok := ctx.Data["Title"].(string); ok { - title = t - } - - if len(params["branchname"]) == 0 { - params["branchname"] = "master" - } - - ctx.Data["Branchname"] = params["branchname"] - ctx.Data["Title"] = title + " - settings" - ctx.HTML(200, "repo/setting") -} - -func Commits(ctx *middleware.Context, params martini.Params) { - brs, err := models.GetBranches(params["username"], params["reponame"]) - if err != nil { - ctx.Handle(200, "repo.Commits", err) - return - } else if len(brs) == 0 { - ctx.Error(404) - return - } - - ctx.Data["IsRepoToolbarCommits"] = true - commits, err := models.GetCommits(params["username"], - params["reponame"], params["branchname"]) - if err != nil { - ctx.Error(404) - return - } - ctx.Data["Username"] = params["username"] - ctx.Data["Reponame"] = params["reponame"] - ctx.Data["CommitCount"] = commits.Len() - ctx.Data["Commits"] = commits - ctx.HTML(200, "repo/commits") -} - -func Issues(ctx *middleware.Context) { - ctx.Data["IsRepoToolbarIssues"] = true - ctx.HTML(200, "repo/issues") -} - -func Pulls(ctx *middleware.Context) { - ctx.Data["IsRepoToolbarPulls"] = true - ctx.HTML(200, "repo/pulls") -} - -func Action(ctx *middleware.Context, params martini.Params) { - var err error - switch params["action"] { - case "watch": - err = models.WatchRepo(ctx.User.Id, ctx.Repo.Repository.Id, true) - case "unwatch": - err = models.WatchRepo(ctx.User.Id, ctx.Repo.Repository.Id, false) - } - - if err != nil { - log.Error("repo.Action(%s): %v", params["action"], err) - ctx.JSON(200, map[string]interface{}{ - "ok": false, - "err": err.Error(), - }) - return - } - ctx.JSON(200, map[string]interface{}{ - "ok": true, - }) -} -- cgit v1.2.3 From ad31893bbbb1479f6801235ddca44b5bae2cc5c2 Mon Sep 17 00:00:00 2001 From: Unknown Date: Sat, 22 Mar 2014 20:25:39 -0400 Subject: Update README --- README.md | 14 ++++++++----- README_ZH.md | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ gogs.go | 2 +- templates/repo/nav.tmpl | 4 ++-- 4 files changed, 65 insertions(+), 8 deletions(-) create mode 100644 README_ZH.md (limited to 'gogs.go') diff --git a/README.md b/README.md index 325c3a9736..504c21975b 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,19 @@ -Gogs - Go Git Service [![wercker status](https://app.wercker.com/status/ad0bdb0bc450ac6f09bc56b9640a50aa/s/ "wercker status")](https://app.wercker.com/project/bykey/ad0bdb0bc450ac6f09bc56b9640a50aa) [![Go Walker](http://gowalker.org/api/v1/badge)](https://gowalker.org/github.com/gogits/gogs) +Gogs - Go Git Service [![wercker status](https://app.wercker.com/status/ad0bdb0bc450ac6f09bc56b9640a50aa/s/ "wercker status")](https://app.wercker.com/project/bykey/ad0bdb0bc450ac6f09bc56b9640a50aa) [![Build Status](https://drone.io/github.com/gogits/gogs/status.png)](https://drone.io/github.com/gogits/gogs/latest) ===================== -Gogs(Go Git Service) is a GitHub-like clone in the Go Programming Language. +Gogs(Go Git Service) is a Self Hosted Git Service in the Go Programming Language. -Since we choose to use pure Go implementation of Git manipulation, Gogs certainly supports **ALL platforms** that Go supports, including Linux, Max OS X, and Windows with **ZERO** dependency. +![Demo](http://gowalker.org/public/gogs_demo.gif) ##### Current version: 0.1.6 Alpha +[简体中文](README_ZH.md) + ## Purpose -There are some very good products in this category such as [gitlab](http://gitlab.com), but the environment setup steps often make us crazy. So our goal of Gogs is to build a GitHub-like clone with very easy setup steps, which take advantages of the Go Programming Language. +Since we choose to use pure Go implementation of Git manipulation, Gogs certainly supports **ALL platforms** that Go supports, including Linux, Mac OS X, and Windows with **ZERO** dependency. + +More importantly, Gogs only needs one binary to setup your own project hosting on the fly! ## Overview @@ -23,7 +27,7 @@ There are some very good products in this category such as [gitlab](http://gitla - Activity timeline - SSH protocol support. - Register/delete account. -- Create/delete public repository. +- Create/delete/watch public repository. - User profile page. - Repository viewer. - Gravatar support. diff --git a/README_ZH.md b/README_ZH.md new file mode 100644 index 0000000000..0ab8dfdd07 --- /dev/null +++ b/README_ZH.md @@ -0,0 +1,53 @@ +Gogs - Go Git Service [![wercker status](https://app.wercker.com/status/ad0bdb0bc450ac6f09bc56b9640a50aa/s/ "wercker status")](https://app.wercker.com/project/bykey/ad0bdb0bc450ac6f09bc56b9640a50aa) [![Build Status](https://drone.io/github.com/gogits/gogs/status.png)](https://drone.io/github.com/gogits/gogs/latest) +===================== + +Gogs(Go Git Service) 是一个由 Go 语言编写的自助 Git 托管服务。 + +![Demo](http://gowalker.org/public/gogs_demo.gif) + +##### 当前版本:0.1.6 Alpha + +## 开发目的 + +Gogs 完全使用 Go 语言来实现对 Git 数据的操作,实现 **零** 依赖,并且支持 Go 语言所支持的 **所有平台**,包括 Linux、Mac OS X 以及 Windows。 + +更重要的是,您只需要一个可执行文件就能借助 Gogs 快速搭建属于您自己的代码托管服务! + +## 项目概览 + +- 有关项目设计、开发说明、变更日志和路线图,请通过 [Wiki](https://github.com/gogits/gogs/wiki) 查看。 +- 您可以到 [Trello Broad](https://trello.com/b/uxAoeLUl/gogs-go-git-service) 跟随开发团队的脚步。 +- 想要先睹为快?通过 [在线体验](http://try.gogits.org/Unknown/gogs) 或查看 **安装部署 -> 二进制安装** 小节。 +- 使用过程中遇到问题?尝试从 [故障排查](https://github.com/gogits/gogs/wiki/Troubleshooting) 页面获取帮助。 + +## 功能特性 + +- 活动时间线 +- SSH 协议支持 +- 注册/删除用户 +- 创建/删除/关注公开仓库 +- 用户个人信息页面 +- 仓库浏览器 +- Gravatar 支持 +- 邮件服务(注册) +- 管理员面板 +- 支持 MySQL、PostgreSQL 以及 SQLite3(仅限二进制版本) + +## 安装部署 + +在安装 Gogs 之前,您需要先安装 [基本环境](https://github.com/gogits/gogs/wiki/Prerequirements)。 + +然后,您可以通过以下两种方式来安装 Gogs: + +- [二进制安装](https://github.com/gogits/gogs/wiki/Install-from-binary): **强烈推荐** 适合体验者和实际部署 +- [源码安装](https://github.com/gogits/gogs/wiki/Install-from-source) + +## 特别鸣谢 + +- Logo 基于 [martini](https://github.com/martini-contrib) 修改而来。 +- 邮件服务、模块设计基于 [WeTalk](https://github.com/beego/wetalk) 修改而来。 +- 系统监视状态基于 [GoBlog](https://github.com/fuxiaohei/goblog) 修改而来。 + +## 贡献成员 + +本项目最初由 [Unknown](https://github.com/Unknwon) 和 [lunny](https://github.com/lunny) 发起,随后 [fuxiaohei](https://github.com/fuxiaohei) 与 [slene](https://github.com/slene) 加入到开发团队。您可以通过查看 [贡献者页面](https://github.com/gogits/gogs/graphs/contributors) 获取完整的贡献者列表。 \ No newline at end of file diff --git a/gogs.go b/gogs.go index 2bb80a6644..0bdbbc0697 100644 --- a/gogs.go +++ b/gogs.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -// gogs(Go Git Service) is a Go clone of Github. +// Gogs(Go Git Service) is a Self Hosted Git Service in the Go Programming Language. package main import ( diff --git a/templates/repo/nav.tmpl b/templates/repo/nav.tmpl index d4a692fd03..cf1b7d0389 100644 --- a/templates/repo/nav.tmpl +++ b/templates/repo/nav.tmpl @@ -1,11 +1,11 @@
-
+

{{.Owner.Name}} / {{.Repository.Name}}

{{.Repository.Description}}{{if .Repository.Website}}{{.Repository.Website}}{{end}}

-
+
{{if not .IsBareRepo}}