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.

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