@@ -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 | |||
} |
@@ -134,6 +134,8 @@ func init() { | |||
new(BlockChain), | |||
new(RecommendOrg), | |||
new(AiModelManage), | |||
new(OfficialTag), | |||
new(OfficialTagRepos), | |||
) | |||
tablesStatistic = append(tablesStatistic, | |||
@@ -0,0 +1,154 @@ | |||
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"` | |||
Code 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 | |||
} | |||
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, | |||
} | |||
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 | |||
} | |||
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 | |||
} |
@@ -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 | |||
} |
@@ -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) | |||
} |
@@ -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.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() { | |||