diff options
author | Unknown <joe2010xtmf@163.com> | 2014-06-08 04:45:34 -0400 |
---|---|---|
committer | Unknown <joe2010xtmf@163.com> | 2014-06-08 04:45:34 -0400 |
commit | 302c863cda651130286838309d3d897cace93534 (patch) | |
tree | bc2b5e8efd513304806e1e900141856d3adfce48 /models | |
parent | a0318db2f9094eda2beea19ed323244b4ae30831 (diff) | |
download | gitea-302c863cda651130286838309d3d897cace93534.tar.gz gitea-302c863cda651130286838309d3d897cace93534.zip |
Fix #242
Diffstat (limited to 'models')
-rw-r--r-- | models/action.go | 23 | ||||
-rw-r--r-- | models/models.go | 2 | ||||
-rw-r--r-- | models/webhook.go | 130 |
3 files changed, 133 insertions, 22 deletions
diff --git a/models/action.go b/models/action.go index 9fc9d89b9f..e39b04a1ad 100644 --- a/models/action.go +++ b/models/action.go @@ -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 } diff --git a/models/models.go b/models/models.go index fa65ef30f6..dca77e00e1 100644 --- a/models/models.go +++ b/models/models.go @@ -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() { diff --git a/models/webhook.go b/models/webhook.go index f10fa2131e..e68edc813d 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:"-"` @@ -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 + }) +} |