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 9.1 kB

11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
8 years ago
10 years ago
8 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package routers
  5. import (
  6. "bytes"
  7. "strings"
  8. "code.gitea.io/gitea/models"
  9. "code.gitea.io/gitea/modules/base"
  10. "code.gitea.io/gitea/modules/context"
  11. "code.gitea.io/gitea/modules/search"
  12. "code.gitea.io/gitea/modules/setting"
  13. "code.gitea.io/gitea/modules/util"
  14. "code.gitea.io/gitea/routers/user"
  15. "github.com/Unknwon/paginater"
  16. )
  17. const (
  18. // tplHome home page template
  19. tplHome base.TplName = "home"
  20. // tplExploreRepos explore repositories page template
  21. tplExploreRepos base.TplName = "explore/repos"
  22. // tplExploreUsers explore users page template
  23. tplExploreUsers base.TplName = "explore/users"
  24. // tplExploreOrganizations explore organizations page template
  25. tplExploreOrganizations base.TplName = "explore/organizations"
  26. // tplExploreCode explore code page template
  27. tplExploreCode base.TplName = "explore/code"
  28. )
  29. // Home render home page
  30. func Home(ctx *context.Context) {
  31. if ctx.IsSigned {
  32. if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm {
  33. ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
  34. ctx.HTML(200, user.TplActivate)
  35. } else {
  36. user.Dashboard(ctx)
  37. }
  38. return
  39. }
  40. // Check auto-login.
  41. uname := ctx.GetCookie(setting.CookieUserName)
  42. if len(uname) != 0 {
  43. ctx.Redirect(setting.AppSubURL + "/user/login")
  44. return
  45. }
  46. ctx.Data["PageIsHome"] = true
  47. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  48. ctx.HTML(200, tplHome)
  49. }
  50. // RepoSearchOptions when calling search repositories
  51. type RepoSearchOptions struct {
  52. OwnerID int64
  53. Private bool
  54. PageSize int
  55. TplName base.TplName
  56. }
  57. var (
  58. nullByte = []byte{0x00}
  59. )
  60. func isKeywordValid(keyword string) bool {
  61. return !bytes.Contains([]byte(keyword), nullByte)
  62. }
  63. // RenderRepoSearch render repositories search page
  64. func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
  65. page := ctx.QueryInt("page")
  66. if page <= 0 {
  67. page = 1
  68. }
  69. var (
  70. repos []*models.Repository
  71. count int64
  72. err error
  73. orderBy models.SearchOrderBy
  74. )
  75. ctx.Data["SortType"] = ctx.Query("sort")
  76. switch ctx.Query("sort") {
  77. case "newest":
  78. orderBy = models.SearchOrderByNewest
  79. case "oldest":
  80. orderBy = models.SearchOrderByOldest
  81. case "recentupdate":
  82. orderBy = models.SearchOrderByRecentUpdated
  83. case "leastupdate":
  84. orderBy = models.SearchOrderByLeastUpdated
  85. case "reversealphabetically":
  86. orderBy = models.SearchOrderByAlphabeticallyReverse
  87. case "alphabetically":
  88. orderBy = models.SearchOrderByAlphabetically
  89. case "reversesize":
  90. orderBy = models.SearchOrderBySizeReverse
  91. case "size":
  92. orderBy = models.SearchOrderBySize
  93. default:
  94. ctx.Data["SortType"] = "recentupdate"
  95. orderBy = models.SearchOrderByRecentUpdated
  96. }
  97. keyword := strings.Trim(ctx.Query("q"), " ")
  98. repos, count, err = models.SearchRepositoryByName(&models.SearchRepoOptions{
  99. Page: page,
  100. PageSize: opts.PageSize,
  101. OrderBy: orderBy,
  102. Private: opts.Private,
  103. Keyword: keyword,
  104. OwnerID: opts.OwnerID,
  105. AllPublic: true,
  106. })
  107. if err != nil {
  108. ctx.ServerError("SearchRepositoryByName", err)
  109. return
  110. }
  111. ctx.Data["Keyword"] = keyword
  112. ctx.Data["Total"] = count
  113. ctx.Data["Page"] = paginater.New(int(count), opts.PageSize, page, 5)
  114. ctx.Data["Repos"] = repos
  115. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  116. ctx.HTML(200, opts.TplName)
  117. }
  118. // ExploreRepos render explore repositories page
  119. func ExploreRepos(ctx *context.Context) {
  120. ctx.Data["Title"] = ctx.Tr("explore")
  121. ctx.Data["PageIsExplore"] = true
  122. ctx.Data["PageIsExploreRepositories"] = true
  123. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  124. var ownerID int64
  125. if ctx.User != nil && !ctx.User.IsAdmin {
  126. ownerID = ctx.User.ID
  127. }
  128. RenderRepoSearch(ctx, &RepoSearchOptions{
  129. PageSize: setting.UI.ExplorePagingNum,
  130. OwnerID: ownerID,
  131. Private: ctx.User != nil,
  132. TplName: tplExploreRepos,
  133. })
  134. }
  135. // RenderUserSearch render user search page
  136. func RenderUserSearch(ctx *context.Context, opts *models.SearchUserOptions, tplName base.TplName) {
  137. opts.Page = ctx.QueryInt("page")
  138. if opts.Page <= 1 {
  139. opts.Page = 1
  140. }
  141. var (
  142. users []*models.User
  143. count int64
  144. err error
  145. orderBy string
  146. )
  147. ctx.Data["SortType"] = ctx.Query("sort")
  148. switch ctx.Query("sort") {
  149. case "newest":
  150. orderBy = "id DESC"
  151. case "oldest":
  152. orderBy = "id ASC"
  153. case "recentupdate":
  154. orderBy = "updated_unix DESC"
  155. case "leastupdate":
  156. orderBy = "updated_unix ASC"
  157. case "reversealphabetically":
  158. orderBy = "name DESC"
  159. case "alphabetically":
  160. orderBy = "name ASC"
  161. default:
  162. ctx.Data["SortType"] = "alphabetically"
  163. orderBy = "name ASC"
  164. }
  165. opts.Keyword = strings.Trim(ctx.Query("q"), " ")
  166. opts.OrderBy = orderBy
  167. if len(opts.Keyword) == 0 || isKeywordValid(opts.Keyword) {
  168. users, count, err = models.SearchUsers(opts)
  169. if err != nil {
  170. ctx.ServerError("SearchUsers", err)
  171. return
  172. }
  173. }
  174. ctx.Data["Keyword"] = opts.Keyword
  175. ctx.Data["Total"] = count
  176. ctx.Data["Page"] = paginater.New(int(count), opts.PageSize, opts.Page, 5)
  177. ctx.Data["Users"] = users
  178. ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail
  179. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  180. ctx.HTML(200, tplName)
  181. }
  182. // ExploreUsers render explore users page
  183. func ExploreUsers(ctx *context.Context) {
  184. ctx.Data["Title"] = ctx.Tr("explore")
  185. ctx.Data["PageIsExplore"] = true
  186. ctx.Data["PageIsExploreUsers"] = true
  187. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  188. RenderUserSearch(ctx, &models.SearchUserOptions{
  189. Type: models.UserTypeIndividual,
  190. PageSize: setting.UI.ExplorePagingNum,
  191. IsActive: util.OptionalBoolTrue,
  192. }, tplExploreUsers)
  193. }
  194. // ExploreOrganizations render explore organizations page
  195. func ExploreOrganizations(ctx *context.Context) {
  196. ctx.Data["Title"] = ctx.Tr("explore")
  197. ctx.Data["PageIsExplore"] = true
  198. ctx.Data["PageIsExploreOrganizations"] = true
  199. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  200. RenderUserSearch(ctx, &models.SearchUserOptions{
  201. Type: models.UserTypeOrganization,
  202. PageSize: setting.UI.ExplorePagingNum,
  203. }, tplExploreOrganizations)
  204. }
  205. // ExploreCode render explore code page
  206. func ExploreCode(ctx *context.Context) {
  207. if !setting.Indexer.RepoIndexerEnabled {
  208. ctx.Redirect("/explore", 302)
  209. return
  210. }
  211. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  212. ctx.Data["Title"] = ctx.Tr("explore")
  213. ctx.Data["PageIsExplore"] = true
  214. ctx.Data["PageIsExploreCode"] = true
  215. keyword := strings.TrimSpace(ctx.Query("q"))
  216. page := ctx.QueryInt("page")
  217. if page <= 0 {
  218. page = 1
  219. }
  220. var (
  221. repoIDs []int64
  222. err error
  223. isAdmin bool
  224. userID int64
  225. )
  226. if ctx.User != nil {
  227. userID = ctx.User.ID
  228. isAdmin = ctx.User.IsAdmin
  229. }
  230. // guest user or non-admin user
  231. if ctx.User == nil || !isAdmin {
  232. repoIDs, err = models.FindUserAccessibleRepoIDs(userID)
  233. if err != nil {
  234. ctx.ServerError("SearchResults", err)
  235. return
  236. }
  237. }
  238. var (
  239. total int
  240. searchResults []*search.Result
  241. )
  242. // if non-admin login user, we need check UnitTypeCode at first
  243. if ctx.User != nil && len(repoIDs) > 0 {
  244. repoMaps, err := models.GetRepositoriesMapByIDs(repoIDs)
  245. if err != nil {
  246. ctx.ServerError("SearchResults", err)
  247. return
  248. }
  249. var rightRepoMap = make(map[int64]*models.Repository, len(repoMaps))
  250. repoIDs = make([]int64, 0, len(repoMaps))
  251. for id, repo := range repoMaps {
  252. if repo.CheckUnitUser(userID, isAdmin, models.UnitTypeCode) {
  253. rightRepoMap[id] = repo
  254. repoIDs = append(repoIDs, id)
  255. }
  256. }
  257. ctx.Data["RepoMaps"] = rightRepoMap
  258. total, searchResults, err = search.PerformSearch(repoIDs, keyword, page, setting.UI.RepoSearchPagingNum)
  259. if err != nil {
  260. ctx.ServerError("SearchResults", err)
  261. return
  262. }
  263. // if non-login user or isAdmin, no need to check UnitTypeCode
  264. } else if (ctx.User == nil && len(repoIDs) > 0) || isAdmin {
  265. total, searchResults, err = search.PerformSearch(repoIDs, keyword, page, setting.UI.RepoSearchPagingNum)
  266. if err != nil {
  267. ctx.ServerError("SearchResults", err)
  268. return
  269. }
  270. var loadRepoIDs = make([]int64, 0, len(searchResults))
  271. for _, result := range searchResults {
  272. var find bool
  273. for _, id := range loadRepoIDs {
  274. if id == result.RepoID {
  275. find = true
  276. break
  277. }
  278. }
  279. if !find {
  280. loadRepoIDs = append(loadRepoIDs, result.RepoID)
  281. }
  282. }
  283. repoMaps, err := models.GetRepositoriesMapByIDs(loadRepoIDs)
  284. if err != nil {
  285. ctx.ServerError("SearchResults", err)
  286. return
  287. }
  288. ctx.Data["RepoMaps"] = repoMaps
  289. }
  290. ctx.Data["Keyword"] = keyword
  291. pager := paginater.New(total, setting.UI.RepoSearchPagingNum, page, 5)
  292. ctx.Data["Page"] = pager
  293. ctx.Data["SearchResults"] = searchResults
  294. ctx.Data["RequireHighlightJS"] = true
  295. ctx.Data["PageIsViewCode"] = true
  296. ctx.HTML(200, tplExploreCode)
  297. }
  298. // NotFound render 404 page
  299. func NotFound(ctx *context.Context) {
  300. ctx.Data["Title"] = "Page Not Found"
  301. ctx.NotFound("home.NotFound", nil)
  302. }