refactory

This commit is contained in:
Martin/Geno 2019-02-13 03:24:38 +01:00
parent ae15e1341e
commit afdbf52d94
No known key found for this signature in database
GPG Key ID: 9D7D3C6BFF600C6A
10 changed files with 123 additions and 157 deletions

View File

@ -8,53 +8,42 @@ import (
libHTTP "github.com/genofire/golang-lib/http" libHTTP "github.com/genofire/golang-lib/http"
xmpp "github.com/mattn/go-xmpp" xmpp "github.com/mattn/go-xmpp"
"github.com/genofire/hook2xmpp/config" "dev.sum7.eu/genofire/hook2xmpp/runtime"
ownXMPP "github.com/genofire/hook2xmpp/xmpp"
) )
type Handler struct { func init() {
client *xmpp.Client runtime.HookRegister["circleci"] = func(client *xmpp.Client, hooks []runtime.Hook) func(w http.ResponseWriter, r *http.Request) {
hooks map[string]config.Hook return func(w http.ResponseWriter, r *http.Request) {
} var body map[string]interface{}
libHTTP.Read(r, &body)
payload := body["payload"].(map[string]interface{})
vcsURL, ok := payload["vcs_url"].(string)
if !ok {
log.Fatal("no readable payload")
http.Error(w, fmt.Sprintf("no readable payload"), http.StatusInternalServerError)
return
}
func NewHandler(client *xmpp.Client, newHooks []config.Hook) *Handler { status := payload["status"].(string)
hooks := make(map[string]config.Hook) buildNum := payload["build_num"].(float64)
buildURL := payload["build_url"].(string)
buildTime := payload["build_time_millis"].(float64)
subject := payload["subject"].(string)
msg := fmt.Sprintf("[%s] %s (%0.fs) - #%0.f: %s \n%s", vcsURL, status, buildTime/1000, buildNum, subject, buildURL)
for _, hook := range newHooks { ok = false
if hook.Type == "circleci" { for _, hook := range hooks {
hooks[hook.URL] = hook if vcsURL != hook.URL {
continue
}
log.Printf("run hook for circleci: %s", msg)
runtime.Notify(client, hook, msg)
ok = true
}
if !ok {
log.Fatalf("No hook found for: '%s'", vcsURL)
http.Error(w, fmt.Sprintf("no configuration for circleci for url %s", vcsURL), http.StatusNotFound)
}
} }
} }
return &Handler{
client: client,
hooks: hooks,
}
}
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var body map[string]interface{}
libHTTP.Read(r, &body)
payload := body["payload"].(map[string]interface{})
vcsURL, ok := payload["vcs_url"].(string)
if !ok {
log.Fatal("no readable payload")
http.Error(w, fmt.Sprintf("no readable payload"), http.StatusInternalServerError)
return
}
hook, ok := h.hooks[vcsURL]
if !ok {
log.Fatalf("No hook found for: '%s'", vcsURL)
http.Error(w, fmt.Sprintf("no configuration for circleci for url %s", vcsURL), http.StatusNotFound)
return
}
status := payload["status"].(string)
buildNum := payload["build_num"].(float64)
buildURL := payload["build_url"].(string)
buildTime := payload["build_time_millis"].(float64)
subject := payload["subject"].(string)
msg := fmt.Sprintf("[%s] %s (%0.fs) - #%0.f: %s \n%s", vcsURL, status, buildTime/1000, buildNum, subject, buildURL)
log.Printf("circle ci: %s", msg)
ownXMPP.Notify(h.client, hook, msg)
} }

View File

@ -1 +0,0 @@
package config

View File

@ -4,9 +4,9 @@ webserver_bind = ":8080"
host = "fireorbit.de" host = "fireorbit.de"
username = "bot@fireorbit.de" username = "bot@fireorbit.de"
password = "example" password = "example"
startup_notify = "geno@fireorbit.de" startup_notify_user = ["geno@fireorbit.de"]
startup_notify_muc = []
[[hooks]] [[hooks.git]]
notify_user = ["geno@fireorbit.de"] notify_user = ["geno@fireorbit.de"]
type = "git"
url = "https://github.com/FreifunkBremen/yanic" url = "https://github.com/FreifunkBremen/yanic"

View File

