@@ -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,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 { | 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 | |||||
} |
@@ -130,5 +130,13 @@ func Home(ctx *context.Context) { | |||||
pager.SetDefaultParams(ctx) | pager.SetDefaultParams(ctx) | ||||
ctx.Data["Page"] = pager | 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) | 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.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() { | ||||