|
|
package api
import ( "context" "git.aiterp.net/lucifer/new-server/app/config" "git.aiterp.net/lucifer/new-server/models" "github.com/gin-gonic/gin" "log" "strings" )
func fetchDevices(ctx context.Context, fetchStr string) ([]models.Device, error) { if strings.HasPrefix(fetchStr, "tag:") { return config.DeviceRepository().FetchByReference(ctx, models.RKTag, fetchStr[4:]) } else if strings.HasPrefix(fetchStr, "bridge:") { return config.DeviceRepository().FetchByReference(ctx, models.RKBridgeID, fetchStr[7:]) } else if fetchStr == "all" { return config.DeviceRepository().FetchByReference(ctx, models.RKAll, "") } else { return config.DeviceRepository().FetchByReference(ctx, models.RKDeviceID, fetchStr) } }
func Devices(r gin.IRoutes) { r.GET("", handler(func(c *gin.Context) (interface{}, error) { return config.DeviceRepository().FetchByReference(ctxOf(c), models.RKAll, "") }))
r.GET("/:fetch", handler(func(c *gin.Context) (interface{}, error) { return fetchDevices(ctxOf(c), c.Param("fetch")) }))
r.PUT("/batch", handler(func(c *gin.Context) (interface{}, error) { var body []struct { Fetch string `json:"fetch"` SetState models.NewDeviceState `json:"setState"` } err := parseBody(c, &body) if err != nil { return nil, err }
set := make(map[int]bool) changed := make([]models.Device, 0, 64) for _, job := range body { devices, err := fetchDevices(ctxOf(c), job.Fetch) if err != nil { return nil, err } if len(devices) == 0 { return []models.Device{}, nil }
for i := range devices { if set[devices[i].ID] { continue }
err := devices[i].SetState(job.SetState) if err != nil { return nil, err }
set[devices[i].ID] = true changed = append(changed, devices[i]) } }
config.PublishChannel <- changed
go func() { for _, device := range changed { err := config.DeviceRepository().Save(context.Background(), &device) if err != nil { log.Println("Failed to save device for state:", err) continue } } }()
return changed, nil }))
r.PUT("/:fetch/state", handler(func(c *gin.Context) (interface{}, error) { state := models.NewDeviceState{} err := parseBody(c, &state) if err != nil { return nil, err }
devices, err := fetchDevices(ctxOf(c), c.Param("fetch")) if err != nil { return nil, err } if len(devices) == 0 { return []models.Device{}, nil }
for i := range devices { err := devices[i].SetState(state) if err != nil { return nil, err } }
config.PublishChannel <- devices
go func() { for _, device := range devices { err := config.DeviceRepository().Save(context.Background(), &device) if err != nil { log.Println("Failed to save device for state:", err) continue } } }()
return devices, nil }))
r.PUT("/:fetch/tags", handler(func(c *gin.Context) (interface{}, error) { var body struct { Add []string `json:"add"` Remove []string `json:"remove"` } err := parseBody(c, &body) if err != nil { return nil, err }
devices, err := fetchDevices(ctxOf(c), c.Param("fetch")) if err != nil { return nil, err } if len(devices) == 0 { return []models.Device{}, nil }
for i := range devices { device := &devices[i]
for _, tag := range body.Add { found := false for _, tag2 := range device.Tags { if tag == tag2 { found = true break } }
if !found { device.Tags = append(device.Tags, tag) } } for _, tag := range body.Remove { index := -1 for i, tag2 := range device.Tags { if tag == tag2 { index = i } }
device.Tags = append(device.Tags[:index], device.Tags[index+1:]...) }
err = config.DeviceRepository().Save(ctxOf(c), device) if err != nil { return nil, err } }
return devices, nil })) }
|