@@ -6,9 +6,11 @@ package base | |||||
import ( | import ( | ||||
"bytes" | "bytes" | ||||
"fmt" | |||||
"net/http" | "net/http" | ||||
"path" | "path" | ||||
"path/filepath" | "path/filepath" | ||||
"regexp" | |||||
"strings" | "strings" | ||||
"github.com/gogits/gfm" | "github.com/gogits/gfm" | ||||
@@ -87,7 +89,28 @@ func (options *CustomRender) Link(out *bytes.Buffer, link []byte, title []byte, | |||||
options.Renderer.Link(out, link, title, content) | options.Renderer.Link(out, link, title, content) | ||||
} | } | ||||
var ( | |||||
mentionPattern = regexp.MustCompile(`@[0-9a-zA-Z_]{1,}`) | |||||
commitPattern = regexp.MustCompile(`[^>]http[s]{0,}.*commit/[0-9a-zA-Z]{1,}`) | |||||
) | |||||
func RenderSpecialLink(rawBytes []byte, urlPrefix string) []byte { | |||||
ms := mentionPattern.FindAll(rawBytes, -1) | |||||
for _, m := range ms { | |||||
rawBytes = bytes.Replace(rawBytes, m, | |||||
[]byte(fmt.Sprintf(`<a href="/user/%s">%s</a>`, m[1:], m)), -1) | |||||
} | |||||
ms = commitPattern.FindAll(rawBytes, -1) | |||||
for _, m := range ms { | |||||
rawBytes = bytes.Replace(rawBytes, m, | |||||
[]byte(fmt.Sprintf(`<code><a href="%s">%s</a></code>`, m, m)), -1) | |||||
} | |||||
return rawBytes | |||||
} | |||||
func RenderMarkdown(rawBytes []byte, urlPrefix string) []byte { | func RenderMarkdown(rawBytes []byte, urlPrefix string) []byte { | ||||
body := RenderSpecialLink(rawBytes, urlPrefix) | |||||
fmt.Println(string(body)) | |||||
htmlFlags := 0 | htmlFlags := 0 | ||||
// htmlFlags |= gfm.HTML_USE_XHTML | // htmlFlags |= gfm.HTML_USE_XHTML | ||||
// htmlFlags |= gfm.HTML_USE_SMARTYPANTS | // htmlFlags |= gfm.HTML_USE_SMARTYPANTS | ||||
@@ -115,7 +138,7 @@ func RenderMarkdown(rawBytes []byte, urlPrefix string) []byte { | |||||
extensions |= gfm.EXTENSION_SPACE_HEADERS | extensions |= gfm.EXTENSION_SPACE_HEADERS | ||||
extensions |= gfm.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK | extensions |= gfm.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK | ||||
body := gfm.Markdown(rawBytes, renderer, extensions) | |||||
body = gfm.Markdown(body, renderer, extensions) | |||||
fmt.Println(string(body)) | |||||
return body | return body | ||||
} | } |
@@ -5,7 +5,9 @@ | |||||
package base | package base | ||||
import ( | import ( | ||||
"bytes" | |||||
"container/list" | "container/list" | ||||
"encoding/json" | |||||
"fmt" | "fmt" | ||||
"html/template" | "html/template" | ||||
"strings" | "strings" | ||||
@@ -85,3 +87,107 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{ | |||||
"DiffLineTypeToStr": DiffLineTypeToStr, | "DiffLineTypeToStr": DiffLineTypeToStr, | ||||
"ShortSha": ShortSha, | "ShortSha": ShortSha, | ||||
} | } | ||||
type Actioner interface { | |||||
GetOpType() int | |||||
GetActUserName() string | |||||
GetActEmail() string | |||||
GetRepoName() string | |||||
GetBranch() string | |||||
GetContent() string | |||||
} | |||||
// ActionIcon accepts a int that represents action operation type | |||||
// and returns a icon class name. | |||||
func ActionIcon(opType int) string { | |||||
switch opType { | |||||
case 1: // Create repository. | |||||
return "plus-circle" | |||||
case 5: // Commit repository. | |||||
return "arrow-circle-o-right" | |||||
case 6: // Create issue. | |||||
return "exclamation-circle" | |||||
case 8: // Transfer repository. | |||||
return "share" | |||||
default: | |||||
return "invalid type" | |||||
} | |||||
} | |||||
const ( | |||||
TPL_CREATE_REPO = `<a href="/user/%s">%s</a> created repository <a href="/%s">%s</a>` | |||||
TPL_COMMIT_REPO = `<a href="/user/%s">%s</a> pushed to <a href="/%s/src/%s">%s</a> at <a href="/%s">%s</a>%s` | |||||
TPL_COMMIT_REPO_LI = `<div><img src="%s?s=16" alt="user-avatar"/> <a href="/%s/commit/%s">%s</a> %s</div>` | |||||
TPL_CREATE_ISSUE = `<a href="/user/%s">%s</a> opened issue <a href="/%s/issues/%s">%s#%s</a> | |||||
<div><img src="%s?s=16" alt="user-avatar"/> %s</div>` | |||||
TPL_TRANSFER_REPO = `<a href="/user/%s">%s</a> transfered repository <code>%s</code> to <a href="/%s">%s</a>` | |||||
) | |||||
type PushCommit struct { | |||||
Sha1 string | |||||
Message string | |||||
AuthorEmail string | |||||
AuthorName string | |||||
} | |||||
type PushCommits struct { | |||||
Len int | |||||
Commits []*PushCommit | |||||
} | |||||
// ActionDesc accepts int that represents action operation type | |||||
// and returns the description. | |||||
func ActionDesc(act Actioner) string { | |||||
actUserName := act.GetActUserName() | |||||
email := act.GetActEmail() | |||||
repoName := act.GetRepoName() | |||||
repoLink := actUserName + "/" + repoName | |||||
branch := act.GetBranch() | |||||
content := act.GetContent() | |||||
switch act.GetOpType() { | |||||
case 1: // Create repository. | |||||
return fmt.Sprintf(TPL_CREATE_REPO, actUserName, actUserName, repoLink, repoName) | |||||
case 5: // Commit repository. | |||||
var push *PushCommits | |||||
if err := json.Unmarshal([]byte(content), &push); err != nil { | |||||
return err.Error() | |||||
} | |||||
buf := bytes.NewBuffer([]byte("\n")) | |||||
for _, commit := range push.Commits { | |||||
buf.WriteString(fmt.Sprintf(TPL_COMMIT_REPO_LI, AvatarLink(commit.AuthorEmail), repoLink, commit.Sha1, commit.Sha1[:7], commit.Message) + "\n") | |||||
} | |||||
if push.Len > 3 { | |||||
buf.WriteString(fmt.Sprintf(`<div><a href="/%s/%s/commits/%s">%d other commits >></a></div>`, actUserName, repoName, branch, push.Len)) | |||||
} | |||||
return fmt.Sprintf(TPL_COMMIT_REPO, actUserName, actUserName, repoLink, branch, branch, repoLink, repoLink, | |||||
buf.String()) | |||||
case 6: // Create issue. | |||||
infos := strings.SplitN(content, "|", 2) | |||||
return fmt.Sprintf(TPL_CREATE_ISSUE, actUserName, actUserName, repoLink, infos[0], repoLink, infos[0], | |||||
AvatarLink(email), infos[1]) | |||||
case 8: // Transfer repository. | |||||
newRepoLink := content + "/" + repoName | |||||
return fmt.Sprintf(TPL_TRANSFER_REPO, actUserName, actUserName, repoLink, newRepoLink, newRepoLink) | |||||
default: | |||||
return "invalid type" | |||||
} | |||||
} | |||||
func DiffTypeToStr(diffType int) string { | |||||
diffTypes := map[int]string{ | |||||
1: "add", 2: "modify", 3: "del", | |||||
} | |||||
return diffTypes[diffType] | |||||
} | |||||
func DiffLineTypeToStr(diffType int) string { | |||||
switch diffType { | |||||
case 2: | |||||
return "add" | |||||
case 3: | |||||
return "del" | |||||
case 4: | |||||
return "tag" | |||||
} | |||||
return "same" | |||||
} |
@@ -5,13 +5,11 @@ | |||||
package base | package base | ||||
import ( | import ( | ||||
"bytes" | |||||
"crypto/hmac" | "crypto/hmac" | ||||
"crypto/md5" | "crypto/md5" | ||||
"crypto/rand" | "crypto/rand" | ||||
"crypto/sha1" | "crypto/sha1" | ||||
"encoding/hex" | "encoding/hex" | ||||
"encoding/json" | |||||
"fmt" | "fmt" | ||||
"hash" | "hash" | ||||
"math" | "math" | ||||
@@ -514,107 +512,3 @@ func (a argInt) Get(i int, args ...int) (r int) { | |||||
} | } | ||||
return | return | ||||
} | } | ||||
type Actioner interface { | |||||
GetOpType() int | |||||
GetActUserName() string | |||||
GetActEmail() string | |||||
GetRepoName() string | |||||
GetBranch() string | |||||
GetContent() string | |||||
} | |||||
// ActionIcon accepts a int that represents action operation type | |||||
// and returns a icon class name. | |||||
func ActionIcon(opType int) string { | |||||
switch opType { | |||||
case 1: // Create repository. | |||||
return "plus-circle" | |||||
case 5: // Commit repository. | |||||
return "arrow-circle-o-right" | |||||
case 6: // Create issue. | |||||
return "exclamation-circle" | |||||
case 8: // Transfer repository. | |||||
return "share" | |||||
default: | |||||
return "invalid type" | |||||
} | |||||
} | |||||
const ( | |||||
TPL_CREATE_REPO = `<a href="/user/%s">%s</a> created repository <a href="/%s">%s</a>` | |||||
TPL_COMMIT_REPO = `<a href="/user/%s">%s</a> pushed to <a href="/%s/src/%s">%s</a> at <a href="/%s">%s</a>%s` | |||||
TPL_COMMIT_REPO_LI = `<div><img src="%s?s=16" alt="user-avatar"/> <a href="/%s/commit/%s">%s</a> %s</div>` | |||||
TPL_CREATE_ISSUE = `<a href="/user/%s">%s</a> opened issue <a href="/%s/issues/%s">%s#%s</a> | |||||
<div><img src="%s?s=16" alt="user-avatar"/> %s</div>` | |||||
TPL_TRANSFER_REPO = `<a href="/user/%s">%s</a> transfered repository <code>%s</code> to <a href="/%s">%s</a>` | |||||
) | |||||
type PushCommit struct { | |||||
Sha1 string | |||||
Message string | |||||
AuthorEmail string | |||||
AuthorName string | |||||
} | |||||
type PushCommits struct { | |||||
Len int | |||||
Commits []*PushCommit | |||||
} | |||||
// ActionDesc accepts int that represents action operation type | |||||
// and returns the description. | |||||
func ActionDesc(act Actioner) string { | |||||
actUserName := act.GetActUserName() | |||||
email := act.GetActEmail() | |||||
repoName := act.GetRepoName() | |||||
repoLink := actUserName + "/" + repoName | |||||
branch := act.GetBranch() | |||||
content := act.GetContent() | |||||
switch act.GetOpType() { | |||||
case 1: // Create repository. | |||||
return fmt.Sprintf(TPL_CREATE_REPO, actUserName, actUserName, repoLink, repoName) | |||||
case 5: // Commit repository. | |||||
var push *PushCommits | |||||
if err := json.Unmarshal([]byte(content), &push); err != nil { | |||||
return err.Error() | |||||
} | |||||
buf := bytes.NewBuffer([]byte("\n")) | |||||
for _, commit := range push.Commits { | |||||
buf.WriteString(fmt.Sprintf(TPL_COMMIT_REPO_LI, AvatarLink(commit.AuthorEmail), repoLink, commit.Sha1, commit.Sha1[:7], commit.Message) + "\n") | |||||
} | |||||
if push.Len > 3 { | |||||
buf.WriteString(fmt.Sprintf(`<div><a href="/%s/%s/commits/%s">%d other commits >></a></div>`, actUserName, repoName, branch, push.Len)) | |||||
} | |||||
return fmt.Sprintf(TPL_COMMIT_REPO, actUserName, actUserName, repoLink, branch, branch, repoLink, repoLink, | |||||
buf.String()) | |||||
case 6: // Create issue. | |||||
infos := strings.SplitN(content, "|", 2) | |||||
return fmt.Sprintf(TPL_CREATE_ISSUE, actUserName, actUserName, repoLink, infos[0], repoLink, infos[0], | |||||
AvatarLink(email), infos[1]) | |||||
case 8: // Transfer repository. | |||||
newRepoLink := content + "/" + repoName | |||||
return fmt.Sprintf(TPL_TRANSFER_REPO, actUserName, actUserName, repoLink, newRepoLink, newRepoLink) | |||||
default: | |||||
return "invalid type" | |||||
} | |||||
} | |||||
func DiffTypeToStr(diffType int) string { | |||||
diffTypes := map[int]string{ | |||||
1: "add", 2: "modify", 3: "del", | |||||
} | |||||
return diffTypes[diffType] | |||||
} | |||||
func DiffLineTypeToStr(diffType int) string { | |||||
switch diffType { | |||||
case 2: | |||||
return "add" | |||||
case 3: | |||||
return "del" | |||||
case 4: | |||||
return "tag" | |||||
} | |||||
return "same" | |||||
} |