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