color api
This commit is contained in:
@@ -12,6 +12,10 @@ func Bridges(r gin.IRoutes) {
|
||||
return config.BridgeRepository().FetchAll(ctxOf(c))
|
||||
}))
|
||||
|
||||
r.GET("/:id", handler(func(c *gin.Context) (interface{}, error) {
|
||||
return config.BridgeRepository().Find(ctxOf(c), intParam(c, "id"))
|
||||
}))
|
||||
|
||||
r.POST("", handler(func(c *gin.Context) (interface{}, error) {
|
||||
var body struct {
|
||||
Driver models.DriverKind `json:"driver"`
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"git.aiterp.net/lucifer/new-server/app/config"
|
||||
"git.aiterp.net/lucifer/new-server/models"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func ColorPresets(r gin.IRoutes) {
|
||||
r.GET("", handler(func(c *gin.Context) (interface{}, error) {
|
||||
return config.ColorPresetRepository().FetchAll(ctxOf(c))
|
||||
}))
|
||||
|
||||
r.GET("/:id", handler(func(c *gin.Context) (interface{}, error) {
|
||||
return config.ColorPresetRepository().Find(ctxOf(c), intParam(c, "id"))
|
||||
}))
|
||||
|
||||
r.POST("", handler(func(c *gin.Context) (interface{}, error) {
|
||||
var body struct {
|
||||
Name string `json:"name"`
|
||||
ColorString string `json:"colorString"`
|
||||
}
|
||||
err := parseBody(c, &body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newColor, err := models.ParseColorValue(body.ColorString)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
preset := models.ColorPreset{
|
||||
Name: body.Name,
|
||||
Value: newColor,
|
||||
}
|
||||
|
||||
preset.Validate()
|
||||
err = config.ColorPresetRepository().Save(ctxOf(c), &preset)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return preset, nil
|
||||
}))
|
||||
|
||||
r.PUT("/:id", handler(func(c *gin.Context) (interface{}, error) {
|
||||
var body struct {
|
||||
Name *string `json:"name"`
|
||||
ColorString *string `json:"colorString"`
|
||||
}
|
||||
err := parseBody(c, &body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
preset, err := config.ColorPresetRepository().Find(ctxOf(c), intParam(c, "id"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if body.Name != nil {
|
||||
preset.Name = *body.Name
|
||||
}
|
||||
|
||||
if body.ColorString != nil {
|
||||
newColor, err := models.ParseColorValue(*body.ColorString)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
preset.Value = newColor
|
||||
}
|
||||
|
||||
preset.Validate()
|
||||
err = config.ColorPresetRepository().Save(ctxOf(c), &preset)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return preset, nil
|
||||
}))
|
||||
}
|
||||
@@ -15,9 +15,9 @@ func DriverProvider() models.DriverProvider {
|
||||
defer dpMutex.Unlock()
|
||||
|
||||
if dp == nil {
|
||||
dp = &drivers.MapBasedDriverProvider{Data: map[models.DriverKind]models.Driver{
|
||||
dp = drivers.DriverMap{
|
||||
models.DTNanoLeaf: &nanoleaf.Driver{},
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
return dp
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
var (
|
||||
bRepo models.BridgeRepository
|
||||
cpRepo models.ColorPresetRepository
|
||||
dRepo models.DeviceRepository
|
||||
ehRepo models.EventHandlerRepository
|
||||
)
|
||||
@@ -19,6 +20,14 @@ func BridgeRepository() models.BridgeRepository {
|
||||
return bRepo
|
||||
}
|
||||
|
||||
func ColorPresetRepository() models.ColorPresetRepository {
|
||||
if cpRepo == nil {
|
||||
cpRepo = &mysql.ColorPresetRepo{DBX: DBX()}
|
||||
}
|
||||
|
||||
return cpRepo
|
||||
}
|
||||
|
||||
func DeviceRepository() models.DeviceRepository {
|
||||
if dRepo == nil {
|
||||
panic("panik")
|
||||
|
||||
@@ -17,6 +17,7 @@ func StartServer() {
|
||||
|
||||
apiGin := ginny.Group("/api")
|
||||
api.Bridges(apiGin.Group("/bridges"))
|
||||
api.ColorPresets(apiGin.Group("/color-presets"))
|
||||
api.DriverKinds(apiGin.Group("/driver-kinds"))
|
||||
api.Events(apiGin.Group("/events"))
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ func main() {
|
||||
|
||||
_ = driver.Publish(context.Background(), bridge, devices)
|
||||
|
||||
ch := make(chan models.Event)
|
||||
ch := config.EventChannel
|
||||
go func() {
|
||||
err := driver.Run(context.Background(), bridge, ch)
|
||||
if err != nil {
|
||||
|
||||
@@ -4,11 +4,13 @@ import (
|
||||
"git.aiterp.net/lucifer/new-server/app/config"
|
||||
"github.com/pressly/goose"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
db := config.DBX().DB
|
||||
|
||||
log.Printf("Target version: %s",time.Now().Format("20060102150405"))
|
||||
log.Printf("Database: %s:%d/%s", config.MySqlHost(), config.MySqlPort(), config.MySqlSchema())
|
||||
log.Printf("Authenticating as: %s", config.MySqlUsername())
|
||||
|
||||
|
||||
@@ -2,15 +2,13 @@ package drivers
|
||||
|
||||
import "git.aiterp.net/lucifer/new-server/models"
|
||||
|
||||
type MapBasedDriverProvider struct {
|
||||
Data map[models.DriverKind]models.Driver
|
||||
}
|
||||
type DriverMap map[models.DriverKind]models.Driver
|
||||
|
||||
func (m *MapBasedDriverProvider) Provide(kind models.DriverKind) (models.Driver, error) {
|
||||
if m.Data[kind] == nil {
|
||||
func (m DriverMap) Provide(kind models.DriverKind) (models.Driver, error) {
|
||||
if m[kind] == nil {
|
||||
return nil, models.ErrUnknownDriver
|
||||
}
|
||||
|
||||
return m.Data[kind], nil
|
||||
return m[kind], nil
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ func (b *BridgeRepo) Find(ctx context.Context, id int) (models.Bridge, error) {
|
||||
|
||||
func (b *BridgeRepo) FetchAll(ctx context.Context) ([]models.Bridge, error) {
|
||||
bridges := make([]models.Bridge, 0, 8)
|
||||
err := b.DBX.GetContext(ctx, bridges, "SELECT * FROM bridge")
|
||||
err := b.DBX.GetContext(ctx, &bridges, "SELECT * FROM bridge")
|
||||
if err != nil {
|
||||
return nil, dbErr(err)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
package mysql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.aiterp.net/lucifer/new-server/models"
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
type presetRecord struct {
|
||||
ID int `db:"id"`
|
||||
Name string `db:"name"`
|
||||
Hue float64 `db:"hue"`
|
||||
Saturation float64 `db:"saturation"`
|
||||
Kelvin int `db:"kelvin"`
|
||||
}
|
||||
|
||||
type ColorPresetRepo struct {
|
||||
DBX *sqlx.DB
|
||||
}
|
||||
|
||||
func (c *ColorPresetRepo) Find(ctx context.Context, id int) (models.ColorPreset, error) {
|
||||
var record presetRecord
|
||||
err := c.DBX.GetContext(ctx, &record, "SELECT * FROM color_preset WHERE id = ?", id)
|
||||
if err != nil {
|
||||
return models.ColorPreset{}, dbErr(err)
|
||||
}
|
||||
|
||||
return c.fromRecords(record)[0], nil
|
||||
}
|
||||
|
||||
func (c *ColorPresetRepo) FetchAll(ctx context.Context) ([]models.ColorPreset, error) {
|
||||
records := make([]presetRecord, 0, 16)
|
||||
err := c.DBX.SelectContext(ctx, &records, "SELECT * FROM color_preset")
|
||||
if err != nil {
|
||||
return nil, dbErr(err)
|
||||
}
|
||||
|
||||
return c.fromRecords(records...), nil
|
||||
}
|
||||
|
||||
func (c *ColorPresetRepo) Save(ctx context.Context, preset *models.ColorPreset) error {
|
||||
if preset.ID > 0 {
|
||||
_, err := c.DBX.ExecContext(
|
||||
ctx,
|
||||
"UPDATE color_preset SET name = ?, hue = ?, saturation = ?, kelvin = ? WHERE id = ?",
|
||||
preset.Name, preset.Value.Hue, preset.Value.Saturation, preset.Value.Kelvin, preset.ID,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return dbErr(err)
|
||||
}
|
||||
} else {
|
||||
rs, err := c.DBX.ExecContext(
|
||||
ctx,
|
||||
"INSERT INTO color_preset (name, hue, saturation, kelvin) VALUES (?, ?, ?, ?)",
|
||||
preset.Name, preset.Value.Hue, preset.Value.Saturation, preset.Value.Kelvin,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return dbErr(err)
|
||||
}
|
||||
|
||||
id, err := rs.LastInsertId()
|
||||
if err != nil {
|
||||
return dbErr(err)
|
||||
}
|
||||
|
||||
preset.ID = int(id)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ColorPresetRepo) Delete(ctx context.Context, preset *models.ColorPreset) error {
|
||||
_, err := c.DBX.ExecContext(ctx, "DELETE FROM color_preset WHERE id = ?", preset.ID)
|
||||
if err != nil {
|
||||
return dbErr(err)
|
||||
}
|
||||
|
||||
preset.ID = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ColorPresetRepo) fromRecords(records ...presetRecord) []models.ColorPreset {
|
||||
newList := make([]models.ColorPreset, len(records), len(records))
|
||||
for i, record := range records {
|
||||
newList[i] = models.ColorPreset{
|
||||
ID: record.ID,
|
||||
Name: record.Name,
|
||||
Value: models.ColorValue{
|
||||
Hue: record.Hue,
|
||||
Saturation: record.Saturation,
|
||||
Kelvin: record.Kelvin,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return newList
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ColorPreset struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Value ColorValue `json:"value"`
|
||||
}
|
||||
|
||||
type ColorPresetRepository interface {
|
||||
Find(ctx context.Context, id int) (ColorPreset, error)
|
||||
FetchAll(ctx context.Context) ([]ColorPreset, error)
|
||||
Save(ctx context.Context, preset *ColorPreset) error
|
||||
Delete(ctx context.Context, preset *ColorPreset) error
|
||||
}
|
||||
|
||||
func (c *ColorPreset) Validate() {
|
||||
c.Name = strings.Trim(c.Name, " \t\n")
|
||||
if len(c.Name) == 0 {
|
||||
c.Name = c.Value.String()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE TABLE color_preset
|
||||
(
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
hue DOUBLE NOT NULL,
|
||||
saturation DOUBLE NOT NULL,
|
||||
kelvin INT NOT NULL,
|
||||
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE color_preset;
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,11 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
ALTER TABLE color_preset
|
||||
ADD COLUMN name VARCHAR(255) NOT NULL DEFAULT 'Unnamed';
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
ALTER TABLE color_preset
|
||||
DROP COLUMN name;
|
||||
-- +goose StatementEnd
|
||||
Reference in New Issue
Block a user