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.

profile.go 6.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. // Copyright 2015 The Gogs Authors. All rights reserved.
  2. // Copyright 2019 The Gitea Authors. All rights reserved.
  3. // Use of this source code is governed by a MIT-style
  4. // license that can be found in the LICENSE file.
  5. package user
  6. import (
  7. "fmt"
  8. "path"
  9. "strings"
  10. "code.gitea.io/gitea/models"
  11. "code.gitea.io/gitea/modules/context"
  12. "code.gitea.io/gitea/modules/setting"
  13. "code.gitea.io/gitea/modules/util"
  14. "code.gitea.io/gitea/routers/org"
  15. )
  16. // GetUserByName get user by name
  17. func GetUserByName(ctx *context.Context, name string) *models.User {
  18. user, err := models.GetUserByName(name)
  19. if err != nil {
  20. if models.IsErrUserNotExist(err) {
  21. ctx.NotFound("GetUserByName", nil)
  22. } else {
  23. ctx.ServerError("GetUserByName", err)
  24. }
  25. return nil
  26. }
  27. return user
  28. }
  29. // GetUserByParams returns user whose name is presented in URL paramenter.
  30. func GetUserByParams(ctx *context.Context) *models.User {
  31. return GetUserByName(ctx, ctx.Params(":username"))
  32. }
  33. // Profile render user's profile page
  34. func Profile(ctx *context.Context) {
  35. uname := ctx.Params(":username")
  36. // Special handle for FireFox requests favicon.ico.
  37. if uname == "favicon.ico" {
  38. ctx.ServeFile(path.Join(setting.StaticRootPath, "public/img/favicon.png"))
  39. return
  40. } else if strings.HasSuffix(uname, ".png") {
  41. ctx.Error(404)
  42. return
  43. }
  44. isShowKeys := false
  45. if strings.HasSuffix(uname, ".keys") {
  46. isShowKeys = true
  47. uname = strings.TrimSuffix(uname, ".keys")
  48. }
  49. isShowGPG := false
  50. if strings.HasSuffix(uname, ".gpg") {
  51. isShowGPG = true
  52. uname = strings.TrimSuffix(uname, ".gpg")
  53. }
  54. ctxUser := GetUserByName(ctx, uname)
  55. if ctx.Written() {
  56. return
  57. }
  58. // Show SSH keys.
  59. if isShowKeys {
  60. ShowSSHKeys(ctx, ctxUser.ID)
  61. return
  62. }
  63. // Show GPG keys.
  64. if isShowGPG {
  65. ShowGPGKeys(ctx, ctxUser.ID)
  66. return
  67. }
  68. if ctxUser.IsOrganization() {
  69. org.Home(ctx)
  70. return
  71. }
  72. // Show OpenID URIs
  73. openIDs, err := models.GetUserOpenIDs(ctxUser.ID)
  74. if err != nil {
  75. ctx.ServerError("GetUserOpenIDs", err)
  76. return
  77. }
  78. ctx.Data["Title"] = ctxUser.DisplayName()
  79. ctx.Data["PageIsUserProfile"] = true
  80. ctx.Data["Owner"] = ctxUser
  81. ctx.Data["OpenIDs"] = openIDs
  82. ctx.Data["EnableHeatmap"] = setting.Service.EnableUserHeatmap
  83. ctx.Data["HeatmapUser"] = ctxUser.Name
  84. showPrivate := ctx.IsSigned && (ctx.User.IsAdmin || ctx.User.ID == ctxUser.ID)
  85. orgs, err := models.GetOrgsByUserID(ctxUser.ID, showPrivate)
  86. if err != nil {
  87. ctx.ServerError("GetOrgsByUserIDDesc", err)
  88. return
  89. }
  90. ctx.Data["Orgs"] = orgs
  91. ctx.Data["HasOrgsVisible"] = models.HasOrgsVisible(orgs, ctx.User)
  92. tab := ctx.Query("tab")
  93. ctx.Data["TabName"] = tab
  94. page := ctx.QueryInt("page")
  95. if page <= 0 {
  96. page = 1
  97. }
  98. topicOnly := ctx.QueryBool("topic")
  99. var (
  100. repos []*models.Repository
  101. count int64
  102. total int
  103. orderBy models.SearchOrderBy
  104. )
  105. ctx.Data["SortType"] = ctx.Query("sort")
  106. switch ctx.Query("sort") {
  107. case "newest":
  108. orderBy = models.SearchOrderByNewest
  109. case "oldest":
  110. orderBy = models.SearchOrderByOldest
  111. case "recentupdate":
  112. orderBy = models.SearchOrderByRecentUpdated
  113. case "leastupdate":
  114. orderBy = models.SearchOrderByLeastUpdated
  115. case "reversealphabetically":
  116. orderBy = models.SearchOrderByAlphabeticallyReverse
  117. case "alphabetically":
  118. orderBy = models.SearchOrderByAlphabetically
  119. case "moststars":
  120. orderBy = models.SearchOrderByStarsReverse
  121. case "feweststars":
  122. orderBy = models.SearchOrderByStars
  123. case "mostforks":
  124. orderBy = models.SearchOrderByForksReverse
  125. case "fewestforks":
  126. orderBy = models.SearchOrderByForks
  127. default:
  128. ctx.Data["SortType"] = "recentupdate"
  129. orderBy = models.SearchOrderByRecentUpdated
  130. }
  131. requestingUserID := int64(0)
  132. if ctx.User != nil {
  133. requestingUserID = ctx.User.ID
  134. }
  135. keyword := strings.Trim(ctx.Query("q"), " ")
  136. ctx.Data["Keyword"] = keyword
  137. switch tab {
  138. case "followers":
  139. items, err := ctxUser.GetFollowers(page)
  140. if err != nil {
  141. ctx.ServerError("GetFollowers", err)
  142. return
  143. }
  144. ctx.Data["Cards"] = items
  145. total = ctxUser.NumFollowers
  146. case "following":
  147. items, err := ctxUser.GetFollowing(page)
  148. if err != nil {
  149. ctx.ServerError("GetFollowing", err)
  150. return
  151. }
  152. ctx.Data["Cards"] = items
  153. total = ctxUser.NumFollowing
  154. case "activity":
  155. retrieveFeeds(ctx, models.GetFeedsOptions{RequestedUser: ctxUser,
  156. RequestingUserID: requestingUserID,
  157. IncludePrivate: showPrivate,
  158. OnlyPerformedBy: true,
  159. IncludeDeleted: false,
  160. })
  161. if ctx.Written() {
  162. return
  163. }
  164. case "stars":
  165. ctx.Data["PageIsProfileStarList"] = true
  166. repos, count, err = models.SearchRepository(&models.SearchRepoOptions{
  167. Keyword: keyword,
  168. OrderBy: orderBy,
  169. Private: ctx.IsSigned,
  170. UserIsAdmin: ctx.IsUserSiteAdmin(),
  171. UserID: ctx.Data["SignedUserID"].(int64),
  172. Page: page,
  173. PageSize: setting.UI.User.RepoPagingNum,
  174. StarredByID: ctxUser.ID,
  175. Collaborate: util.OptionalBoolFalse,
  176. TopicOnly: topicOnly,
  177. IncludeDescription: setting.UI.SearchRepoDescription,
  178. })
  179. if err != nil {
  180. ctx.ServerError("SearchRepository", err)
  181. return
  182. }
  183. total = int(count)
  184. default:
  185. repos, count, err = models.SearchRepository(&models.SearchRepoOptions{
  186. Keyword: keyword,
  187. OwnerID: ctxUser.ID,
  188. OrderBy: orderBy,
  189. Private: ctx.IsSigned,
  190. UserIsAdmin: ctx.IsUserSiteAdmin(),
  191. UserID: ctx.Data["SignedUserID"].(int64),
  192. Page: page,
  193. IsProfile: true,
  194. PageSize: setting.UI.User.RepoPagingNum,
  195. Collaborate: util.OptionalBoolFalse,
  196. TopicOnly: topicOnly,
  197. IncludeDescription: setting.UI.SearchRepoDescription,
  198. })
  199. if err != nil {
  200. ctx.ServerError("SearchRepository", err)
  201. return
  202. }
  203. total = int(count)
  204. }
  205. ctx.Data["Repos"] = repos
  206. ctx.Data["Total"] = total
  207. pager := context.NewPagination(total, setting.UI.User.RepoPagingNum, page, 5)
  208. pager.SetDefaultParams(ctx)
  209. ctx.Data["Page"] = pager
  210. ctx.Data["ShowUserEmail"] = len(ctxUser.Email) > 0 && ctx.IsSigned && (!ctxUser.KeepEmailPrivate || ctxUser.ID == ctx.User.ID)
  211. ctx.HTML(200, tplProfile)
  212. }
  213. // Action response for follow/unfollow user request
  214. func Action(ctx *context.Context) {
  215. u := GetUserByParams(ctx)
  216. if ctx.Written() {
  217. return
  218. }
  219. var err error
  220. switch ctx.Params(":action") {
  221. case "follow":
  222. err = models.FollowUser(ctx.User.ID, u.ID)
  223. case "unfollow":
  224. err = models.UnfollowUser(ctx.User.ID, u.ID)
  225. }
  226. if err != nil {
  227. ctx.ServerError(fmt.Sprintf("Action (%s)", ctx.Params(":action")), err)
  228. return
  229. }
  230. ctx.RedirectToFirst(ctx.Query("redirect_to"), u.HomeLink())
  231. }