This commit is contained in:
Stian Fredrik Aune
2021-05-23 14:00:42 +02:00
parent f7f8989d20
commit 21157e4330
25 changed files with 24454 additions and 11560 deletions
+88
View File
@@ -1 +1,89 @@
package api
import (
"git.aiterp.net/lucifer/new-server/app/config"
"git.aiterp.net/lucifer/new-server/models"
"github.com/gin-gonic/gin"
"log"
)
func Bridges(r gin.IRoutes) {
r.GET("", handler(func(c *gin.Context) (interface{}, error) {
return config.BridgeRepository().FetchAll(ctxOf(c))
}))
r.POST("", handler(func(c *gin.Context) (interface{}, error) {
var body struct {
Driver models.DriverKind `json:"driver"`
Address string `json:"address"`
DryRun bool `json:"dryRun"`
}
err := parseBody(c, &body)
if err != nil {
return nil, err
}
driver, err := config.DriverProvider().Provide(body.Driver)
if err != nil {
return nil, err
}
bridges, err := driver.SearchBridge(ctxOf(c), body.Address, body.DryRun)
if err != nil {
return nil, err
}
if !body.DryRun {
for _, bridge := range bridges {
err := config.BridgeRepository().Save(ctxOf(c), &bridge)
if err != nil {
return nil, err
}
log.Printf("Saved new bridge: %s (%s)", bridge.Name, bridge.Address)
}
}
return bridges, nil
}))
r.PUT("/:id", handler(func(c *gin.Context) (interface{}, error) {
var body struct {
Name *string `json:"name"`
}
err := parseBody(c, &body)
if err != nil {
return nil, err
}
bridge, err := config.BridgeRepository().Find(ctxOf(c), intParam(c, "id"))
if err != nil {
return nil, err
}
if body.Name != nil {
bridge.Name = *body.Name
}
err = config.BridgeRepository().Save(ctxOf(c), &bridge)
if err != nil {
return nil, err
}
return bridge, nil
}))
r.DELETE("/:id", handler(func(c *gin.Context) (interface{}, error) {
bridge, err := config.BridgeRepository().Find(ctxOf(c), intParam(c, "id"))
if err != nil {
return nil, err
}
err = config.BridgeRepository().Delete(ctxOf(c), &bridge)
if err != nil {
return nil, err
}
return bridge, nil
}))
}
+27 -3
View File
@@ -1,13 +1,20 @@
package api
import (
"context"
"encoding/json"
"git.aiterp.net/lucifer/new-server/models"
"github.com/gin-gonic/gin"
"strconv"
)
var errorMap = map[error]int{
models.ErrInvalidName: 400,
models.ErrNotFound: 404,
models.ErrInvalidName: 400,
models.ErrBadInput: 400,
models.ErrBadColor: 400,
models.ErrInternal: 500,
models.ErrUnknownColorFormat: 400,
}
type response struct {
@@ -26,16 +33,29 @@ func handler(fun func(c *gin.Context) (interface{}, error)) gin.HandlerFunc {
}
c.JSON(errCode, response{
Code: errCode,
Code: errCode,
Message: err.Error(),
})
return
}
c.JSON(200, val)
c.JSON(200, response{
Code: 200,
Message: "success",
Data: val,
})
}
}
func intParam(c *gin.Context, key string) int {
i, err := strconv.Atoi(c.Param(key))
if err != nil {
return 0
}
return i
}
func parseBody(c *gin.Context, target interface{}) error {
err := json.NewDecoder(c.Request.Body).Decode(target)
if err != nil {
@@ -44,3 +64,7 @@ func parseBody(c *gin.Context, target interface{}) error {
return nil
}
func ctxOf(c *gin.Context) context.Context {
return c.Request.Context()
}
+2
View File
@@ -5,3 +5,5 @@ import "git.aiterp.net/lucifer/new-server/models"
var EventChannel = make(chan models.Event, 8)
var ChangeChannel = make(chan string, 16)
var PublishChannel = make(chan []models.Device, 32)
+13 -1
View File
@@ -1,12 +1,24 @@
package config
import "git.aiterp.net/lucifer/new-server/models"
import (
"git.aiterp.net/lucifer/new-server/internal/mysql"
"git.aiterp.net/lucifer/new-server/models"
)
var (
bRepo models.BridgeRepository
dRepo models.DeviceRepository
ehRepo models.EventHandlerRepository
)
func BridgeRepository() models.BridgeRepository {
if bRepo == nil {
bRepo = &mysql.BridgeRepo{DBX: DBX()}
}
return bRepo
}
func DeviceRepository() models.DeviceRepository {
if dRepo == nil {
panic("panik")
+2 -1
View File
@@ -16,8 +16,9 @@ func StartServer() {
ginny := gin.New()
apiGin := ginny.Group("/api")
api.Bridges(apiGin.Group("/bridges"))
api.DriverKinds(apiGin.Group("/driver-kinds"))
api.Events(apiGin.Group("/events"))
log.Fatal(ginny.Run(fmt.Sprintf("0.0.0.0:%d", config.ServerPort)))
log.Fatal(ginny.Run(fmt.Sprintf("0.0.0.0:%d", config.ServerPort())))
}
+1 -2
View File
@@ -41,6 +41,7 @@ func handleEvent(event models.Event) {
}
if !X {
log.Println("Unhandled event: " + event.Name)
return
}
@@ -62,6 +63,4 @@ func handleEvent(event models.Event) {
}
}
log.Println("Unhandled event: " + event.Name)
}
+46
View File
@@ -1 +1,47 @@
package services
import (
"context"
"git.aiterp.net/lucifer/new-server/app/config"
"git.aiterp.net/lucifer/new-server/models"
"log"
)
func StartPublisher() {
ctx := context.Background()
go func() {
for devices := range config.PublishChannel {
if len(devices) == 0 {
continue
}
// Emergency solution! Please avoid!
// Send devices not belonging to the first channel separately
bridgeID := devices[0].BridgeID
for _, device := range devices {
if device.BridgeID != bridgeID {
config.PublishChannel<-[]models.Device{device}
}
}
bridge, err := config.BridgeRepository().Find(ctx, devices[0].BridgeID)
if err != nil {
log.Println("Publishing error (1): " + err.Error())
continue
}
driver, err := config.DriverProvider().Provide(bridge.Driver)
if err != nil {
log.Println("Publishing error (2): " + err.Error())
continue
}
err = driver.Publish(ctx, bridge, devices)
if err != nil {
log.Println("Publishing error (3): " + err.Error())
continue
}
}
}()
}