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