| @@ -129,6 +129,7 @@ func init() { | |||||
| new(Cloudbrain), | new(Cloudbrain), | ||||
| new(FileChunk), | new(FileChunk), | ||||
| new(BlockChain), | new(BlockChain), | ||||
| new(RecommendOrg), | |||||
| ) | ) | ||||
| gonicNames := []string{"SSL", "UID"} | gonicNames := []string{"SSL", "UID"} | ||||
| @@ -0,0 +1,48 @@ | |||||
| package models | |||||
| import ( | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/timeutil" | |||||
| ) | |||||
| type RecommendOrg struct { | |||||
| ID int64 `xorm:"pk autoincr"` | |||||
| Order int64 `xorm:"INDEX NOT NULL unique"` | |||||
| OrgID int64 `xorm:"INDEX NOT NULL unique"` | |||||
| CreatedUnix timeutil.TimeStamp `xorm:"created"` | |||||
| Org *User `xorm:"-"` | |||||
| } | |||||
| type RecommendOrgList []*RecommendOrg | |||||
| func getRecommendOrgs(e Engine) (RecommendOrgList, error) { | |||||
| orgs := make(RecommendOrgList, 0, 10) | |||||
| err := e.Asc("order"). | |||||
| Find(&orgs) | |||||
| return orgs, err | |||||
| } | |||||
| func GetRecommendOrgs() (RecommendOrgList, error) { | |||||
| return getRecommendOrgs(x) | |||||
| } | |||||
| func delRecommendOrgs(e Engine) error { | |||||
| sql := "delete from recommend_org" | |||||
| _, err := e.Exec(sql) | |||||
| return err | |||||
| } | |||||
| func UpdateRecommendOrgs(orgs RecommendOrgList) error { | |||||
| if err := delRecommendOrgs(x); err != nil { | |||||
| log.Error("delRecommendOrgs failed:%v", err.Error()) | |||||
| return err | |||||
| } | |||||
| if _, err := x.Insert(&orgs); err != nil { | |||||
| log.Error("Insert failed:%v", err.Error()) | |||||
| return err | |||||
| } | |||||
| return nil | |||||
| } | |||||
| @@ -199,7 +199,7 @@ const ( | |||||
| SearchOrderByForksReverse SearchOrderBy = "num_forks DESC" | SearchOrderByForksReverse SearchOrderBy = "num_forks DESC" | ||||
| SearchOrderByDownloadTimes SearchOrderBy = "download_times DESC" | SearchOrderByDownloadTimes SearchOrderBy = "download_times DESC" | ||||
| SearchOrderByHot SearchOrderBy = "(num_watches + num_stars + num_forks + clone_cnt) DESC" | SearchOrderByHot SearchOrderBy = "(num_watches + num_stars + num_forks + clone_cnt) DESC" | ||||
| SearchOrderByActive SearchOrderBy = "(num_issues + num_pulls) DESC" | |||||
| SearchOrderByActive SearchOrderBy = "(num_issues + num_pulls + num_commit) DESC" | |||||
| ) | ) | ||||
| // SearchRepositoryCondition creates a query condition according search repository options | // SearchRepositoryCondition creates a query condition according search repository options | ||||
| @@ -26,6 +26,7 @@ type ToggleOptions struct { | |||||
| AdminRequired bool | AdminRequired bool | ||||
| DisableCSRF bool | DisableCSRF bool | ||||
| BasicAuthRequired bool | BasicAuthRequired bool | ||||
| OperationRequired bool | |||||
| } | } | ||||
| // Toggle returns toggle options as middleware | // Toggle returns toggle options as middleware | ||||
| @@ -142,6 +143,15 @@ func Toggle(options *ToggleOptions) macaron.Handler { | |||||
| return | return | ||||
| } | } | ||||
| } | } | ||||
| if options.OperationRequired { | |||||
| //todo: add isOperator judgement | |||||
| if !ctx.User.IsAdmin { | |||||
| ctx.Error(403) | |||||
| return | |||||
| } | |||||
| ctx.Data["PageIsOperation"] = true | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -139,7 +139,7 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) { | |||||
| case "hot": | case "hot": | ||||
| orderBy = models.SearchOrderByHot | orderBy = models.SearchOrderByHot | ||||
| case "active": | case "active": | ||||
| orderBy = models.SearchOrderByHot | |||||
| orderBy = models.SearchOrderByActive | |||||
| default: | default: | ||||
| ctx.Data["SortType"] = "recentupdate" | ctx.Data["SortType"] = "recentupdate" | ||||
| @@ -0,0 +1,64 @@ | |||||
| // Copyright 2014 The Gogs Authors. All rights reserved. | |||||
| // Copyright 2020 The Gitea Authors. | |||||
| // Use of this source code is governed by a MIT-style | |||||
| // license that can be found in the LICENSE file. | |||||
| package operation | |||||
| import ( | |||||
| "code.gitea.io/gitea/models" | |||||
| "code.gitea.io/gitea/modules/base" | |||||
| "code.gitea.io/gitea/modules/context" | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/setting" | |||||
| "code.gitea.io/gitea/modules/structs" | |||||
| "code.gitea.io/gitea/routers" | |||||
| ) | |||||
| const ( | |||||
| tplOrgs base.TplName = "admin/org/list" | |||||
| ) | |||||
| type UpdateRecommendOrgs struct { | |||||
| OrgInfos string `binding:"required"` | |||||
| } | |||||
| type OrgInfo struct { | |||||
| OrgID int64 `json:"org_id"` | |||||
| Order int64 `json:"order"` | |||||
| } | |||||
| type OrgInfos struct { | |||||
| OrgInfo []OrgInfo `json:"org_infos"` | |||||
| } | |||||
| // Organizations show all the organizations recommended | |||||
| func Organizations(ctx *context.Context) { | |||||
| ctx.Data["PageIsAdmin"] = true | |||||
| ctx.Data["PageIsAdminOrganizations"] = true | |||||
| routers.RenderUserSearch(ctx, &models.SearchUserOptions{ | |||||
| Type: models.UserTypeOrganization, | |||||
| ListOptions: models.ListOptions{ | |||||
| PageSize: setting.UI.Admin.OrgPagingNum, | |||||
| }, | |||||
| Visible: []structs.VisibleType{structs.VisibleTypePublic, structs.VisibleTypeLimited, structs.VisibleTypePrivate}, | |||||
| }, tplOrgs) | |||||
| } | |||||
| // UpdateRecommendOrganizations update the organizations recommended | |||||
| func UpdateRecommendOrganizations(ctx *context.Context, req OrgInfos) { | |||||
| orgs := make(models.RecommendOrgList, 0, 10) | |||||
| for _, org := range req.OrgInfo { | |||||
| orgs = append(orgs, &models.RecommendOrg{ | |||||
| OrgID: org.OrgID, | |||||
| Order: org.Order, | |||||
| }) | |||||
| } | |||||
| if err := models.UpdateRecommendOrgs(orgs); err != nil { | |||||
| log.Error("UpdateRecommendOrgs failed:%v", err.Error(), ctx.Data["MsgID"]) | |||||
| ctx.ServerError("UpdateRecommendOrgs failed", err) | |||||
| return | |||||
| } | |||||
| } | |||||
| @@ -520,7 +520,7 @@ func HookPostReceive(ctx *macaron.Context, opts private.HookOptions) { | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if err := updateRepoCommitCnt(ctx, repo); err != nil { | if err := updateRepoCommitCnt(ctx, repo); err != nil { | ||||
| log.Error("updateRepoCommitCnt failed:%v", err.Error(), ctx.Data["MsgID"]) | log.Error("updateRepoCommitCnt failed:%v", err.Error(), ctx.Data["MsgID"]) | ||||
| } | } | ||||
| @@ -6,6 +6,7 @@ package routes | |||||
| import ( | import ( | ||||
| "bytes" | "bytes" | ||||
| "code.gitea.io/gitea/routers/operation" | |||||
| "encoding/gob" | "encoding/gob" | ||||
| "net/http" | "net/http" | ||||
| "path" | "path" | ||||
| @@ -539,6 +540,15 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| }, adminReq) | }, adminReq) | ||||
| // ***** END: Admin ***** | // ***** END: Admin ***** | ||||
| //operationReq := context.Toggle(&context.ToggleOptions{SignInRequired: true, OperationRequired: true}) | |||||
| // ***** START: Operation ***** | |||||
| m.Group("/operation", func() { | |||||
| m.Get("/config/recommend_org", operation.Organizations) | |||||
| m.Post("/config/recommend_org", bindIgnErr(operation.OrgInfos{}), operation.UpdateRecommendOrganizations) | |||||
| }) | |||||
| // ***** END: Operation ***** | |||||
| m.Group("", func() { | m.Group("", func() { | ||||
| m.Get("/:username", user.Profile) | m.Get("/:username", user.Profile) | ||||
| }, ignSignIn) | }, ignSignIn) | ||||