You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

home.go 20 kB

11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
3 years ago
4 years ago
4 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
Restricted users (#6274) * Restricted users (#4334): initial implementation * Add User.IsRestricted & UI to edit it * Pass user object instead of user id to places where IsRestricted flag matters * Restricted users: maintain access rows for all referenced repos (incl public) * Take logged in user & IsRestricted flag into account in org/repo listings, searches and accesses * Add basic repo access tests for restricted users Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Mention restricted users in the faq Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Revert unnecessary change `.isUserPartOfOrg` -> `.IsUserPartOfOrg` Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Remove unnecessary `org.IsOrganization()` call Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Revert to an `int64` keyed `accessMap` * Add type `userAccess` * Add convenience func updateUserAccess() * Turn accessMap into a `map[int64]userAccess` Signed-off-by: Manush Dodunekov <manush@stendahls.se> * or even better: `map[int64]*userAccess` * updateUserAccess(): use tighter syntax as suggested by lafriks * even tighter * Avoid extra loop * Don't disclose limited orgs to unauthenticated users * Don't assume block only applies to orgs * Use an array of `VisibleType` for filtering * fix yet another thinko * Ok - no need for u * Revert "Ok - no need for u" This reverts commit 5c3e886aabd5acd997a3b35687d322439732c200. Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com> Co-authored-by: Lauris BH <lauris@nix.lv>
5 years ago
3 years ago
3 years ago
3 years ago
3 years ago
API add/generalize pagination (#9452) * paginate results * fixed deadlock * prevented breaking change * updated swagger * go fmt * fixed find topic * go mod tidy * go mod vendor with go1.13.5 * fixed repo find topics * fixed unit test * added Limit method to Engine struct; use engine variable when provided; fixed gitignore * use ItemsPerPage for default pagesize; fix GetWatchers, getOrgUsersByOrgID and GetStargazers; fix GetAllCommits headers; reverted some changed behaviors * set Page value on Home route * improved memory allocations * fixed response headers * removed logfiles * fixed import order * import order * improved swagger * added function to get models.ListOptions from context * removed pagesize diff on unit test * fixed imports * removed unnecessary struct field * fixed go fmt * scoped PR * code improvements * code improvements * go mod tidy * fixed import order * fixed commit statuses session * fixed files headers * fixed headers; added pagination for notifications * go mod tidy * go fmt * removed Private from user search options; added setting.UI.IssuePagingNum as default valeu on repo's issues list * Apply suggestions from code review Co-Authored-By: 6543 <6543@obermui.de> Co-Authored-By: zeripath <art27@cantab.net> * fixed build error * CI.restart() * fixed merge conflicts resolve * fixed conflicts resolve * improved FindTrackedTimesOptions.ToOptions() method * added backwards compatibility on ListReleases request; fixed issue tracked time ToSession * fixed build error; fixed swagger template * fixed swagger template * fixed ListReleases backwards compatibility * added page to user search route Co-authored-by: techknowlogick <matti@mdranta.net> Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: zeripath <art27@cantab.net>
5 years ago
Restricted users (#6274) * Restricted users (#4334): initial implementation * Add User.IsRestricted & UI to edit it * Pass user object instead of user id to places where IsRestricted flag matters * Restricted users: maintain access rows for all referenced repos (incl public) * Take logged in user & IsRestricted flag into account in org/repo listings, searches and accesses * Add basic repo access tests for restricted users Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Mention restricted users in the faq Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Revert unnecessary change `.isUserPartOfOrg` -> `.IsUserPartOfOrg` Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Remove unnecessary `org.IsOrganization()` call Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Revert to an `int64` keyed `accessMap` * Add type `userAccess` * Add convenience func updateUserAccess() * Turn accessMap into a `map[int64]userAccess` Signed-off-by: Manush Dodunekov <manush@stendahls.se> * or even better: `map[int64]*userAccess` * updateUserAccess(): use tighter syntax as suggested by lafriks * even tighter * Avoid extra loop * Don't disclose limited orgs to unauthenticated users * Don't assume block only applies to orgs * Use an array of `VisibleType` for filtering * fix yet another thinko * Ok - no need for u * Revert "Ok - no need for u" This reverts commit 5c3e886aabd5acd997a3b35687d322439732c200. Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com> Co-authored-by: Lauris BH <lauris@nix.lv>
5 years ago
10 years ago
3 years ago
10 years ago
10 years ago
3 years ago
3 years ago
API add/generalize pagination (#9452) * paginate results * fixed deadlock * prevented breaking change * updated swagger * go fmt * fixed find topic * go mod tidy * go mod vendor with go1.13.5 * fixed repo find topics * fixed unit test * added Limit method to Engine struct; use engine variable when provided; fixed gitignore * use ItemsPerPage for default pagesize; fix GetWatchers, getOrgUsersByOrgID and GetStargazers; fix GetAllCommits headers; reverted some changed behaviors * set Page value on Home route * improved memory allocations * fixed response headers * removed logfiles * fixed import order * import order * improved swagger * added function to get models.ListOptions from context * removed pagesize diff on unit test * fixed imports * removed unnecessary struct field * fixed go fmt * scoped PR * code improvements * code improvements * go mod tidy * fixed import order * fixed commit statuses session * fixed files headers * fixed headers; added pagination for notifications * go mod tidy * go fmt * removed Private from user search options; added setting.UI.IssuePagingNum as default valeu on repo's issues list * Apply suggestions from code review Co-Authored-By: 6543 <6543@obermui.de> Co-Authored-By: zeripath <art27@cantab.net> * fixed build error * CI.restart() * fixed merge conflicts resolve * fixed conflicts resolve * improved FindTrackedTimesOptions.ToOptions() method * added backwards compatibility on ListReleases request; fixed issue tracked time ToSession * fixed build error; fixed swagger template * fixed swagger template * fixed ListReleases backwards compatibility * added page to user search route Co-authored-by: techknowlogick <matti@mdranta.net> Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: zeripath <art27@cantab.net>
5 years ago
10 years ago
Restricted users (#6274) * Restricted users (#4334): initial implementation * Add User.IsRestricted & UI to edit it * Pass user object instead of user id to places where IsRestricted flag matters * Restricted users: maintain access rows for all referenced repos (incl public) * Take logged in user & IsRestricted flag into account in org/repo listings, searches and accesses * Add basic repo access tests for restricted users Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Mention restricted users in the faq Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Revert unnecessary change `.isUserPartOfOrg` -> `.IsUserPartOfOrg` Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Remove unnecessary `org.IsOrganization()` call Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Revert to an `int64` keyed `accessMap` * Add type `userAccess` * Add convenience func updateUserAccess() * Turn accessMap into a `map[int64]userAccess` Signed-off-by: Manush Dodunekov <manush@stendahls.se> * or even better: `map[int64]*userAccess` * updateUserAccess(): use tighter syntax as suggested by lafriks * even tighter * Avoid extra loop * Don't disclose limited orgs to unauthenticated users * Don't assume block only applies to orgs * Use an array of `VisibleType` for filtering * fix yet another thinko * Ok - no need for u * Revert "Ok - no need for u" This reverts commit 5c3e886aabd5acd997a3b35687d322439732c200. Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com> Co-authored-by: Lauris BH <lauris@nix.lv>
5 years ago
Restricted users (#6274) * Restricted users (#4334): initial implementation * Add User.IsRestricted & UI to edit it * Pass user object instead of user id to places where IsRestricted flag matters * Restricted users: maintain access rows for all referenced repos (incl public) * Take logged in user & IsRestricted flag into account in org/repo listings, searches and accesses * Add basic repo access tests for restricted users Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Mention restricted users in the faq Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Revert unnecessary change `.isUserPartOfOrg` -> `.IsUserPartOfOrg` Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Remove unnecessary `org.IsOrganization()` call Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Revert to an `int64` keyed `accessMap` * Add type `userAccess` * Add convenience func updateUserAccess() * Turn accessMap into a `map[int64]userAccess` Signed-off-by: Manush Dodunekov <manush@stendahls.se> * or even better: `map[int64]*userAccess` * updateUserAccess(): use tighter syntax as suggested by lafriks * even tighter * Avoid extra loop * Don't disclose limited orgs to unauthenticated users * Don't assume block only applies to orgs * Use an array of `VisibleType` for filtering * fix yet another thinko * Ok - no need for u * Revert "Ok - no need for u" This reverts commit 5c3e886aabd5acd997a3b35687d322439732c200. Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com> Co-authored-by: Lauris BH <lauris@nix.lv>
5 years ago
API add/generalize pagination (#9452) * paginate results * fixed deadlock * prevented breaking change * updated swagger * go fmt * fixed find topic * go mod tidy * go mod vendor with go1.13.5 * fixed repo find topics * fixed unit test * added Limit method to Engine struct; use engine variable when provided; fixed gitignore * use ItemsPerPage for default pagesize; fix GetWatchers, getOrgUsersByOrgID and GetStargazers; fix GetAllCommits headers; reverted some changed behaviors * set Page value on Home route * improved memory allocations * fixed response headers * removed logfiles * fixed import order * import order * improved swagger * added function to get models.ListOptions from context * removed pagesize diff on unit test * fixed imports * removed unnecessary struct field * fixed go fmt * scoped PR * code improvements * code improvements * go mod tidy * fixed import order * fixed commit statuses session * fixed files headers * fixed headers; added pagination for notifications * go mod tidy * go fmt * removed Private from user search options; added setting.UI.IssuePagingNum as default valeu on repo's issues list * Apply suggestions from code review Co-Authored-By: 6543 <6543@obermui.de> Co-Authored-By: zeripath <art27@cantab.net> * fixed build error * CI.restart() * fixed merge conflicts resolve * fixed conflicts resolve * improved FindTrackedTimesOptions.ToOptions() method * added backwards compatibility on ListReleases request; fixed issue tracked time ToSession * fixed build error; fixed swagger template * fixed swagger template * fixed ListReleases backwards compatibility * added page to user search route Co-authored-by: techknowlogick <matti@mdranta.net> Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: zeripath <art27@cantab.net>
5 years ago
Restricted users (#6274) * Restricted users (#4334): initial implementation * Add User.IsRestricted & UI to edit it * Pass user object instead of user id to places where IsRestricted flag matters * Restricted users: maintain access rows for all referenced repos (incl public) * Take logged in user & IsRestricted flag into account in org/repo listings, searches and accesses * Add basic repo access tests for restricted users Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Mention restricted users in the faq Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Revert unnecessary change `.isUserPartOfOrg` -> `.IsUserPartOfOrg` Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Remove unnecessary `org.IsOrganization()` call Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Revert to an `int64` keyed `accessMap` * Add type `userAccess` * Add convenience func updateUserAccess() * Turn accessMap into a `map[int64]userAccess` Signed-off-by: Manush Dodunekov <manush@stendahls.se> * or even better: `map[int64]*userAccess` * updateUserAccess(): use tighter syntax as suggested by lafriks * even tighter * Avoid extra loop * Don't disclose limited orgs to unauthenticated users * Don't assume block only applies to orgs * Use an array of `VisibleType` for filtering * fix yet another thinko * Ok - no need for u * Revert "Ok - no need for u" This reverts commit 5c3e886aabd5acd997a3b35687d322439732c200. Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com> Co-authored-by: Lauris BH <lauris@nix.lv>
5 years ago
Restricted users (#6274) * Restricted users (#4334): initial implementation * Add User.IsRestricted & UI to edit it * Pass user object instead of user id to places where IsRestricted flag matters * Restricted users: maintain access rows for all referenced repos (incl public) * Take logged in user & IsRestricted flag into account in org/repo listings, searches and accesses * Add basic repo access tests for restricted users Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Mention restricted users in the faq Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Revert unnecessary change `.isUserPartOfOrg` -> `.IsUserPartOfOrg` Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Remove unnecessary `org.IsOrganization()` call Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Revert to an `int64` keyed `accessMap` * Add type `userAccess` * Add convenience func updateUserAccess() * Turn accessMap into a `map[int64]userAccess` Signed-off-by: Manush Dodunekov <manush@stendahls.se> * or even better: `map[int64]*userAccess` * updateUserAccess(): use tighter syntax as suggested by lafriks * even tighter * Avoid extra loop * Don't disclose limited orgs to unauthenticated users * Don't assume block only applies to orgs * Use an array of `VisibleType` for filtering * fix yet another thinko * Ok - no need for u * Revert "Ok - no need for u" This reverts commit 5c3e886aabd5acd997a3b35687d322439732c200. Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com> Co-authored-by: Lauris BH <lauris@nix.lv>
5 years ago
3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Copyright 2019 The Gitea Authors. All rights reserved.
  3. // Use of this source code is governed by a MIT-style
  4. // license that can be found in the LICENSE file.
  5. package routers
  6. import (
  7. "bytes"
  8. "fmt"
  9. "io/ioutil"
  10. "net/http"
  11. "strings"
  12. "code.gitea.io/gitea/models"
  13. "code.gitea.io/gitea/modules/base"
  14. "code.gitea.io/gitea/modules/context"
  15. code_indexer "code.gitea.io/gitea/modules/indexer/code"
  16. "code.gitea.io/gitea/modules/log"
  17. "code.gitea.io/gitea/modules/setting"
  18. "code.gitea.io/gitea/modules/structs"
  19. "code.gitea.io/gitea/modules/util"
  20. "code.gitea.io/gitea/routers/user"
  21. )
  22. const (
  23. // tplHome home page template
  24. tplHome base.TplName = "home"
  25. // tplExploreRepos explore repositories page template
  26. tplExploreRepos base.TplName = "explore/repos"
  27. // tplExploreDataset explore datasets page template
  28. tplExploreDataset base.TplName = "explore/datasets"
  29. // tplExploreUsers explore users page template
  30. tplExploreUsers base.TplName = "explore/users"
  31. // tplExploreOrganizations explore organizations page template
  32. tplExploreOrganizations base.TplName = "explore/organizations"
  33. // tplExploreCode explore code page template
  34. tplExploreCode base.TplName = "explore/code"
  35. tplExploreImages base.TplName = "explore/images"
  36. tplExploreExploreDataAnalysis base.TplName = "explore/data_analysis"
  37. )
  38. // Home render home page
  39. func Home(ctx *context.Context) {
  40. ctx.Data["PageIsHome"] = true
  41. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  42. setRecommendURL(ctx)
  43. ctx.HTML(200, tplHome)
  44. }
  45. func setRecommendURL(ctx *context.Context) {
  46. addr := setting.RecommentRepoAddr[10:]
  47. start := strings.Index(addr, "/")
  48. end := strings.Index(addr, "raw")
  49. if start != -1 && end != -1 {
  50. ctx.Data["RecommendURL"] = addr[start:end]
  51. } else {
  52. ctx.Data["RecommendURL"] = setting.RecommentRepoAddr
  53. }
  54. ctx.Data["page_title"] = ctx.Tr("home.page_title")
  55. ctx.Data["page_small_title"] = ctx.Tr("home.page_small_title")
  56. ctx.Data["page_description"] = ctx.Tr("home.page_description")
  57. ctx.Data["page_use"] = ctx.Tr("home.page_use")
  58. ctx.Data["page_only_dynamic"] = ctx.Tr("home.page_only_dynamic")
  59. ctx.Data["page_recommend_org"] = ctx.Tr("home.page_recommend_org")
  60. ctx.Data["page_recommend_org_desc"] = ctx.Tr("home.page_recommend_org_desc")
  61. ctx.Data["page_recommend_org_commit"] = ctx.Tr("home.page_recommend_org_commit")
  62. ctx.Data["page_recommend_org_more"] = ctx.Tr("home.page_recommend_org_more")
  63. ctx.Data["page_recommend_repo"] = ctx.Tr("home.page_recommend_repo")
  64. ctx.Data["page_recommend_repo_desc"] = ctx.Tr("home.page_recommend_repo_desc")
  65. ctx.Data["page_recommend_repo_commit"] = ctx.Tr("home.page_recommend_repo_commit")
  66. ctx.Data["page_recommend_repo_go"] = ctx.Tr("home.page_recommend_repo_go")
  67. ctx.Data["page_recommend_repo_more"] = ctx.Tr("home.page_recommend_repo_more")
  68. ctx.Data["page_dev_env"] = ctx.Tr("home.page_dev_env")
  69. ctx.Data["page_dev_env_desc"] = ctx.Tr("home.page_dev_env_desc")
  70. ctx.Data["page_dev_env_desc_title"] = ctx.Tr("home.page_dev_env_desc_title")
  71. ctx.Data["page_dev_env_desc_desc"] = ctx.Tr("home.page_dev_env_desc_desc")
  72. ctx.Data["page_dev_env_desc1_title"] = ctx.Tr("home.page_dev_env_desc1_title")
  73. ctx.Data["page_dev_env_desc1_desc"] = ctx.Tr("home.page_dev_env_desc1_desc")
  74. ctx.Data["page_dev_env_desc2_title"] = ctx.Tr("home.page_dev_env_desc2_title")
  75. ctx.Data["page_dev_env_desc2_desc"] = ctx.Tr("home.page_dev_env_desc2_desc")
  76. ctx.Data["page_dev_env_desc3_title"] = ctx.Tr("home.page_dev_env_desc3_title")
  77. ctx.Data["page_dev_env_desc3_desc"] = ctx.Tr("home.page_dev_env_desc3_desc")
  78. ctx.Data["page_dev_yunlao"] = ctx.Tr("home.page_dev_yunlao")
  79. ctx.Data["page_dev_yunlao_desc1"] = ctx.Tr("home.page_dev_yunlao_desc1")
  80. ctx.Data["page_dev_yunlao_desc2"] = ctx.Tr("home.page_dev_yunlao_desc2")
  81. ctx.Data["page_dev_yunlao_desc3"] = ctx.Tr("home.page_dev_yunlao_desc3")
  82. ctx.Data["page_dev_yunlao_desc4"] = ctx.Tr("home.page_dev_yunlao_desc4")
  83. ctx.Data["page_dev_yunlao_apply"] = ctx.Tr("home.page_dev_yunlao_apply")
  84. }
  85. func Dashboard(ctx *context.Context) {
  86. if ctx.IsSigned {
  87. if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm {
  88. ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
  89. ctx.HTML(200, user.TplActivate)
  90. } else if !ctx.User.IsActive || ctx.User.ProhibitLogin {
  91. log.Info("Failed authentication attempt for %s from %s", ctx.User.Name, ctx.RemoteAddr())
  92. ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
  93. ctx.HTML(200, "user/auth/prohibit_login")
  94. } else if ctx.User.MustChangePassword {
  95. ctx.Data["Title"] = ctx.Tr("auth.must_change_password")
  96. ctx.Data["ChangePasscodeLink"] = setting.AppSubURL + "/user/change_password"
  97. ctx.SetCookie("redirect_to", setting.AppSubURL+ctx.Req.URL.RequestURI(), 0, setting.AppSubURL)
  98. ctx.Redirect(setting.AppSubURL + "/user/settings/change_password")
  99. } else {
  100. user.Dashboard(ctx)
  101. }
  102. return
  103. // Check non-logged users landing page.
  104. } else if setting.LandingPageURL != setting.LandingPageHome {
  105. ctx.Redirect(setting.AppSubURL + string(setting.LandingPageURL))
  106. return
  107. }
  108. // Check auto-login.
  109. uname := ctx.GetCookie(setting.CookieUserName)
  110. if len(uname) != 0 {
  111. ctx.Redirect(setting.AppSubURL + "/user/login")
  112. return
  113. }
  114. setRecommendURL(ctx)
  115. ctx.Data["PageIsHome"] = true
  116. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  117. ctx.HTML(200, tplHome)
  118. }
  119. // RepoSearchOptions when calling search repositories
  120. type RepoSearchOptions struct {
  121. OwnerID int64
  122. Private bool
  123. Restricted bool
  124. PageSize int
  125. TplName base.TplName
  126. }
  127. var (
  128. nullByte = []byte{0x00}
  129. )
  130. func isKeywordValid(keyword string) bool {
  131. return !bytes.Contains([]byte(keyword), nullByte)
  132. }
  133. // RenderRepoSearch render repositories search page
  134. func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
  135. page := ctx.QueryInt("page")
  136. if page <= 0 {
  137. page = 1
  138. }
  139. var (
  140. repos []*models.Repository
  141. count int64
  142. err error
  143. orderBy models.SearchOrderBy
  144. )
  145. ctx.Data["SortType"] = ctx.Query("sort")
  146. switch ctx.Query("sort") {
  147. case "newest":
  148. orderBy = models.SearchOrderByNewest
  149. case "oldest":
  150. orderBy = models.SearchOrderByOldest
  151. case "recentupdate":
  152. orderBy = models.SearchOrderByRecentUpdated
  153. case "leastupdate":
  154. orderBy = models.SearchOrderByLeastUpdated
  155. case "reversealphabetically":
  156. orderBy = models.SearchOrderByAlphabeticallyReverse
  157. case "alphabetically":
  158. orderBy = models.SearchOrderByAlphabetically
  159. case "reversesize":
  160. orderBy = models.SearchOrderBySizeReverse
  161. case "size":
  162. orderBy = models.SearchOrderBySize
  163. case "moststars":
  164. orderBy = models.SearchOrderByStarsReverse
  165. case "feweststars":
  166. orderBy = models.SearchOrderByStars
  167. case "mostforks":
  168. orderBy = models.SearchOrderByForksReverse
  169. case "fewestforks":
  170. orderBy = models.SearchOrderByForks
  171. case "hot":
  172. orderBy = models.SearchOrderByHot
  173. case "active":
  174. orderBy = models.SearchOrderByActive
  175. default:
  176. ctx.Data["SortType"] = "hot"
  177. orderBy = models.SearchOrderByHot
  178. }
  179. orderBy = orderBy + ",id"
  180. //todo:support other topics
  181. keyword := strings.Trim(ctx.Query("q"), " ")
  182. topic := strings.Trim(ctx.Query("topic"), " ")
  183. repos, count, err = models.SearchRepository(&models.SearchRepoOptions{
  184. ListOptions: models.ListOptions{
  185. Page: page,
  186. PageSize: opts.PageSize,
  187. },
  188. Actor: ctx.User,
  189. OrderBy: orderBy,
  190. Private: opts.Private,
  191. Keyword: keyword,
  192. OwnerID: opts.OwnerID,
  193. AllPublic: true,
  194. AllLimited: true,
  195. TopicName: topic,
  196. IncludeDescription: setting.UI.SearchRepoDescription,
  197. })
  198. if err != nil {
  199. ctx.ServerError("SearchRepository", err)
  200. return
  201. }
  202. for _, repo := range repos {
  203. repo.Hot = int64(repo.NumWatches) + int64(repo.NumStars) + int64(repo.NumForks) + int64(repo.CloneCnt)
  204. repo.Active = int64(repo.NumIssues) + int64(repo.NumPulls) + int64(repo.NumCommit)
  205. }
  206. ctx.Data["Keyword"] = keyword
  207. ctx.Data["Topic"] = topic
  208. ctx.Data["Total"] = count
  209. ctx.Data["Repos"] = repos
  210. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  211. pager := context.NewPagination(int(count), opts.PageSize, page, 5)
  212. pager.SetDefaultParams(ctx)
  213. pager.AddParam(ctx, "topic", "TopicOnly")
  214. ctx.Data["Page"] = pager
  215. recommendOrgs, err := models.GetRecommendOrgInfos()
  216. if err != nil {
  217. log.Error("GetRecommendOrgInfos failed:%v", err.Error(), ctx.Data["MsgID"])
  218. ctx.ServerError("GetRecommendOrgInfos", err)
  219. return
  220. }
  221. ctx.Data["RecommendOrgs"] = recommendOrgs
  222. ctx.HTML(http.StatusOK, opts.TplName)
  223. }
  224. // ExploreRepos render explore repositories page
  225. func ExploreRepos(ctx *context.Context) {
  226. ctx.Data["Title"] = ctx.Tr("explore")
  227. ctx.Data["PageIsExplore"] = true
  228. ctx.Data["PageIsExploreRepositories"] = true
  229. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  230. var ownerID int64
  231. if ctx.User != nil && !ctx.User.IsAdmin {
  232. ownerID = ctx.User.ID
  233. }
  234. RenderRepoSearch(ctx, &RepoSearchOptions{
  235. PageSize: setting.UI.ExplorePagingNum,
  236. OwnerID: ownerID,
  237. Private: ctx.User != nil,
  238. TplName: tplExploreRepos,
  239. })
  240. }
  241. func ExploreDatasets(ctx *context.Context) {
  242. ctx.Data["Title"] = ctx.Tr("explore")
  243. ctx.Data["PageIsExplore"] = true
  244. ctx.Data["PageIsExploreDatasets"] = true
  245. // ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  246. var (
  247. datasets []*models.Dataset
  248. count int64
  249. err error
  250. orderBy models.SearchOrderBy
  251. )
  252. page := ctx.QueryInt("page")
  253. if page <= 0 {
  254. page = 1
  255. }
  256. ctx.Data["SortType"] = ctx.Query("sort")
  257. switch ctx.Query("sort") {
  258. case "newest":
  259. orderBy = models.SearchOrderByNewest
  260. case "oldest":
  261. orderBy = models.SearchOrderByOldest
  262. case "recentupdate":
  263. orderBy = models.SearchOrderByRecentUpdated
  264. case "leastupdate":
  265. orderBy = models.SearchOrderByLeastUpdated
  266. case "reversealphabetically":
  267. orderBy = models.SearchOrderByAlphabeticallyReverse
  268. case "alphabetically":
  269. orderBy = models.SearchOrderByAlphabetically
  270. case "reversesize":
  271. orderBy = models.SearchOrderBySizeReverse
  272. case "downloadtimes":
  273. orderBy = models.SearchOrderByDownloadTimes
  274. default:
  275. ctx.Data["SortType"] = "recentupdate"
  276. orderBy = models.SearchOrderByRecentUpdated
  277. }
  278. keyword := strings.Trim(ctx.Query("q"), " ")
  279. var ownerID int64
  280. if ctx.User != nil && !ctx.User.IsAdmin {
  281. ownerID = ctx.User.ID
  282. }
  283. opts := &models.SearchDatasetOptions{
  284. Keyword: keyword,
  285. IncludePublic: true,
  286. SearchOrderBy: orderBy,
  287. OwnerID: ownerID,
  288. ListOptions: models.ListOptions{
  289. Page: page,
  290. PageSize: setting.UI.ExplorePagingNum,
  291. },
  292. }
  293. datasets, count, err = models.SearchDataset(opts)
  294. if err != nil {
  295. ctx.ServerError("SearchDatasets", err)
  296. return
  297. }
  298. pager := context.NewPagination(int(count), opts.PageSize, page, 5)
  299. ctx.Data["Keyword"] = opts.Keyword
  300. pager.SetDefaultParams(ctx)
  301. ctx.Data["Page"] = pager
  302. ctx.Data["Datasets"] = datasets
  303. ctx.Data["Total"] = count
  304. ctx.Data["PageIsDatasets"] = true
  305. ctx.HTML(200, tplExploreDataset)
  306. }
  307. // RenderUserSearch render user search page
  308. func RenderUserSearch(ctx *context.Context, opts *models.SearchUserOptions, tplName base.TplName) {
  309. opts.Page = ctx.QueryInt("page")
  310. if opts.Page <= 1 {
  311. opts.Page = 1
  312. }
  313. var (
  314. users []*models.User
  315. count int64
  316. err error
  317. orderBy models.SearchOrderBy
  318. )
  319. ctx.Data["SortType"] = ctx.Query("sort")
  320. switch ctx.Query("sort") {
  321. case "newest":
  322. orderBy = models.SearchOrderByIDReverse
  323. case "oldest":
  324. orderBy = models.SearchOrderByID
  325. case "recentupdate":
  326. orderBy = models.SearchOrderByRecentUpdated
  327. case "leastupdate":
  328. orderBy = models.SearchOrderByLeastUpdated
  329. case "reversealphabetically":
  330. orderBy = models.SearchOrderByAlphabeticallyReverse
  331. case "alphabetically":
  332. orderBy = models.SearchOrderByAlphabetically
  333. default:
  334. ctx.Data["SortType"] = "alphabetically"
  335. orderBy = models.SearchOrderByAlphabetically
  336. }
  337. opts.Keyword = strings.Trim(ctx.Query("q"), " ")
  338. opts.OrderBy = orderBy
  339. if len(opts.Keyword) == 0 || isKeywordValid(opts.Keyword) {
  340. users, count, err = models.SearchUsers(opts)
  341. if err != nil {
  342. ctx.ServerError("SearchUsers", err)
  343. return
  344. }
  345. }
  346. ctx.Data["Keyword"] = opts.Keyword
  347. ctx.Data["Total"] = count
  348. ctx.Data["Users"] = users
  349. ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail
  350. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  351. pager := context.NewPagination(int(count), opts.PageSize, opts.Page, 5)
  352. pager.SetDefaultParams(ctx)
  353. ctx.Data["Page"] = pager
  354. ctx.HTML(200, tplName)
  355. }
  356. // ExploreUsers render explore users page
  357. func ExploreUsers(ctx *context.Context) {
  358. ctx.Data["Title"] = ctx.Tr("explore")
  359. ctx.Data["PageIsExplore"] = true
  360. ctx.Data["PageIsExploreUsers"] = true
  361. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  362. RenderUserSearch(ctx, &models.SearchUserOptions{
  363. Actor: ctx.User,
  364. Type: models.UserTypeIndividual,
  365. ListOptions: models.ListOptions{PageSize: setting.UI.ExplorePagingNum},
  366. IsActive: util.OptionalBoolTrue,
  367. Visible: []structs.VisibleType{structs.VisibleTypePublic, structs.VisibleTypeLimited, structs.VisibleTypePrivate},
  368. }, tplExploreUsers)
  369. }
  370. // ExploreOrganizations render explore organizations page
  371. func ExploreOrganizations(ctx *context.Context) {
  372. ctx.Data["Title"] = ctx.Tr("explore")
  373. ctx.Data["PageIsExplore"] = true
  374. ctx.Data["PageIsExploreOrganizations"] = true
  375. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  376. visibleTypes := []structs.VisibleType{structs.VisibleTypePublic}
  377. if ctx.User != nil {
  378. visibleTypes = append(visibleTypes, structs.VisibleTypeLimited, structs.VisibleTypePrivate)
  379. }
  380. RenderUserSearch(ctx, &models.SearchUserOptions{
  381. Actor: ctx.User,
  382. Type: models.UserTypeOrganization,
  383. ListOptions: models.ListOptions{PageSize: setting.UI.ExplorePagingNum},
  384. Visible: visibleTypes,
  385. }, tplExploreOrganizations)
  386. }
  387. // ExploreCode render explore code page
  388. func ExploreCode(ctx *context.Context) {
  389. if !setting.Indexer.RepoIndexerEnabled {
  390. ctx.Redirect(setting.AppSubURL+"/explore", 302)
  391. return
  392. }
  393. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  394. ctx.Data["Title"] = ctx.Tr("explore")
  395. ctx.Data["PageIsExplore"] = true
  396. ctx.Data["PageIsExploreCode"] = true
  397. language := strings.TrimSpace(ctx.Query("l"))
  398. keyword := strings.TrimSpace(ctx.Query("q"))
  399. page := ctx.QueryInt("page")
  400. if page <= 0 {
  401. page = 1
  402. }
  403. var (
  404. repoIDs []int64
  405. err error
  406. isAdmin bool
  407. userID int64
  408. )
  409. if ctx.User != nil {
  410. userID = ctx.User.ID
  411. isAdmin = ctx.User.IsAdmin
  412. }
  413. // guest user or non-admin user
  414. if ctx.User == nil || !isAdmin {
  415. repoIDs, err = models.FindUserAccessibleRepoIDs(ctx.User)
  416. if err != nil {
  417. ctx.ServerError("SearchResults", err)
  418. return
  419. }
  420. }
  421. var (
  422. total int
  423. searchResults []*code_indexer.Result
  424. searchResultLanguages []*code_indexer.SearchResultLanguages
  425. )
  426. // if non-admin login user, we need check UnitTypeCode at first
  427. if ctx.User != nil && len(repoIDs) > 0 {
  428. repoMaps, err := models.GetRepositoriesMapByIDs(repoIDs)
  429. if err != nil {
  430. ctx.ServerError("SearchResults", err)
  431. return
  432. }
  433. var rightRepoMap = make(map[int64]*models.Repository, len(repoMaps))
  434. repoIDs = make([]int64, 0, len(repoMaps))
  435. for id, repo := range repoMaps {
  436. if repo.CheckUnitUser(userID, isAdmin, models.UnitTypeCode) {
  437. rightRepoMap[id] = repo
  438. repoIDs = append(repoIDs, id)
  439. }
  440. }
  441. ctx.Data["RepoMaps"] = rightRepoMap
  442. total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum)
  443. if err != nil {
  444. ctx.ServerError("SearchResults", err)
  445. return
  446. }
  447. // if non-login user or isAdmin, no need to check UnitTypeCode
  448. } else if (ctx.User == nil && len(repoIDs) > 0) || isAdmin {
  449. total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum)
  450. if err != nil {
  451. ctx.ServerError("SearchResults", err)
  452. return
  453. }
  454. var loadRepoIDs = make([]int64, 0, len(searchResults))
  455. for _, result := range searchResults {
  456. var find bool
  457. for _, id := range loadRepoIDs {
  458. if id == result.RepoID {
  459. find = true
  460. break
  461. }
  462. }
  463. if !find {
  464. loadRepoIDs = append(loadRepoIDs, result.RepoID)
  465. }
  466. }
  467. repoMaps, err := models.GetRepositoriesMapByIDs(loadRepoIDs)
  468. if err != nil {
  469. ctx.ServerError("SearchResults", err)
  470. return
  471. }
  472. ctx.Data["RepoMaps"] = repoMaps
  473. }
  474. ctx.Data["Keyword"] = keyword
  475. ctx.Data["Language"] = language
  476. ctx.Data["SearchResults"] = searchResults
  477. ctx.Data["SearchResultLanguages"] = searchResultLanguages
  478. ctx.Data["RequireHighlightJS"] = true
  479. ctx.Data["PageIsViewCode"] = true
  480. pager := context.NewPagination(total, setting.UI.RepoSearchPagingNum, page, 5)
  481. pager.SetDefaultParams(ctx)
  482. pager.AddParam(ctx, "l", "Language")
  483. ctx.Data["Page"] = pager
  484. ctx.HTML(200, tplExploreCode)
  485. }
  486. func ExploreImages(ctx *context.Context) {
  487. ctx.HTML(200, tplExploreImages)
  488. }
  489. func ExploreDataAnalysis(ctx *context.Context) {
  490. ctx.HTML(200, tplExploreExploreDataAnalysis)
  491. }
  492. // NotFound render 404 page
  493. func NotFound(ctx *context.Context) {
  494. ctx.Data["Title"] = "Page Not Found"
  495. ctx.NotFound("home.NotFound", nil)
  496. }
  497. func RecommendOrgFromPromote(ctx *context.Context) {
  498. url := setting.RecommentRepoAddr + "organizations"
  499. result, err := recommendFromPromote(url)
  500. if err != nil {
  501. ctx.ServerError("500", err)
  502. return
  503. }
  504. resultOrg := make([]map[string]interface{}, 0)
  505. for _, userName := range result {
  506. user, err := models.GetUserByName(userName)
  507. if err == nil {
  508. userMap := make(map[string]interface{})
  509. userMap["Name"] = user.Name
  510. userMap["Description"] = user.Description
  511. userMap["FullName"] = user.FullName
  512. userMap["ID"] = user.ID
  513. userMap["Avatar"] = user.RelAvatarLink()
  514. userMap["NumRepos"] = user.NumRepos
  515. userMap["NumTeams"] = user.NumTeams
  516. userMap["NumMembers"] = user.NumMembers
  517. resultOrg = append(resultOrg, userMap)
  518. } else {
  519. log.Info("query user error," + err.Error())
  520. }
  521. }
  522. ctx.JSON(200, resultOrg)
  523. }
  524. func recommendFromPromote(url string) ([]string, error) {
  525. resp, err := http.Get(url)
  526. if err != nil || resp.StatusCode != 200 {
  527. log.Info("Get organizations url error=" + err.Error())
  528. return nil, err
  529. }
  530. bytes, err := ioutil.ReadAll(resp.Body)
  531. resp.Body.Close()
  532. if err != nil {
  533. log.Info("Get organizations url error=" + err.Error())
  534. return nil, err
  535. }
  536. allLineStr := string(bytes)
  537. lines := strings.Split(allLineStr, "\n")
  538. result := make([]string, len(lines))
  539. for i, line := range lines {
  540. log.Info("i=" + fmt.Sprint(i) + " line=" + line)
  541. result[i] = strings.Trim(line, " ")
  542. }
  543. return result, nil
  544. }
  545. func RecommendRepoFromPromote(ctx *context.Context) {
  546. url := setting.RecommentRepoAddr + "projects"
  547. result, err := recommendFromPromote(url)
  548. if err != nil {
  549. ctx.ServerError("500", err)
  550. return
  551. }
  552. resultRepo := make([]map[string]interface{}, 0)
  553. //resultRepo := make([]*models.Repository, 0)
  554. for _, repoName := range result {
  555. tmpIndex := strings.Index(repoName, "/")
  556. if tmpIndex == -1 {
  557. log.Info("error repo name format.")
  558. } else {
  559. ownerName := strings.Trim(repoName[0:tmpIndex], " ")
  560. repoName := strings.Trim(repoName[tmpIndex+1:], " ")
  561. repo, err := models.GetRepositoryByOwnerAndName(ownerName, repoName)
  562. if err == nil {
  563. repoMap := make(map[string]interface{})
  564. repoMap["ID"] = fmt.Sprint(repo.ID)
  565. repoMap["Name"] = repo.Name
  566. repoMap["OwnerName"] = repo.OwnerName
  567. repoMap["NumStars"] = repo.NumStars
  568. repoMap["NumForks"] = repo.NumForks
  569. repoMap["Description"] = repo.Description
  570. repoMap["NumWatchs"] = repo.NumWatches
  571. repoMap["Topics"] = repo.Topics
  572. repoMap["Avatar"] = repo.RelAvatarLink()
  573. resultRepo = append(resultRepo, repoMap)
  574. } else {
  575. log.Info("query repo error," + err.Error())
  576. }
  577. }
  578. }
  579. ctx.JSON(200, resultRepo)
  580. }