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.

123 lines
2.8 KiB

  1. package api
  2. import (
  3. "context"
  4. "git.aiterp.net/lucifer/new-server/app/config"
  5. "git.aiterp.net/lucifer/new-server/models"
  6. "github.com/gin-gonic/gin"
  7. "log"
  8. "strings"
  9. )
  10. func fetchDevices(ctx context.Context, fetchStr string) ([]models.Device, error) {
  11. if strings.HasPrefix(fetchStr, "tag:") {
  12. return config.DeviceRepository().FetchByReference(ctx, models.RKTag, fetchStr[4:])
  13. } else if strings.HasPrefix(fetchStr, "bridge:") {
  14. return config.DeviceRepository().FetchByReference(ctx, models.RKBridgeID, fetchStr[7:])
  15. } else if fetchStr == "all" {
  16. return config.DeviceRepository().FetchByReference(ctx, models.RKAll, "")
  17. } else {
  18. return config.DeviceRepository().FetchByReference(ctx, models.RKDeviceID, fetchStr)
  19. }
  20. }
  21. func Devices(r gin.IRoutes) {
  22. r.GET("", handler(func(c *gin.Context) (interface{}, error) {
  23. return config.DeviceRepository().FetchByReference(ctxOf(c), models.RKAll, "")
  24. }))
  25. r.GET("/:fetch", handler(func(c *gin.Context) (interface{}, error) {
  26. return fetchDevices(ctxOf(c), c.Param("fetch"))
  27. }))
  28. r.PUT("/:fetch/state", handler(func(c *gin.Context) (interface{}, error) {
  29. state := models.NewDeviceState{}
  30. err := parseBody(c, &state)
  31. if err != nil {
  32. return nil, err
  33. }
  34. devices, err := fetchDevices(ctxOf(c), c.Param("fetch"))
  35. if err != nil {
  36. return nil, err
  37. }
  38. if len(devices) == 0 {
  39. return []models.Device{}, nil
  40. }
  41. for i := range devices {
  42. err := devices[i].SetState(state)
  43. if err != nil {
  44. return nil, err
  45. }
  46. }
  47. config.PublishChannel <- devices
  48. go func() {
  49. for _, device := range devices {
  50. err := config.DeviceRepository().Save(context.Background(), &device)
  51. if err != nil {
  52. log.Println("Failed to save device for state:", err)
  53. continue
  54. }
  55. }
  56. }()
  57. return devices, nil
  58. }))
  59. r.PUT("/:fetch/tags", handler(func(c *gin.Context) (interface{}, error) {
  60. var body struct {
  61. Add []string `json:"add"`
  62. Remove []string `json:"remove"`
  63. }
  64. err := parseBody(c, &body)
  65. if err != nil {
  66. return nil, err
  67. }
  68. devices, err := fetchDevices(ctxOf(c), c.Param("fetch"))
  69. if err != nil {
  70. return nil, err
  71. }
  72. if len(devices) == 0 {
  73. return []models.Device{}, nil
  74. }
  75. for i := range devices {
  76. device := &devices[i]
  77. for _, tag := range body.Add {
  78. found := false
  79. for _, tag2 := range device.Tags {
  80. if tag == tag2 {
  81. found = true
  82. break
  83. }
  84. }
  85. if !found {
  86. device.Tags = append(device.Tags, tag)
  87. }
  88. }
  89. for _, tag := range body.Remove {
  90. index := -1
  91. for i, tag2 := range device.Tags {
  92. if tag == tag2 {
  93. index = i
  94. }
  95. }
  96. device.Tags = append(device.Tags[:index], device.Tags[index+1:]...)
  97. }
  98. err = config.DeviceRepository().Save(ctxOf(c), device)
  99. if err != nil {
  100. return nil, err
  101. }
  102. }
  103. return devices, nil
  104. }))
  105. }