mirror of
https://github.com/go-gitea/gitea
synced 2025-12-07 13:28:25 +00:00
Implemented Badge Management in administration panel (#29798)
Co-authored-by: Diogo Vicente <diogo.m.s.vicente@tecnico.ulisboa.pt>
This commit is contained in:
committed by
Henrique Pimentel
co-authored by
Diogo Vicente
parent
7adf8d7727
commit
8b86c3140a
+159
-2
@@ -6,8 +6,14 @@ package user
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"xorm.io/builder"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
// Badge represents a user badge
|
||||
@@ -30,6 +36,10 @@ func init() {
|
||||
db.RegisterModel(new(UserBadge))
|
||||
}
|
||||
|
||||
func AdminCreateBadge(ctx context.Context, badge *Badge) error {
|
||||
return CreateBadge(ctx, badge)
|
||||
}
|
||||
|
||||
// GetUserBadges returns the user's badges.
|
||||
func GetUserBadges(ctx context.Context, u *User) ([]*Badge, int64, error) {
|
||||
sess := db.GetEngine(ctx).
|
||||
@@ -42,9 +52,30 @@ func GetUserBadges(ctx context.Context, u *User) ([]*Badge, int64, error) {
|
||||
return badges, count, err
|
||||
}
|
||||
|
||||
// GetBadgeUsers returns the badges users.
|
||||
func GetBadgeUsers(ctx context.Context, b *Badge) ([]*User, int64, error) {
|
||||
sess := db.GetEngine(ctx).
|
||||
Select("`user`.*").
|
||||
Join("INNER", "user_badge", "`user_badge`.user_id=user.id").
|
||||
Where("user_badge.badge_id=?", b.ID)
|
||||
|
||||
users := make([]*User, 0, 8)
|
||||
count, err := sess.FindAndCount(&users)
|
||||
return users, count, err
|
||||
}
|
||||
|
||||
// CreateBadge creates a new badge.
|
||||
func CreateBadge(ctx context.Context, badge *Badge) error {
|
||||
_, err := db.GetEngine(ctx).Insert(badge)
|
||||
isExist, err := IsBadgeExist(ctx, 0, badge.Slug)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if isExist {
|
||||
return ErrBadgeAlreadyExist{badge.Slug}
|
||||
}
|
||||
|
||||
_, err = db.GetEngine(ctx).Insert(badge)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -58,9 +89,22 @@ func GetBadge(ctx context.Context, slug string) (*Badge, error) {
|
||||
return badge, err
|
||||
}
|
||||
|
||||
// GetBadgeByID returns a badge
|
||||
func GetBadgeByID(ctx context.Context, id int64) (*Badge, error) {
|
||||
badge := new(Badge)
|
||||
has, err := db.GetEngine(ctx).Where("id=?", id).Get(badge)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrBadgeNotExist{ID: id}
|
||||
}
|
||||
|
||||
return badge, err
|
||||
}
|
||||
|
||||
// UpdateBadge updates a badge based on its slug.
|
||||
func UpdateBadge(ctx context.Context, badge *Badge) error {
|
||||
_, err := db.GetEngine(ctx).Where("slug=?", badge.Slug).Update(badge)
|
||||
_, err := db.GetEngine(ctx).Where("id=?", badge.ID).Cols("slug", "description", "image_url").Update(badge)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -70,6 +114,15 @@ func DeleteBadge(ctx context.Context, badge *Badge) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteUserBadgeRecord deletes a user badge record.
|
||||
func DeleteUserBadgeRecord(ctx context.Context, badge *Badge) error {
|
||||
userBadge := &UserBadge{
|
||||
BadgeID: badge.ID,
|
||||
}
|
||||
_, err := db.GetEngine(ctx).Where("badge_id=?", userBadge.BadgeID).Delete(userBadge)
|
||||
return err
|
||||
}
|
||||
|
||||
// AddUserBadge adds a badge to a user.
|
||||
func AddUserBadge(ctx context.Context, u *User, badge *Badge) error {
|
||||
return AddUserBadges(ctx, u, []*Badge{badge})
|
||||
@@ -122,3 +175,107 @@ func RemoveAllUserBadges(ctx context.Context, u *User) error {
|
||||
_, err := db.GetEngine(ctx).Where("user_id=?", u.ID).Delete(&UserBadge{})
|
||||
return err
|
||||
}
|
||||
|
||||
// HTMLURL returns the badges full link.
|
||||
func (u *Badge) HTMLURL() string {
|
||||
return setting.AppURL + url.PathEscape(u.Slug)
|
||||
}
|
||||
|
||||
// IsBadgeExist checks if given badge slug exist,
|
||||
// it is used when creating/updating a badge slug
|
||||
func IsBadgeExist(ctx context.Context, uid int64, slug string) (bool, error) {
|
||||
if len(slug) == 0 {
|
||||
return false, nil
|
||||
}
|
||||
return db.GetEngine(ctx).
|
||||
Where("slug!=?", uid).
|
||||
Get(&Badge{Slug: strings.ToLower(slug)})
|
||||
}
|
||||
|
||||
// SearchBadgeOptions represents the options when fdin badges
|
||||
type SearchBadgeOptions struct {
|
||||
db.ListOptions
|
||||
|
||||
Keyword string
|
||||
Slug string
|
||||
ID int64
|
||||
OrderBy db.SearchOrderBy
|
||||
Actor *User // The user doing the search
|
||||
|
||||
ExtraParamStrings map[string]string
|
||||
}
|
||||
|
||||
func (opts *SearchBadgeOptions) ToConds() builder.Cond {
|
||||
cond := builder.NewCond()
|
||||
|
||||
if opts.Keyword != "" {
|
||||
cond = cond.And(builder.Like{"badge.slug", opts.Keyword})
|
||||
}
|
||||
|
||||
return cond
|
||||
}
|
||||
|
||||
func (opts *SearchBadgeOptions) ToOrders() string {
|
||||
orderBy := "badge.slug"
|
||||
return orderBy
|
||||
}
|
||||
|
||||
func (opts *SearchBadgeOptions) ToJoins() []db.JoinFunc {
|
||||
return []db.JoinFunc{
|
||||
func(e db.Engine) error {
|
||||
e.Join("INNER", "badge", "badge.badge_id = badge.id")
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func SearchBadges(ctx context.Context, opts *SearchBadgeOptions) (badges []*Badge, _ int64, _ error) {
|
||||
sessCount := opts.toSearchQueryBase(ctx)
|
||||
defer sessCount.Close()
|
||||
count, err := sessCount.Count(new(Badge))
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("count: %w", err)
|
||||
}
|
||||
|
||||
if len(opts.OrderBy) == 0 {
|
||||
opts.OrderBy = db.SearchOrderByID
|
||||
}
|
||||
|
||||
sessQuery := opts.toSearchQueryBase(ctx).OrderBy(opts.OrderBy.String())
|
||||
defer sessQuery.Close()
|
||||
if opts.Page != 0 {
|
||||
sessQuery = db.SetSessionPagination(sessQuery, opts)
|
||||
}
|
||||
|
||||
// the sql may contain JOIN, so we must only select Badge related columns
|
||||
sessQuery = sessQuery.Select("`badge`.*")
|
||||
badges = make([]*Badge, 0, opts.PageSize)
|
||||
return badges, count, sessQuery.Find(&badges)
|
||||
}
|
||||
|
||||
func (opts *SearchBadgeOptions) toSearchQueryBase(ctx context.Context) *xorm.Session {
|
||||
var cond builder.Cond
|
||||
cond = builder.Neq{"id": -1}
|
||||
|
||||
if len(opts.Keyword) > 0 {
|
||||
lowerKeyword := strings.ToLower(opts.Keyword)
|
||||
keywordCond := builder.Or(
|
||||
builder.Like{"slug", lowerKeyword},
|
||||
builder.Like{"description", lowerKeyword},
|
||||
builder.Like{"id", lowerKeyword},
|
||||
)
|
||||
cond = cond.And(keywordCond)
|
||||
}
|
||||
|
||||
if opts.ID > 0 {
|
||||
cond = cond.And(builder.Eq{"id": opts.ID})
|
||||
}
|
||||
|
||||
if len(opts.Slug) > 0 {
|
||||
cond = cond.And(builder.Eq{"slug": opts.Slug})
|
||||
}
|
||||
|
||||
e := db.GetEngine(ctx)
|
||||
|
||||
return e.Where(cond)
|
||||
}
|
||||
|
||||
@@ -107,3 +107,44 @@ func IsErrUserIsNotLocal(err error) bool {
|
||||
_, ok := err.(ErrUserIsNotLocal)
|
||||
return ok
|
||||
}
|
||||
|
||||
// ErrBadgeAlreadyExist represents a "badge already exists" error.
|
||||
type ErrBadgeAlreadyExist struct {
|
||||
Slug string
|
||||
}
|
||||
|
||||
// IsErrBadgeAlreadyExist checks if an error is a ErrBadgeAlreadyExist.
|
||||
func IsErrBadgeAlreadyExist(err error) bool {
|
||||
_, ok := err.(ErrBadgeAlreadyExist)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrBadgeAlreadyExist) Error() string {
|
||||
return fmt.Sprintf("badge already exists [slug: %s]", err.Slug)
|
||||
}
|
||||
|
||||
// Unwrap unwraps this error as a ErrExist error
|
||||
func (err ErrBadgeAlreadyExist) Unwrap() error {
|
||||
return util.ErrAlreadyExist
|
||||
}
|
||||
|
||||
// ErrBadgeNotExist represents a "BadgeNotExist" kind of error.
|
||||
type ErrBadgeNotExist struct {
|
||||
Slug string
|
||||
ID int64
|
||||
}
|
||||
|
||||
// IsErrBadgeNotExist checks if an error is a ErrBadgeNotExist.
|
||||
func IsErrBadgeNotExist(err error) bool {
|
||||
_, ok := err.(ErrBadgeNotExist)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrBadgeNotExist) Error() string {
|
||||
return fmt.Sprintf("badge does not exist [slug: %s | id: %i]", err.Slug, err.ID)
|
||||
}
|
||||
|
||||
// Unwrap unwraps this error as a ErrNotExist error
|
||||
func (err ErrBadgeNotExist) Unwrap() error {
|
||||
return util.ErrNotExist
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user