From 48b2425c1d49560094b2935e6451d55cd5aa1f1a Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 16 Mar 2014 11:30:35 -0400 Subject: Push feed --- modules/base/tool.go | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'modules/base') diff --git a/modules/base/tool.go b/modules/base/tool.go index 3f8b8ffa..5746cc8f 100644 --- a/modules/base/tool.go +++ b/modules/base/tool.go @@ -7,6 +7,7 @@ package base import ( "crypto/md5" "encoding/hex" + "encoding/json" "fmt" "math" "strings" @@ -235,6 +236,7 @@ type Actioner interface { GetOpType() int GetActUserName() string GetRepoName() string + GetContent() string } // ActionIcon accepts a int that represents action operation type @@ -243,13 +245,19 @@ func ActionIcon(opType int) string { switch opType { case 1: // Create repository. return "plus-circle" + case 5: // Commit repository. + return "arrow-circle-o-right" default: return "invalid type" } } const ( - CreateRepoTpl = `%s created repository %s` + TPL_CREATE_REPO = `%s created repository %s` + TPL_COMMIT_REPO = `%s pushed to %s at %s/%s +` ) // ActionDesc accepts int that represents action operation type @@ -257,9 +265,17 @@ const ( func ActionDesc(act Actioner) string { actUserName := act.GetActUserName() repoName := act.GetRepoName() + content := act.GetContent() switch act.GetOpType() { case 1: // Create repository. - return fmt.Sprintf(CreateRepoTpl, actUserName, actUserName, actUserName, repoName, repoName) + return fmt.Sprintf(TPL_CREATE_REPO, actUserName, actUserName, actUserName, repoName, repoName) + case 5: // Commit repository. + var commits [][]string + if err := json.Unmarshal([]byte(content), &commits); err != nil { + return err.Error() + } + return fmt.Sprintf(TPL_COMMIT_REPO, actUserName, actUserName, actUserName, repoName, "master", "master", actUserName, repoName, actUserName, repoName, + actUserName, repoName, commits[0][0], commits[0][0][:7], commits[0][1]) default: return "invalid type" } -- cgit v1.2.3 From ec65be79f0337b11c01121eae9fd54fe49bee830 Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 16 Mar 2014 12:07:35 -0400 Subject: Fix commit feed ui --- gogs.go | 2 +- modules/base/tool.go | 17 ++++++++++------- public/css/gogs.css | 6 ++++++ routers/user/user.go | 2 +- templates/user/profile.tmpl | 3 ++- 5 files changed, 20 insertions(+), 10 deletions(-) (limited to 'modules/base') diff --git a/gogs.go b/gogs.go index 9d1f2032..2d5283f3 100644 --- a/gogs.go +++ b/gogs.go @@ -20,7 +20,7 @@ import ( // Test that go1.1 tag above is included in builds. main.go refers to this definition. const go11tag = true -const APP_VER = "0.0.8.0316.1" +const APP_VER = "0.0.9.0316.1" func init() { base.AppVer = APP_VER diff --git a/modules/base/tool.go b/modules/base/tool.go index 5746cc8f..10b3fee3 100644 --- a/modules/base/tool.go +++ b/modules/base/tool.go @@ -5,6 +5,7 @@ package base import ( + "bytes" "crypto/md5" "encoding/hex" "encoding/json" @@ -253,16 +254,14 @@ func ActionIcon(opType int) string { } const ( - TPL_CREATE_REPO = `%s created repository %s` - TPL_COMMIT_REPO = `%s pushed to %s at %s/%s -` + TPL_CREATE_REPO = `%s created repository %s` + TPL_COMMIT_REPO = `%s pushed to %s at %s/%s%s` + TPL_COMMIT_REPO_LI = `
user-avatar %s %s
` ) // ActionDesc accepts int that represents action operation type // and returns the description. -func ActionDesc(act Actioner) string { +func ActionDesc(act Actioner, avatarLink string) string { actUserName := act.GetActUserName() repoName := act.GetRepoName() content := act.GetContent() @@ -274,8 +273,12 @@ func ActionDesc(act Actioner) string { if err := json.Unmarshal([]byte(content), &commits); err != nil { return err.Error() } + buf := bytes.NewBuffer([]byte("\n")) + for _, commit := range commits { + buf.WriteString(fmt.Sprintf(TPL_COMMIT_REPO_LI, avatarLink, actUserName, repoName, commit[0], commit[0][:7], commit[1]) + "\n") + } return fmt.Sprintf(TPL_COMMIT_REPO, actUserName, actUserName, actUserName, repoName, "master", "master", actUserName, repoName, actUserName, repoName, - actUserName, repoName, commits[0][0], commits[0][0][:7], commits[0][1]) + buf.String()) default: return "invalid type" } diff --git a/public/css/gogs.css b/public/css/gogs.css index 89da6055..45ce5d21 100755 --- a/public/css/gogs.css +++ b/public/css/gogs.css @@ -228,6 +228,12 @@ html, body { border-radius: 6px; } +#gogs-user-avatar-commit { + width: 16px; + height: 16px; + border-radius: 2px; +} + #gogs-user-name { margin-top: 20px; font-size: 1.6em; diff --git a/routers/user/user.go b/routers/user/user.go index 0ff5058d..c43cf84a 100644 --- a/routers/user/user.go +++ b/routers/user/user.go @@ -195,7 +195,7 @@ func Feeds(ctx *middleware.Context, form auth.FeedsForm) { feeds := make([]string, len(actions)) for i := range actions { feeds[i] = fmt.Sprintf(feedTpl, base.ActionIcon(actions[i].OpType), - base.TimeSince(actions[i].Created), base.ActionDesc(actions[i])) + base.TimeSince(actions[i].Created), base.ActionDesc(actions[i], ctx.User.AvatarLink())) } ctx.Render.JSON(200, &feeds) } diff --git a/templates/user/profile.tmpl b/templates/user/profile.tmpl index 84d3b13c..24ae76fe 100644 --- a/templates/user/profile.tmpl +++ b/templates/user/profile.tmpl @@ -32,10 +32,11 @@ {{if eq .TabName "activity"}}
    + {{$avatarLink := .Owner.AvatarLink}} {{range .Feeds}}
  • -
    {{TimeSince .Created}}
    {{ActionDesc . | str2html}}
    +
    {{TimeSince .Created}}
    {{ActionDesc . $avatarLink | str2html}}
  • {{else}} -- cgit v1.2.3 From 0f68930892bc49966769f8931e9a531b37dacb3b Mon Sep 17 00:00:00 2001 From: Unknown Date: Mon, 17 Mar 2014 00:57:18 -0400 Subject: Add latest commit in repo viewer --- gogs.go | 2 +- models/repo2.go | 41 +++++++++++++++++++++++++++++++++++++++++ modules/base/template.go | 1 + modules/base/tool.go | 5 +++++ routers/repo/single.go | 7 +++++++ templates/repo/single.tmpl | 4 ++-- 6 files changed, 57 insertions(+), 3 deletions(-) (limited to 'modules/base') diff --git a/gogs.go b/gogs.go index 2d5283f3..6b587993 100644 --- a/gogs.go +++ b/gogs.go @@ -20,7 +20,7 @@ import ( // Test that go1.1 tag above is included in builds. main.go refers to this definition. const go11tag = true -const APP_VER = "0.0.9.0316.1" +const APP_VER = "0.0.9.0317.1" func init() { base.AppVer = APP_VER diff --git a/models/repo2.go b/models/repo2.go index a8dbc44d..0c17a583 100644 --- a/models/repo2.go +++ b/models/repo2.go @@ -6,11 +6,22 @@ package models import ( "path" + "strings" "time" + "github.com/Unknwon/com" + "github.com/gogits/git" ) +type Commit struct { + Author string + Email string + Date time.Time + SHA string + Message string +} + type RepoFile struct { *git.TreeEntry Path string @@ -85,3 +96,33 @@ func GetReposFiles(userName, reposName, branchName, rpath string) ([]*RepoFile, return append(repodirs, repofiles...), nil } + +func GetLastestCommit(userName, repoName string) (*Commit, error) { + stdout, _, err := com.ExecCmd("git", "--git-dir="+RepoPath(userName, repoName), "log", "-1") + if err != nil { + return nil, err + } + + commit := new(Commit) + for _, line := range strings.Split(stdout, "\n") { + if len(line) == 0 { + continue + } + switch { + case line[0] == 'c': + commit.SHA = line[7:] + case line[0] == 'A': + infos := strings.SplitN(line, " ", 3) + commit.Author = infos[1] + commit.Email = infos[2][1 : len(infos[2])-1] + case line[0] == 'D': + commit.Date, err = time.Parse("Mon Jan 02 15:04:05 2006 -0700", line[8:]) + if err != nil { + return nil, err + } + case line[:4] == " ": + commit.Message = line[4:] + } + } + return commit, nil +} diff --git a/modules/base/template.go b/modules/base/template.go index b38ab140..1a0b5977 100644 --- a/modules/base/template.go +++ b/modules/base/template.go @@ -19,6 +19,7 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{ "AppVer": func() string { return AppVer }, + "AvatarLink": AvatarLink, "str2html": Str2html, "TimeSince": TimeSince, "FileSize": FileSize, diff --git a/modules/base/tool.go b/modules/base/tool.go index 10b3fee3..046b2c51 100644 --- a/modules/base/tool.go +++ b/modules/base/tool.go @@ -22,6 +22,11 @@ func EncodeMd5(str string) string { return hex.EncodeToString(m.Sum(nil)) } +// AvatarLink returns avatar link by given e-mail. +func AvatarLink(email string) string { + return "http://1.gravatar.com/avatar/" + EncodeMd5(email) +} + // Seconds-based time units const ( Minute = 60 diff --git a/routers/repo/single.go b/routers/repo/single.go index fd4d5290..10b2ae81 100644 --- a/routers/repo/single.go +++ b/routers/repo/single.go @@ -50,6 +50,13 @@ func Single(ctx *middleware.Context, params martini.Params) { } } + commit, err := models.GetLastestCommit(params["username"], params["reponame"]) + if err != nil { + ctx.Handle(200, "repo.Single", err) + return + } + ctx.Data["LatestCommit"] = commit + ctx.Data["Paths"] = Paths ctx.Data["Treenames"] = treenames ctx.Data["IsRepoToolbarSource"] = true diff --git a/templates/repo/single.tmpl b/templates/repo/single.tmpl index e1fb05bd..4c6c7dd9 100644 --- a/templates/repo/single.tmpl +++ b/templates/repo/single.tmpl @@ -36,10 +36,10 @@
- Merge branch 'release/1.1.1' + {{.LatestCommit.Message}}
- slene authored 4 days ago + {{.LatestCommit.Author}} {{TimeSince .LatestCommit.Date}}
-- cgit v1.2.3 From 26f9962b6e0089773615ca34ab80ca01ede79790 Mon Sep 17 00:00:00 2001 From: slene Date: Mon, 17 Mar 2014 18:13:07 +0800 Subject: clone in ssh --- conf/app.ini | 1 + modules/base/conf.go | 2 ++ modules/base/template.go | 3 +++ public/css/gogs.css | 12 ++------- public/js/app.js | 20 +++++++++++++++ templates/repo/nav.tmpl | 65 ++++++++++++++++++++++++------------------------ 6 files changed, 60 insertions(+), 43 deletions(-) (limited to 'modules/base') diff --git a/conf/app.ini b/conf/app.ini index f8ff81db..cc7d0a90 100644 --- a/conf/app.ini +++ b/conf/app.ini @@ -7,6 +7,7 @@ LANG_IGNS=Google Go|C|Python|Ruby LICENSES=Apache v2 License|GPL v2|MIT License|BSD (3-Clause) License [server] +DOMAIN = gogits.org HTTP_ADDR = HTTP_PORT = 3000 diff --git a/modules/base/conf.go b/modules/base/conf.go index f1508d7a..05412f38 100644 --- a/modules/base/conf.go +++ b/modules/base/conf.go @@ -18,6 +18,7 @@ import ( var ( AppVer string AppName string + Domain string Cfg *goconfig.ConfigFile ) @@ -58,4 +59,5 @@ func init() { Cfg.BlockMode = false AppName = Cfg.MustValue("", "APP_NAME") + Domain = Cfg.MustValue("server", "DOMAIN") } diff --git a/modules/base/template.go b/modules/base/template.go index 1a0b5977..4517cd47 100644 --- a/modules/base/template.go +++ b/modules/base/template.go @@ -19,6 +19,9 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{ "AppVer": func() string { return AppVer }, + "AppDomain": func() string { + return Domain + }, "AvatarLink": AvatarLink, "str2html": Str2html, "TimeSince": TimeSince, diff --git a/public/css/gogs.css b/public/css/gogs.css index 668df4f7..5352f8e3 100755 --- a/public/css/gogs.css +++ b/public/css/gogs.css @@ -415,16 +415,8 @@ html, body { margin-left: 0; } -.gogs-repo-btns { - margin-top: 18px; -} - -.gogs-repo-btns .btn-group { - margin-left: 1em; -} - -.gogs-repo-btns .btn-group .btn { - padding-left: 6px; +.gogs-repo-nav .actions { + padding-top: 20px; } #gogs-repo-watching .dropdown-menu { diff --git a/public/js/app.js b/public/js/app.js index 58633718..30296bc3 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -40,6 +40,25 @@ var Gogits = { //container: "body" }); }; + Gogits.initPopovers = function () { + var hideAllPopovers = function() { + $('[data-toggle=popover]').each(function() { + $(this).popover('hide'); + }); + }; + + $(document).on('click', function(e) { + var $e = $(e.target); + if($e.data('toggle') == 'popover'||$e.parents("[data-toggle=popover], .popover").length > 0){ + return; + } + hideAllPopovers(); + }); + + $("body").popover({ + selector: "[data-toggle=popover]" + }); + }; Gogits.initTabs = function () { var $tabs = $('[data-init=tabs]'); $tabs.find("li:eq(0) a").tab("show"); @@ -76,6 +95,7 @@ var Gogits = { function initCore() { Gogits.initTooltips(); + Gogits.initPopovers(); Gogits.initTabs(); Gogits.initModals(); Gogits.renderMarkdown(); diff --git a/templates/repo/nav.tmpl b/templates/repo/nav.tmpl index 6637062a..b41b62d5 100644 --- a/templates/repo/nav.tmpl +++ b/templates/repo/nav.tmpl @@ -1,42 +1,41 @@
-
-
- - - +
+
+

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

-
- - -
\ No newline at end of file -- cgit v1.2.3 From 5bc2a1a6f98ae42ab5c30299d26082ffae54b859 Mon Sep 17 00:00:00 2001 From: slene Date: Mon, 17 Mar 2014 18:46:54 +0800 Subject: show readme.md --- models/repo2.go | 16 +++++++++++++++ modules/base/markdown.go | 39 +++++++++++++++++++++++++++++++++++ routers/repo/single.go | 51 +++++++++++++++++++++++++++++++++------------- templates/repo/single.tmpl | 12 ++++++++--- 4 files changed, 101 insertions(+), 17 deletions(-) create mode 100644 modules/base/markdown.go (limited to 'modules/base') diff --git a/models/repo2.go b/models/repo2.go index 0c17a583..b31244b4 100644 --- a/models/repo2.go +++ b/models/repo2.go @@ -5,6 +5,7 @@ package models import ( + "fmt" "path" "strings" "time" @@ -22,12 +23,25 @@ type Commit struct { Message string } +var ( + ErrRepoFileNotLoaded = fmt.Errorf("repo file not loaded") +) + type RepoFile struct { *git.TreeEntry Path string Message string Created time.Time Size int64 + Repo *git.Repository +} + +func (file *RepoFile) LookupBlob() (*git.Blob, error) { + if file.Repo == nil { + return nil, ErrRepoFileNotLoaded + } + + return file.Repo.LookupBlob(file.Id) } func GetBranches(userName, reposName string) ([]string, error) { @@ -80,6 +94,7 @@ func GetReposFiles(userName, reposName, branchName, rpath string) ([]*RepoFile, lastCommit.Message(), lastCommit.Committer.When, size, + repo, }) case git.FileModeTree: repodirs = append(repodirs, &RepoFile{ @@ -88,6 +103,7 @@ func GetReposFiles(userName, reposName, branchName, rpath string) ([]*RepoFile, lastCommit.Message(), lastCommit.Committer.When, size, + repo, }) } } diff --git a/modules/base/markdown.go b/modules/base/markdown.go new file mode 100644 index 00000000..d170abe1 --- /dev/null +++ b/modules/base/markdown.go @@ -0,0 +1,39 @@ +// 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 base + +import ( + "github.com/slene/blackfriday" +) + +func RenderMarkdown(rawBytes []byte) []byte { + htmlFlags := 0 + htmlFlags |= blackfriday.HTML_USE_XHTML + // htmlFlags |= blackfriday.HTML_USE_SMARTYPANTS + // htmlFlags |= blackfriday.HTML_SMARTYPANTS_FRACTIONS + // htmlFlags |= blackfriday.HTML_SMARTYPANTS_LATEX_DASHES + htmlFlags |= blackfriday.HTML_SKIP_HTML + htmlFlags |= blackfriday.HTML_SKIP_STYLE + htmlFlags |= blackfriday.HTML_SKIP_SCRIPT + htmlFlags |= blackfriday.HTML_GITHUB_BLOCKCODE + htmlFlags |= blackfriday.HTML_OMIT_CONTENTS + htmlFlags |= blackfriday.HTML_COMPLETE_PAGE + renderer := blackfriday.HtmlRenderer(htmlFlags, "", "") + + // set up the parser + extensions := 0 + extensions |= blackfriday.EXTENSION_NO_INTRA_EMPHASIS + extensions |= blackfriday.EXTENSION_TABLES + extensions |= blackfriday.EXTENSION_FENCED_CODE + extensions |= blackfriday.EXTENSION_AUTOLINK + extensions |= blackfriday.EXTENSION_STRIKETHROUGH + extensions |= blackfriday.EXTENSION_HARD_LINE_BREAK + extensions |= blackfriday.EXTENSION_SPACE_HEADERS + extensions |= blackfriday.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK + + body := blackfriday.Markdown(rawBytes, renderer, extensions) + + return body +} diff --git a/routers/repo/single.go b/routers/repo/single.go index c144106c..f47a2f7b 100644 --- a/routers/repo/single.go +++ b/routers/repo/single.go @@ -8,9 +8,11 @@ import ( "strings" "github.com/codegangsta/martini" - // "github.com/slene/blackfriday" + + "github.com/gogits/git" "github.com/gogits/gogs/models" + "github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/middleware" ) @@ -43,12 +45,14 @@ func Single(ctx *middleware.Context, params martini.Params) { params["branchname"] = "master" } - // Directory and file list. + // Get tree path treename := params["_1"] + + // Directory and file list. files, err := models.GetReposFiles(params["username"], params["reponame"], params["branchname"], treename) if err != nil { - ctx.Handle(200, "repo.Single", err) + ctx.Render.Error(404) return } ctx.Data["Username"] = params["username"] @@ -58,7 +62,7 @@ func Single(ctx *middleware.Context, params martini.Params) { // Branches. brs, err := models.GetBranches(params["username"], params["reponame"]) if err != nil { - ctx.Handle(200, "repo.Single", err) + ctx.Render.Error(404) return } ctx.Data["Branches"] = brs @@ -73,22 +77,41 @@ func Single(ctx *middleware.Context, params martini.Params) { } } - // Latest commit. + // Get latest commit according username and repo name commit, err := models.GetLastestCommit(params["username"], params["reponame"]) if err != nil { - ctx.Handle(200, "repo.Single", err) + ctx.Render.Error(404) return } ctx.Data["LatestCommit"] = commit - // README. - // for _, f := range files { - // if f.Name == "README.md" { - // ctx.Data["ReadmeName"] = "README.md" - // ctx.Data["ReadmeContent"] = - // break - // } - // } + var readmeFile *models.RepoFile + + for _, f := range files { + if !f.IsFile() { + continue + } + + if len(f.Name) < 6 { + continue + } + + if strings.ToLower(f.Name[:6]) == "readme" { + readmeFile = f + break + } + } + + if readmeFile != nil { + // 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 { + ctx.Data["FileIsLarge"] = true + } else { + ctx.Data["ReadmeContent"] = string(base.RenderMarkdown(blob.Contents())) + } + } ctx.Data["Paths"] = Paths ctx.Data["Treenames"] = treenames diff --git a/templates/repo/single.tmpl b/templates/repo/single.tmpl index 153910f7..c22f129f 100644 --- a/templates/repo/single.tmpl +++ b/templates/repo/single.tmpl @@ -87,9 +87,15 @@
README.md
-
- markdown content -
+ {{if .FileIsLarge}} + + {{else}} +
+ {{.ReadmeContent|str2html}} +
+ {{end}}
-- cgit v1.2.3