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.

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