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.4 kB

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