diff options
Diffstat (limited to 'routers/web/user/profile.go')
-rw-r--r-- | routers/web/user/profile.go | 329 |
1 files changed, 329 insertions, 0 deletions
diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go new file mode 100644 index 0000000000..e66820e131 --- /dev/null +++ b/routers/web/user/profile.go @@ -0,0 +1,329 @@ +// Copyright 2015 The Gogs Authors. All rights reserved. +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package user + +import ( + "fmt" + "net/http" + "path" + "strings" + + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/markup" + "code.gitea.io/gitea/modules/markup/markdown" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/routers/web/org" +) + +// GetUserByName get user by name +func GetUserByName(ctx *context.Context, name string) *models.User { + user, err := models.GetUserByName(name) + if err != nil { + if models.IsErrUserNotExist(err) { + if redirectUserID, err := models.LookupUserRedirect(name); err == nil { + context.RedirectToUser(ctx, name, redirectUserID) + } else { + ctx.NotFound("GetUserByName", err) + } + } else { + ctx.ServerError("GetUserByName", err) + } + return nil + } + return user +} + +// GetUserByParams returns user whose name is presented in URL paramenter. +func GetUserByParams(ctx *context.Context) *models.User { + return GetUserByName(ctx, ctx.Params(":username")) +} + +// Profile render user's profile page +func Profile(ctx *context.Context) { + uname := ctx.Params(":username") + + // Special handle for FireFox requests favicon.ico. + if uname == "favicon.ico" { + ctx.ServeFile(path.Join(setting.StaticRootPath, "public/img/favicon.png")) + return + } + + if strings.HasSuffix(uname, ".png") { + ctx.Error(http.StatusNotFound) + return + } + + isShowKeys := false + if strings.HasSuffix(uname, ".keys") { + isShowKeys = true + uname = strings.TrimSuffix(uname, ".keys") + } + + isShowGPG := false + if strings.HasSuffix(uname, ".gpg") { + isShowGPG = true + uname = strings.TrimSuffix(uname, ".gpg") + } + + ctxUser := GetUserByName(ctx, uname) + if ctx.Written() { + return + } + + // Show SSH keys. + if isShowKeys { + ShowSSHKeys(ctx, ctxUser.ID) + return + } + + // Show GPG keys. + if isShowGPG { + ShowGPGKeys(ctx, ctxUser.ID) + return + } + + if ctxUser.IsOrganization() { + org.Home(ctx) + return + } + + // Show OpenID URIs + openIDs, err := models.GetUserOpenIDs(ctxUser.ID) + if err != nil { + ctx.ServerError("GetUserOpenIDs", err) + return + } + + ctx.Data["Title"] = ctxUser.DisplayName() + ctx.Data["PageIsUserProfile"] = true + ctx.Data["Owner"] = ctxUser + ctx.Data["OpenIDs"] = openIDs + + if setting.Service.EnableUserHeatmap { + data, err := models.GetUserHeatmapDataByUser(ctxUser, ctx.User) + if err != nil { + ctx.ServerError("GetUserHeatmapDataByUser", err) + return + } + ctx.Data["HeatmapData"] = data + } + + if len(ctxUser.Description) != 0 { + content, err := markdown.RenderString(&markup.RenderContext{ + URLPrefix: ctx.Repo.RepoLink, + Metas: map[string]string{"mode": "document"}, + }, ctxUser.Description) + if err != nil { + ctx.ServerError("RenderString", err) + return + } + ctx.Data["RenderedDescription"] = content + } + + showPrivate := ctx.IsSigned && (ctx.User.IsAdmin || ctx.User.ID == ctxUser.ID) + + orgs, err := models.GetOrgsByUserID(ctxUser.ID, showPrivate) + if err != nil { + ctx.ServerError("GetOrgsByUserIDDesc", err) + return + } + + ctx.Data["Orgs"] = orgs + ctx.Data["HasOrgsVisible"] = models.HasOrgsVisible(orgs, ctx.User) + + tab := ctx.Query("tab") + ctx.Data["TabName"] = tab + + page := ctx.QueryInt("page") + if page <= 0 { + page = 1 + } + + topicOnly := ctx.QueryBool("topic") + + var ( + repos []*models.Repository + count int64 + total int + orderBy models.SearchOrderBy + ) + + ctx.Data["SortType"] = ctx.Query("sort") + switch ctx.Query("sort") { + case "newest": + orderBy = models.SearchOrderByNewest + case "oldest": + orderBy = models.SearchOrderByOldest + case "recentupdate": + orderBy = models.SearchOrderByRecentUpdated + case "leastupdate": + orderBy = models.SearchOrderByLeastUpdated + case "reversealphabetically": + orderBy = models.SearchOrderByAlphabeticallyReverse + case "alphabetically": + orderBy = models.SearchOrderByAlphabetically + case "moststars": + orderBy = models.SearchOrderByStarsReverse + case "feweststars": + orderBy = models.SearchOrderByStars + case "mostforks": + orderBy = models.SearchOrderByForksReverse + case "fewestforks": + orderBy = models.SearchOrderByForks + default: + ctx.Data["SortType"] = "recentupdate" + orderBy = models.SearchOrderByRecentUpdated + } + + keyword := strings.Trim(ctx.Query("q"), " ") + ctx.Data["Keyword"] = keyword + switch tab { + case "followers": + items, err := ctxUser.GetFollowers(models.ListOptions{ + PageSize: setting.UI.User.RepoPagingNum, + Page: page, + }) + if err != nil { + ctx.ServerError("GetFollowers", err) + return + } + ctx.Data["Cards"] = items + + total = ctxUser.NumFollowers + case "following": + items, err := ctxUser.GetFollowing(models.ListOptions{ + PageSize: setting.UI.User.RepoPagingNum, + Page: page, + }) + if err != nil { + ctx.ServerError("GetFollowing", err) + return + } + ctx.Data["Cards"] = items + + total = ctxUser.NumFollowing + case "activity": + retrieveFeeds(ctx, models.GetFeedsOptions{RequestedUser: ctxUser, + Actor: ctx.User, + IncludePrivate: showPrivate, + OnlyPerformedBy: true, + IncludeDeleted: false, + Date: ctx.Query("date"), + }) + if ctx.Written() { + return + } + case "stars": + ctx.Data["PageIsProfileStarList"] = true + repos, count, err = models.SearchRepository(&models.SearchRepoOptions{ + ListOptions: models.ListOptions{ + PageSize: setting.UI.User.RepoPagingNum, + Page: page, + }, + Actor: ctx.User, + Keyword: keyword, + OrderBy: orderBy, + Private: ctx.IsSigned, + StarredByID: ctxUser.ID, + Collaborate: util.OptionalBoolFalse, + TopicOnly: topicOnly, + IncludeDescription: setting.UI.SearchRepoDescription, + }) + if err != nil { + ctx.ServerError("SearchRepository", err) + return + } + + total = int(count) + case "projects": + ctx.Data["OpenProjects"], _, err = models.GetProjects(models.ProjectSearchOptions{ + Page: -1, + IsClosed: util.OptionalBoolFalse, + Type: models.ProjectTypeIndividual, + }) + if err != nil { + ctx.ServerError("GetProjects", err) + return + } + case "watching": + repos, count, err = models.SearchRepository(&models.SearchRepoOptions{ + ListOptions: models.ListOptions{ + PageSize: setting.UI.User.RepoPagingNum, + Page: page, + }, + Actor: ctx.User, + Keyword: keyword, + OrderBy: orderBy, + Private: ctx.IsSigned, + WatchedByID: ctxUser.ID, + Collaborate: util.OptionalBoolFalse, + TopicOnly: topicOnly, + IncludeDescription: setting.UI.SearchRepoDescription, + }) + if err != nil { + ctx.ServerError("SearchRepository", err) + return + } + + total = int(count) + default: + repos, count, err = models.SearchRepository(&models.SearchRepoOptions{ + ListOptions: models.ListOptions{ + PageSize: setting.UI.User.RepoPagingNum, + Page: page, + }, + Actor: ctx.User, + Keyword: keyword, + OwnerID: ctxUser.ID, + OrderBy: orderBy, + Private: ctx.IsSigned, + Collaborate: util.OptionalBoolFalse, + TopicOnly: topicOnly, + IncludeDescription: setting.UI.SearchRepoDescription, + }) + if err != nil { + ctx.ServerError("SearchRepository", err) + return + } + + total = int(count) + } + ctx.Data["Repos"] = repos + ctx.Data["Total"] = total + + pager := context.NewPagination(total, setting.UI.User.RepoPagingNum, page, 5) + pager.SetDefaultParams(ctx) + ctx.Data["Page"] = pager + + ctx.Data["ShowUserEmail"] = len(ctxUser.Email) > 0 && ctx.IsSigned && (!ctxUser.KeepEmailPrivate || ctxUser.ID == ctx.User.ID) + + ctx.HTML(http.StatusOK, tplProfile) +} + +// Action response for follow/unfollow user request +func Action(ctx *context.Context) { + u := GetUserByParams(ctx) + if ctx.Written() { + return + } + + var err error + switch ctx.Params(":action") { + case "follow": + err = models.FollowUser(ctx.User.ID, u.ID) + case "unfollow": + err = models.UnfollowUser(ctx.User.ID, u.ID) + } + + if err != nil { + ctx.ServerError(fmt.Sprintf("Action (%s)", ctx.Params(":action")), err) + return + } + + ctx.RedirectToFirst(ctx.Query("redirect_to"), u.HomeLink()) +} |