You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

164 lines
3.4 KiB

package main
import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"math/rand"
"net/http"
"os"
"path"
"path/filepath"
"strconv"
"time"
"git.oyohyee.com/OhYee/action/lib/gitea"
"git.oyohyee.com/OhYee/action/lib/hook"
"github.com/OhYee/goutils/file"
"github.com/OhYee/rainbow/color"
"github.com/OhYee/rainbow/errors"
"github.com/OhYee/rainbow/log"
)
type handle struct {
Root string
}
func readJson(r io.Reader, res interface{}) (err error) {
b, err := ioutil.ReadAll(r)
if err != nil {
log.Error.Println(errors.ShowStack(errors.NewErr(err)))
return
}
if err = json.Unmarshal(b, res); err != nil {
log.Error.Println(errors.ShowStack(errors.NewErr(err)))
return
}
return
}
func (serv handle) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h := new(hook.Hook)
switch r.URL.Path {
case "/gitea":
m := new(gitea.Hook)
readJson(r.Body, m)
h = m.ToHook()
s, err := json.MarshalIndent(m, "", " ")
if err != nil {
log.Error.Println(errors.ShowStack(errors.NewErr(err)))
return
}
log.Debug.Printf("%s\n", s)
case "/hook":
readJson(r.Body, h)
h.Type = "hook"
s, err := json.MarshalIndent(h, "", " ")
if err != nil {
log.Error.Println(errors.ShowStack(errors.NewErr(err)))
return
}
log.Debug.Printf("%s\n", s)
default:
w.WriteHeader(501)
w.Write([]byte(fmt.Sprintf("Can not solve request %s", r.RequestURI)))
}
go h.Handle(path.Join(serv.Root, "repos", h.Repo))
}
var nocolor = color.New()
func help() {
fmt.Println("OhYee Action Web Hook 监听程序")
fmt.Println(" -t --token 生成随机 Token")
fmt.Println(" -r --root Action 根目录,将会在该目录检索 repos 文件夹")
fmt.Println(" -a --address 监听地址(默认 0.0.0.0)")
fmt.Println(" -p --port 监听端口(默认42179)")
fmt.Println(" -h --help 查看帮助")
os.Exit(0)
}
func main() {
pre := ""
root := file.AbsPath()
address := "0.0.0.0"
port := 42179
gToken := 0
for _, arg := range os.Args {
switch pre {
case "-r", "--root":
if filepath.IsAbs(arg) {
root = path.Join(arg)
} else {
root = path.Join(root, arg)
}
case "-t", "--token":
if l, err := strconv.ParseInt(arg, 10, 32); err == nil {
gToken = int(l)
}
case "-a", "--address":
address = arg
case "-p", "--port":
if l, err := strconv.ParseInt(arg, 10, 32); err == nil {
port = int(l)
}
default:
switch arg {
case "-t":
gToken = 20
case "-h", "--help":
help()
}
}
pre = arg
}
if gToken != 0 {
fmt.Println(randStringRunes(gToken))
return
}
f, err := os.OpenFile(path.Join(root, "log.log"), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0777)
if err != nil {
panic(err)
}
defer f.Close()
resetLog(log.Info, f, "[Info] ")
resetLog(log.Debug, f, "[Debug] ")
resetLog(log.Error, f, "[Error] ")
addr := fmt.Sprintf("%s:%d", address, port)
fmt.Printf("Action works on %s\nFolder: %s\n", addr, root)
log.Info.Printf("Action works on %s\nFolder: %s\n", addr, root)
http.ListenAndServe(addr, handle{
Root: root,
})
}
func resetLog(l *log.Logger, f *os.File, prefix string) {
l.SetColor(nocolor)
l.SetOutput(f)
l.SetPrefix(func(s string) string {
return prefix
})
l.SetSuffix(nil)
}
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
func randStringRunes(n int) string {
rand.Seed(time.Now().UnixNano())
b := make([]rune, n)
for i := range b {
b[i] = letterRunes[rand.Intn(len(letterRunes))]
}
return string(b)
}