From 5a85fe9f837ef44098a20b63ba44247f4b100426 Mon Sep 17 00:00:00 2001 From: Michael Mayer Date: Sun, 17 Nov 2019 03:08:13 +0100 Subject: [PATCH] Save and load settings to / from settings.yml Signed-off-by: Michael Mayer --- assets/config/settings.yml | 2 ++ assets/resources/templates/index.tmpl | 3 +- frontend/src/model/settings.js | 12 +++++-- frontend/src/pages/settings/general.vue | 8 ++--- internal/api/settings.go | 20 +++++++++-- internal/config/config.go | 15 ++++++++- internal/config/settings.go | 44 +++++++++++++++++++++++++ 7 files changed, 93 insertions(+), 11 deletions(-) create mode 100644 assets/config/settings.yml diff --git a/assets/config/settings.yml b/assets/config/settings.yml new file mode 100644 index 000000000..df5fcf465 --- /dev/null +++ b/assets/config/settings.yml @@ -0,0 +1,2 @@ +theme: dark +language: en diff --git a/assets/resources/templates/index.tmpl b/assets/resources/templates/index.tmpl index c377f10fc..b5a45c987 100644 --- a/assets/resources/templates/index.tmpl +++ b/assets/resources/templates/index.tmpl @@ -41,7 +41,8 @@ "public": {{ .public }}, "cameras": {{ .cameras }}, "countries": {{ .countries }}, - "thumbnails": {{ .thumbnails }} + "thumbnails": {{ .thumbnails }}, + "settings": {{ .settings }}, }; diff --git a/frontend/src/model/settings.js b/frontend/src/model/settings.js index 0739e191d..4359a52aa 100644 --- a/frontend/src/model/settings.js +++ b/frontend/src/model/settings.js @@ -4,9 +4,16 @@ class Settings { constructor(values) { this.__originalValues = {}; - if (values) { - this.setValues(values); + if (!values) { + values = { + theme: "dark", + language: "en", + }; } + + console.log("config values", values); + + this.setValues(values); } setValues(values) { @@ -41,6 +48,7 @@ class Settings { } save() { + return Api.post("settings", this.getValues()).then((response) => Promise.resolve(this.setValues(response.data))); } } diff --git a/frontend/src/pages/settings/general.vue b/frontend/src/pages/settings/general.vue index e0a058c5e..9534aa4b4 100644 --- a/frontend/src/pages/settings/general.vue +++ b/frontend/src/pages/settings/general.vue @@ -8,7 +8,7 @@ :items="languages" label="Language" color="blue-grey" - value="en" + v-model="settings.language" flat > @@ -18,7 +18,7 @@ :items="themes" label="Theme" color="blue-grey" - value="" + v-model="settings.theme" flat > @@ -45,9 +45,9 @@ return { readonly: this.$config.getValue("readonly"), active: 0, - settings: new Settings(), + settings: new Settings(this.$config.values.settings), list: {}, - themes: [{text: "Default", value: ""}], + themes: [{text: "Dark", value: "dark"}, {text: "Light", value: "light"}], languages: [{text: "English", value: "en"}], }; }, diff --git a/internal/api/settings.go b/internal/api/settings.go index 1634d2ee9..dc803f0a9 100644 --- a/internal/api/settings.go +++ b/internal/api/settings.go @@ -5,6 +5,8 @@ import ( "github.com/gin-gonic/gin" "github.com/photoprism/photoprism/internal/config" + "github.com/photoprism/photoprism/internal/event" + "github.com/photoprism/photoprism/internal/util" ) // GET /api/v1/settings @@ -15,9 +17,9 @@ func GetSettings(router *gin.RouterGroup, conf *config.Config) { return } - result := conf.Settings() + s := conf.Settings() - c.JSON(http.StatusOK, result) + c.JSON(http.StatusOK, s) }) } @@ -29,7 +31,19 @@ func SaveSettings(router *gin.RouterGroup, conf *config.Config) { return } - // TODO + s := conf.Settings() + + if err := c.BindJSON(s); err != nil { + c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": util.UcFirst(err.Error())}) + return + } + + if err := s.WriteValuesToFile(conf.SettingsFile()); err != nil { + c.AbortWithStatusJSON(http.StatusInternalServerError, err) + return + } + + event.Publish("config.updated", event.Data(conf.ClientConfig())) c.JSON(http.StatusOK, gin.H{"message": "saved"}) }) diff --git a/internal/config/config.go b/internal/config/config.go index 7f5982930..28d8d8a74 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -240,6 +240,11 @@ func (c *Config) ConfigFile() string { return c.config.ConfigFile } +// SettingsFile returns the user settings file name. +func (c *Config) SettingsFile() string { + return c.ConfigPath() + "/settings.yml" +} + // ConfigPath returns the config path. func (c *Config) ConfigPath() string { if c.config.ConfigPath == "" { @@ -532,6 +537,7 @@ func (c *Config) ClientConfig() ClientConfig { "thumbnails": Thumbnails, "jsHash": jsHash, "cssHash": cssHash, + "settings": c.Settings(), } return result @@ -553,5 +559,12 @@ func (c *Config) Shutdown() { // Settings returns the current user settings. func (c *Config) Settings() *Settings { - return &Settings{} + s := NewSettings() + p := c.SettingsFile() + + if err := s.SetValuesFromFile(p); err != nil { + log.Error(err) + } + + return s } diff --git a/internal/config/settings.go b/internal/config/settings.go index 717abed0e..3250ed5a4 100644 --- a/internal/config/settings.go +++ b/internal/config/settings.go @@ -1,6 +1,50 @@ package config +import ( + "fmt" + "io/ioutil" + "os" + + "github.com/photoprism/photoprism/internal/util" + "gopkg.in/yaml.v2" +) + type Settings struct { Theme string `json:"theme" yaml:"theme" flag:"theme"` Language string `json:"language" yaml:"language" flag:"language"` } + +func NewSettings() *Settings { + return &Settings{} +} + +// SetValuesFromFile uses a yaml config file to initiate the configuration entity. +func (s *Settings) SetValuesFromFile(fileName string) error { + if !util.Exists(fileName) { + return fmt.Errorf("settings file not found: \"%s\"", fileName) + } + + yamlConfig, err := ioutil.ReadFile(fileName) + + if err != nil { + return err + } + + return yaml.Unmarshal(yamlConfig, s) +} + +// WriteValuesToFile uses a yaml config file to initiate the configuration entity. +func (s *Settings) WriteValuesToFile(fileName string) error { + if !util.Exists(fileName) { + return fmt.Errorf("settings file not found: \"%s\"", fileName) + } + + data, err := yaml.Marshal(s) + + if err != nil { + return err + } + + return ioutil.WriteFile(fileName, data, os.ModePerm) +} +