This commit is contained in:
Unknown 2014-06-08 04:45:34 -04:00
parent a0318db2f9
commit 302c863cda
14 changed files with 432 additions and 375 deletions

View file

@ -15,7 +15,6 @@ import (
qlog "github.com/qiniu/log"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/hooks"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/setting"
)
@ -131,35 +130,35 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
}
repoLink := fmt.Sprintf("%s%s/%s", setting.AppUrl, repoUserName, repoName)
commits := make([]*hooks.PayloadCommit, len(commit.Commits))
commits := make([]*PayloadCommit, len(commit.Commits))
for i, cmt := range commit.Commits {
commits[i] = &hooks.PayloadCommit{
commits[i] = &PayloadCommit{
Id: cmt.Sha1,
Message: cmt.Message,
Url: fmt.Sprintf("%s/commit/%s", repoLink, cmt.Sha1),
Author: &hooks.PayloadAuthor{
Author: &PayloadAuthor{
Name: cmt.AuthorName,
Email: cmt.AuthorEmail,
},
}
}
p := &hooks.Payload{
p := &Payload{
Ref: refFullName,
Commits: commits,
Repo: &hooks.PayloadRepo{
Repo: &PayloadRepo{
Id: repo.Id,
Name: repo.LowerName,
Url: repoLink,
Description: repo.Description,
Website: repo.Website,
Watchers: repo.NumWatches,
Owner: &hooks.PayloadAuthor{
Owner: &PayloadAuthor{
Name: repoUserName,
Email: actEmail,
},
Private: repo.IsPrivate,
},
Pusher: &hooks.PayloadAuthor{
Pusher: &PayloadAuthor{
Name: repo.Owner.LowerName,
Email: repo.Owner.Email,
},
@ -172,7 +171,13 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
}
p.Secret = w.Secret
hooks.AddHookTask(&hooks.HookTask{hooks.HTT_WEBHOOK, w.Url, p, w.ContentType, w.IsSsl})
CreateHookTask(&HookTask{
Type: WEBHOOK,
Url: w.Url,
Payload: p,
ContentType: w.ContentType,
IsSsl: w.IsSsl,
})
}
return nil
}

View file

@ -35,7 +35,7 @@ func init() {
tables = append(tables, new(User), new(PublicKey), new(Repository), new(Watch),
new(Action), new(Access), new(Issue), new(Comment), new(Oauth2), new(Follow),
new(Mirror), new(Release), new(LoginSource), new(Webhook), new(IssueUser),
new(Milestone), new(Label))
new(Milestone), new(Label), new(HookTask))
}
func LoadModelsConfig() {

View file

@ -7,29 +7,35 @@ package models
import (
"encoding/json"
"errors"
"time"
"github.com/gogits/gogs/modules/httplib"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/setting"
)
var (
ErrWebhookNotExist = errors.New("Webhook does not exist")
)
// Content types.
type HookContentType int
const (
CT_JSON = iota + 1
CT_FORM
JSON HookContentType = iota + 1
FORM
)
// HookEvent represents events that will delivery hook.
type HookEvent struct {
PushOnly bool `json:"push_only"`
}
// Webhook represents a web hook object.
type Webhook struct {
Id int64
RepoId int64
Url string `xorm:"TEXT"`
ContentType int
ContentType HookContentType
Secret string `xorm:"TEXT"`
Events string `xorm:"TEXT"`
*HookEvent `xorm:"-"`
@ -44,7 +50,7 @@ func (w *Webhook) GetEvent() {
}
}
func (w *Webhook) SaveEvent() error {
func (w *Webhook) UpdateEvent() error {
data, err := json.Marshal(w.HookEvent)
w.Events = string(data)
return err
@ -57,18 +63,12 @@ func (w *Webhook) HasPushEvent() bool {
return false
}
// CreateWebhook creates new webhook.
// CreateWebhook creates a new web hook.
func CreateWebhook(w *Webhook) error {
_, err := orm.Insert(w)
return err
}
// UpdateWebhook updates information of webhook.
func UpdateWebhook(w *Webhook) error {
_, err := orm.AllCols().Update(w)
return err
}
// GetWebhookById returns webhook by given ID.
func GetWebhookById(hookId int64) (*Webhook, error) {
w := &Webhook{Id: hookId}
@ -93,8 +93,114 @@ func GetWebhooksByRepoId(repoId int64) (ws []*Webhook, err error) {
return ws, err
}
// UpdateWebhook updates information of webhook.
func UpdateWebhook(w *Webhook) error {
_, err := orm.AllCols().Update(w)
return err
}
// DeleteWebhook deletes webhook of repository.
func DeleteWebhook(hookId int64) error {
_, err := orm.Delete(&Webhook{Id: hookId})
return err
}
// ___ ___ __ ___________ __
// / | \ ____ ____ | | _\__ ___/____ _____| | __
// / ~ \/ _ \ / _ \| |/ / | | \__ \ / ___/ |/ /
// \ Y ( <_> | <_> ) < | | / __ \_\___ \| <
// \___|_ / \____/ \____/|__|_ \ |____| (____ /____ >__|_ \
// \/ \/ \/ \/ \/
type HookTaskType int
const (
WEBHOOK = iota + 1
SERVICE
)
type PayloadAuthor struct {
Name string `json:"name"`
Email string `json:"email"`
}
type PayloadCommit struct {
Id string `json:"id"`
Message string `json:"message"`
Url string `json:"url"`
Author *PayloadAuthor `json:"author"`
}
type PayloadRepo struct {
Id int64 `json:"id"`
Name string `json:"name"`
Url string `json:"url"`
Description string `json:"description"`
Website string `json:"website"`
Watchers int `json:"watchers"`
Owner *PayloadAuthor `json:"author"`
Private bool `json:"private"`
}
// Payload represents payload information of hook.
type Payload struct {
Secret string `json:"secret"`
Ref string `json:"ref"`
Commits []*PayloadCommit `json:"commits"`
Repo *PayloadRepo `json:"repository"`
Pusher *PayloadAuthor `json:"pusher"`
}
// HookTask represents hook task.
type HookTask struct {
Id int64
Type int
Url string
*Payload `xorm:"-"`
PayloadContent string `xorm:"TEXT"`
ContentType HookContentType
IsSsl bool
IsDeliveried bool
}
// CreateHookTask creates a new hook task,
// it handles conversion from Payload to PayloadContent.
func CreateHookTask(t *HookTask) error {
data, err := json.Marshal(t.Payload)
if err != nil {
return err
}
t.PayloadContent = string(data)
_, err = orm.Insert(t)
return err
}
// UpdateHookTask updates information of hook task.
func UpdateHookTask(t *HookTask) error {
_, err := orm.AllCols().Update(t)
return err
}
// DeliverHooks checks and delivers undelivered hooks.
func DeliverHooks() {
timeout := time.Duration(setting.WebhookDeliverTimeout) * time.Second
orm.Where("is_deliveried=?", false).Iterate(new(HookTask),
func(idx int, bean interface{}) error {
t := bean.(*HookTask)
// Only support JSON now.
if _, err := httplib.Post(t.Url).SetTimeout(timeout, timeout).
Body([]byte(t.PayloadContent)).Response(); err != nil {
log.Error("webhook.DeliverHooks(Delivery): %v", err)
return nil
}
t.IsDeliveried = true
if err := UpdateHookTask(t); err != nil {
log.Error("webhook.DeliverHooks(UpdateHookTask): %v", err)
return nil
}
log.Trace("Hook delivered: %s", t.PayloadContent)
return nil
})
}