diff --git a/client/admin/stores/SettingsStore.tsx b/client/admin/stores/SettingsStore.tsx index a13a690..071c15d 100644 --- a/client/admin/stores/SettingsStore.tsx +++ b/client/admin/stores/SettingsStore.tsx @@ -38,7 +38,7 @@ export class SettingsStore extends StoreBase { @observable public ssrPageCache: boolean; - @observable + @observable.shallow public cloudflare: ICloudflare; constructor() { diff --git a/server/controllers/settings.go b/server/controllers/settings.go index 985afa5..dcb98c7 100644 --- a/server/controllers/settings.go +++ b/server/controllers/settings.go @@ -3,6 +3,7 @@ package controllers import ( "github.com/labstack/echo/v4" "github.com/mohemohe/parakeet/server/models" + "github.com/mohemohe/parakeet/server/util" "net/http" ) @@ -187,7 +188,7 @@ func SetCloudflare(c echo.Context) error { panic("bind error") } - if err := models.SetKVS(models.KVCloudflare, reqBody); err != nil { + if err := models.SetKVS(models.KVCloudflare, util.StructToJsonMap(reqBody)); err != nil { panic(err) } diff --git a/server/models/cache.go b/server/models/cache.go index 4a89b13..5bb0c0a 100644 --- a/server/models/cache.go +++ b/server/models/cache.go @@ -28,13 +28,17 @@ func SetCache(key string, value interface{}) error { return connection.DsCache().Set(key, v, 365*24*time.Hour) } +func PurgeInternalCache() { + connection.PurgeDsCache() + + if err := pubsub.Publish(purgeCacheEvent, ""); err != nil { + util.Logger().Warn(err) + } +} + func PurgeCache() { go func() { - connection.PurgeDsCache() - - if err := pubsub.Publish(purgeCacheEvent, ""); err != nil { - util.Logger().Warn(err) - } + PurgeInternalCache() if kv := GetKVS(KVCloudflare); kv != nil { v := new(Cloudflare) diff --git a/server/models/entry.go b/server/models/entry.go index faac652..12d5b05 100644 --- a/server/models/entry.go +++ b/server/models/entry.go @@ -62,6 +62,9 @@ func GetEntries(perPage int, page int, includeDraft bool) *Entries { entries := new(Entries) if err := GetCache(cacheKey, entries); err == nil { + if len(entries.Entries) == 0 { + entries.Entries = []Entry{} + } return entries } @@ -86,6 +89,9 @@ func GetEntries(perPage int, page int, includeDraft bool) *Entries { for i := 0; i < info.RecordsOnPage; i++ { _ = find.Next(&entryArray[i]) } + if len(entryArray) == 0 { + entryArray = []Entry{} + } entries = &Entries{ Info: info, diff --git a/server/models/kvs.go b/server/models/kvs.go index 4097086..ac165d5 100644 --- a/server/models/kvs.go +++ b/server/models/kvs.go @@ -35,6 +35,7 @@ func GetKVS(key string) *KV { func SetKVS(key string, value interface{}) error { _, err := connection.Mongo().Collection(collections.KVS).Collection().Upsert(bson.M{"key": key}, bson.M{"key": key, "value": value}) if err == nil { + PurgeInternalCache() _ = SetCache("kvs:"+key, value) } return err diff --git a/server/models/model.go b/server/models/model.go index d54640e..03a887d 100644 --- a/server/models/model.go +++ b/server/models/model.go @@ -68,22 +68,22 @@ func InitDB() { setDefaultConfig(KVSiteTitle, "parakeet") setDefaultConfig(KVSideNavContents, []string{}) - setDefaultConfig(KVNotifyMastodon, NotifyMastodon{ + setDefaultConfig(KVNotifyMastodon, util.StructToJsonMap(NotifyMastodon{ BaseURL: "", Token: "", Template: "ブログを書きました: %ENTRY_TITLE% %ENTRY_URL%", - }) - setDefaultConfig(KVServerSideRendering, ServerSideRendering{ + })) + setDefaultConfig(KVServerSideRendering, util.StructToJsonMap(ServerSideRendering{ Entries: true, Entry: true, - }) + })) setDefaultConfig(KVEnableMongoDBQueryCache, true) setDefaultConfig(KVEnableSSRPageCache, false) - setDefaultConfig(KVCloudflare, Cloudflare{ + setDefaultConfig(KVCloudflare, util.StructToJsonMap(Cloudflare{ Enable: false, ZoneID: "", APIToken: "", - }) + })) user := GetUserByEmail("root") if user == nil { diff --git a/server/util/map.go b/server/util/map.go new file mode 100644 index 0000000..acbbf89 --- /dev/null +++ b/server/util/map.go @@ -0,0 +1,31 @@ +package util + +import ( + "reflect" +) + +func StructToJsonMap(item interface{}) map[string]interface{} { + m := map[string]interface{}{} + + v := reflect.ValueOf(item) + v = reflect.Indirect(v) + + t := reflect.TypeOf(item) + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + + for i := 0; i < t.NumField(); i++ { + tag := t.Field(i).Tag.Get("json") + f := v.Field(i).Interface() + if tag != "" && tag != "-" { + if t.Field(i).Type.Kind() == reflect.Struct { + m[tag] = StructToJsonMap(f) + } else { + m[tag] = f + } + } + } + + return m +}