| @@ -1999,3 +1999,16 @@ func IsErrJobNotExist(err error) bool { | |||||
| func (err ErrJobNotExist) Error() string { | func (err ErrJobNotExist) Error() string { | ||||
| return fmt.Sprintf("the job does not exist") | return fmt.Sprintf("the job does not exist") | ||||
| } | } | ||||
| type ErrTagNotExist struct { | |||||
| TagID int64 | |||||
| } | |||||
| func (err ErrTagNotExist) Error() string { | |||||
| return fmt.Sprintf("the tag does not exist") | |||||
| } | |||||
| func IsErrTagNotExist(err error) bool { | |||||
| _, ok := err.(ErrTagNotExist) | |||||
| return ok | |||||
| } | |||||
| @@ -134,6 +134,8 @@ func init() { | |||||
| new(BlockChain), | new(BlockChain), | ||||
| new(RecommendOrg), | new(RecommendOrg), | ||||
| new(AiModelManage), | new(AiModelManage), | ||||
| new(OfficialTag), | |||||
| new(OfficialTagRepos), | |||||
| ) | ) | ||||
| tablesStatistic = append(tablesStatistic, | tablesStatistic = append(tablesStatistic, | ||||
| @@ -0,0 +1,107 @@ | |||||
| package models | |||||
| import ( | |||||
| "code.gitea.io/gitea/modules/timeutil" | |||||
| "fmt" | |||||
| ) | |||||
| const DefaultOrgTagLimit = -1 | |||||
| type OfficialTag struct { | |||||
| ID int64 `xorm:"pk autoincr"` | |||||
| Name string `xorm:"NOT NULL"` | |||||
| Limit int `xorm:"NOT NULL default(-1)"` | |||||
| CreatedUnix timeutil.TimeStamp `xorm:"created"` | |||||
| UpdatedUnix timeutil.TimeStamp `xorm:"updated"` | |||||
| } | |||||
| type OfficialTagRepos struct { | |||||
| ID int64 `xorm:"pk autoincr"` | |||||
| OrgID int64 `xorm:"NOT NULL INDEX"` | |||||
| TagID int64 `xorm:"NOT NULL"` | |||||
| RepoID int64 `xorm:"NOT NULL INDEX"` | |||||
| CreatedUnix timeutil.TimeStamp `xorm:"created"` | |||||
| UpdatedUnix timeutil.TimeStamp `xorm:"updated"` | |||||
| } | |||||
| type TagReposBrief struct { | |||||
| RepoID int64 | |||||
| RepoName string | |||||
| TagID int64 | |||||
| } | |||||
| type TagReposSelected struct { | |||||
| RepoID int64 | |||||
| RepoName string | |||||
| Selected bool | |||||
| } | |||||
| func GetTagByID(id int64) (*OfficialTag, error) { | |||||
| r := &OfficialTag{ | |||||
| ID: id, | |||||
| } | |||||
| has, err := x.Get(r) | |||||
| if err != nil { | |||||
| return nil, err | |||||
| } else if !has { | |||||
| return nil, ErrTagNotExist{0} | |||||
| } | |||||
| return r, nil | |||||
| } | |||||
| func UpdateTagReposByID(tagID, orgID int64, repoIdList []int64) error { | |||||
| sess := x.NewSession() | |||||
| defer sess.Close() | |||||
| if err := sess.Begin(); err != nil { | |||||
| return fmt.Errorf("UpdateTagReposByID[tagId: %d, orgID: %d,error:%v", tagID, orgID, err) | |||||
| } | |||||
| //delete old tag repos | |||||
| r := &OfficialTagRepos{ | |||||
| TagID: tagID, | |||||
| OrgID: orgID, | |||||
| } | |||||
| _, err := sess.Delete(r) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| //add new tag repos | |||||
| data := make([]*OfficialTagRepos, 0) | |||||
| for _, repoId := range repoIdList { | |||||
| data = append(data, &OfficialTagRepos{ | |||||
| OrgID: orgID, | |||||
| TagID: tagID, | |||||
| RepoID: repoId, | |||||
| }) | |||||
| } | |||||
| _, err = sess.Insert(&data) | |||||
| if err != nil { | |||||
| sess.Rollback() | |||||
| return err | |||||
| } | |||||
| return sess.Commit() | |||||
| } | |||||
| func GetTagRepos(tagID, orgID int64) ([]TagReposSelected, error) { | |||||
| t := make([]TagReposBrief, 0) | |||||
| const SQLCmd = "select t1.id as repo_id,t1.name as repo_name,t2.id as tag_id from repository t1 left join official_tag_repos t2 on (t1.id = t2.repo_id and t2.tag_id = ?) where t1.owner_id = ? and t1.is_private = false" | |||||
| if err := x.SQL(SQLCmd, tagID, orgID).Find(&t); err != nil { | |||||
| return nil, err | |||||
| } | |||||
| r := make([]TagReposSelected, 0) | |||||
| for _, v := range t { | |||||
| selected := false | |||||
| if v.TagID > 0 { | |||||
| selected = true | |||||
| } | |||||
| r = append(r, TagReposSelected{ | |||||
| RepoID: v.RepoID, | |||||
| RepoName: v.RepoName, | |||||
| Selected: selected, | |||||
| }) | |||||
| } | |||||
| return r, nil | |||||
| } | |||||
| @@ -70,3 +70,7 @@ type CreateTeamForm struct { | |||||
| func (f *CreateTeamForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | func (f *CreateTeamForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | ||||
| return validate(errs, ctx.Data, f, ctx.Locale) | return validate(errs, ctx.Data, f, ctx.Locale) | ||||
| } | } | ||||
| type SubmitReposOfTagForm struct { | |||||
| RepoList []int64 | |||||
| } | |||||
| @@ -0,0 +1,98 @@ | |||||
| // 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 org | |||||
| import ( | |||||
| "code.gitea.io/gitea/models" | |||||
| "code.gitea.io/gitea/modules/auth" | |||||
| "code.gitea.io/gitea/modules/context" | |||||
| "errors" | |||||
| "strconv" | |||||
| ) | |||||
| // SubmitTags submit repos of org tag | |||||
| func SubmitTags(ctx *context.Context, form auth.SubmitReposOfTagForm) { | |||||
| org, tag := getOrgAndTagFromContext(ctx) | |||||
| if ctx.Written() { | |||||
| return | |||||
| } | |||||
| err := models.UpdateTagReposByID(tag.ID, org.ID, form.RepoList) | |||||
| if err != nil { | |||||
| ctx.ServerError("UpdateTagReposByID", err) | |||||
| return | |||||
| } | |||||
| ctx.JSON(200, map[string]interface{}{ | |||||
| "code": "00", | |||||
| "msg": "success", | |||||
| }) | |||||
| } | |||||
| // GetTagRepos get repos under org tag | |||||
| func GetTagRepos(ctx *context.Context) { | |||||
| org, tag := getOrgAndTagFromContext(ctx) | |||||
| if ctx.Written() { | |||||
| return | |||||
| } | |||||
| r, err := models.GetTagRepos(tag.ID, org.ID) | |||||
| if err != nil { | |||||
| ctx.ServerError("GetTagRepos", err) | |||||
| return | |||||
| } | |||||
| ctx.JSON(200, map[string]interface{}{ | |||||
| "code": "00", | |||||
| "msg": "success", | |||||
| "data": r, | |||||
| }) | |||||
| } | |||||
| // getDashboardContextUser finds out dashboard is viewing as which context user. | |||||
| func getOrgAndTagFromContext(ctx *context.Context) (*models.User, *models.OfficialTag) { | |||||
| var org *models.User | |||||
| var tag *models.OfficialTag | |||||
| var err error | |||||
| orgName := ctx.Params(":org") | |||||
| if len(orgName) > 0 { | |||||
| // Organization. | |||||
| org, err = models.GetUserByName(orgName) | |||||
| if err != nil { | |||||
| if models.IsErrUserNotExist(err) { | |||||
| ctx.NotFound("GetUserByName", err) | |||||
| } else { | |||||
| ctx.ServerError("GetUserByName", err) | |||||
| } | |||||
| return nil, nil | |||||
| } | |||||
| if !org.IsOrganization() { | |||||
| ctx.ServerError("GetUserByName", errors.New("it is not an organization")) | |||||
| return nil, nil | |||||
| } | |||||
| } | |||||
| tagIdStr := ctx.Query("tagId") | |||||
| if len(tagIdStr) == 0 { | |||||
| ctx.ServerError("GetTagInfo", errors.New("tag is not exist")) | |||||
| return nil, nil | |||||
| } | |||||
| tagId, _ := strconv.ParseInt(tagIdStr, 10, 32) | |||||
| tag, err = models.GetTagByID(tagId) | |||||
| if err != nil { | |||||
| if models.IsErrTagNotExist(err) { | |||||
| ctx.NotFound("GetTagInfo", err) | |||||
| } else { | |||||
| ctx.ServerError("GetTagInfo", err) | |||||
| } | |||||
| return nil, nil | |||||
| } | |||||
| return org, tag | |||||
| } | |||||
| @@ -627,6 +627,10 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Group("/org", func() { | m.Group("/org", func() { | ||||
| m.Group("/:org", func() { | m.Group("/:org", func() { | ||||
| m.Get("/members", org.Members) | m.Get("/members", org.Members) | ||||
| m.Group("/org_tag", func() { | |||||
| m.Get("/repo_list", org.GetTagRepos) | |||||
| m.Post("/repo_submit", bindIgnErr(auth.SubmitReposOfTagForm{}), org.SubmitTags) | |||||
| }) | |||||
| }, context.OrgAssignment()) | }, context.OrgAssignment()) | ||||
| }) | }) | ||||
| m.Group("/org", func() { | m.Group("/org", func() { | ||||