更改贡献者效率以及webhook更新http_method支持 #3
|
|
@ -0,0 +1,76 @@
|
|||
package git
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
gitea_git "code.gitea.io/gitea/modules/git"
|
||||
)
|
||||
|
||||
type RepoContributor struct {
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
Commits int `json:"commits"`
|
||||
}
|
||||
|
||||
func GetRepoContributors(repo *gitea_git.Repository, page, pageSize int) (int, []*RepoContributor, error) {
|
||||
var total, skip int
|
||||
var contributors []*RepoContributor
|
||||
|
||||
skip = (page - 1) * pageSize
|
||||
|
||||
stdoutReader, stdoutWriter, err := os.Pipe()
|
||||
if err != nil {
|
||||
return total, nil, err
|
||||
}
|
||||
defer func() {
|
||||
_ = stdoutReader.Close()
|
||||
_ = stdoutWriter.Close()
|
||||
}()
|
||||
cmd := gitea_git.NewCommand(repo.Ctx, "shortlog", "-sne", "HEAD")
|
||||
|
||||
stderr := new(strings.Builder)
|
||||
err = cmd.Run(&gitea_git.RunOpts{
|
||||
Env: []string{},
|
||||
Dir: repo.Path,
|
||||
Stdout: stdoutWriter,
|
||||
Stderr: stderr,
|
||||
PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error {
|
||||
_ = stdoutWriter.Close()
|
||||
scanner := bufio.NewScanner(stdoutReader)
|
||||
scanner.Split(bufio.ScanLines)
|
||||
var ca int
|
||||
for scanner.Scan() {
|
||||
total++
|
||||
if skip > 0 {
|
||||
skip--
|
||||
} else {
|
||||
if ca < pageSize {
|
||||
l := strings.TrimSpace(scanner.Text())
|
||||
commits := l[0:strings.Index(l, "\t")]
|
||||
commitsInt, err := strconv.Atoi(commits)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name := l[strings.Index(l, "\t")+1 : strings.Index(l, " <")]
|
||||
email := l[strings.Index(l, "<")+1 : strings.Index(l, ">")]
|
||||
contributors = append(contributors, &RepoContributor{
|
||||
Commits: commitsInt,
|
||||
Name: name,
|
||||
Email: email,
|
||||
})
|
||||
ca++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_ = stdoutReader.Close()
|
||||
return nil
|
||||
},
|
||||
})
|
||||
|
||||
return total, contributors, nil
|
||||
}
|
||||
|
|
@ -16,6 +16,13 @@ type CreateHookOption struct {
|
|||
Active bool `json:"active"`
|
||||
}
|
||||
|
||||
type EditHookOption struct {
|
||||
Config map[string]string `json:"config"`
|
||||
Events []string `json:"events"`
|
||||
BranchFilter string `json:"branch_filter" binding:"GlobPattern"`
|
||||
Active *bool `json:"active"`
|
||||
}
|
||||
|
||||
type HookTask struct {
|
||||
ID int64 `json:"id"`
|
||||
UUID string `json:"uuid"`
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ func Routers(ctx gocontext.Context) *web.Route {
|
|||
m.Group("/hooks", func() {
|
||||
m.Combo("").Post(bind(hat_api.CreateHookOption{}), repo.CreateHook)
|
||||
m.Group("/{id}", func() {
|
||||
m.Combo("").Patch(bind(hat_api.EditHookOption{}), repo.EditHook)
|
||||
m.Get("/hooktasks", repo.ListHookTask)
|
||||
})
|
||||
}, reqToken(), reqAdmin(), reqWebhooksEnabled())
|
||||
|
|
|
|||
|
|
@ -16,8 +16,127 @@ import (
|
|||
hat_webhook "code.gitlink.org.cn/Gitlink/gitea_hat.git/models/webhook"
|
||||
hat_convert "code.gitlink.org.cn/Gitlink/gitea_hat.git/modules/convert"
|
||||
hat_api "code.gitlink.org.cn/Gitlink/gitea_hat.git/modules/structs"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
)
|
||||
|
||||
func EditHook(ctx *context.APIContext) {
|
||||
form := web.GetForm(ctx).(*hat_api.EditHookOption)
|
||||
hookID := ctx.ParamsInt64(":id")
|
||||
editRepoHook(ctx, form, hookID)
|
||||
}
|
||||
|
||||
func editRepoHook(ctx *context.APIContext, form *hat_api.EditHookOption, hookID int64) {
|
||||
repo := ctx.Repo
|
||||
hook, err := utils.GetRepoHook(ctx, repo.Repository.ID, hookID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if !editHook(ctx, form, hook) {
|
||||
return
|
||||
}
|
||||
|
||||
updated, err := utils.GetRepoHook(ctx, repo.Repository.ID, hookID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, convert.ToHook(repo.RepoLink, updated))
|
||||
}
|
||||
|
||||
func editHook(ctx *context.APIContext, form *hat_api.EditHookOption, w *webhook.Webhook) bool {
|
||||
if form.Config != nil {
|
||||
if url, ok := form.Config["url"]; ok {
|
||||
w.URL = url
|
||||
}
|
||||
if secret, ok := form.Config["secret"]; ok {
|
||||
w.Secret = secret
|
||||
}
|
||||
|
||||
if ct, ok := form.Config["content_type"]; ok {
|
||||
if !webhook.IsValidHookContentType(ct) {
|
||||
ctx.Error(http.StatusUnprocessableEntity, "", "Invalid content type")
|
||||
return false
|
||||
}
|
||||
w.ContentType = webhook.ToHookContentType(ct)
|
||||
}
|
||||
|
||||
if hw, ok := form.Config["http_method"]; ok {
|
||||
if !isValidHookHttpMethod(hw) {
|
||||
ctx.Error(http.StatusUnprocessableEntity, "", "Invalid http method")
|
||||
return false
|
||||
}
|
||||
w.HTTPMethod = hw
|
||||
}
|
||||
|
||||
if w.Type == webhook.SLACK {
|
||||
if channel, ok := form.Config["channel"]; ok {
|
||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
meta, err := json.Marshal(&webhook_service.SlackMeta{
|
||||
Channel: channel,
|
||||
Username: form.Config["username"],
|
||||
IconURL: form.Config["icon_url"],
|
||||
Color: form.Config["color"],
|
||||
})
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "slack: JSON marshal failed", err)
|
||||
return false
|
||||
}
|
||||
w.Meta = string(meta)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update events
|
||||
if len(form.Events) == 0 {
|
||||
form.Events = []string{"push"}
|
||||
}
|
||||
w.PushOnly = false
|
||||
w.SendEverything = false
|
||||
w.ChooseEvents = true
|
||||
w.Create = util.IsStringInSlice(string(webhook.HookEventCreate), form.Events, true)
|
||||
w.Push = util.IsStringInSlice(string(webhook.HookEventPush), form.Events, true)
|
||||
w.PullRequest = util.IsStringInSlice(string(webhook.HookEventPullRequest), form.Events, true)
|
||||
// w.Create = util.IsStringInSlice(string(webhook.HookEventCreate), form.Events, true)
|
||||
w.Delete = util.IsStringInSlice(string(webhook.HookEventDelete), form.Events, true)
|
||||
w.Fork = util.IsStringInSlice(string(webhook.HookEventFork), form.Events, true)
|
||||
w.Issues = util.IsStringInSlice(string(webhook.HookEventIssues), form.Events, true)
|
||||
w.Issues = issuesHook(form.Events, "issues_only")
|
||||
w.IssueAssign = issuesHook(form.Events, string(webhook.HookEventIssueAssign))
|
||||
w.IssueLabel = issuesHook(form.Events, string(webhook.HookEventIssueLabel))
|
||||
w.IssueMilestone = issuesHook(form.Events, string(webhook.HookEventIssueMilestone))
|
||||
w.IssueComment = issuesHook(form.Events, string(webhook.HookEventIssueComment))
|
||||
// w.IssueComment = util.IsStringInSlice(string(webhook.HookEventIssueComment), form.Events, true)
|
||||
w.Push = util.IsStringInSlice(string(webhook.HookEventPush), form.Events, true)
|
||||
// w.PullRequest = util.IsStringInSlice(string(webhook.HookEventPullRequest), form.Events, true)
|
||||
w.PullRequest = pullHook(form.Events, "pull_request_only")
|
||||
w.PullRequestAssign = pullHook(form.Events, string(webhook.HookEventPullRequestAssign))
|
||||
w.PullRequestLabel = pullHook(form.Events, string(webhook.HookEventPullRequestLabel))
|
||||
w.PullRequestMilestone = pullHook(form.Events, string(webhook.HookEventPullRequestMilestone))
|
||||
w.PullRequestComment = pullHook(form.Events, string(webhook.HookEventPullRequestComment))
|
||||
w.PullRequestReview = pullHook(form.Events, "pull_request_review")
|
||||
w.PullRequestSync = pullHook(form.Events, string(webhook.HookEventPullRequestSync))
|
||||
w.Repository = util.IsStringInSlice(string(webhook.HookEventRepository), form.Events, true)
|
||||
w.Release = util.IsStringInSlice(string(webhook.HookEventRelease), form.Events, true)
|
||||
w.BranchFilter = form.BranchFilter
|
||||
w.HookEvent.BranchFilter = form.BranchFilter
|
||||
|
||||
if err := w.UpdateEvent(); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "UpdateEvent", err)
|
||||
return false
|
||||
}
|
||||
|
||||
if form.Active != nil {
|
||||
w.IsActive = *form.Active
|
||||
}
|
||||
|
||||
if err := webhook.UpdateWebhook(w); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "UpdateWebhook", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func CreateHook(ctx *context.APIContext) {
|
||||
form := web.GetForm(ctx).(*hat_api.CreateHookOption)
|
||||
if !checkCreateHookOption(ctx, form) {
|
||||
|
|
|
|||
|
|
@ -483,11 +483,10 @@ func SetDiffViewStyle(ctx *context.Context) {
|
|||
|
||||
func GetContributors(ctx *context.APIContext) {
|
||||
listOptions := utils.GetListOptions(ctx)
|
||||
branch := ctx.FormString("branch")
|
||||
|
||||
total, list, err := hat_git.GetPaginateCodeAuthorsWithoutSince(ctx.Repo.GitRepo, branch, listOptions.Page, listOptions.PageSize)
|
||||
total, list, err := hat_git.GetRepoContributors(ctx.Repo.GitRepo, listOptions.Page, listOptions.PageSize)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "GetContributors", err)
|
||||
ctx.Error(http.StatusInternalServerError, "GetRepoContributors", err)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue