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

11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 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
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 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
10 years ago
3 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
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773
  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. "net/http"
  9. "strconv"
  10. "strings"
  11. "code.gitea.io/gitea/services/repository"
  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. tplHomeTerm base.TplName = "terms"
  38. )
  39. // Home render home page
  40. func Home(ctx *context.Context) {
  41. ctx.Data["PageIsHome"] = true
  42. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  43. setRecommendURL(ctx)
  44. ctx.HTML(200, tplHome)
  45. }
  46. func setRecommendURLOnly(ctx *context.Context) {
  47. addr := setting.RecommentRepoAddr[10:]
  48. start := strings.Index(addr, "/")
  49. end := strings.Index(addr, "raw")
  50. if start != -1 && end != -1 {
  51. ctx.Data["RecommendURL"] = addr[start:end]
  52. } else {
  53. ctx.Data["RecommendURL"] = setting.RecommentRepoAddr
  54. }
  55. }
  56. func setRecommendURL(ctx *context.Context) {
  57. setRecommendURLOnly(ctx)
  58. ctx.Data["page_title"] = ctx.Tr("home.page_title")
  59. ctx.Data["page_small_title"] = ctx.Tr("home.page_small_title")
  60. ctx.Data["page_description"] = ctx.Tr("home.page_description")
  61. ctx.Data["page_use"] = ctx.Tr("home.page_use")
  62. ctx.Data["page_only_dynamic"] = ctx.Tr("home.page_only_dynamic")
  63. ctx.Data["page_recommend_org"] = ctx.Tr("home.page_recommend_org")
  64. ctx.Data["page_recommend_org_desc"] = ctx.Tr("home.page_recommend_org_desc")
  65. ctx.Data["page_recommend_org_commit"] = ctx.Tr("home.page_recommend_org_commit")
  66. ctx.Data["page_recommend_org_more"] = ctx.Tr("home.page_recommend_org_more")
  67. ctx.Data["page_recommend_repo"] = ctx.Tr("home.page_recommend_repo")
  68. ctx.Data["page_recommend_repo_desc"] = ctx.Tr("home.page_recommend_repo_desc")
  69. ctx.Data["page_recommend_repo_commit"] = ctx.Tr("home.page_recommend_repo_commit")
  70. ctx.Data["page_recommend_repo_go"] = ctx.Tr("home.page_recommend_repo_go")
  71. ctx.Data["page_recommend_repo_more"] = ctx.Tr("home.page_recommend_repo_more")
  72. ctx.Data["page_dev_env"] = ctx.Tr("home.page_dev_env")
  73. ctx.Data["page_dev_env_desc"] = ctx.Tr("home.page_dev_env_desc")
  74. ctx.Data["page_dev_env_desc_title"] = ctx.Tr("home.page_dev_env_desc_title")
  75. ctx.Data["page_dev_env_desc_desc"] = ctx.Tr("home.page_dev_env_desc_desc")
  76. ctx.Data["page_dev_env_desc1_title"] = ctx.Tr("home.page_dev_env_desc1_title")
  77. ctx.Data["page_dev_env_desc1_desc"] = ctx.Tr("home.page_dev_env_desc1_desc")
  78. ctx.Data["page_dev_env_desc2_title"] = ctx.Tr("home.page_dev_env_desc2_title")
  79. ctx.Data["page_dev_env_desc2_desc"] = ctx.Tr("home.page_dev_env_desc2_desc")
  80. ctx.Data["page_dev_env_desc3_title"] = ctx.Tr("home.page_dev_env_desc3_title")
  81. ctx.Data["page_dev_env_desc3_desc"] = ctx.Tr("home.page_dev_env_desc3_desc")
  82. ctx.Data["page_dev_yunlao"] = ctx.Tr("home.page_dev_yunlao")
  83. ctx.Data["page_dev_yunlao_desc1"] = ctx.Tr("home.page_dev_yunlao_desc1")
  84. ctx.Data["page_dev_yunlao_desc2"] = ctx.Tr("home.page_dev_yunlao_desc2")
  85. ctx.Data["page_dev_yunlao_desc3"] = ctx.Tr("home.page_dev_yunlao_desc3")
  86. ctx.Data["page_dev_yunlao_desc4"] = ctx.Tr("home.page_dev_yunlao_desc4")
  87. ctx.Data["page_dev_yunlao_apply"] = ctx.Tr("home.page_dev_yunlao_apply")
  88. ctx.Data["page_recommend_activity"] = ctx.Tr("home.page_recommend_activity")
  89. ctx.Data["page_recommend_activity_desc"] = ctx.Tr("home.page_recommend_activity_desc")
  90. }
  91. func Dashboard(ctx *context.Context) {
  92. if ctx.IsSigned {
  93. if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm {
  94. ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
  95. ctx.HTML(200, user.TplActivate)
  96. } else if !ctx.User.IsActive || ctx.User.ProhibitLogin {
  97. log.Info("Failed authentication attempt for %s from %s", ctx.User.Name, ctx.RemoteAddr())
  98. ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
  99. ctx.HTML(200, "user/auth/prohibit_login")
  100. } else if ctx.User.MustChangePassword {
  101. ctx.Data["Title"] = ctx.Tr("auth.must_change_password")
  102. ctx.Data["ChangePasscodeLink"] = setting.AppSubURL + "/user/change_password"
  103. ctx.SetCookie("redirect_to", setting.AppSubURL+ctx.Req.URL.RequestURI(), 0, setting.AppSubURL)
  104. ctx.Redirect(setting.AppSubURL + "/user/settings/change_password")
  105. } else {
  106. user.Dashboard(ctx)
  107. }
  108. return
  109. // Check non-logged users landing page.
  110. } else if setting.LandingPageURL != setting.LandingPageHome {
  111. ctx.Redirect(setting.AppSubURL + string(setting.LandingPageURL))
  112. return
  113. }
  114. // Check auto-login.
  115. uname := ctx.GetCookie(setting.CookieUserName)
  116. if len(uname) != 0 {
  117. ctx.Redirect(setting.AppSubURL + "/user/login")
  118. return
  119. }
  120. setRecommendURL(ctx)
  121. ctx.Data["PageIsHome"] = true
  122. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  123. ctx.HTML(200, tplHome)
  124. }
  125. // RepoSearchOptions when calling search repositories
  126. type RepoSearchOptions struct {
  127. OwnerID int64
  128. Private bool
  129. Restricted bool
  130. PageSize int
  131. TplName base.TplName
  132. Course util.OptionalBool
  133. }
  134. var (
  135. nullByte = []byte{0x00}
  136. )
  137. func isKeywordValid(keyword string) bool {
  138. return !bytes.Contains([]byte(keyword), nullByte)
  139. }
  140. // RenderRepoSearch render repositories search page
  141. func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
  142. page := ctx.QueryInt("page")
  143. if page <= 0 {
  144. page = 1
  145. }
  146. var (
  147. repos []*models.Repository
  148. count int64
  149. err error
  150. orderBy models.SearchOrderBy
  151. )
  152. ctx.Data["SortType"] = ctx.Query("sort")
  153. switch ctx.Query("sort") {
  154. case "newest":
  155. orderBy = models.SearchOrderByNewest
  156. case "oldest":
  157. orderBy = models.SearchOrderByOldest
  158. case "recentupdate":
  159. orderBy = models.SearchOrderByRecentUpdated
  160. case "leastupdate":
  161. orderBy = models.SearchOrderByLeastUpdated
  162. case "reversealphabetically":
  163. orderBy = models.SearchOrderByAlphabeticallyReverse
  164. case "alphabetically":
  165. orderBy = models.SearchOrderByAlphabetically
  166. case "reversesize":
  167. orderBy = models.SearchOrderBySizeReverse
  168. case "size":
  169. orderBy = models.SearchOrderBySize
  170. case "moststars":
  171. orderBy = models.SearchOrderByStarsReverse
  172. case "feweststars":
  173. orderBy = models.SearchOrderByStars
  174. case "mostforks":
  175. orderBy = models.SearchOrderByForksReverse
  176. case "fewestforks":
  177. orderBy = models.SearchOrderByForks
  178. case "hot":
  179. orderBy = models.SearchOrderByHot
  180. case "active":
  181. orderBy = models.SearchOrderByActive
  182. default:
  183. ctx.Data["SortType"] = "hot"
  184. orderBy = models.SearchOrderByHot
  185. }
  186. orderBy = orderBy + ",id"
  187. //todo:support other topics
  188. keyword := strings.Trim(ctx.Query("q"), " ")
  189. topic := strings.Trim(ctx.Query("topic"), " ")
  190. repos, count, err = models.SearchRepository(&models.SearchRepoOptions{
  191. ListOptions: models.ListOptions{
  192. Page: page,
  193. PageSize: opts.PageSize,
  194. },
  195. Actor: ctx.User,
  196. OrderBy: orderBy,
  197. Private: opts.Private,
  198. Keyword: keyword,
  199. OwnerID: opts.OwnerID,
  200. AllPublic: true,
  201. AllLimited: true,
  202. TopicName: topic,
  203. IncludeDescription: setting.UI.SearchRepoDescription,
  204. Course: opts.Course,
  205. })
  206. if err != nil {
  207. ctx.ServerError("SearchRepository", err)
  208. return
  209. }
  210. for _, repo := range repos {
  211. repo.Hot = int64(repo.NumWatches) + int64(repo.NumStars) + int64(repo.NumForks) + int64(repo.CloneCnt)
  212. repo.Active = int64(repo.NumIssues) + int64(repo.NumPulls) + int64(repo.NumCommit)
  213. }
  214. ctx.Data["Keyword"] = keyword
  215. ctx.Data["Topic"] = topic
  216. ctx.Data["Total"] = count
  217. ctx.Data["Repos"] = repos
  218. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  219. pager := context.NewPagination(int(count), opts.PageSize, page, 5)
  220. pager.SetDefaultParams(ctx)
  221. pager.AddParam(ctx, "topic", "TopicOnly")
  222. ctx.Data["Page"] = pager
  223. recommendOrgs, err := models.GetRecommendOrgInfos()
  224. if err != nil {
  225. log.Error("GetRecommendOrgInfos failed:%v", err.Error(), ctx.Data["MsgID"])
  226. ctx.ServerError("GetRecommendOrgInfos", err)
  227. return
  228. }
  229. ctx.Data["RecommendOrgs"] = recommendOrgs
  230. ctx.HTML(http.StatusOK, opts.TplName)
  231. }
  232. // ExploreRepos render explore repositories page
  233. func ExploreRepos(ctx *context.Context) {
  234. ctx.Data["Title"] = ctx.Tr("explore")
  235. ctx.Data["PageIsExplore"] = true
  236. ctx.Data["PageIsExploreRepositories"] = true
  237. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  238. var ownerID int64
  239. if ctx.User != nil && !ctx.User.IsAdmin {
  240. ownerID = ctx.User.ID
  241. }
  242. RenderRepoSearch(ctx, &RepoSearchOptions{
  243. PageSize: setting.UI.ExplorePagingNum,
  244. OwnerID: ownerID,
  245. Private: ctx.User != nil,
  246. TplName: tplExploreRepos,
  247. })
  248. }
  249. func ExploreDatasets(ctx *context.Context) {
  250. ctx.Data["Title"] = ctx.Tr("explore")
  251. ctx.Data["PageIsExplore"] = true
  252. ctx.Data["PageIsExploreDatasets"] = true
  253. // ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  254. var (
  255. datasets []*models.Dataset
  256. datasetsWithStar []*models.DatasetWithStar
  257. count int64
  258. err error
  259. orderBy models.SearchOrderBy
  260. )
  261. page := ctx.QueryInt("page")
  262. if page <= 0 {
  263. page = 1
  264. }
  265. ctx.Data["SortType"] = ctx.Query("sort")
  266. switch ctx.Query("sort") {
  267. case "newest":
  268. orderBy = models.SearchOrderByNewest
  269. case "oldest":
  270. orderBy = models.SearchOrderByOldest
  271. case "recentupdate":
  272. orderBy = models.SearchOrderByRecentUpdated
  273. case "leastupdate":
  274. orderBy = models.SearchOrderByLeastUpdated
  275. case "reversealphabetically":
  276. orderBy = models.SearchOrderByAlphabeticallyReverse
  277. case "alphabetically":
  278. orderBy = models.SearchOrderByAlphabetically
  279. case "reversesize":
  280. orderBy = models.SearchOrderBySizeReverse
  281. case "downloadtimes":
  282. orderBy = models.SearchOrderByDownloadTimes
  283. case "moststars":
  284. orderBy = models.SearchOrderByStarsReverse
  285. case "feweststars":
  286. orderBy = models.SearchOrderByStars
  287. case "default":
  288. orderBy = models.SearchOrderByDefault
  289. default:
  290. ctx.Data["SortType"] = "default"
  291. orderBy = models.SearchOrderByDefault
  292. }
  293. keyword := strings.Trim(ctx.Query("q"), " ")
  294. category := ctx.Query("category")
  295. task := ctx.Query("task")
  296. license := ctx.Query("license")
  297. var ownerID int64
  298. if ctx.User != nil && !ctx.User.IsAdmin {
  299. ownerID = ctx.User.ID
  300. }
  301. opts := &models.SearchDatasetOptions{
  302. Keyword: keyword,
  303. IncludePublic: true,
  304. SearchOrderBy: orderBy,
  305. Category: category,
  306. Task: task,
  307. License: license,
  308. OwnerID: ownerID,
  309. RecommendOnly: ctx.QueryBool("recommend"),
  310. ListOptions: models.ListOptions{
  311. Page: page,
  312. PageSize: 30,
  313. },
  314. }
  315. datasets, count, err = models.SearchDataset(opts)
  316. if err != nil {
  317. ctx.ServerError("SearchDatasets", err)
  318. return
  319. }
  320. for _, dataset := range datasets {
  321. if !ctx.IsSigned {
  322. datasetsWithStar = append(datasetsWithStar, &models.DatasetWithStar{Dataset: *dataset, IsStaring: false})
  323. } else {
  324. datasetsWithStar = append(datasetsWithStar, &models.DatasetWithStar{Dataset: *dataset, IsStaring: models.IsDatasetStaring(ctx.User.ID, dataset.ID)})
  325. }
  326. }
  327. pager := context.NewPagination(int(count), opts.PageSize, page, 5)
  328. ctx.Data["Keyword"] = opts.Keyword
  329. ctx.Data["Category"] = category
  330. ctx.Data["Task"] = task
  331. ctx.Data["License"] = license
  332. ctx.Data["Recommend"] = ctx.QueryBool("recommend")
  333. pager.SetDefaultParams(ctx)
  334. ctx.Data["Page"] = pager
  335. ctx.Data["Datasets"] = datasetsWithStar
  336. ctx.Data["Total"] = count
  337. ctx.Data["PageIsDatasets"] = true
  338. ctx.HTML(200, tplExploreDataset)
  339. }
  340. // RenderUserSearch render user search page
  341. func RenderUserSearch(ctx *context.Context, opts *models.SearchUserOptions, tplName base.TplName) {
  342. opts.Page = ctx.QueryInt("page")
  343. if opts.Page <= 1 {
  344. opts.Page = 1
  345. }
  346. var (
  347. users []*models.User
  348. count int64
  349. err error
  350. orderBy models.SearchOrderBy
  351. )
  352. ctx.Data["SortType"] = ctx.Query("sort")
  353. switch ctx.Query("sort") {
  354. case "newest":
  355. orderBy = models.SearchOrderByIDReverse
  356. case "oldest":
  357. orderBy = models.SearchOrderByID
  358. case "recentupdate":
  359. orderBy = models.SearchOrderByRecentUpdated
  360. case "leastupdate":
  361. orderBy = models.SearchOrderByLeastUpdated
  362. case "reversealphabetically":
  363. orderBy = models.SearchOrderByAlphabeticallyReverse
  364. case "alphabetically":
  365. orderBy = models.SearchOrderByAlphabetically
  366. default:
  367. ctx.Data["SortType"] = "alphabetically"
  368. orderBy = models.SearchOrderByAlphabetically
  369. }
  370. opts.Keyword = strings.Trim(ctx.Query("q"), " ")
  371. opts.OrderBy = orderBy
  372. if len(opts.Keyword) == 0 || isKeywordValid(opts.Keyword) {
  373. users, count, err = models.SearchUsers(opts)
  374. if err != nil {
  375. ctx.ServerError("SearchUsers", err)
  376. return
  377. }
  378. }
  379. ctx.Data["Keyword"] = opts.Keyword
  380. ctx.Data["Total"] = count
  381. ctx.Data["Users"] = users
  382. ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail
  383. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  384. pager := context.NewPagination(int(count), opts.PageSize, opts.Page, 5)
  385. pager.SetDefaultParams(ctx)
  386. ctx.Data["Page"] = pager
  387. ctx.HTML(200, tplName)
  388. }
  389. // ExploreUsers render explore users page
  390. func ExploreUsers(ctx *context.Context) {
  391. ctx.Data["Title"] = ctx.Tr("explore")
  392. ctx.Data["PageIsExplore"] = true
  393. ctx.Data["PageIsExploreUsers"] = true
  394. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  395. RenderUserSearch(ctx, &models.SearchUserOptions{
  396. Actor: ctx.User,
  397. Type: models.UserTypeIndividual,
  398. ListOptions: models.ListOptions{PageSize: setting.UI.ExplorePagingNum},
  399. IsActive: util.OptionalBoolTrue,
  400. Visible: []structs.VisibleType{structs.VisibleTypePublic, structs.VisibleTypeLimited, structs.VisibleTypePrivate},
  401. }, tplExploreUsers)
  402. }
  403. // ExploreOrganizations render explore organizations page
  404. func ExploreOrganizations(ctx *context.Context) {
  405. ctx.Data["Title"] = ctx.Tr("explore")
  406. ctx.Data["PageIsExplore"] = true
  407. ctx.Data["PageIsExploreOrganizations"] = true
  408. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  409. N := 10
  410. starInfo, err := models.FindTopNStarsOrgs(N)
  411. if err != nil {
  412. log.Error("GetStarOrgInfos failed:%v", err.Error(), ctx.Data["MsgID"])
  413. ctx.ServerError("GetStarOrgInfos", err)
  414. return
  415. }
  416. memberInfo, err := models.FindTopNMembersOrgs(N)
  417. if err != nil {
  418. log.Error("GetMemberOrgInfos failed:%v", err.Error(), ctx.Data["MsgID"])
  419. ctx.ServerError("GetMemberOrgInfos", err)
  420. return
  421. }
  422. openIInfo, err := models.FindTopNOpenIOrgs(N)
  423. if err != nil {
  424. log.Error("GetOpenIOrgInfos failed:%v", err.Error(), ctx.Data["MsgID"])
  425. ctx.ServerError("GetOpenIOrgInfos", err)
  426. return
  427. }
  428. recommendOrgs, err := GetRecommendOrg()
  429. if err != nil {
  430. log.Error("GetRecommendOrgInfos failed:%v", err.Error(), ctx.Data["MsgID"])
  431. ctx.ServerError("GetRecommendOrgInfos", err)
  432. return
  433. }
  434. setRecommendURLOnly(ctx)
  435. ctx.Data["RecommendOrgs"] = recommendOrgs
  436. ctx.Data["StarOrgs"] = starInfo
  437. ctx.Data["MemberOrgs"] = memberInfo
  438. ctx.Data["ActiveOrgs"] = openIInfo
  439. ctx.HTML(http.StatusOK, tplExploreOrganizations)
  440. }
  441. // ExploreCode render explore code page
  442. func ExploreCode(ctx *context.Context) {
  443. if !setting.Indexer.RepoIndexerEnabled {
  444. ctx.Redirect(setting.AppSubURL+"/explore", 302)
  445. return
  446. }
  447. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  448. ctx.Data["Title"] = ctx.Tr("explore")
  449. ctx.Data["PageIsExplore"] = true
  450. ctx.Data["PageIsExploreCode"] = true
  451. language := strings.TrimSpace(ctx.Query("l"))
  452. keyword := strings.TrimSpace(ctx.Query("q"))
  453. page := ctx.QueryInt("page")
  454. if page <= 0 {
  455. page = 1
  456. }
  457. var (
  458. repoIDs []int64
  459. err error
  460. isAdmin bool
  461. userID int64
  462. )
  463. if ctx.User != nil {
  464. userID = ctx.User.ID
  465. isAdmin = ctx.User.IsAdmin
  466. }
  467. // guest user or non-admin user
  468. if ctx.User == nil || !isAdmin {
  469. repoIDs, err = models.FindUserAccessibleRepoIDs(ctx.User)
  470. if err != nil {
  471. ctx.ServerError("SearchResults", err)
  472. return
  473. }
  474. }
  475. var (
  476. total int
  477. searchResults []*code_indexer.Result
  478. searchResultLanguages []*code_indexer.SearchResultLanguages
  479. )
  480. // if non-admin login user, we need check UnitTypeCode at first
  481. if ctx.User != nil && len(repoIDs) > 0 {
  482. repoMaps, err := models.GetRepositoriesMapByIDs(repoIDs)
  483. if err != nil {
  484. ctx.ServerError("SearchResults", err)
  485. return
  486. }
  487. var rightRepoMap = make(map[int64]*models.Repository, len(repoMaps))
  488. repoIDs = make([]int64, 0, len(repoMaps))
  489. for id, repo := range repoMaps {
  490. if repo.CheckUnitUser(userID, isAdmin, models.UnitTypeCode) {
  491. rightRepoMap[id] = repo
  492. repoIDs = append(repoIDs, id)
  493. }
  494. }
  495. ctx.Data["RepoMaps"] = rightRepoMap
  496. total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum)
  497. if err != nil {
  498. ctx.ServerError("SearchResults", err)
  499. return
  500. }
  501. // if non-login user or isAdmin, no need to check UnitTypeCode
  502. } else if (ctx.User == nil && len(repoIDs) > 0) || isAdmin {
  503. total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum)
  504. if err != nil {
  505. ctx.ServerError("SearchResults", err)
  506. return
  507. }
  508. var loadRepoIDs = make([]int64, 0, len(searchResults))
  509. for _, result := range searchResults {
  510. var find bool
  511. for _, id := range loadRepoIDs {
  512. if id == result.RepoID {
  513. find = true
  514. break
  515. }
  516. }
  517. if !find {
  518. loadRepoIDs = append(loadRepoIDs, result.RepoID)
  519. }
  520. }
  521. repoMaps, err := models.GetRepositoriesMapByIDs(loadRepoIDs)
  522. if err != nil {
  523. ctx.ServerError("SearchResults", err)
  524. return
  525. }
  526. ctx.Data["RepoMaps"] = repoMaps
  527. }
  528. ctx.Data["Keyword"] = keyword
  529. ctx.Data["Language"] = language
  530. ctx.Data["SearchResults"] = searchResults
  531. ctx.Data["SearchResultLanguages"] = searchResultLanguages
  532. ctx.Data["RequireHighlightJS"] = true
  533. ctx.Data["PageIsViewCode"] = true
  534. pager := context.NewPagination(total, setting.UI.RepoSearchPagingNum, page, 5)
  535. pager.SetDefaultParams(ctx)
  536. pager.AddParam(ctx, "l", "Language")
  537. ctx.Data["Page"] = pager
  538. ctx.HTML(200, tplExploreCode)
  539. }
  540. func ExploreImages(ctx *context.Context) {
  541. ctx.HTML(200, tplExploreImages)
  542. }
  543. func ExploreDataAnalysisUserTrend(ctx *context.Context) {
  544. ctx.Data["url_params"]="UserTrend"
  545. ctx.HTML(200, tplExploreExploreDataAnalysis)
  546. }
  547. func ExploreDataAnalysisUserAnalysis(ctx *context.Context) {
  548. ctx.Data["url_params"]="UserAnalysis"
  549. ctx.HTML(200, tplExploreExploreDataAnalysis)
  550. }
  551. func ExploreDataAnalysisProTrend(ctx *context.Context) {
  552. ctx.Data["url_params"]="ProTrend"
  553. ctx.HTML(200, tplExploreExploreDataAnalysis)
  554. }
  555. func ExploreDataAnalysisProAnalysis(ctx *context.Context) {
  556. ctx.Data["url_params"]="ProAnalysis"
  557. ctx.HTML(200, tplExploreExploreDataAnalysis)
  558. }
  559. func ExploreDataAnalysisOverview(ctx *context.Context) {
  560. ctx.Data["url_params"]="Overview"
  561. ctx.HTML(200, tplExploreExploreDataAnalysis)
  562. }
  563. func ExploreDataAnalysisBrainAnalysis(ctx *context.Context) {
  564. ctx.Data["url_params"]="BrainAnalysis"
  565. ctx.HTML(200, tplExploreExploreDataAnalysis)
  566. }
  567. func ExploreDataAnalysis(ctx *context.Context) {
  568. ctx.Data["url_params"]=""
  569. ctx.HTML(200, tplExploreExploreDataAnalysis)
  570. }
  571. // NotFound render 404 page
  572. func NotFound(ctx *context.Context) {
  573. ctx.Data["Title"] = "Page Not Found"
  574. ctx.NotFound("home.NotFound", nil)
  575. }
  576. func GetRecommendOrg() ([]map[string]interface{}, error) {
  577. url := setting.RecommentRepoAddr + "organizations"
  578. result, err := repository.RecommendFromPromote(url)
  579. if err != nil {
  580. return nil, err
  581. }
  582. resultOrg := make([]map[string]interface{}, 0)
  583. for _, userName := range result {
  584. user, err := models.GetUserByName(userName)
  585. if err == nil {
  586. userMap := make(map[string]interface{})
  587. userMap["Name"] = user.Name
  588. userMap["Description"] = user.Description
  589. userMap["FullName"] = user.FullName
  590. userMap["HomeLink"] = user.HomeLink()
  591. userMap["ID"] = user.ID
  592. userMap["Avatar"] = user.RelAvatarLink()
  593. userMap["NumRepos"] = user.NumRepos
  594. userMap["NumTeams"] = user.NumTeams
  595. userMap["NumMembers"] = user.NumMembers
  596. resultOrg = append(resultOrg, userMap)
  597. } else {
  598. log.Info("query user error," + err.Error())
  599. }
  600. }
  601. return resultOrg, nil
  602. }
  603. func GetImageInfo() ([]map[string]interface{}, error) {
  604. url := setting.RecommentRepoAddr + "picture_info"
  605. result, err := repository.RecommendFromPromote(url)
  606. if err != nil {
  607. return nil, err
  608. }
  609. imageInfo := make([]map[string]interface{}, 0)
  610. for i := 0; i < (len(result) - 1); i++ {
  611. line := result[i]
  612. imageMap := make(map[string]interface{})
  613. if line[0:4] == "url=" {
  614. url := line[4:]
  615. imageMap["url"] = url
  616. if result[i+1][0:11] == "image_link=" {
  617. image_link := result[i+1][11:]
  618. imageMap["image_link"] = image_link
  619. }
  620. }
  621. imageInfo = append(imageInfo, imageMap)
  622. i = i + 1
  623. }
  624. return imageInfo, nil
  625. }
  626. func GetRankUser(index string) ([]map[string]interface{}, error) {
  627. url := setting.RecommentRepoAddr + "user_rank_" + index
  628. result, err := repository.RecommendFromPromote(url)
  629. if err != nil {
  630. return nil, err
  631. }
  632. resultOrg := make([]map[string]interface{}, 0)
  633. for _, userRank := range result {
  634. tmpIndex := strings.Index(userRank, " ")
  635. userName := userRank
  636. score := 0
  637. if tmpIndex != -1 {
  638. userName = userRank[0:tmpIndex]
  639. tmpScore, err := strconv.Atoi(userRank[tmpIndex+1:])
  640. if err != nil {
  641. log.Info("convert to int error.")
  642. }
  643. score = tmpScore
  644. }
  645. user, err := models.GetUserByName(userName)
  646. if err == nil {
  647. userMap := make(map[string]interface{})
  648. userMap["Name"] = user.Name
  649. userMap["Description"] = user.Description
  650. userMap["FullName"] = user.FullName
  651. userMap["HomeLink"] = user.HomeLink()
  652. userMap["ID"] = user.ID
  653. userMap["Avatar"] = user.RelAvatarLink()
  654. userMap["Score"] = score
  655. resultOrg = append(resultOrg, userMap)
  656. } else {
  657. log.Info("query user error," + err.Error())
  658. }
  659. }
  660. return resultOrg, nil
  661. }
  662. func GetImageInfoFromPromote(ctx *context.Context) {
  663. imageInfo, err := GetImageInfo()
  664. if err != nil {
  665. ctx.ServerError("500", err)
  666. return
  667. }
  668. ctx.JSON(200, imageInfo)
  669. }
  670. func GetUserRankFromPromote(ctx *context.Context) {
  671. index := ctx.Params("index")
  672. resultUserRank, err := GetRankUser(index)
  673. if err != nil {
  674. ctx.ServerError("500", err)
  675. return
  676. }
  677. ctx.JSON(200, resultUserRank)
  678. }
  679. func RecommendOrgFromPromote(ctx *context.Context) {
  680. resultOrg, err := GetRecommendOrg()
  681. if err != nil {
  682. ctx.ServerError("500", err)
  683. return
  684. }
  685. ctx.JSON(200, resultOrg)
  686. }
  687. func RecommendRepoFromPromote(ctx *context.Context) {
  688. result, err := repository.GetRecommendRepoFromPromote("projects")
  689. if err != nil {
  690. ctx.ServerError("500", err)
  691. } else {
  692. ctx.JSON(200, result)
  693. }
  694. }
  695. func HomeTerm(ctx *context.Context) {
  696. ctx.HTML(200, tplHomeTerm)
  697. }