@ -1,63 +1,53 @@
package git package git
import ( import (
"fmt"
"log" "log"
"net/http" "net/http"
libHTTP "github.com/genofire/golang-lib/http" libHTTP "github.com/genofire/golang-lib/http"
xmpp "github.com/mattn/go-xmpp" xmpp "github.com/mattn/go-xmpp"
"github.com/genofire/hook2xmpp/config" "dev.sum7.eu/genofire/hook2xmpp/runtime"
ownXMPP "github.com/genofire/hook2xmpp/xmpp"
) )
type Handler struct {
client *xmpp.Client
hooks map[string]config.Hook
}
func NewHandler(client *xmpp.Client, newHooks []config.Hook) *Handler {
hooks := make(map[string]config.Hook)
for _, hook := range newHooks {
if hook.Type == "git" {
hooks[hook.URL] = hook
}
}
return &Handler{
client: client,
hooks: hooks,
}
}
var eventHeader = []string{"X-GitHub-Event", "X-Gogs-Event"} var eventHeader = []string{"X-GitHub-Event", "X-Gogs-Event"}
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func init() {
var payload map[string]interface{} runtime.HookRegister["git"] = func(client *xmpp.Client, hooks []runtime.Hook) func(w http.ResponseWriter, r *http.Request) {
event := "" return func(w http.ResponseWriter, r *http.Request) {
for _, head := range eventHeader { var payload map[string]interface{}
event = r.Header.Get(head) event := ""
for _, head := range eventHeader {
event = r.Header.Get(head)
if event != "" { if event != "" {
break break
}
}
if event == "status" {
return
}
libHTTP.Read(r, &payload)
msg := PayloadToString(event, payload)
repository := payload["repository"].(map[string]interface{})
url := repository["html_url"].(string)
ok := false
for _, hook := range hooks {
if url != hook.URL {
continue
}
log.Printf("run hook for git: %s", msg)
runtime.Notify(client, hook, msg)
ok = true
}
if !ok {
log.Fatalf("No hook found for: '%s'", url)
http.Error(w, fmt.Sprintf("no configuration for git for url %s", url), http.StatusNotFound)
}
} }
} }
if event == "status" {
return
}
libHTTP.Read(r, &payload)
msg := PayloadToString(event, payload)
repository := payload["repository"].(map[string]interface{})
url := repository["html_url"].(string)
hook, ok := h.hooks[url]
if !ok {
log.Fatalf("No hook found for: '%s'", url)
return
}
log.Printf("git: %s", msg)
ownXMPP.Notify(h.client, hook, msg)
} }

View File

