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.

repo.go 9.1 kB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  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. "path"
  7. "path/filepath"
  8. "strings"
  9. "github.com/codegangsta/martini"
  10. "github.com/gogits/webdav"
  11. "github.com/gogits/gogs/models"
  12. "github.com/gogits/gogs/modules/auth"
  13. "github.com/gogits/gogs/modules/base"
  14. "github.com/gogits/gogs/modules/log"
  15. "github.com/gogits/gogs/modules/middleware"
  16. )
  17. func Create(ctx *middleware.Context, form auth.CreateRepoForm) {
  18. ctx.Data["Title"] = "Create repository"
  19. ctx.Data["PageIsNewRepo"] = true // For navbar arrow.
  20. ctx.Data["LanguageIgns"] = models.LanguageIgns
  21. ctx.Data["Licenses"] = models.Licenses
  22. if ctx.Req.Method == "GET" {
  23. ctx.HTML(200, "repo/create")
  24. return
  25. }
  26. if ctx.HasError() {
  27. ctx.HTML(200, "repo/create")
  28. return
  29. }
  30. _, err := models.CreateRepository(ctx.User, form.RepoName, form.Description,
  31. form.Language, form.License, form.Visibility == "private", form.InitReadme == "on")
  32. if err == nil {
  33. log.Trace("%s Repository created: %s/%s", ctx.Req.RequestURI, ctx.User.LowerName, form.RepoName)
  34. ctx.Redirect("/" + ctx.User.Name + "/" + form.RepoName)
  35. return
  36. } else if err == models.ErrRepoAlreadyExist {
  37. ctx.RenderWithErr("Repository name has already been used", "repo/create", &form)
  38. return
  39. } else if err == models.ErrRepoNameIllegal {
  40. ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), "repo/create", &form)
  41. return
  42. }
  43. ctx.Handle(200, "repo.Create", err)
  44. }
  45. func Single(ctx *middleware.Context, params martini.Params) {
  46. branchName := ctx.Repo.BranchName
  47. commitId := ctx.Repo.CommitId
  48. userName := ctx.Repo.Owner.Name
  49. repoName := ctx.Repo.Repository.Name
  50. repoLink := ctx.Repo.RepoLink
  51. branchLink := ctx.Repo.RepoLink + "/src/" + branchName
  52. rawLink := ctx.Repo.RepoLink + "/raw/" + branchName
  53. // Get tree path
  54. treename := params["_1"]
  55. if len(treename) > 0 && treename[len(treename)-1] == '/' {
  56. ctx.Redirect(repoLink + "/src/" + branchName + "/" + treename[:len(treename)-1])
  57. return
  58. }
  59. ctx.Data["IsRepoToolbarSource"] = true
  60. // Branches.
  61. brs, err := models.GetBranches(userName, repoName)
  62. if err != nil {
  63. ctx.Handle(404, "repo.Single(GetBranches)", err)
  64. return
  65. } else if ctx.Repo.Repository.IsBare {
  66. ctx.Data["IsBareRepo"] = true
  67. ctx.HTML(200, "repo/single")
  68. return
  69. }
  70. ctx.Data["Branches"] = brs
  71. isViewBranch := ctx.Repo.IsBranch
  72. ctx.Data["IsViewBranch"] = isViewBranch
  73. repoFile, err := models.GetTargetFile(userName, repoName,
  74. branchName, commitId, treename)
  75. if err != nil && err != models.ErrRepoFileNotExist {
  76. ctx.Handle(404, "repo.Single(GetTargetFile)", err)
  77. return
  78. }
  79. if len(treename) != 0 && repoFile == nil {
  80. ctx.Handle(404, "repo.Single", nil)
  81. return
  82. }
  83. if repoFile != nil && repoFile.IsFile() {
  84. if blob, err := repoFile.LookupBlob(); err != nil {
  85. ctx.Handle(404, "repo.Single(repoFile.LookupBlob)", err)
  86. } else {
  87. ctx.Data["FileSize"] = repoFile.Size
  88. ctx.Data["IsFile"] = true
  89. ctx.Data["FileName"] = repoFile.Name
  90. ext := path.Ext(repoFile.Name)
  91. if len(ext) > 0 {
  92. ext = ext[1:]
  93. }
  94. ctx.Data["FileExt"] = ext
  95. ctx.Data["FileLink"] = rawLink + "/" + treename
  96. data := blob.Contents()
  97. _, isTextFile := base.IsTextFile(data)
  98. _, isImageFile := base.IsImageFile(data)
  99. ctx.Data["FileIsText"] = isTextFile
  100. if isImageFile {
  101. ctx.Data["IsImageFile"] = true
  102. } else {
  103. readmeExist := base.IsMarkdownFile(repoFile.Name) || base.IsReadmeFile(repoFile.Name)
  104. ctx.Data["ReadmeExist"] = readmeExist
  105. if readmeExist {
  106. ctx.Data["FileContent"] = string(base.RenderMarkdown(data, ""))
  107. } else {
  108. if isTextFile {
  109. ctx.Data["FileContent"] = string(data)
  110. }
  111. }
  112. }
  113. }
  114. } else {
  115. // Directory and file list.
  116. files, err := models.GetReposFiles(userName, repoName, ctx.Repo.CommitId, treename)
  117. if err != nil {
  118. ctx.Handle(404, "repo.Single(GetReposFiles)", err)
  119. return
  120. }
  121. ctx.Data["Files"] = files
  122. var readmeFile *models.RepoFile
  123. for _, f := range files {
  124. if !f.IsFile() || !base.IsReadmeFile(f.Name) {
  125. continue
  126. } else {
  127. readmeFile = f
  128. break
  129. }
  130. }
  131. if readmeFile != nil {
  132. ctx.Data["ReadmeInSingle"] = true
  133. ctx.Data["ReadmeExist"] = true
  134. if blob, err := readmeFile.LookupBlob(); err != nil {
  135. ctx.Handle(404, "repo.Single(readmeFile.LookupBlob)", err)
  136. return
  137. } else {
  138. ctx.Data["FileSize"] = readmeFile.Size
  139. ctx.Data["FileLink"] = rawLink + "/" + treename
  140. data := blob.Contents()
  141. _, isTextFile := base.IsTextFile(data)
  142. ctx.Data["FileIsText"] = isTextFile
  143. ctx.Data["FileName"] = readmeFile.Name
  144. if isTextFile {
  145. ctx.Data["FileContent"] = string(base.RenderMarkdown(data, branchLink))
  146. }
  147. }
  148. }
  149. }
  150. ctx.Data["Username"] = userName
  151. ctx.Data["Reponame"] = repoName
  152. var treenames []string
  153. Paths := make([]string, 0)
  154. if len(treename) > 0 {
  155. treenames = strings.Split(treename, "/")
  156. for i, _ := range treenames {
  157. Paths = append(Paths, strings.Join(treenames[0:i+1], "/"))
  158. }
  159. ctx.Data["HasParentPath"] = true
  160. if len(Paths)-2 >= 0 {
  161. ctx.Data["ParentPath"] = "/" + Paths[len(Paths)-2]
  162. }
  163. }
  164. ctx.Data["LastCommit"] = ctx.Repo.Commit
  165. ctx.Data["Paths"] = Paths
  166. ctx.Data["Treenames"] = treenames
  167. ctx.Data["BranchLink"] = branchLink
  168. ctx.HTML(200, "repo/single")
  169. }
  170. func SingleDownload(ctx *middleware.Context, params martini.Params) {
  171. // Get tree path
  172. treename := params["_1"]
  173. branchName := params["branchname"]
  174. userName := params["username"]
  175. repoName := params["reponame"]
  176. var commitId string
  177. if !models.IsBranchExist(userName, repoName, branchName) {
  178. commitId = branchName
  179. branchName = ""
  180. }
  181. repoFile, err := models.GetTargetFile(userName, repoName,
  182. branchName, commitId, treename)
  183. if err != nil {
  184. ctx.Handle(404, "repo.SingleDownload(GetTargetFile)", err)
  185. return
  186. }
  187. blob, err := repoFile.LookupBlob()
  188. if err != nil {
  189. ctx.Handle(404, "repo.SingleDownload(LookupBlob)", err)
  190. return
  191. }
  192. data := blob.Contents()
  193. contentType, isTextFile := base.IsTextFile(data)
  194. _, isImageFile := base.IsImageFile(data)
  195. ctx.Res.Header().Set("Content-Type", contentType)
  196. if !isTextFile && !isImageFile {
  197. ctx.Res.Header().Set("Content-Disposition", "attachment; filename="+filepath.Base(treename))
  198. ctx.Res.Header().Set("Content-Transfer-Encoding", "binary")
  199. }
  200. ctx.Res.Write(data)
  201. }
  202. func Http(ctx *middleware.Context, params martini.Params) {
  203. // TODO: access check
  204. username := params["username"]
  205. reponame := params["reponame"]
  206. if strings.HasSuffix(reponame, ".git") {
  207. reponame = reponame[:len(reponame)-4]
  208. }
  209. prefix := path.Join("/", username, params["reponame"])
  210. server := webdav.NewServer(
  211. models.RepoPath(username, reponame),
  212. prefix, true)
  213. server.ServeHTTP(ctx.ResponseWriter, ctx.Req)
  214. }
  215. func Setting(ctx *middleware.Context, params martini.Params) {
  216. if !ctx.Repo.IsOwner {
  217. ctx.Handle(404, "repo.Setting", nil)
  218. return
  219. }
  220. ctx.Data["IsRepoToolbarSetting"] = true
  221. if ctx.Repo.Repository.IsBare {
  222. ctx.Data["IsBareRepo"] = true
  223. ctx.HTML(200, "repo/setting")
  224. return
  225. }
  226. var title string
  227. if t, ok := ctx.Data["Title"].(string); ok {
  228. title = t
  229. }
  230. ctx.Data["Title"] = title + " - settings"
  231. ctx.HTML(200, "repo/setting")
  232. }
  233. func SettingPost(ctx *middleware.Context) {
  234. if !ctx.Repo.IsOwner {
  235. ctx.Error(404)
  236. return
  237. }
  238. switch ctx.Query("action") {
  239. case "update":
  240. ctx.Repo.Repository.Description = ctx.Query("desc")
  241. ctx.Repo.Repository.Website = ctx.Query("site")
  242. if err := models.UpdateRepository(ctx.Repo.Repository); err != nil {
  243. ctx.Handle(404, "repo.SettingPost(update)", err)
  244. return
  245. }
  246. ctx.Data["IsSuccess"] = true
  247. ctx.HTML(200, "repo/setting")
  248. log.Trace("%s Repository updated: %s/%s", ctx.Req.RequestURI, ctx.User.LowerName, ctx.Repo.Repository.LowerName)
  249. case "delete":
  250. if len(ctx.Repo.Repository.Name) == 0 || ctx.Repo.Repository.Name != ctx.Query("repository") {
  251. ctx.Data["ErrorMsg"] = "Please make sure you entered repository name is correct."
  252. ctx.HTML(200, "repo/setting")
  253. return
  254. }
  255. if err := models.DeleteRepository(ctx.User.Id, ctx.Repo.Repository.Id, ctx.User.LowerName); err != nil {
  256. ctx.Handle(200, "repo.Delete", err)
  257. return
  258. }
  259. log.Trace("%s Repository deleted: %s/%s", ctx.Req.RequestURI, ctx.User.LowerName, ctx.Repo.Repository.LowerName)
  260. ctx.Redirect("/")
  261. }
  262. }
  263. func Action(ctx *middleware.Context, params martini.Params) {
  264. var err error
  265. switch params["action"] {
  266. case "watch":
  267. err = models.WatchRepo(ctx.User.Id, ctx.Repo.Repository.Id, true)
  268. case "unwatch":
  269. err = models.WatchRepo(ctx.User.Id, ctx.Repo.Repository.Id, false)
  270. case "desc":
  271. if !ctx.Repo.IsOwner {
  272. ctx.Error(404)
  273. return
  274. }
  275. ctx.Repo.Repository.Description = ctx.Query("desc")
  276. ctx.Repo.Repository.Website = ctx.Query("site")
  277. err = models.UpdateRepository(ctx.Repo.Repository)
  278. }
  279. if err != nil {
  280. log.Error("repo.Action(%s): %v", params["action"], err)
  281. ctx.JSON(200, map[string]interface{}{
  282. "ok": false,
  283. "err": err.Error(),
  284. })
  285. return
  286. }
  287. ctx.JSON(200, map[string]interface{}{
  288. "ok": true,
  289. })
  290. }