settings: Save future changes in a dedicated file
This commit is contained in:
parent
465a48c1c0
commit
3c237819c3
5 changed files with 295 additions and 15 deletions
|
@ -9,6 +9,7 @@ import (
|
|||
"os"
|
||||
"path"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"srs.epita.fr/fic-server/admin/sync"
|
||||
|
@ -38,9 +39,34 @@ func declareSettingsRoutes(router *gin.RouterGroup) {
|
|||
c.JSON(http.StatusOK, true)
|
||||
})
|
||||
|
||||
router.GET("/settings-next", listNextSettings)
|
||||
|
||||
apiNextSettingsRoutes := router.Group("/settings-next/:ts")
|
||||
apiNextSettingsRoutes.Use(NextSettingsHandler)
|
||||
apiNextSettingsRoutes.GET("", getNextSettings)
|
||||
apiNextSettingsRoutes.DELETE("", deleteNextSettings)
|
||||
|
||||
router.POST("/reset", reset)
|
||||
}
|
||||
|
||||
func NextSettingsHandler(c *gin.Context) {
|
||||
ts, err := strconv.ParseInt(string(c.Params.ByName("ts")), 10, 64)
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": "Invalid next settings identifier"})
|
||||
return
|
||||
}
|
||||
|
||||
nsf, err := settings.ReadNextSettingsFile(path.Join(settings.SettingsDir, fmt.Sprintf("%d.json", ts)), ts)
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": "Next settings not found"})
|
||||
return
|
||||
}
|
||||
|
||||
c.Set("next-settings", nsf)
|
||||
|
||||
c.Next()
|
||||
}
|
||||
|
||||
func getROSettings(c *gin.Context) {
|
||||
syncMtd := "Disabled"
|
||||
if sync.GlobalImporter != nil {
|
||||
|
@ -142,14 +168,102 @@ func saveSettings(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
if err := settings.SaveSettings(path.Join(settings.SettingsDir, settings.SettingsFile), config); err != nil {
|
||||
log.Println("Unable to SaveSettings:", err.Error())
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Unable to save settings: %s", err.Error())})
|
||||
// Is this a future setting?
|
||||
if c.Request.URL.Query().Has("t") {
|
||||
t, err := time.Parse(time.RFC3339, c.Request.URL.Query().Get("t"))
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Load current settings to perform diff later
|
||||
init_settings, err := settings.ReadSettings(path.Join(settings.SettingsDir, settings.SettingsFile))
|
||||
if err != nil {
|
||||
log.Println("Unable to ReadSettings:", err.Error())
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Unable to read settings: %s", err.Error())})
|
||||
return
|
||||
}
|
||||
|
||||
current_settings := init_settings
|
||||
// Apply already registered settings
|
||||
nsu, err := settings.MergeNextSettingsUntil(&t)
|
||||
if err == nil {
|
||||
current_settings = settings.MergeSettings(*init_settings, nsu)
|
||||
} else {
|
||||
log.Println("Unable to MergeNextSettingsUntil:", err.Error())
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Unable to merge next settings: %s", err.Error())})
|
||||
return
|
||||
}
|
||||
|
||||
// Keep only diff
|
||||
diff := settings.DiffSettings(current_settings, config)
|
||||
|
||||
hasItems := false
|
||||
for _, _ = range diff {
|
||||
hasItems = true
|
||||
break
|
||||
}
|
||||
|
||||
if !hasItems {
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": "No difference to apply."})
|
||||
return
|
||||
}
|
||||
|
||||
if !c.Request.URL.Query().Has("erase") {
|
||||
// Check if there is already diff to apply at the given time
|
||||
if nsf, err := settings.ReadNextSettingsFile(path.Join(settings.SettingsDir, fmt.Sprintf("%d.json", t.Unix())), t.Unix()); err == nil {
|
||||
for k, v := range nsf.Values {
|
||||
if _, ok := diff[k]; !ok {
|
||||
diff[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save the diff
|
||||
settings.SaveSettings(path.Join(settings.SettingsDir, fmt.Sprintf("%d.json", t.Unix())), diff)
|
||||
|
||||
// Return current settings
|
||||
c.JSON(http.StatusOK, current_settings)
|
||||
} else {
|
||||
// Just apply settings right now!
|
||||
if err := settings.SaveSettings(path.Join(settings.SettingsDir, settings.SettingsFile), config); err != nil {
|
||||
log.Println("Unable to SaveSettings:", err.Error())
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Unable to save settings: %s", err.Error())})
|
||||
return
|
||||
}
|
||||
|
||||
ApplySettings(config)
|
||||
c.JSON(http.StatusOK, config)
|
||||
}
|
||||
}
|
||||
|
||||
func listNextSettings(c *gin.Context) {
|
||||
nsf, err := settings.ListNextSettingsFiles()
|
||||
if err != nil {
|
||||
log.Println("Unable to ListNextSettingsFiles:", err.Error())
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Unable to list next settings files: %s", err.Error())})
|
||||
return
|
||||
}
|
||||
|
||||
ApplySettings(config)
|
||||
c.JSON(http.StatusOK, config)
|
||||
c.JSON(http.StatusOK, nsf)
|
||||
}
|
||||
|
||||
func getNextSettings(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, c.MustGet("next-settings").(*settings.NextSettingsFile))
|
||||
}
|
||||
|
||||
func deleteNextSettings(c *gin.Context) {
|
||||
nsf := c.MustGet("next-settings").(*settings.NextSettingsFile)
|
||||
|
||||
err := os.Remove(path.Join(settings.SettingsDir, fmt.Sprintf("%d.json", nsf.Id)))
|
||||
if err != nil {
|
||||
log.Println("Unable to remove the file:", err.Error())
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Unable to remove the file: %s", err.Error())})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, true)
|
||||
}
|
||||
|
||||
func ApplySettings(config *settings.Settings) {
|
||||
|
|
Reference in a new issue