You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

277 lines
5.6 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package base
  5. import (
  6. "container/list"
  7. "encoding/json"
  8. "fmt"
  9. "html/template"
  10. "runtime"
  11. "strings"
  12. "time"
  13. "golang.org/x/net/html/charset"
  14. "golang.org/x/text/transform"
  15. "github.com/gogits/chardet"
  16. "github.com/gogits/gogs/modules/setting"
  17. )
  18. func Str2html(raw string) template.HTML {
  19. return template.HTML(Sanitizer.Sanitize(raw))
  20. }
  21. func Range(l int) []int {
  22. return make([]int, l)
  23. }
  24. func List(l *list.List) chan interface{} {
  25. e := l.Front()
  26. c := make(chan interface{})
  27. go func() {
  28. for e != nil {
  29. c <- e.Value
  30. e = e.Next()
  31. }
  32. close(c)
  33. }()
  34. return c
  35. }
  36. func Sha1(str string) string {
  37. return EncodeSha1(str)
  38. }
  39. func ShortSha(sha1 string) string {
  40. if len(sha1) == 40 {
  41. return sha1[:10]
  42. }
  43. return sha1
  44. }
  45. func DetectEncoding(content []byte) (string, error) {
  46. detector := chardet.NewTextDetector()
  47. result, err := detector.DetectBest(content)
  48. return result.Charset, err
  49. }
  50. func ToUtf8WithErr(content []byte) (error, string) {
  51. charsetLabel, err := DetectEncoding(content)
  52. if err != nil {
  53. return err, ""
  54. }
  55. if charsetLabel == "utf8" {
  56. return nil, string(content)
  57. }
  58. encoding, _ := charset.Lookup(charsetLabel)
  59. if encoding == nil {
  60. return fmt.Errorf("unknow char decoder %s", charsetLabel), string(content)
  61. }
  62. result, n, err := transform.String(encoding.NewDecoder(), string(content))
  63. // If there is an error, we concatenate the nicely decoded part and the
  64. // original left over. This way we won't loose data.
  65. if err != nil {
  66. result = result + string(content[n:])
  67. }
  68. return err, result
  69. }
  70. func ToUtf8(content string) string {
  71. _, res := ToUtf8WithErr([]byte(content))
  72. return res
  73. }
  74. // RenderCommitMessage renders commit message with XSS-safe and special links.
  75. func RenderCommitMessage(msg, urlPrefix string) template.HTML {
  76. return template.HTML(string(RenderIssueIndexPattern([]byte(template.HTMLEscapeString(msg)), urlPrefix)))
  77. }
  78. var mailDomains = map[string]string{
  79. "gmail.com": "gmail.com",
  80. }
  81. var TemplateFuncs template.FuncMap = map[string]interface{}{
  82. "GoVer": func() string {
  83. return strings.Title(runtime.Version())
  84. },
  85. "AppName": func() string {
  86. return setting.AppName
  87. },
  88. "AppSubUrl": func() string {
  89. return setting.AppSubUrl
  90. },
  91. "AppVer": func() string {
  92. return setting.AppVer
  93. },
  94. "AppDomain": func() string {
  95. return setting.Domain
  96. },
  97. "CdnMode": func() bool {
  98. return setting.ProdMode && !setting.OfflineMode
  99. },
  100. "LoadTimes": func(startTime time.Time) string {
  101. return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms"
  102. },
  103. "AvatarLink": AvatarLink,
  104. "Str2html": Str2html,
  105. "TimeSince": TimeSince,
  106. "FileSize": FileSize,
  107. "Subtract": Subtract,
  108. "Add": func(a, b int) int {
  109. return a + b
  110. },
  111. "ActionIcon": ActionIcon,
  112. "DateFmtLong": func(t time.Time) string {
  113. return t.Format(time.RFC1123Z)
  114. },
  115. "DateFmtShort": func(t time.Time) string {
  116. return t.Format("Jan 02, 2006")
  117. },
  118. "List": List,
  119. "Mail2Domain": func(mail string) string {
  120. if !strings.Contains(mail, "@") {
  121. return "try.gogs.io"
  122. }
  123. suffix := strings.SplitN(mail, "@", 2)[1]
  124. domain, ok := mailDomains[suffix]
  125. if !ok {
  126. return "mail." + suffix
  127. }
  128. return domain
  129. },
  130. "SubStr": func(str string, start, length int) string {
  131. if len(str) == 0 {
  132. return ""
  133. }
  134. end := start + length
  135. if length == -1 {
  136. end = len(str)
  137. }
  138. if len(str) < end {
  139. return str
  140. }
  141. return str[start:end]
  142. },
  143. "DiffTypeToStr": DiffTypeToStr,
  144. "DiffLineTypeToStr": DiffLineTypeToStr,
  145. "Sha1": Sha1,
  146. "ShortSha": ShortSha,
  147. "Md5": EncodeMd5,
  148. "ActionContent2Commits": ActionContent2Commits,
  149. "Oauth2Icon": Oauth2Icon,
  150. "Oauth2Name": Oauth2Name,
  151. "ToUtf8": ToUtf8,
  152. "EscapePound": func(str string) string {
  153. return strings.Replace(str, "#", "%23", -1)
  154. },
  155. "RenderCommitMessage": RenderCommitMessage,
  156. }
  157. type Actioner interface {
  158. GetOpType() int
  159. GetActUserName() string
  160. GetActEmail() string
  161. GetRepoUserName() string
  162. GetRepoName() string
  163. GetBranch() string
  164. GetContent() string
  165. }
  166. // ActionIcon accepts a int that represents action operation type
  167. // and returns a icon class name.
  168. func ActionIcon(opType int) string {
  169. switch opType {
  170. case 1, 8: // Create, transfer repository.
  171. return "repo"
  172. case 5, 9: // Commit repository.
  173. return "git-commit"
  174. case 6: // Create issue.
  175. return "issue-opened"
  176. case 10: // Comment issue.
  177. return "comment"
  178. default:
  179. return "invalid type"
  180. }
  181. }
  182. type PushCommit struct {
  183. Sha1 string
  184. Message string
  185. AuthorEmail string
  186. AuthorName string
  187. }
  188. type PushCommits struct {
  189. Len int
  190. Commits []*PushCommit
  191. CompareUrl string
  192. }
  193. func ActionContent2Commits(act Actioner) *PushCommits {
  194. var push *PushCommits
  195. if err := json.Unmarshal([]byte(act.GetContent()), &push); err != nil {
  196. return nil
  197. }
  198. return push
  199. }
  200. func DiffTypeToStr(diffType int) string {
  201. diffTypes := map[int]string{
  202. 1: "add", 2: "modify", 3: "del",
  203. }
  204. return diffTypes[diffType]
  205. }
  206. func DiffLineTypeToStr(diffType int) string {
  207. switch diffType {
  208. case 2:
  209. return "add"
  210. case 3:
  211. return "del"
  212. case 4:
  213. return "tag"
  214. }
  215. return "same"
  216. }
  217. func Oauth2Icon(t int) string {
  218. switch t {
  219. case 1:
  220. return "fa-github-square"
  221. case 2:
  222. return "fa-google-plus-square"
  223. case 3:
  224. return "fa-twitter-square"
  225. case 4:
  226. return "fa-qq"
  227. case 5:
  228. return "fa-weibo"
  229. }
  230. return ""
  231. }
  232. func Oauth2Name(t int) string {
  233. switch t {
  234. case 1:
  235. return "GitHub"
  236. case 2:
  237. return "Google+"
  238. case 3:
  239. return "Twitter"
  240. case 4:
  241. return "腾讯 QQ"
  242. case 5:
  243. return "Weibo"
  244. }
  245. return ""
  246. }