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.

374 lines
9.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
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 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. if !ctx.Repo.IsValid {
  47. return
  48. }
  49. branchName := params["branchname"]
  50. userName := params["username"]
  51. repoName := params["reponame"]
  52. // Get tree path
  53. treename := params["_1"]
  54. if len(treename) > 0 && treename[len(treename)-1] == '/' {
  55. ctx.Redirect("/" + ctx.Repo.Owner.LowerName + "/" +
  56. ctx.Repo.Repository.Name + "/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. var commitId string
  72. isViewBranch := models.IsBranchExist(userName, repoName, branchName)
  73. if !isViewBranch {
  74. commitId = branchName
  75. }
  76. ctx.Data["IsViewBranch"] = isViewBranch
  77. repoFile, err := models.GetTargetFile(userName, repoName,
  78. branchName, commitId, treename)
  79. if err != nil && err != models.ErrRepoFileNotExist {
  80. ctx.Handle(404, "repo.Single(GetTargetFile)", err)
  81. return
  82. }
  83. branchLink := "/" + ctx.Repo.Owner.LowerName + "/" + ctx.Repo.Repository.Name + "/src/" + branchName
  84. rawLink := "/" + ctx.Repo.Owner.LowerName + "/" + ctx.Repo.Repository.Name + "/raw/" + branchName
  85. if len(treename) != 0 && repoFile == nil {
  86. ctx.Handle(404, "repo.Single", nil)
  87. return
  88. }
  89. if repoFile != nil && repoFile.IsFile() {
  90. if blob, err := repoFile.LookupBlob(); err != nil {
  91. ctx.Handle(404, "repo.Single(repoFile.LookupBlob)", err)
  92. } else {
  93. ctx.Data["FileSize"] = repoFile.Size
  94. ctx.Data["IsFile"] = true
  95. ctx.Data["FileName"] = repoFile.Name
  96. ext := path.Ext(repoFile.Name)
  97. if len(ext) > 0 {
  98. ext = ext[1:]
  99. }
  100. ctx.Data["FileExt"] = ext
  101. ctx.Data["FileLink"] = rawLink + "/" + treename
  102. data := blob.Contents()
  103. _, isTextFile := base.IsTextFile(data)
  104. _, isImageFile := base.IsImageFile(data)
  105. ctx.Data["FileIsText"] = isTextFile
  106. if isImageFile {
  107. ctx.Data["IsImageFile"] = true
  108. } else {
  109. readmeExist := base.IsMarkdownFile(repoFile.Name) || base.IsReadmeFile(repoFile.Name)
  110. ctx.Data["ReadmeExist"] = readmeExist
  111. if readmeExist {
  112. ctx.Data["FileContent"] = string(base.RenderMarkdown(data, ""))
  113. } else {
  114. if isTextFile {
  115. ctx.Data["FileContent"] = string(data)
  116. }
  117. }
  118. }
  119. }
  120. } else {
  121. // Directory and file list.
  122. files, err := models.GetReposFiles(userName, repoName,
  123. branchName, commitId, treename)
  124. if err != nil {
  125. ctx.Handle(404, "repo.Single(GetReposFiles)", err)
  126. return
  127. }
  128. ctx.Data["Files"] = files
  129. var readmeFile *models.RepoFile
  130. for _, f := range files {
  131. if !f.IsFile() || !base.IsReadmeFile(f.Name) {
  132. continue
  133. } else {
  134. readmeFile = f
  135. break
  136. }
  137. }
  138. if readmeFile != nil {
  139. ctx.Data["ReadmeInSingle"] = true
  140. ctx.Data["ReadmeExist"] = true
  141. if blob, err := readmeFile.LookupBlob(); err != nil {
  142. ctx.Handle(404, "repo.Single(readmeFile.LookupBlob)", err)
  143. return
  144. } else {
  145. ctx.Data["FileSize"] = readmeFile.Size
  146. ctx.Data["FileLink"] = rawLink + "/" + treename
  147. data := blob.Contents()
  148. _, isTextFile := base.IsTextFile(data)
  149. ctx.Data["FileIsText"] = isTextFile
  150. ctx.Data["FileName"] = readmeFile.Name
  151. if isTextFile {
  152. ctx.Data["FileContent"] = string(base.RenderMarkdown(data, branchLink))
  153. }
  154. }
  155. }
  156. }
  157. ctx.Data["Username"] = userName
  158. ctx.Data["Reponame"] = repoName
  159. var treenames []string
  160. Paths := make([]string, 0)
  161. if len(treename) > 0 {
  162. treenames = strings.Split(treename, "/")
  163. for i, _ := range treenames {
  164. Paths = append(Paths, strings.Join(treenames[0:i+1], "/"))
  165. }
  166. ctx.Data["HasParentPath"] = true
  167. if len(Paths)-2 >= 0 {
  168. ctx.Data["ParentPath"] = "/" + Paths[len(Paths)-2]
  169. }
  170. }
  171. // Get latest commit according username and repo name.
  172. commit, err := models.GetCommit(userName, repoName,
  173. branchName, commitId)
  174. if err != nil {
  175. log.Error("repo.Single(GetCommit): %v", err)
  176. ctx.Handle(404, "repo.Single(GetCommit)", err)
  177. return
  178. }
  179. ctx.Data["LastCommit"] = commit
  180. ctx.Data["CommitId"] = commitId
  181. ctx.Data["Paths"] = Paths
  182. ctx.Data["Treenames"] = treenames
  183. ctx.Data["BranchLink"] = branchLink
  184. ctx.HTML(200, "repo/single")
  185. }
  186. func SingleDownload(ctx *middleware.Context, params martini.Params) {
  187. if !ctx.Repo.IsValid {
  188. ctx.Handle(404, "repo.SingleDownload", nil)
  189. return
  190. }
  191. // Get tree path
  192. treename := params["_1"]
  193. branchName := params["branchname"]
  194. userName := params["username"]
  195. repoName := params["reponame"]
  196. var commitId string
  197. if !models.IsBranchExist(userName, repoName, branchName) {
  198. commitId = branchName
  199. branchName = ""
  200. }
  201. repoFile, err := models.GetTargetFile(userName, repoName,
  202. branchName, commitId, treename)
  203. if err != nil {
  204. ctx.Handle(404, "repo.SingleDownload(GetTargetFile)", err)
  205. return
  206. }
  207. blob, err := repoFile.LookupBlob()
  208. if err != nil {
  209. ctx.Handle(404, "repo.SingleDownload(LookupBlob)", err)
  210. return
  211. }
  212. data := blob.Contents()
  213. contentType, isTextFile := base.IsTextFile(data)
  214. _, isImageFile := base.IsImageFile(data)
  215. ctx.Res.Header().Set("Content-Type", contentType)
  216. if !isTextFile && !isImageFile {
  217. ctx.Res.Header().Set("Content-Disposition", "attachment; filename="+filepath.Base(treename))
  218. ctx.Res.Header().Set("Content-Transfer-Encoding", "binary")
  219. }
  220. ctx.Res.Write(data)
  221. }
  222. func Http(ctx *middleware.Context, params martini.Params) {
  223. /*if !ctx.Repo.IsValid {
  224. return
  225. }*/
  226. // TODO: access check
  227. username := params["username"]
  228. reponame := params["reponame"]
  229. if strings.HasSuffix(reponame, ".git") {
  230. reponame = reponame[:len(reponame)-4]
  231. }
  232. prefix := path.Join("/", username, params["reponame"])
  233. server := &webdav.Server{
  234. Fs: webdav.Dir(models.RepoPath(username, reponame)),
  235. TrimPrefix: prefix,
  236. Listings: true,
  237. }
  238. server.ServeHTTP(ctx.ResponseWriter, ctx.Req)
  239. }
  240. func Setting(ctx *middleware.Context, params martini.Params) {
  241. if !ctx.Repo.IsOwner {
  242. ctx.Handle(404, "repo.Setting", nil)
  243. return
  244. }
  245. ctx.Data["IsRepoToolbarSetting"] = true
  246. if ctx.Repo.Repository.IsBare {
  247. ctx.Data["IsBareRepo"] = true
  248. ctx.HTML(200, "repo/setting")
  249. return
  250. }
  251. var title string
  252. if t, ok := ctx.Data["Title"].(string); ok {
  253. title = t
  254. }
  255. ctx.Data["Title"] = title + " - settings"
  256. ctx.HTML(200, "repo/setting")
  257. }
  258. func SettingPost(ctx *middleware.Context) {
  259. if !ctx.Repo.IsOwner {
  260. ctx.Error(404)
  261. return
  262. }
  263. switch ctx.Query("action") {
  264. case "update":
  265. ctx.Repo.Repository.Description = ctx.Query("desc")
  266. ctx.Repo.Repository.Website = ctx.Query("site")
  267. if err := models.UpdateRepository(ctx.Repo.Repository); err != nil {
  268. ctx.Handle(404, "repo.SettingPost(update)", err)
  269. return
  270. }
  271. ctx.Data["IsSuccess"] = true
  272. ctx.HTML(200, "repo/setting")
  273. log.Trace("%s Repository updated: %s/%s", ctx.Req.RequestURI, ctx.User.LowerName, ctx.Repo.Repository.LowerName)
  274. case "delete":
  275. if len(ctx.Repo.Repository.Name) == 0 || ctx.Repo.Repository.Name != ctx.Query("repository") {
  276. ctx.Data["ErrorMsg"] = "Please make sure you entered repository name is correct."
  277. ctx.HTML(200, "repo/setting")
  278. return
  279. }
  280. if err := models.DeleteRepository(ctx.User.Id, ctx.Repo.Repository.Id, ctx.User.LowerName); err != nil {
  281. ctx.Handle(200, "repo.Delete", err)
  282. return
  283. }
  284. log.Trace("%s Repository deleted: %s/%s", ctx.Req.RequestURI, ctx.User.LowerName, ctx.Repo.Repository.LowerName)
  285. ctx.Redirect("/")
  286. }
  287. }
  288. func Action(ctx *middleware.Context, params martini.Params) {
  289. var err error
  290. switch params["action"] {
  291. case "watch":
  292. err = models.WatchRepo(ctx.User.Id, ctx.Repo.Repository.Id, true)
  293. case "unwatch":
  294. err = models.WatchRepo(ctx.User.Id, ctx.Repo.Repository.Id, false)
  295. case "desc":
  296. if !ctx.Repo.IsOwner {
  297. ctx.Error(404)
  298. return
  299. }
  300. ctx.Repo.Repository.Description = ctx.Query("desc")
  301. ctx.Repo.Repository.Website = ctx.Query("site")
  302. err = models.UpdateRepository(ctx.Repo.Repository)
  303. }
  304. if err != nil {
  305. log.Error("repo.Action(%s): %v", params["action"], err)
  306. ctx.JSON(200, map[string]interface{}{
  307. "ok": false,
  308. "err": err.Error(),
  309. })
  310. return
  311. }
  312. ctx.JSON(200, map[string]interface{}{
  313. "ok": true,
  314. })
  315. }