morningalarm/internal/webserver.go
2023-08-26 02:12:30 +02:00

140 lines
3.1 KiB
Go

package morningalarm
import (
"net/http"
"time"
"github.com/gin-gonic/gin"
)
type Device struct {
Name string `json:"name"`
ID string `json:"id"`
}
func (ma *MorningAlarm) setupWebserver() {
ma.ro.POST("/api/alarm", func(c *gin.Context) {
var body alarm
if err := c.BindJSON(&body); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// Check if alarm name is valid
if body.Name == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "Alarm name cannot be empty"})
return
}
// Chekc if alarm name contains only alphanumeric characters
for _, char := range body.Name {
if !((char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') || (char >= '0' && char <= '9')) {
c.JSON(http.StatusBadRequest, gin.H{"error": "Alarm name must contain only alphanumeric characters"})
return
}
}
_, err := ma.addAlarm(body.Time, body.Name)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
} else {
err = ma.saveAlarms()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.Header("Location", "/api/alarm/"+body.Name)
c.JSON(http.StatusCreated, gin.H{})
}
})
ma.ro.GET("/api/alarm/:id", func(c *gin.Context) {
id := c.Param("id")
alarm := ma.getAlarm(id)
if alarm == nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Alarm not found"})
return
}
c.JSON(http.StatusOK, alarm)
})
ma.ro.GET("/api/alarm", func(c *gin.Context) {
c.JSON(http.StatusOK, ma.alarms)
})
ma.ro.DELETE("/api/alarm/:id", func(c *gin.Context) {
id := c.Param("id")
if ma.deleteAlarm(id) {
err := ma.saveAlarms()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{})
} else {
c.JSON(http.StatusNotFound, gin.H{"error": "Alarm not found"})
}
})
ma.ro.GET("/api/info", func(c *gin.Context) {
spotifyUser, err := ma.sp.CurrentUser(c)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
currentTime := time.Now()
zone, offset := currentTime.Zone()
nextIn := ma.nextAlarm()
response := gin.H{
"spotifyUser": spotifyUser.User.DisplayName,
"serverTime": currentTime.Format("15:04:05"),
"timezone": zone,
"timezoneOffsetInH": offset / 60 / 60,
"alarms": len(ma.cr.Entries()),
"wakeupPlaylist": ma.config.PlaylistID,
"deviceId": ma.config.DeviceID,
}
if nextIn != nil {
response["nextAlarmAt"] = nextIn.String()
response["nextAlarmIn"] = nextIn.Sub(currentTime).String()
}
c.JSON(http.StatusOK, response)
})
ma.ro.GET("/api/device", func(c *gin.Context) {
devices, err := ma.getAvailableDevices()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, devices)
})
ma.ro.POST("/api/trigger", func(c *gin.Context) {
if _, err := ma.playWakeUpMusic(); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{})
})
}