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.

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