@ -10,11 +10,11 @@ import (
"github.com/mattn/go-xmpp" "github.com/mattn/go-xmpp"
"github.com/genofire/hook2xmpp/circleci" "dev.sum7.eu/genofire/golang-lib/file"
configuration "github.com/genofire/hook2xmpp/config"
"github.com/genofire/hook2xmpp/git" _ "dev.sum7.eu/genofire/hook2xmpp/circleci"
"github.com/genofire/hook2xmpp/syslog" _ "dev.sum7.eu/genofire/hook2xmpp/git"
ownXMPP "github.com/genofire/hook2xmpp/xmpp" "dev.sum7.eu/genofire/hook2xmpp/runtime"
) )
func main() { func main() {
@ -22,10 +22,10 @@ func main() {
flag.StringVar(&configFile, "config", configFile, "path of configuration file") flag.StringVar(&configFile, "config", configFile, "path of configuration file")
flag.Parse() flag.Parse()
config := configuration.ReadConfigFile(configFile) config := &runtime.Config{}
if config.Syslog.Enable { if err := file.ReadTOML(configFile, config); err != nil {
syslog.Bind(config) log.Panicf("error on read config: %s", err)
} }
// load config // load config
@ -47,13 +47,14 @@ func main() {
log.Printf("Started hock2xmpp with %s", client.JID()) log.Printf("Started hock2xmpp with %s", client.JID())
client.SendHtml(xmpp.Chat{Remote: config.XMPP.StartupNotify, Type: "chat", Text: "startup of hock2xmpp"}) client.SendHtml(xmpp.Chat{Remote: config.XMPP.StartupNotify, Type: "chat", Text: "startup of hock2xmpp"})
go ownXMPP.Start(client) go runtime.Start(client)
circleciHandler := circleci.NewHandler(client, config.Hooks) for hookType, getHandler := range runtime.HookRegister {
http.Handle("/circleci", circleciHandler) hooks, ok := config.Hooks[hookType]
if ok {
gitHandler := git.NewHandler(client, config.Hooks) http.HandleFunc(hookType, getHandler(client, hooks))
http.Handle("/git", gitHandler) }
}
srv := &http.Server{ srv := &http.Server{
Addr: config.WebserverBind, Addr: config.WebserverBind,

View File

@ -1,19 +1,6 @@
package config package runtime
import (
"io/ioutil"
"log"
"github.com/BurntSushi/toml"
)
type Config struct { type Config struct {
Syslog struct {
Enable bool `toml:"enable"`
Type string `toml:"type"`
Address string `toml:"address"`
} `toml:"syslog"`
WebserverBind string `toml:"webserver_bind"` WebserverBind string `toml:"webserver_bind"`
XMPP struct { XMPP struct {
@ -28,25 +15,14 @@ type Config struct {
StartupNotify string `toml:"startup_notify"` StartupNotify string `toml:"startup_notify"`
} `toml:"xmpp"` } `toml:"xmpp"`
Hooks []Hook `toml:"hooks"` StartupNotifyUser []string `toml:"startup_notify_user"`
StartupNotifyMuc []string `toml:"startup_notify_muc"`
Hooks map[string][]Hook `toml:"hooks"`
} }
type Hook struct { type Hook struct {
Type string `toml:"type"`
URL string `toml:"url"` URL string `toml:"url"`
NotifyUser []string `toml:"notify_user"` NotifyUser []string `toml:"notify_user"`
NotifyMuc []string `toml:"notify_muc"` NotifyMuc []string `toml:"notify_muc"`
} }
func ReadConfigFile(path string) *Config {
config := &Config{}
file, err := ioutil.ReadFile(path)
if err != nil {
log.Panic(err)
}
if err := toml.Unmarshal(file, config); err != nil {
log.Panic(err)
}
return config
}

15
runtime/hooks.go Normal file
View File

@ -0,0 +1,15 @@
package runtime
import (
"net/http"
xmpp "github.com/mattn/go-xmpp"
)
type HookHandler func(*xmpp.Client, []Hook) func(http.ResponseWriter, *http.Request)
var HookRegister map[string]HookHandler
func init() {
HookRegister = make(map[string]HookHandler)
}

View File

@ -1,10 +1,9 @@
package xmpp package runtime
import ( import (
"fmt"
"log" "log"
"github.com/genofire/hook2xmpp/config"
xmpp "github.com/mattn/go-xmpp" xmpp "github.com/mattn/go-xmpp"
) )
@ -26,8 +25,22 @@ func Start(client *xmpp.Client) {
} }
} }
} }
func NotifyImage(client *xmpp.Client, hook Hook, url string) {
msg := fmt.Sprintf(`<message to='%%s' type='%%s'>
<body>%s</body>
<x xmlns='jabber:x:oob'>
<url>%s</url>
</x>
</message>`, url, url)
func Notify(client *xmpp.Client, hook config.Hook, msg string) { for _, muc := range hook.NotifyMuc {
client.SendOrg(fmt.Sprintf(msg, muc, "groupchat"))
}
for _, user := range hook.NotifyUser {
client.SendOrg(fmt.Sprintf(msg, user, "chat"))
}
}
func Notify(client *xmpp.Client, hook Hook, msg string) {
for _, muc := range hook.NotifyMuc { for _, muc := range hook.NotifyMuc {
client.SendHtml(xmpp.Chat{Remote: muc, Type: "groupchat", Text: msg}) client.SendHtml(xmpp.Chat{Remote: muc, Type: "groupchat", Text: msg})
} }

View File

@ -1,16 +0,0 @@
package syslog
import (
"log"
"log/syslog"
"github.com/genofire/hook2xmpp/config"
)
func Bind(config *config.Config) {
sysLog, err := syslog.Dial(config.Syslog.Type, config.Syslog.Address, syslog.LOG_WARNING|syslog.LOG_DAEMON, "hook2xmpp")
if err != nil {
log.Fatal(err)
}
log.SetOutput(sysLog)
}

View File

@ -1 +0,0 @@
package xmpp