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.

339 lines
8.3 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
  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 user
  5. import (
  6. "fmt"
  7. "github.com/Unknwon/com"
  8. "github.com/gogits/gogs/models"
  9. "github.com/gogits/gogs/modules/base"
  10. "github.com/gogits/gogs/modules/log"
  11. "github.com/gogits/gogs/modules/middleware"
  12. )
  13. const (
  14. DASHBOARD base.TplName = "user/dashboard/dashboard"
  15. PULLS base.TplName = "user/dashboard/pulls"
  16. ISSUES base.TplName = "user/issues"
  17. STARS base.TplName = "user/stars"
  18. PROFILE base.TplName = "user/profile"
  19. )
  20. func Dashboard(ctx *middleware.Context) {
  21. ctx.Data["Title"] = ctx.Tr("dashboard")
  22. ctx.Data["PageIsDashboard"] = true
  23. ctx.Data["PageIsNews"] = true
  24. var ctxUser *models.User
  25. // Check context type.
  26. orgName := ctx.Params(":org")
  27. if len(orgName) > 0 {
  28. // Organization.
  29. org, err := models.GetUserByName(orgName)
  30. if err != nil {
  31. if err == models.ErrUserNotExist {
  32. ctx.Handle(404, "GetUserByName", err)
  33. } else {
  34. ctx.Handle(500, "GetUserByName", err)
  35. }
  36. return
  37. }
  38. ctxUser = org
  39. } else {
  40. // Normal user.
  41. ctxUser = ctx.User
  42. collaborates, err := models.GetCollaborativeRepos(ctxUser.Name)
  43. if err != nil {
  44. ctx.Handle(500, "GetCollaborativeRepos", err)
  45. return
  46. }
  47. ctx.Data["CollaborateCount"] = len(collaborates)
  48. ctx.Data["CollaborativeRepos"] = collaborates
  49. }
  50. ctx.Data["ContextUser"] = ctxUser
  51. if err := ctx.User.GetOrganizations(); err != nil {
  52. ctx.Handle(500, "GetOrganizations", err)
  53. return
  54. }
  55. ctx.Data["Orgs"] = ctx.User.Orgs
  56. repos, err := models.GetRepositories(ctxUser.Id, true)
  57. if err != nil {
  58. ctx.Handle(500, "GetRepositories", err)
  59. return
  60. }
  61. ctx.Data["Repos"] = repos
  62. // Get mirror repositories.
  63. mirrors := make([]*models.Repository, 0, len(repos)/2)
  64. for _, repo := range repos {
  65. if repo.IsMirror {
  66. if err = repo.GetMirror(); err != nil {
  67. ctx.Handle(500, "GetMirror: "+repo.Name, err)
  68. return
  69. }
  70. mirrors = append(mirrors, repo)
  71. }
  72. }
  73. ctx.Data["MirrorCount"] = len(mirrors)
  74. ctx.Data["Mirrors"] = mirrors
  75. // Get feeds.
  76. actions, err := models.GetFeeds(ctxUser.Id, 0, false)
  77. if err != nil {
  78. ctx.Handle(500, "GetFeeds", err)
  79. return
  80. }
  81. // Check access of private repositories.
  82. feeds := make([]*models.Action, 0, len(actions))
  83. for _, act := range actions {
  84. if act.IsPrivate {
  85. if has, _ := models.HasAccess(ctxUser.Name, act.RepoUserName+"/"+act.RepoName,
  86. models.READABLE); !has {
  87. continue
  88. }
  89. }
  90. feeds = append(feeds, act)
  91. }
  92. ctx.Data["Feeds"] = feeds
  93. ctx.HTML(200, DASHBOARD)
  94. }
  95. func Pulls(ctx *middleware.Context) {
  96. ctx.Data["Title"] = ctx.Tr("pull_requests")
  97. ctx.Data["PageIsDashboard"] = true
  98. ctx.Data["PageIsPulls"] = true
  99. if err := ctx.User.GetOrganizations(); err != nil {
  100. ctx.Handle(500, "GetOrganizations", err)
  101. return
  102. }
  103. ctx.Data["ContextUser"] = ctx.User
  104. ctx.HTML(200, PULLS)
  105. }
  106. func Profile(ctx *middleware.Context) {
  107. ctx.Data["Title"] = "Profile"
  108. ctx.Data["PageIsUserProfile"] = true
  109. uname := ctx.Params(":username")
  110. // Special handle for FireFox requests favicon.ico.
  111. if uname == "favicon.ico" {
  112. ctx.Redirect("/img/favicon.png")
  113. return
  114. }
  115. u, err := models.GetUserByName(uname)
  116. if err != nil {
  117. if err == models.ErrUserNotExist {
  118. ctx.Handle(404, "GetUserByName", err)
  119. } else {
  120. ctx.Handle(500, "GetUserByName", err)
  121. }
  122. return
  123. }
  124. if u.IsOrganization() {
  125. ctx.Redirect("/org/" + u.Name)
  126. return
  127. }
  128. // For security reason, hide e-mail address for anonymous visitors.
  129. if !ctx.IsSigned {
  130. u.Email = ""
  131. }
  132. ctx.Data["Owner"] = u
  133. tab := ctx.Query("tab")
  134. ctx.Data["TabName"] = tab
  135. switch tab {
  136. case "activity":
  137. ctx.Data["Feeds"], err = models.GetFeeds(u.Id, 0, true)
  138. if err != nil {
  139. ctx.Handle(500, "GetFeeds", err)
  140. return
  141. }
  142. default:
  143. ctx.Data["Repos"], err = models.GetRepositories(u.Id, ctx.IsSigned && ctx.User.Id == u.Id)
  144. if err != nil {
  145. ctx.Handle(500, "GetRepositories", err)
  146. return
  147. }
  148. }
  149. ctx.HTML(200, PROFILE)
  150. }
  151. func Email2User(ctx *middleware.Context) {
  152. u, err := models.GetUserByEmail(ctx.Query("email"))
  153. if err != nil {
  154. if err == models.ErrUserNotExist {
  155. ctx.Handle(404, "user.Email2User(GetUserByEmail)", err)
  156. } else {
  157. ctx.Handle(500, "user.Email2User(GetUserByEmail)", err)
  158. }
  159. return
  160. }
  161. ctx.Redirect("/user/" + u.Name)
  162. }
  163. const (
  164. TPL_FEED = `<i class="icon fa fa-%s"></i>
  165. <div class="info"><span class="meta">%s</span><br>%s</div>`
  166. )
  167. // func Feeds(ctx *middleware.Context, form auth.FeedsForm) {
  168. // actions, err := models.GetFeeds(form.UserId, form.Page*20, false)
  169. // if err != nil {
  170. // ctx.JSON(500, err)
  171. // return
  172. // }
  173. // feeds := make([]string, 0, len(actions))
  174. // for _, act := range actions {
  175. // if act.IsPrivate {
  176. // if has, _ := models.HasAccess(ctx.User.Name, act.RepoUserName+"/"+act.RepoName,
  177. // models.READABLE); !has {
  178. // continue
  179. // }
  180. // }
  181. // feeds = append(feeds, fmt.Sprintf(TPL_FEED, base.ActionIcon(act.OpType),
  182. // base.TimeSince(act.Created), base.ActionDesc(act)))
  183. // }
  184. // ctx.JSON(200, &feeds)
  185. // }
  186. func Issues(ctx *middleware.Context) {
  187. ctx.Data["Title"] = "Your Issues"
  188. viewType := ctx.Query("type")
  189. types := []string{"assigned", "created_by"}
  190. if !com.IsSliceContainsStr(types, viewType) {
  191. viewType = "all"
  192. }
  193. isShowClosed := ctx.Query("state") == "closed"
  194. var filterMode int
  195. switch viewType {
  196. case "assigned":
  197. filterMode = models.FM_ASSIGN
  198. case "created_by":
  199. filterMode = models.FM_CREATE
  200. }
  201. repoId, _ := com.StrTo(ctx.Query("repoid")).Int64()
  202. issueStats := models.GetUserIssueStats(ctx.User.Id, filterMode)
  203. // Get all repositories.
  204. repos, err := models.GetRepositories(ctx.User.Id, true)
  205. if err != nil {
  206. ctx.Handle(500, "user.Issues(GetRepositories)", err)
  207. return
  208. }
  209. repoIds := make([]int64, 0, len(repos))
  210. showRepos := make([]*models.Repository, 0, len(repos))
  211. for _, repo := range repos {
  212. if repo.NumIssues == 0 {
  213. continue
  214. }
  215. repoIds = append(repoIds, repo.Id)
  216. repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues
  217. issueStats.AllCount += int64(repo.NumOpenIssues)
  218. if isShowClosed {
  219. if repo.NumClosedIssues > 0 {
  220. if filterMode == models.FM_CREATE {
  221. repo.NumClosedIssues = int(models.GetIssueCountByPoster(ctx.User.Id, repo.Id, isShowClosed))
  222. }
  223. showRepos = append(showRepos, repo)
  224. }
  225. } else {
  226. if repo.NumOpenIssues > 0 {
  227. if filterMode == models.FM_CREATE {
  228. repo.NumOpenIssues = int(models.GetIssueCountByPoster(ctx.User.Id, repo.Id, isShowClosed))
  229. }
  230. showRepos = append(showRepos, repo)
  231. }
  232. }
  233. }
  234. if repoId > 0 {
  235. repoIds = []int64{repoId}
  236. }
  237. page, _ := com.StrTo(ctx.Query("page")).Int()
  238. // Get all issues.
  239. var ius []*models.IssueUser
  240. switch viewType {
  241. case "assigned":
  242. fallthrough
  243. case "created_by":
  244. ius, err = models.GetIssueUserPairsByMode(ctx.User.Id, repoId, isShowClosed, page, filterMode)
  245. default:
  246. ius, err = models.GetIssueUserPairsByRepoIds(repoIds, isShowClosed, page)
  247. }
  248. if err != nil {
  249. ctx.Handle(500, "user.Issues(GetAllIssueUserPairs)", err)
  250. return
  251. }
  252. issues := make([]*models.Issue, len(ius))
  253. for i := range ius {
  254. issues[i], err = models.GetIssueById(ius[i].IssueId)
  255. if err != nil {
  256. if err == models.ErrIssueNotExist {
  257. log.Warn("user.Issues(GetIssueById #%d): issue not exist", ius[i].IssueId)
  258. continue
  259. } else {
  260. ctx.Handle(500, fmt.Sprintf("user.Issues(GetIssueById #%d)", ius[i].IssueId), err)
  261. return
  262. }
  263. }
  264. issues[i].Repo, err = models.GetRepositoryById(issues[i].RepoId)
  265. if err != nil {
  266. if err == models.ErrRepoNotExist {
  267. log.Warn("user.Issues(GetRepositoryById #%d): repository not exist", issues[i].RepoId)
  268. continue
  269. } else {
  270. ctx.Handle(500, fmt.Sprintf("user.Issues(GetRepositoryById #%d)", issues[i].RepoId), err)
  271. return
  272. }
  273. }
  274. if err = issues[i].Repo.GetOwner(); err != nil {
  275. ctx.Handle(500, "user.Issues(GetOwner)", err)
  276. return
  277. }
  278. if err = issues[i].GetPoster(); err != nil {
  279. ctx.Handle(500, "user.Issues(GetUserById)", err)
  280. return
  281. }
  282. }
  283. ctx.Data["RepoId"] = repoId
  284. ctx.Data["Repos"] = showRepos
  285. ctx.Data["Issues"] = issues
  286. ctx.Data["ViewType"] = viewType
  287. ctx.Data["IssueStats"] = issueStats
  288. ctx.Data["IsShowClosed"] = isShowClosed
  289. if isShowClosed {
  290. ctx.Data["State"] = "closed"
  291. ctx.Data["ShowCount"] = issueStats.ClosedCount
  292. } else {
  293. ctx.Data["ShowCount"] = issueStats.OpenCount
  294. }
  295. ctx.HTML(200, ISSUES)
  296. }