gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. // Copyright 2021 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package explore
  4. import (
  5. "net/http"
  6. "code.gitea.io/gitea/models/db"
  7. repo_model "code.gitea.io/gitea/models/repo"
  8. "code.gitea.io/gitea/modules/log"
  9. "code.gitea.io/gitea/modules/setting"
  10. "code.gitea.io/gitea/modules/sitemap"
  11. "code.gitea.io/gitea/modules/templates"
  12. "code.gitea.io/gitea/services/context"
  13. )
  14. const (
  15. // tplExploreRepos explore repositories page template
  16. tplExploreRepos templates.TplName = "explore/repos"
  17. relevantReposOnlyParam string = "only_show_relevant"
  18. )
  19. // RepoSearchOptions when calling search repositories
  20. type RepoSearchOptions struct {
  21. OwnerID int64
  22. Private bool
  23. Restricted bool
  24. PageSize int
  25. OnlyShowRelevant bool
  26. TplName templates.TplName
  27. }
  28. // RenderRepoSearch render repositories search page
  29. // This function is also used to render the Admin Repository Management page.
  30. func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
  31. // Sitemap index for sitemap paths
  32. page := int(ctx.PathParamInt64("idx"))
  33. isSitemap := ctx.PathParam("idx") != ""
  34. if page <= 1 {
  35. page = ctx.FormInt("page")
  36. }
  37. if page <= 0 {
  38. page = 1
  39. }
  40. if isSitemap {
  41. opts.PageSize = setting.UI.SitemapPagingNum
  42. }
  43. var (
  44. repos []*repo_model.Repository
  45. count int64
  46. err error
  47. orderBy db.SearchOrderBy
  48. )
  49. sortOrder := ctx.FormString("sort")
  50. if sortOrder == "" {
  51. sortOrder = setting.UI.ExploreDefaultSort
  52. }
  53. if order, ok := repo_model.OrderByFlatMap[sortOrder]; ok {
  54. orderBy = order
  55. } else {
  56. sortOrder = "recentupdate"
  57. orderBy = db.SearchOrderByRecentUpdated
  58. }
  59. ctx.Data["SortType"] = sortOrder
  60. keyword := ctx.FormTrim("q")
  61. ctx.Data["OnlyShowRelevant"] = opts.OnlyShowRelevant
  62. topicOnly := ctx.FormBool("topic")
  63. ctx.Data["TopicOnly"] = topicOnly
  64. language := ctx.FormTrim("language")
  65. ctx.Data["Language"] = language
  66. archived := ctx.FormOptionalBool("archived")
  67. ctx.Data["IsArchived"] = archived
  68. fork := ctx.FormOptionalBool("fork")
  69. ctx.Data["IsFork"] = fork
  70. mirror := ctx.FormOptionalBool("mirror")
  71. ctx.Data["IsMirror"] = mirror
  72. template := ctx.FormOptionalBool("template")
  73. ctx.Data["IsTemplate"] = template
  74. private := ctx.FormOptionalBool("private")
  75. ctx.Data["IsPrivate"] = private
  76. repos, count, err = repo_model.SearchRepository(ctx, repo_model.SearchRepoOptions{
  77. ListOptions: db.ListOptions{
  78. Page: page,
  79. PageSize: opts.PageSize,
  80. },
  81. Actor: ctx.Doer,
  82. OrderBy: orderBy,
  83. Private: opts.Private,
  84. Keyword: keyword,
  85. OwnerID: opts.OwnerID,
  86. AllPublic: true,
  87. AllLimited: true,
  88. TopicOnly: topicOnly,
  89. Language: language,
  90. IncludeDescription: setting.UI.SearchRepoDescription,
  91. OnlyShowRelevant: opts.OnlyShowRelevant,
  92. Archived: archived,
  93. Fork: fork,
  94. Mirror: mirror,
  95. Template: template,
  96. IsPrivate: private,
  97. })
  98. if err != nil {
  99. ctx.ServerError("SearchRepository", err)
  100. return
  101. }
  102. if isSitemap {
  103. m := sitemap.NewSitemap()
  104. for _, item := range repos {
  105. m.Add(sitemap.URL{URL: item.HTMLURL(), LastMod: item.UpdatedUnix.AsTimePtr()})
  106. }
  107. ctx.Resp.Header().Set("Content-Type", "text/xml")
  108. if _, err := m.WriteTo(ctx.Resp); err != nil {
  109. log.Error("Failed writing sitemap: %v", err)
  110. }
  111. return
  112. }
  113. ctx.Data["Keyword"] = keyword
  114. ctx.Data["Total"] = count
  115. ctx.Data["Repos"] = repos
  116. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  117. pager := context.NewPagination(int(count), opts.PageSize, page, 5)
  118. pager.AddParamFromRequest(ctx.Req)
  119. ctx.Data["Page"] = pager
  120. ctx.HTML(http.StatusOK, opts.TplName)
  121. }
  122. // Repos render explore repositories page
  123. func Repos(ctx *context.Context) {
  124. ctx.Data["UsersPageIsDisabled"] = setting.Service.Explore.DisableUsersPage
  125. ctx.Data["OrganizationsPageIsDisabled"] = setting.Service.Explore.DisableOrganizationsPage
  126. ctx.Data["CodePageIsDisabled"] = setting.Service.Explore.DisableCodePage
  127. ctx.Data["Title"] = ctx.Tr("explore")
  128. ctx.Data["PageIsExplore"] = true
  129. ctx.Data["ShowRepoOwnerOnList"] = true
  130. ctx.Data["PageIsExploreRepositories"] = true
  131. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  132. var ownerID int64
  133. if ctx.Doer != nil && !ctx.Doer.IsAdmin {
  134. ownerID = ctx.Doer.ID
  135. }
  136. onlyShowRelevant := setting.UI.OnlyShowRelevantRepos
  137. _ = ctx.Req.ParseForm() // parse the form first, to prepare the ctx.Req.Form field
  138. if len(ctx.Req.Form[relevantReposOnlyParam]) != 0 {
  139. onlyShowRelevant = ctx.FormBool(relevantReposOnlyParam)
  140. }
  141. RenderRepoSearch(ctx, &RepoSearchOptions{
  142. PageSize: setting.UI.ExplorePagingNum,
  143. OwnerID: ownerID,
  144. Private: ctx.Doer != nil,
  145. TplName: tplExploreRepos,
  146. OnlyShowRelevant: onlyShowRelevant,
  147. })
  148. }