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

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