gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. // Copyright 2019 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package org
  4. import (
  5. "net/http"
  6. "path"
  7. "strings"
  8. "code.gitea.io/gitea/models/db"
  9. "code.gitea.io/gitea/models/organization"
  10. "code.gitea.io/gitea/models/renderhelper"
  11. repo_model "code.gitea.io/gitea/models/repo"
  12. "code.gitea.io/gitea/modules/git"
  13. "code.gitea.io/gitea/modules/log"
  14. "code.gitea.io/gitea/modules/markup/markdown"
  15. "code.gitea.io/gitea/modules/setting"
  16. "code.gitea.io/gitea/modules/templates"
  17. "code.gitea.io/gitea/modules/util"
  18. shared_user "code.gitea.io/gitea/routers/web/shared/user"
  19. "code.gitea.io/gitea/services/context"
  20. )
  21. const tplOrgHome templates.TplName = "org/home"
  22. // Home show organization home page
  23. func Home(ctx *context.Context) {
  24. uname := ctx.PathParam("username")
  25. if strings.HasSuffix(uname, ".keys") || strings.HasSuffix(uname, ".gpg") {
  26. ctx.NotFound(nil)
  27. return
  28. }
  29. ctx.SetPathParam("org", uname)
  30. context.OrgAssignment(context.OrgAssignmentOptions{})(ctx)
  31. if ctx.Written() {
  32. return
  33. }
  34. home(ctx, false)
  35. }
  36. func Repositories(ctx *context.Context) {
  37. home(ctx, true)
  38. }
  39. func home(ctx *context.Context, viewRepositories bool) {
  40. org := ctx.Org.Organization
  41. ctx.Data["PageIsUserProfile"] = true
  42. ctx.Data["Title"] = org.DisplayName()
  43. var orderBy db.SearchOrderBy
  44. sortOrder := ctx.FormString("sort")
  45. if _, ok := repo_model.OrderByFlatMap[sortOrder]; !ok {
  46. sortOrder = setting.UI.ExploreDefaultSort // TODO: add new default sort order for org home?
  47. }
  48. ctx.Data["SortType"] = sortOrder
  49. orderBy = repo_model.OrderByFlatMap[sortOrder]
  50. keyword := ctx.FormTrim("q")
  51. ctx.Data["Keyword"] = keyword
  52. language := ctx.FormTrim("language")
  53. ctx.Data["Language"] = language
  54. page := ctx.FormInt("page")
  55. if page <= 0 {
  56. page = 1
  57. }
  58. archived := ctx.FormOptionalBool("archived")
  59. ctx.Data["IsArchived"] = archived
  60. fork := ctx.FormOptionalBool("fork")
  61. ctx.Data["IsFork"] = fork
  62. mirror := ctx.FormOptionalBool("mirror")
  63. ctx.Data["IsMirror"] = mirror
  64. template := ctx.FormOptionalBool("template")
  65. ctx.Data["IsTemplate"] = template
  66. private := ctx.FormOptionalBool("private")
  67. ctx.Data["IsPrivate"] = private
  68. opts := &organization.FindOrgMembersOpts{
  69. Doer: ctx.Doer,
  70. OrgID: org.ID,
  71. IsDoerMember: ctx.Org.IsMember,
  72. ListOptions: db.ListOptions{Page: 1, PageSize: 25},
  73. }
  74. members, _, err := organization.FindOrgMembers(ctx, opts)
  75. if err != nil {
  76. ctx.ServerError("FindOrgMembers", err)
  77. return
  78. }
  79. ctx.Data["Members"] = members
  80. ctx.Data["Teams"] = ctx.Org.Teams
  81. ctx.Data["DisableNewPullMirrors"] = setting.Mirror.DisableNewPull
  82. ctx.Data["ShowMemberAndTeamTab"] = ctx.Org.IsMember || len(members) > 0
  83. prepareResult, err := shared_user.RenderUserOrgHeader(ctx)
  84. if err != nil {
  85. ctx.ServerError("RenderUserOrgHeader", err)
  86. return
  87. }
  88. // if no profile readme, it still means "view repositories"
  89. isViewOverview := !viewRepositories && prepareOrgProfileReadme(ctx, prepareResult)
  90. ctx.Data["PageIsViewRepositories"] = !isViewOverview
  91. ctx.Data["PageIsViewOverview"] = isViewOverview
  92. ctx.Data["ShowOrgProfileReadmeSelector"] = isViewOverview && prepareResult.ProfilePublicReadmeBlob != nil && prepareResult.ProfilePrivateReadmeBlob != nil
  93. repos, count, err := repo_model.SearchRepository(ctx, repo_model.SearchRepoOptions{
  94. ListOptions: db.ListOptions{
  95. PageSize: setting.UI.User.RepoPagingNum,
  96. Page: page,
  97. },
  98. Keyword: keyword,
  99. OwnerID: org.ID,
  100. OrderBy: orderBy,
  101. Private: ctx.IsSigned,
  102. Actor: ctx.Doer,
  103. Language: language,
  104. IncludeDescription: setting.UI.SearchRepoDescription,
  105. Archived: archived,
  106. Fork: fork,
  107. Mirror: mirror,
  108. Template: template,
  109. IsPrivate: private,
  110. })
  111. if err != nil {
  112. ctx.ServerError("SearchRepository", err)
  113. return
  114. }
  115. ctx.Data["Repos"] = repos
  116. ctx.Data["Total"] = count
  117. pager := context.NewPagination(int(count), setting.UI.User.RepoPagingNum, page, 5)
  118. pager.AddParamFromRequest(ctx.Req)
  119. ctx.Data["Page"] = pager
  120. ctx.HTML(http.StatusOK, tplOrgHome)
  121. }
  122. func prepareOrgProfileReadme(ctx *context.Context, prepareResult *shared_user.PrepareOwnerHeaderResult) bool {
  123. viewAs := ctx.FormString("view_as", util.Iif(ctx.Org.IsMember, "member", "public"))
  124. viewAsMember := viewAs == "member"
  125. var profileRepo *repo_model.Repository
  126. var readmeBlob *git.Blob
  127. if viewAsMember {
  128. if prepareResult.ProfilePrivateReadmeBlob != nil {
  129. profileRepo, readmeBlob = prepareResult.ProfilePrivateRepo, prepareResult.ProfilePrivateReadmeBlob
  130. } else {
  131. profileRepo, readmeBlob = prepareResult.ProfilePublicRepo, prepareResult.ProfilePublicReadmeBlob
  132. viewAsMember = false
  133. }
  134. } else {
  135. if prepareResult.ProfilePublicReadmeBlob != nil {
  136. profileRepo, readmeBlob = prepareResult.ProfilePublicRepo, prepareResult.ProfilePublicReadmeBlob
  137. } else {
  138. profileRepo, readmeBlob = prepareResult.ProfilePrivateRepo, prepareResult.ProfilePrivateReadmeBlob
  139. viewAsMember = true
  140. }
  141. }
  142. if readmeBlob == nil {
  143. return false
  144. }
  145. readmeBytes, err := readmeBlob.GetBlobContent(setting.UI.MaxDisplayFileSize)
  146. if err != nil {
  147. log.Error("failed to GetBlobContent for profile %q (view as %q) readme: %v", profileRepo.FullName(), viewAs, err)
  148. return false
  149. }
  150. rctx := renderhelper.NewRenderContextRepoFile(ctx, profileRepo, renderhelper.RepoFileOptions{
  151. CurrentRefPath: path.Join("branch", util.PathEscapeSegments(profileRepo.DefaultBranch)),
  152. })
  153. ctx.Data["ProfileReadmeContent"], err = markdown.RenderString(rctx, readmeBytes)
  154. if err != nil {
  155. log.Error("failed to GetBlobContent for profile %q (view as %q) readme: %v", profileRepo.FullName(), viewAs, err)
  156. return false
  157. }
  158. ctx.Data["IsViewingOrgAsMember"] = viewAsMember
  159. return true
  160. }