From e1a4833ba1088dcd3cce041934cd87a9261851a9 Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Tue, 21 Dec 2021 11:01:17 +0800 Subject: [PATCH 1/4] #981 1. submit tag 2. query tag repo list --- models/error.go | 13 +++++ models/models.go | 2 + models/repo_tag.go | 107 +++++++++++++++++++++++++++++++++++++++ modules/auth/org.go | 4 ++ routers/org/tag.go | 98 +++++++++++++++++++++++++++++++++++ routers/routes/routes.go | 4 ++ 6 files changed, 228 insertions(+) create mode 100644 models/repo_tag.go create mode 100644 routers/org/tag.go diff --git a/models/error.go b/models/error.go index 9d1c68658..46917e15e 100755 --- a/models/error.go +++ b/models/error.go @@ -1999,3 +1999,16 @@ func IsErrJobNotExist(err error) bool { func (err ErrJobNotExist) Error() string { 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 +} diff --git a/models/models.go b/models/models.go index e8a71bbd8..a72ebe5db 100755 --- a/models/models.go +++ b/models/models.go @@ -134,6 +134,8 @@ func init() { new(BlockChain), new(RecommendOrg), new(AiModelManage), + new(OfficialTag), + new(OfficialTagRepos), ) tablesStatistic = append(tablesStatistic, diff --git a/models/repo_tag.go b/models/repo_tag.go new file mode 100644 index 000000000..6f3cc510f --- /dev/null +++ b/models/repo_tag.go @@ -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 +} diff --git a/modules/auth/org.go b/modules/auth/org.go index 20e2b0999..9642e1ce6 100644 --- a/modules/auth/org.go +++ b/modules/auth/org.go @@ -70,3 +70,7 @@ type CreateTeamForm struct { func (f *CreateTeamForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { return validate(errs, ctx.Data, f, ctx.Locale) } + +type SubmitReposOfTagForm struct { + RepoList []int64 +} diff --git a/routers/org/tag.go b/routers/org/tag.go new file mode 100644 index 000000000..650d4690c --- /dev/null +++ b/routers/org/tag.go @@ -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 +} diff --git a/routers/routes/routes.go b/routers/routes/routes.go index cfd962603..c3a8b4abd 100755 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -627,6 +627,10 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/org", func() { m.Group("/:org", func() { 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()) }) m.Group("/org", func() { From 74c9595aac9011cd5c115f22a4709527b92a0b83 Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Tue, 21 Dec 2021 14:33:11 +0800 Subject: [PATCH 2/4] #981 add tag in org index --- models/repo_tag.go | 48 ++++++++++++++++++++++++++++++++++++++++++++- routers/org/home.go | 8 ++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/models/repo_tag.go b/models/repo_tag.go index 6f3cc510f..579a6cf5f 100644 --- a/models/repo_tag.go +++ b/models/repo_tag.go @@ -36,6 +36,24 @@ type TagReposSelected struct { Selected bool } +type TagsDetail struct { + TagId int64 + TagName string + RepoList []RepositoryForTag +} + +type RepositoryForTag struct { + TagId int64 + TagName string + ID int64 + Name string + Description string + NumWatches int + NumStars int + NumForks int + Topics []string +} + func GetTagByID(id int64) (*OfficialTag, error) { r := &OfficialTag{ ID: id, @@ -84,7 +102,6 @@ func UpdateTagReposByID(tagID, orgID int64, repoIdList []int64) error { } 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" @@ -105,3 +122,32 @@ func GetTagRepos(tagID, orgID int64) ([]TagReposSelected, error) { } return r, nil } + +func GetTagsDetails(orgID int64) ([]TagsDetail, error) { + t := make([]RepositoryForTag, 0) + const SQLCmd = "select t1.tag_id ,t3.name as tag_name,t2.* from official_tag_repos t1 inner join repository t2 on t1.repo_id = t2.id inner join official_tag t3 on t1.tag_id = t3.id where t1.org_id = ?" + + if err := x.SQL(SQLCmd, orgID).Find(&t); err != nil { + return nil, err + } + r := make([]TagsDetail, 0) + tempMap := make(map[int64]TagsDetail, 0) + for _, v := range t { + tagId := v.TagId + detail, ok := tempMap[tagId] + if !ok { + detail = TagsDetail{ + TagId: v.TagId, + TagName: v.TagName, + RepoList: make([]RepositoryForTag, 0), + } + } + detail.RepoList = append(detail.RepoList, v) + tempMap[tagId] = detail + } + + for _, v := range tempMap { + r = append(r, v) + } + return r, nil +} diff --git a/routers/org/home.go b/routers/org/home.go index b11c179c1..1a80f001f 100755 --- a/routers/org/home.go +++ b/routers/org/home.go @@ -130,5 +130,13 @@ func Home(ctx *context.Context) { pager.SetDefaultParams(ctx) ctx.Data["Page"] = pager + //find org tag info + tags, err := models.GetTagsDetails(org.ID) + if err != nil { + ctx.ServerError("GetTagsDetails", err) + return + } + + ctx.Data["tags"] = tags ctx.HTML(200, tplOrgHome) } From 535835416b52439e50076f788452923c38d3115b Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Tue, 21 Dec 2021 15:08:28 +0800 Subject: [PATCH 3/4] #981 add sql --- models/migrations/migrations.go | 2 ++ models/migrations/v140.go | 31 +++++++++++++++++++++++++++++++ models/repo_tag.go | 1 + 3 files changed, 34 insertions(+) create mode 100644 models/migrations/v140.go diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 00d84da2e..e134a875e 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -212,6 +212,8 @@ var migrations = []Migration{ NewMigration("Add ResolveDoerID to Comment table", addResolveDoerIDCommentColumn), // v139 -> v140 NewMigration("prepend refs/heads/ to issue refs", prependRefsHeadsToIssueRefs), + // v140 -> v141 + NewMigration("init selected tag", initSelectedTag), } // GetCurrentDBVersion returns the current db version diff --git a/models/migrations/v140.go b/models/migrations/v140.go new file mode 100644 index 000000000..5684dba44 --- /dev/null +++ b/models/migrations/v140.go @@ -0,0 +1,31 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package migrations + +import ( + "code.gitea.io/gitea/models" + "xorm.io/xorm" +) + +func initSelectedTag(x *xorm.Engine) error { + p := &models.OfficialTag{ + Code: "Selected", + } + + ok, err := x.Get(p) + + if ok { + return nil + } + + t := &models.OfficialTag{ + ID: 1, + Code: "Selected", + Name: "精选项目", + Limit: 9, + } + _, err = x.Insert(t) + return err +} diff --git a/models/repo_tag.go b/models/repo_tag.go index 579a6cf5f..21e742082 100644 --- a/models/repo_tag.go +++ b/models/repo_tag.go @@ -10,6 +10,7 @@ const DefaultOrgTagLimit = -1 type OfficialTag struct { ID int64 `xorm:"pk autoincr"` Name string `xorm:"NOT NULL"` + Code string `xorm:"NOT NULL"` Limit int `xorm:"NOT NULL default(-1)"` CreatedUnix timeutil.TimeStamp `xorm:"created"` UpdatedUnix timeutil.TimeStamp `xorm:"updated"` From 35fbd89eba87c547ca0f70a19c89e39d1335a091 Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Tue, 21 Dec 2021 15:15:04 +0800 Subject: [PATCH 4/4] #981 delete sql --- models/migrations/migrations.go | 2 -- models/migrations/v140.go | 31 ------------------------------- 2 files changed, 33 deletions(-) delete mode 100644 models/migrations/v140.go diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index e134a875e..00d84da2e 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -212,8 +212,6 @@ var migrations = []Migration{ NewMigration("Add ResolveDoerID to Comment table", addResolveDoerIDCommentColumn), // v139 -> v140 NewMigration("prepend refs/heads/ to issue refs", prependRefsHeadsToIssueRefs), - // v140 -> v141 - NewMigration("init selected tag", initSelectedTag), } // GetCurrentDBVersion returns the current db version diff --git a/models/migrations/v140.go b/models/migrations/v140.go deleted file mode 100644 index 5684dba44..000000000 --- a/models/migrations/v140.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2019 The Gitea Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package migrations - -import ( - "code.gitea.io/gitea/models" - "xorm.io/xorm" -) - -func initSelectedTag(x *xorm.Engine) error { - p := &models.OfficialTag{ - Code: "Selected", - } - - ok, err := x.Get(p) - - if ok { - return nil - } - - t := &models.OfficialTag{ - ID: 1, - Code: "Selected", - Name: "精选项目", - Limit: 9, - } - _, err = x.Insert(t) - return err -}