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.

276 lines
6.5 KiB

8 years ago
  1. // Copyright 2015 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. "path"
  8. "strings"
  9. "github.com/Unknwon/paginater"
  10. "code.gitea.io/gitea/models"
  11. "code.gitea.io/gitea/modules/base"
  12. "code.gitea.io/gitea/modules/context"
  13. "code.gitea.io/gitea/modules/setting"
  14. "code.gitea.io/gitea/routers/repo"
  15. )
  16. const (
  17. tplFollowers base.TplName = "user/meta/followers"
  18. tplStars base.TplName = "user/meta/stars"
  19. )
  20. // GetUserByName get user by name
  21. func GetUserByName(ctx *context.Context, name string) *models.User {
  22. user, err := models.GetUserByName(name)
  23. if err != nil {
  24. if models.IsErrUserNotExist(err) {
  25. ctx.Handle(404, "GetUserByName", nil)
  26. } else {
  27. ctx.Handle(500, "GetUserByName", err)
  28. }
  29. return nil
  30. }
  31. return user
  32. }
  33. // GetUserByParams returns user whose name is presented in URL paramenter.
  34. func GetUserByParams(ctx *context.Context) *models.User {
  35. return GetUserByName(ctx, ctx.Params(":username"))
  36. }
  37. // Profile render user's profile page
  38. func Profile(ctx *context.Context) {
  39. uname := ctx.Params(":username")
  40. // Special handle for FireFox requests favicon.ico.
  41. if uname == "favicon.ico" {
  42. ctx.ServeFile(path.Join(setting.StaticRootPath, "public/img/favicon.png"))
  43. return
  44. } else if strings.HasSuffix(uname, ".png") {
  45. ctx.Error(404)
  46. return
  47. }
  48. isShowKeys := false
  49. if strings.HasSuffix(uname, ".keys") {
  50. isShowKeys = true
  51. }
  52. ctxUser := GetUserByName(ctx, strings.TrimSuffix(uname, ".keys"))
  53. if ctx.Written() {
  54. return
  55. }
  56. // Show SSH keys.
  57. if isShowKeys {
  58. ShowSSHKeys(ctx, ctxUser.ID)
  59. return
  60. }
  61. if ctxUser.IsOrganization() {
  62. showOrgProfile(ctx)
  63. return
  64. }
  65. // Show OpenID URIs
  66. openIDs, err := models.GetUserOpenIDs(ctxUser.ID)
  67. if err != nil {
  68. ctx.Handle(500, "GetUserOpenIDs", err)
  69. return
  70. }
  71. ctx.Data["Title"] = ctxUser.DisplayName()
  72. ctx.Data["PageIsUserProfile"] = true
  73. ctx.Data["Owner"] = ctxUser
  74. ctx.Data["OpenIDs"] = openIDs
  75. showPrivate := ctx.IsSigned && (ctx.User.IsAdmin || ctx.User.ID == ctxUser.ID)
  76. orgs, err := models.GetOrgsByUserID(ctxUser.ID, showPrivate)
  77. if err != nil {
  78. ctx.Handle(500, "GetOrgsByUserIDDesc", err)
  79. return
  80. }
  81. ctx.Data["Orgs"] = orgs
  82. tab := ctx.Query("tab")
  83. ctx.Data["TabName"] = tab
  84. page := ctx.QueryInt("page")
  85. if page <= 0 {
  86. page = 1
  87. }
  88. var (
  89. repos []*models.Repository
  90. count int64
  91. orderBy string
  92. )
  93. ctx.Data["SortType"] = ctx.Query("sort")
  94. switch ctx.Query("sort") {
  95. case "newest":
  96. orderBy = "created_unix DESC"
  97. case "oldest":
  98. orderBy = "created_unix ASC"
  99. case "recentupdate":
  100. orderBy = "updated_unix DESC"
  101. case "leastupdate":
  102. orderBy = "updated_unix ASC"
  103. case "reversealphabetically":
  104. orderBy = "name DESC"
  105. case "alphabetically":
  106. orderBy = "name ASC"
  107. default:
  108. ctx.Data["SortType"] = "recentupdate"
  109. orderBy = "updated_unix DESC"
  110. }
  111. // set default sort value if sort is empty.
  112. if ctx.Query("sort") == "" {
  113. ctx.Data["SortType"] = "recentupdate"
  114. }
  115. keyword := strings.Trim(ctx.Query("q"), " ")
  116. ctx.Data["Keyword"] = keyword
  117. switch tab {
  118. case "activity":
  119. retrieveFeeds(ctx, ctxUser, showPrivate, true)
  120. if ctx.Written() {
  121. return
  122. }
  123. case "stars":
  124. ctx.Data["PageIsProfileStarList"] = true
  125. if len(keyword) == 0 {
  126. repos, err = ctxUser.GetStarredRepos(showPrivate, page, setting.UI.User.RepoPagingNum, orderBy)
  127. if err != nil {
  128. ctx.Handle(500, "GetStarredRepos", err)
  129. return
  130. }
  131. count, err = ctxUser.GetStarredRepoCount(showPrivate)
  132. if err != nil {
  133. ctx.Handle(500, "GetStarredRepoCount", err)
  134. return
  135. }
  136. } else {
  137. repos, count, err = models.SearchRepositoryByName(&models.SearchRepoOptions{
  138. Keyword: keyword,
  139. OwnerID: ctxUser.ID,
  140. OrderBy: orderBy,
  141. Private: showPrivate,
  142. Page: page,
  143. PageSize: setting.UI.User.RepoPagingNum,
  144. Starred: true,
  145. })
  146. if err != nil {
  147. ctx.Handle(500, "SearchRepositoryByName", err)
  148. return
  149. }
  150. }
  151. ctx.Data["Repos"] = repos
  152. ctx.Data["Page"] = paginater.New(int(count), setting.UI.User.RepoPagingNum, page, 5)
  153. ctx.Data["Total"] = count
  154. default:
  155. if len(keyword) == 0 {
  156. var total int
  157. repos, err = models.GetUserRepositories(ctxUser.ID, showPrivate, page, setting.UI.User.RepoPagingNum, orderBy)
  158. if err != nil {
  159. ctx.Handle(500, "GetRepositories", err)
  160. return
  161. }
  162. ctx.Data["Repos"] = repos
  163. if showPrivate {
  164. total = ctxUser.NumRepos
  165. } else {
  166. count, err := models.GetPublicRepositoryCount(ctxUser)
  167. if err != nil {
  168. ctx.Handle(500, "GetPublicRepositoryCount", err)
  169. return
  170. }
  171. total = int(count)
  172. }
  173. ctx.Data["Page"] = paginater.New(total, setting.UI.User.RepoPagingNum, page, 5)
  174. ctx.Data["Total"] = total
  175. } else {
  176. repos, count, err = models.SearchRepositoryByName(&models.SearchRepoOptions{
  177. Keyword: keyword,
  178. OwnerID: ctxUser.ID,
  179. OrderBy: orderBy,
  180. Private: showPrivate,
  181. Page: page,
  182. IsProfile: true,
  183. PageSize: setting.UI.User.RepoPagingNum,
  184. })
  185. if err != nil {
  186. ctx.Handle(500, "SearchRepositoryByName", err)
  187. return
  188. }
  189. ctx.Data["Repos"] = repos
  190. ctx.Data["Page"] = paginater.New(int(count), setting.UI.User.RepoPagingNum, page, 5)
  191. ctx.Data["Total"] = count
  192. }
  193. }
  194. ctx.HTML(200, tplProfile)
  195. }
  196. // Followers render user's followers page
  197. func Followers(ctx *context.Context) {
  198. u := GetUserByParams(ctx)
  199. if ctx.Written() {
  200. return
  201. }
  202. ctx.Data["Title"] = u.DisplayName()
  203. ctx.Data["CardsTitle"] = ctx.Tr("user.followers")
  204. ctx.Data["PageIsFollowers"] = true
  205. ctx.Data["Owner"] = u
  206. repo.RenderUserCards(ctx, u.NumFollowers, u.GetFollowers, tplFollowers)
  207. }
  208. // Following render user's followering page
  209. func Following(ctx *context.Context) {
  210. u := GetUserByParams(ctx)
  211. if ctx.Written() {
  212. return
  213. }
  214. ctx.Data["Title"] = u.DisplayName()
  215. ctx.Data["CardsTitle"] = ctx.Tr("user.following")
  216. ctx.Data["PageIsFollowing"] = true
  217. ctx.Data["Owner"] = u
  218. repo.RenderUserCards(ctx, u.NumFollowing, u.GetFollowing, tplFollowers)
  219. }
  220. // Action response for follow/unfollow user request
  221. func Action(ctx *context.Context) {
  222. u := GetUserByParams(ctx)
  223. if ctx.Written() {
  224. return
  225. }
  226. var err error
  227. switch ctx.Params(":action") {
  228. case "follow":
  229. err = models.FollowUser(ctx.User.ID, u.ID)
  230. case "unfollow":
  231. err = models.UnfollowUser(ctx.User.ID, u.ID)
  232. }
  233. if err != nil {
  234. ctx.Handle(500, fmt.Sprintf("Action (%s)", ctx.Params(":action")), err)
  235. return
  236. }
  237. redirectTo := ctx.Query("redirect_to")
  238. if len(redirectTo) == 0 {
  239. redirectTo = u.HomeLink()
  240. }
  241. ctx.Redirect(redirectTo)
  242. }