aboutsummaryrefslogtreecommitdiff
path: root/models/webhook.go
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2014-06-28 15:00:32 +0800
committerLunny Xiao <xiaolunwen@gmail.com>2014-06-28 15:00:32 +0800
commita357cda9575b482004329e81f0add6e4c32ab02a (patch)
treedb7d7508a039cfd4dd6cedad236e720bcfe1396c /models/webhook.go
parent165e3e8f18bb7d38722d0c836ddbf8c95023cf67 (diff)
parent6e448b07145fbb090e0da6deb97f244c2bfd7ba7 (diff)
Merge branch 'dev' of github.com:gogits/gogs into dev
Diffstat (limited to 'models/webhook.go')
-rw-r--r--models/webhook.go143
1 files changed, 126 insertions, 17 deletions
diff --git a/models/webhook.go b/models/webhook.go
index f10fa213..9044befb 100644
--- a/models/webhook.go
+++ b/models/webhook.go
@@ -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:"-"`
@@ -37,6 +43,7 @@ type Webhook struct {
IsActive bool
}
+// GetEvent handles conversion from Events to HookEvent.
func (w *Webhook) GetEvent() {
w.HookEvent = &HookEvent{}
if err := json.Unmarshal([]byte(w.Events), w.HookEvent); err != nil {
@@ -44,12 +51,14 @@ func (w *Webhook) GetEvent() {
}
}
-func (w *Webhook) SaveEvent() error {
+// UpdateEvent handles conversion from HookEvent to Events.
+func (w *Webhook) UpdateEvent() error {
data, err := json.Marshal(w.HookEvent)
w.Events = string(data)
return err
}
+// HasPushEvent returns true if hook enbaled push event.
func (w *Webhook) HasPushEvent() bool {
if w.PushOnly {
return true
@@ -57,22 +66,16 @@ 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)
+ _, err := x.Insert(w)
return err
}
// GetWebhookById returns webhook by given ID.
func GetWebhookById(hookId int64) (*Webhook, error) {
w := &Webhook{Id: hookId}
- has, err := orm.Get(w)
+ has, err := x.Get(w)
if err != nil {
return nil, err
} else if !has {
@@ -83,18 +86,124 @@ func GetWebhookById(hookId int64) (*Webhook, error) {
// GetActiveWebhooksByRepoId returns all active webhooks of repository.
func GetActiveWebhooksByRepoId(repoId int64) (ws []*Webhook, err error) {
- err = orm.Find(&ws, &Webhook{RepoId: repoId, IsActive: true})
+ err = x.Find(&ws, &Webhook{RepoId: repoId, IsActive: true})
return ws, err
}
// GetWebhooksByRepoId returns all webhooks of repository.
func GetWebhooksByRepoId(repoId int64) (ws []*Webhook, err error) {
- err = orm.Find(&ws, &Webhook{RepoId: repoId})
+ err = x.Find(&ws, &Webhook{RepoId: repoId})
return ws, err
}
+// UpdateWebhook updates information of webhook.
+func UpdateWebhook(w *Webhook) error {
+ _, err := x.AllCols().Update(w)
+ return err
+}
+
// DeleteWebhook deletes webhook of repository.
func DeleteWebhook(hookId int64) error {
- _, err := orm.Delete(&Webhook{Id: hookId})
+ _, err := x.Delete(&Webhook{Id: hookId})
+ return err
+}
+
+// ___ ___ __ ___________ __
+// / | \ ____ ____ | | _\__ ___/____ _____| | __
+// / ~ \/ _ \ / _ \| |/ / | | \__ \ / ___/ |/ /
+// \ Y ( <_> | <_> ) < | | / __ \_\___ \| <
+// \___|_ / \____/ \____/|__|_ \ |____| (____ /____ >__|_ \
+// \/ \/ \/ \/ \/
+
+type HookTaskType int
+
+const (
+ WEBHOOK HookTaskType = 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 a 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 a hook task.
+type HookTask struct {
+ Id int64
+ Type HookTaskType
+ 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 = x.Insert(t)
return err
}
+
+// UpdateHookTask updates information of hook task.
+func UpdateHookTask(t *HookTask) error {
+ _, err := x.AllCols().Update(t)
+ return err
+}
+
+// DeliverHooks checks and delivers undelivered hooks.
+func DeliverHooks() {
+ timeout := time.Duration(setting.WebhookDeliverTimeout) * time.Second
+ x.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
+ })
+}