Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

profile.go 7.2KB

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