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

view.go 7.3 kB

11 years ago
10 years ago
10 years ago
10 years ago
11 years ago
10 years ago
10 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  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 repo
  5. import (
  6. "bytes"
  7. "io/ioutil"
  8. "path"
  9. "strings"
  10. "github.com/Unknwon/paginater"
  11. "github.com/gogits/git-module"
  12. "github.com/gogits/gogs/models"
  13. "github.com/gogits/gogs/modules/base"
  14. "github.com/gogits/gogs/modules/context"
  15. "github.com/gogits/gogs/modules/log"
  16. "github.com/gogits/gogs/modules/markdown"
  17. "github.com/gogits/gogs/modules/setting"
  18. "github.com/gogits/gogs/modules/template"
  19. "github.com/gogits/gogs/modules/template/highlight"
  20. )
  21. const (
  22. HOME base.TplName = "repo/home"
  23. WATCHERS base.TplName = "repo/watchers"
  24. FORKS base.TplName = "repo/forks"
  25. )
  26. func Home(ctx *context.Context) {
  27. title := ctx.Repo.Repository.Owner.Name + "/" + ctx.Repo.Repository.Name
  28. if len(ctx.Repo.Repository.Description) > 0 {
  29. title += ": " + ctx.Repo.Repository.Description
  30. }
  31. ctx.Data["Title"] = title
  32. ctx.Data["PageIsViewCode"] = true
  33. ctx.Data["RequireHighlightJS"] = true
  34. branchName := ctx.Repo.BranchName
  35. userName := ctx.Repo.Owner.Name
  36. repoName := ctx.Repo.Repository.Name
  37. repoLink := ctx.Repo.RepoLink
  38. branchLink := ctx.Repo.RepoLink + "/src/" + branchName
  39. treeLink := branchLink
  40. rawLink := ctx.Repo.RepoLink + "/raw/" + branchName
  41. // Get tree path
  42. treename := ctx.Repo.TreeName
  43. if len(treename) > 0 {
  44. if treename[len(treename)-1] == '/' {
  45. ctx.Redirect(repoLink + "/src/" + branchName + "/" + treename[:len(treename)-1])
  46. return
  47. }
  48. treeLink += "/" + treename
  49. }
  50. treePath := treename
  51. if len(treePath) != 0 {
  52. treePath = treePath + "/"
  53. }
  54. entry, err := ctx.Repo.Commit.GetTreeEntryByPath(treename)
  55. if err != nil && git.IsErrNotExist(err) {
  56. ctx.Handle(404, "GetTreeEntryByPath", err)
  57. return
  58. }
  59. if len(treename) != 0 && entry == nil {
  60. ctx.Handle(404, "repo.Home", nil)
  61. return
  62. }
  63. if entry != nil && !entry.IsDir() {
  64. blob := entry.Blob()
  65. if dataRc, err := blob.Data(); err != nil {
  66. ctx.Handle(404, "blob.Data", err)
  67. return
  68. } else {
  69. ctx.Data["FileSize"] = blob.Size()
  70. ctx.Data["IsFile"] = true
  71. ctx.Data["FileName"] = blob.Name()
  72. ctx.Data["HighlightClass"] = highlight.FileNameToHighlightClass(blob.Name())
  73. ctx.Data["FileLink"] = rawLink + "/" + treename
  74. buf := make([]byte, 1024)
  75. n, _ := dataRc.Read(buf)
  76. if n > 0 {
  77. buf = buf[:n]
  78. }
  79. _, isTextFile := base.IsTextFile(buf)
  80. _, isImageFile := base.IsImageFile(buf)
  81. _, isPDFFile := base.IsPDFFile(buf)
  82. ctx.Data["IsFileText"] = isTextFile
  83. switch {
  84. case isPDFFile:
  85. ctx.Data["IsPDFFile"] = true
  86. case isImageFile:
  87. ctx.Data["IsImageFile"] = true
  88. case isTextFile:
  89. if blob.Size() >= setting.MaxDisplayFileSize {
  90. ctx.Data["IsFileTooLarge"] = true
  91. } else {
  92. ctx.Data["IsFileTooLarge"] = false
  93. d, _ := ioutil.ReadAll(dataRc)
  94. buf = append(buf, d...)
  95. readmeExist := markdown.IsMarkdownFile(blob.Name()) || markdown.IsReadmeFile(blob.Name())
  96. ctx.Data["ReadmeExist"] = readmeExist
  97. if readmeExist {
  98. ctx.Data["FileContent"] = string(markdown.Render(buf, path.Dir(treeLink), ctx.Repo.Repository.ComposeMetas()))
  99. } else {
  100. if err, content := template.ToUtf8WithErr(buf); err != nil {
  101. if err != nil {
  102. log.Error(4, "Convert content encoding: %s", err)
  103. }
  104. ctx.Data["FileContent"] = string(buf)
  105. } else {
  106. ctx.Data["FileContent"] = content
  107. }
  108. }
  109. }
  110. }
  111. }
  112. } else {
  113. // Directory and file list.
  114. tree, err := ctx.Repo.Commit.SubTree(treename)
  115. if err != nil {
  116. ctx.Handle(404, "SubTree", err)
  117. return
  118. }
  119. entries, err := tree.ListEntries()
  120. if err != nil {
  121. ctx.Handle(500, "ListEntries", err)
  122. return
  123. }
  124. entries.Sort()
  125. ctx.Data["Files"], err = entries.GetCommitsInfo(ctx.Repo.Commit, treePath)
  126. if err != nil {
  127. ctx.Handle(500, "GetCommitsInfo", err)
  128. return
  129. }
  130. var readmeFile *git.Blob
  131. for _, f := range entries {
  132. if f.IsDir() || !markdown.IsReadmeFile(f.Name()) {
  133. continue
  134. } else {
  135. readmeFile = f.Blob()
  136. break
  137. }
  138. }
  139. if readmeFile != nil {
  140. ctx.Data["ReadmeInList"] = true
  141. ctx.Data["ReadmeExist"] = true
  142. if dataRc, err := readmeFile.Data(); err != nil {
  143. ctx.Handle(404, "repo.SinglereadmeFile.Data", err)
  144. return
  145. } else {
  146. buf := make([]byte, 1024)
  147. n, _ := dataRc.Read(buf)
  148. if n > 0 {
  149. buf = buf[:n]
  150. }
  151. ctx.Data["FileSize"] = readmeFile.Size()
  152. ctx.Data["FileLink"] = rawLink + "/" + treename
  153. _, isTextFile := base.IsTextFile(buf)
  154. ctx.Data["FileIsText"] = isTextFile
  155. ctx.Data["FileName"] = readmeFile.Name()
  156. if isTextFile {
  157. d, _ := ioutil.ReadAll(dataRc)
  158. buf = append(buf, d...)
  159. switch {
  160. case markdown.IsMarkdownFile(readmeFile.Name()):
  161. buf = markdown.Render(buf, treeLink, ctx.Repo.Repository.ComposeMetas())
  162. default:
  163. buf = bytes.Replace(buf, []byte("\n"), []byte(`<br>`), -1)
  164. }
  165. ctx.Data["FileContent"] = string(buf)
  166. }
  167. }
  168. }
  169. lastCommit := ctx.Repo.Commit
  170. if len(treePath) > 0 {
  171. c, err := ctx.Repo.Commit.GetCommitByPath(treePath)
  172. if err != nil {
  173. ctx.Handle(500, "GetCommitByPath", err)
  174. return
  175. }
  176. lastCommit = c
  177. }
  178. ctx.Data["LastCommit"] = lastCommit
  179. ctx.Data["LastCommitUser"] = models.ValidateCommitWithEmail(lastCommit)
  180. }
  181. ctx.Data["Username"] = userName
  182. ctx.Data["Reponame"] = repoName
  183. var treenames []string
  184. Paths := make([]string, 0)
  185. if len(treename) > 0 {
  186. treenames = strings.Split(treename, "/")
  187. for i, _ := range treenames {
  188. Paths = append(Paths, strings.Join(treenames[0:i+1], "/"))
  189. }
  190. ctx.Data["HasParentPath"] = true
  191. if len(Paths)-2 >= 0 {
  192. ctx.Data["ParentPath"] = "/" + Paths[len(Paths)-2]
  193. }
  194. }
  195. ctx.Data["Paths"] = Paths
  196. ctx.Data["TreeName"] = treename
  197. ctx.Data["Treenames"] = treenames
  198. ctx.Data["TreePath"] = treePath
  199. ctx.Data["BranchLink"] = branchLink
  200. ctx.HTML(200, HOME)
  201. }
  202. func RenderUserCards(ctx *context.Context, total int, getter func(page int) ([]*models.User, error), tpl base.TplName) {
  203. page := ctx.QueryInt("page")
  204. if page <= 0 {
  205. page = 1
  206. }
  207. pager := paginater.New(total, models.ItemsPerPage, page, 5)
  208. ctx.Data["Page"] = pager
  209. items, err := getter(pager.Current())
  210. if err != nil {
  211. ctx.Handle(500, "getter", err)
  212. return
  213. }
  214. ctx.Data["Cards"] = items
  215. ctx.HTML(200, tpl)
  216. }
  217. func Watchers(ctx *context.Context) {
  218. ctx.Data["Title"] = ctx.Tr("repo.watchers")
  219. ctx.Data["CardsTitle"] = ctx.Tr("repo.watchers")
  220. ctx.Data["PageIsWatchers"] = true
  221. RenderUserCards(ctx, ctx.Repo.Repository.NumWatches, ctx.Repo.Repository.GetWatchers, WATCHERS)
  222. }
  223. func Stars(ctx *context.Context) {
  224. ctx.Data["Title"] = ctx.Tr("repo.stargazers")
  225. ctx.Data["CardsTitle"] = ctx.Tr("repo.stargazers")
  226. ctx.Data["PageIsStargazers"] = true
  227. RenderUserCards(ctx, ctx.Repo.Repository.NumStars, ctx.Repo.Repository.GetStargazers, WATCHERS)
  228. }
  229. func Forks(ctx *context.Context) {
  230. ctx.Data["Title"] = ctx.Tr("repos.forks")
  231. forks, err := ctx.Repo.Repository.GetForks()
  232. if err != nil {
  233. ctx.Handle(500, "GetForks", err)
  234. return
  235. }
  236. for _, fork := range forks {
  237. if err = fork.GetOwner(); err != nil {
  238. ctx.Handle(500, "GetOwner", err)
  239. return
  240. }
  241. }
  242. ctx.Data["Forks"] = forks
  243. ctx.HTML(200, FORKS)
  244. }