This commit is contained in:
Jay
2020-04-17 16:41:48 +08:00
parent d7f1b47860
commit 31150c8280
12 changed files with 487 additions and 2 deletions
+11
View File
@@ -0,0 +1,11 @@
package cihook
import "encoding/json"
func Parse(b []byte) (*PipelineEvent, error) {
p := &PipelineEvent{}
if err := json.Unmarshal(b, p); err != nil {
return nil, err
}
return p, nil
}
+71
View File
@@ -0,0 +1,71 @@
package cihook
import "time"
type PipelineEvent struct {
ID string `json:"id"`
EventType string `json:"eventType"`
PublisherID string `json:"publisherId"`
Message struct {
Text string `json:"text"`
HTML string `json:"html"`
Markdown string `json:"markdown"`
} `json:"message"`
DetailedMessage struct {
Text string `json:"text"`
HTML string `json:"html"`
Markdown string `json:"markdown"`
} `json:"detailedMessage"`
Resource struct {
Run struct {
Links struct {
Self struct {
Href string `json:"href"`
} `json:"self"`
Web struct {
Href string `json:"href"`
} `json:"web"`
PipelineWeb struct {
Href string `json:"href"`
} `json:"pipeline.web"`
Pipeline struct {
Href string `json:"href"`
} `json:"pipeline"`
} `json:"_links"`
Pipeline struct {
URL string `json:"url"`
ID int `json:"id"`
Revision int `json:"revision"`
Name string `json:"name"`
Folder string `json:"folder"`
} `json:"pipeline"`
State string `json:"state"`
Result string `json:"result"`
CreatedDate time.Time `json:"createdDate"`
FinishedDate time.Time `json:"finishedDate"`
URL string `json:"url"`
ID int `json:"id"`
Name string `json:"name"`
} `json:"run"`
Pipeline struct {
URL string `json:"url"`
ID int `json:"id"`
Revision int `json:"revision"`
Name string `json:"name"`
Folder string `json:"folder"`
} `json:"pipeline"`
} `json:"resource"`
ResourceVersion string `json:"resourceVersion"`
ResourceContainers struct {
Collection struct {
ID string `json:"id"`
} `json:"collection"`
Account struct {
ID string `json:"id"`
} `json:"account"`
Project struct {
ID string `json:"id"`
} `json:"project"`
} `json:"resourceContainers"`
CreatedDate time.Time `json:"createdDate"`
}
+59
View File
@@ -1,16 +1,75 @@
package config
import (
"errors"
"io/ioutil"
"os"
"path"
"git.trj.tw/golang/utils"
"github.com/jesseduffield/yaml"
"github.com/otakukaze/envconfig"
)
type Server struct {
Port int `yaml:"port" env:"SERVER_PORT"`
}
type Remote struct {
WSLoc string `yaml:"ws_loc" env:"REMOTE_WS_LOC"`
}
type LED struct {
Count int `yaml:"count" env:"LED_COUNT"`
Pin int `yaml:"pin" env:"LED_PIN"`
}
type Config struct {
Server Server `yaml:"server"`
Remote Remote `yaml:"remote"`
LED LED `yaml:"led"`
}
var c *Config
func Load(p ...string) error {
var fp string
if len(p) > 0 && p[0] != "" {
fp = p[0]
} else {
wd, err := os.Getwd()
if err != nil {
return err
}
fp = path.Join(wd, "config.yml")
}
fp = utils.ParsePath(fp)
if !utils.CheckExists(fp, false) {
return errors.New("config file not found")
}
// read config file
b, err := ioutil.ReadFile(fp)
if err != nil {
return err
}
c = &Config{}
if err := yaml.Unmarshal(b, c); err != nil {
return err
}
envconfig.Parse(c)
return nil
}
func Get() *Config {
if c == nil {
panic(errors.New("config not init"))
}
return c
}
+43
View File
@@ -0,0 +1,43 @@
package database
import (
"errors"
"os"
"path"
"git.trj.tw/golang/utils"
"go.etcd.io/bbolt"
)
var db *bbolt.DB
func New(dbPath ...string) error {
var err error
var fp string
if len(dbPath) > 0 && dbPath[0] != "" {
fp = dbPath[0]
} else {
wd, err := os.Getwd()
if err != nil {
return err
}
fp = path.Join(wd, "store.db")
}
fp = utils.ParsePath(fp)
db, err = bbolt.Open(fp, 0664, nil)
if err != nil {
return err
}
return nil
}
func Get() *bbolt.DB {
if db == nil {
panic(errors.New("database not init"))
}
return db
}
+97
View File
@@ -0,0 +1,97 @@
package led
import (
"errors"
"rpi-ci-led/pkg/ws2812b"
"time"
)
type LEDSvc struct {
pin int
count int
blink map[int]chan struct{}
done chan struct{}
}
var led *LEDSvc
func Init(pin, count int) (*LEDSvc, error) {
_, err := ws2812b.Init(pin, count, 255)
if err != nil {
return nil, err
}
return &LEDSvc{
pin: pin,
count: count,
blink: make(map[int]chan struct{}),
done: make(chan struct{}),
}, nil
}
func Get() *LEDSvc {
if led == nil {
panic(errors.New("not init"))
}
return led
}
func (p *LEDSvc) SetColor(pos int, color uint32) error {
if pos < 0 || pos > p.count {
return errors.New("out of range")
}
if ch, ok := p.blink[pos]; ok {
close(ch)
delete(p.blink, pos)
}
ws2812b.WriteColor(pos, color)
return nil
}
func (p *LEDSvc) StopBlink(pos int) {
if ch, ok := p.blink[pos]; ok {
close(ch)
delete(p.blink, pos)
}
}
func (p *LEDSvc) SetBlink(pos int, color uint32, interval time.Duration) {
if ch, ok := p.blink[pos]; ok {
close(ch)
delete(p.blink, pos)
}
go func() {
defer func() {
ws2812b.WriteColor(pos, 0)
delete(p.blink, pos)
}()
ch := make(chan struct{})
p.blink[pos] = ch
timer := time.NewTicker(interval)
on := false
for {
select {
case <-ch:
return
case <-timer.C:
if on {
ws2812b.WriteColor(pos, 0)
} else {
ws2812b.WriteColor(pos, color)
}
on = !on
}
}
}()
}
func (p *LEDSvc) Run() {
ticker := time.NewTicker(time.Millisecond * 100)
for {
select {
case <-p.done:
return
case <-ticker.C:
}
}
}
+91
View File
@@ -0,0 +1,91 @@
package websocket
import (
"errors"
"net/http"
"net/textproto"
"github.com/gorilla/websocket"
)
type Socket struct {
*websocket.Conn
Listeners map[string](chan<- []byte)
done chan struct{}
errd bool
errsig chan error
}
var client *Socket
func NewClient(remote string) (*Socket, error) {
if remote == "" {
return nil, errors.New("remote url is empty")
}
var err error
headers := http.Header{}
headers.Set(
textproto.CanonicalMIMEHeaderKey("X-Auth-Key"),
"rpi",
)
c, resp, err := websocket.DefaultDialer.Dial(remote, headers)
if err != nil {
return nil, err
}
defer resp.Body.Close()
client = &Socket{
Conn: c,
Listeners: make(map[string](chan<- []byte)),
done: make(chan struct{}, 0),
errd: false,
errsig: make(chan error),
}
return client, nil
}
func (p *Socket) Listen() error {
go func() {
defer close(p.done)
for {
_, msg, err := p.ReadMessage()
if err != nil {
p.errsig <- err
}
for _, v := range p.Listeners {
v <- msg
}
}
}()
select {
case <-p.done:
return nil
case err := <-p.errsig:
return err
}
}
func (p *Socket) AddListener(alias string, c chan<- []byte) error {
if _, ok := p.Listeners[alias]; ok {
return errors.New("listener name exists")
}
p.Listeners[alias] = c
return nil
}
func (p *Socket) RemoveListener(alias string) error {
if v, ok := p.Listeners[alias]; !ok {
return errors.New("listener not exists")
} else {
close(v)
delete(p.Listeners, alias)
}
return nil
}
+16
View File
@@ -23,6 +23,7 @@ func Init(gpio, count, brightness int) (*LED, error) {
err := ws2811.Init(gpio, count, brightness)
if err != nil {
led = nil
return nil, err
}
@@ -36,15 +37,30 @@ func Init(gpio, count, brightness int) (*LED, error) {
return led, nil
}
func IsInit() bool {
if led == nil {
return false
}
return led.IsInit
}
func Close() {
ws2811.Clear()
ws2811.Fini()
led.IsInit = false
}
func ClearAll() {
ws2811.Clear()
}
func Len() int {
if led == nil {
return 0
}
return led.Count
}
func WriteColor(pos int, color uint32) error {
if pos < 0 || pos > led.Count {
return errors.New("position out of range")