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.

repo.go 5.5KB

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