From 87f22f72e222e476bcc016d782191f7e45d79db1 Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Sat, 3 Dec 2022 23:49:18 +0800 Subject: [PATCH] =?UTF-8?q?:art:=20=E6=90=9C=E7=B4=A2=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=91=BD=E5=90=8D=E6=9F=A5=E8=AF=A2=20https://github.com/siyua?= =?UTF-8?q?n-note/siyuan/issues/6589?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/api/router.go | 3 +- kernel/api/setting.go | 37 ------ kernel/api/storage.go | 44 +++++++ kernel/conf/criterion.go | 30 ----- kernel/model/conf.go | 49 ++++---- kernel/model/localstorage.go | 110 ------------------ kernel/model/storage.go | 214 +++++++++++++++++++++++++++++++++++ 7 files changed, 284 insertions(+), 203 deletions(-) delete mode 100644 kernel/model/localstorage.go create mode 100644 kernel/model/storage.go diff --git a/kernel/api/router.go b/kernel/api/router.go index 4bd1ec701..c380dc70f 100644 --- a/kernel/api/router.go +++ b/kernel/api/router.go @@ -58,6 +58,8 @@ func ServeAPI(ginServer *gin.Engine) { ginServer.Handle("POST", "/api/storage/getLocalStorage", model.CheckAuth, getLocalStorage) ginServer.Handle("POST", "/api/storage/setLocalStorageVal", model.CheckAuth, setLocalStorageVal) ginServer.Handle("POST", "/api/storage/removeLocalStorageVal", model.CheckAuth, removeLocalStorageVal) + ginServer.Handle("POST", "/api/storage/setCriterion", model.CheckAuth, setCriterion) + ginServer.Handle("POST", "/api/storage/getCriteria", model.CheckAuth, getCriteria) ginServer.Handle("POST", "/api/account/login", model.CheckAuth, login) ginServer.Handle("POST", "/api/account/checkActivationcode", model.CheckAuth, checkActivationcode) @@ -245,7 +247,6 @@ func ServeAPI(ginServer *gin.Engine) { ginServer.Handle("POST", "/api/setting/setExport", model.CheckAuth, setExport) ginServer.Handle("POST", "/api/setting/setFiletree", model.CheckAuth, setFiletree) ginServer.Handle("POST", "/api/setting/setSearch", model.CheckAuth, setSearch) - ginServer.Handle("POST", "/api/setting/setCriterion", model.CheckAuth, setCriterion) ginServer.Handle("POST", "/api/setting/setKeymap", model.CheckAuth, setKeymap) ginServer.Handle("POST", "/api/setting/setAppearance", model.CheckAuth, setAppearance) ginServer.Handle("POST", "/api/setting/getCloudUser", model.CheckAuth, getCloudUser) diff --git a/kernel/api/setting.go b/kernel/api/setting.go index 0f5fe9204..3848dd326 100644 --- a/kernel/api/setting.go +++ b/kernel/api/setting.go @@ -219,43 +219,6 @@ func setSearch(c *gin.Context) { ret.Data = s } -func setCriterion(c *gin.Context) { - ret := gulu.Ret.NewResult() - defer c.JSON(http.StatusOK, ret) - - arg, ok := util.JsonArg(c, ret) - if !ok { - return - } - - param, err := gulu.JSON.MarshalJSON(arg["criterion"]) - if nil != err { - ret.Code = -1 - ret.Msg = err.Error() - return - } - - criterion := &conf.Criterion{} - if err = gulu.JSON.UnmarshalJSON(param, criterion); nil != err { - ret.Code = -1 - ret.Msg = err.Error() - return - } - - update := false - for i, criteria := range model.Conf.Criteria { - if criteria.Name == criterion.Name { - model.Conf.Criteria[i] = criterion - update = true - break - } - } - if !update { - model.Conf.Criteria = append(model.Conf.Criteria, criterion) - } - model.Conf.Save() -} - func setKeymap(c *gin.Context) { ret := gulu.Ret.NewResult() defer c.JSON(http.StatusOK, ret) diff --git a/kernel/api/storage.go b/kernel/api/storage.go index b32cad221..a2384225a 100644 --- a/kernel/api/storage.go +++ b/kernel/api/storage.go @@ -25,6 +25,50 @@ import ( "github.com/siyuan-note/siyuan/kernel/util" ) +func setCriterion(c *gin.Context) { + ret := gulu.Ret.NewResult() + defer c.JSON(http.StatusOK, ret) + + arg, ok := util.JsonArg(c, ret) + if !ok { + return + } + + param, err := gulu.JSON.MarshalJSON(arg["criterion"]) + if nil != err { + ret.Code = -1 + ret.Msg = err.Error() + return + } + + criterion := &model.Criterion{} + if err = gulu.JSON.UnmarshalJSON(param, criterion); nil != err { + ret.Code = -1 + ret.Msg = err.Error() + return + } + + err = model.SetCriterion(criterion) + if nil != err { + ret.Code = -1 + ret.Msg = err.Error() + return + } +} + +func getCriteria(c *gin.Context) { + ret := gulu.Ret.NewResult() + defer c.JSON(http.StatusOK, ret) + + data, err := model.GetCriteria() + if nil != err { + ret.Code = -1 + ret.Msg = err.Error() + return + } + ret.Data = data +} + func removeLocalStorageVal(c *gin.Context) { ret := gulu.Ret.NewResult() defer c.JSON(http.StatusOK, ret) diff --git a/kernel/conf/criterion.go b/kernel/conf/criterion.go index 27b16cbc1..b7bb65ed2 100644 --- a/kernel/conf/criterion.go +++ b/kernel/conf/criterion.go @@ -15,33 +15,3 @@ // along with this program. If not, see . package conf - -type Criterion struct { - Name string `json:"name"` - Sort int `json:"sort"` // 0:按块类型(默认),1:按创建时间升序,2:按创建时间降序,3:按更新时间升序,4:按更新时间降序,5:按内容顺序(仅在按文档分组时) - Group int `json:"group"` // 0:不分组,1:按文档分组 - Layout int `json:"layout"` // 0:上下,1:左右 - HasReplace bool `json:"hasReplace"` // 是否有替换 - Method int `json:"method"` // 0:文本,1:查询语法,2:SQL,3:正则表达式 - HPath string `json:"hPath"` - IDPath []string `json:"idPath"` - K string `json:"k"` // 搜索关键字 - R string `json:"r"` // 替换关键字 - ReplaceList []string `json:"replaceList"` // 替换候选列表 - List []string `json:"list"` // 搜索候选列表 - Types *CriterionTypes `json:"types"` // 类型过滤选项 -} - -type CriterionTypes struct { - MathBlock bool `json:"mathBlock"` - Table bool `json:"table"` - Blockquote bool `json:"blockquote"` - SuperBlock bool `json:"superBlock"` - Paragraph bool `json:"paragraph"` - Document bool `json:"document"` - Heading bool `json:"heading"` - List bool `json:"list"` - ListItem bool `json:"listItem"` - CodeBlock bool `json:"codeBlock"` - HtmlBlock bool `json:"htmlBlock"` -} diff --git a/kernel/model/conf.go b/kernel/model/conf.go index 76baba671..ce42efa38 100644 --- a/kernel/model/conf.go +++ b/kernel/model/conf.go @@ -46,31 +46,30 @@ var Conf *AppConf // AppConf 维护应用元数据,保存在 ~/.siyuan/conf.json。 type AppConf struct { - LogLevel string `json:"logLevel"` // 日志级别:Off, Trace, Debug, Info, Warn, Error, Fatal - Appearance *conf.Appearance `json:"appearance"` // 外观 - Langs []*conf.Lang `json:"langs"` // 界面语言列表 - Lang string `json:"lang"` // 选择的界面语言,同 Appearance.Lang - FileTree *conf.FileTree `json:"fileTree"` // 文档面板 - Tag *conf.Tag `json:"tag"` // 标签面板 - Editor *conf.Editor `json:"editor"` // 编辑器配置 - Export *conf.Export `json:"export"` // 导出配置 - Graph *conf.Graph `json:"graph"` // 关系图配置 - UILayout *conf.UILayout `json:"uiLayout"` // 界面布局 - UserData string `json:"userData"` // 社区用户信息,对 User 加密存储 - User *conf.User `json:"-"` // 社区用户内存结构,不持久化 - Account *conf.Account `json:"account"` // 帐号配置 - ReadOnly bool `json:"readonly"` // 是否是以只读模式运行 - LocalIPs []string `json:"localIPs"` // 本地 IP 列表 - AccessAuthCode string `json:"accessAuthCode"` // 访问授权码 - System *conf.System `json:"system"` // 系统配置 - Keymap *conf.Keymap `json:"keymap"` // 快捷键配置 - Sync *conf.Sync `json:"sync"` // 同步配置 - Search *conf.Search `json:"search"` // 搜索配置 - Stat *conf.Stat `json:"stat"` // 统计 - Api *conf.API `json:"api"` // API - Repo *conf.Repo `json:"repo"` // 数据仓库 - Newbie bool `json:"newbie"` // 是否是安装后第一次启动 - Criteria []*conf.Criterion `json:"criteria"` // 搜索查询 + LogLevel string `json:"logLevel"` // 日志级别:Off, Trace, Debug, Info, Warn, Error, Fatal + Appearance *conf.Appearance `json:"appearance"` // 外观 + Langs []*conf.Lang `json:"langs"` // 界面语言列表 + Lang string `json:"lang"` // 选择的界面语言,同 Appearance.Lang + FileTree *conf.FileTree `json:"fileTree"` // 文档面板 + Tag *conf.Tag `json:"tag"` // 标签面板 + Editor *conf.Editor `json:"editor"` // 编辑器配置 + Export *conf.Export `json:"export"` // 导出配置 + Graph *conf.Graph `json:"graph"` // 关系图配置 + UILayout *conf.UILayout `json:"uiLayout"` // 界面布局 + UserData string `json:"userData"` // 社区用户信息,对 User 加密存储 + User *conf.User `json:"-"` // 社区用户内存结构,不持久化 + Account *conf.Account `json:"account"` // 帐号配置 + ReadOnly bool `json:"readonly"` // 是否是以只读模式运行 + LocalIPs []string `json:"localIPs"` // 本地 IP 列表 + AccessAuthCode string `json:"accessAuthCode"` // 访问授权码 + System *conf.System `json:"system"` // 系统配置 + Keymap *conf.Keymap `json:"keymap"` // 快捷键配置 + Sync *conf.Sync `json:"sync"` // 同步配置 + Search *conf.Search `json:"search"` // 搜索配置 + Stat *conf.Stat `json:"stat"` // 统计 + Api *conf.API `json:"api"` // API + Repo *conf.Repo `json:"repo"` // 数据仓库 + Newbie bool `json:"newbie"` // 是否是安装后第一次启动 } func InitConf() { diff --git a/kernel/model/localstorage.go b/kernel/model/localstorage.go deleted file mode 100644 index dd5129f9f..000000000 --- a/kernel/model/localstorage.go +++ /dev/null @@ -1,110 +0,0 @@ -// SiYuan - Build Your Eternal Digital Garden -// Copyright (c) 2020-present, b3log.org -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package model - -import ( - "os" - "path/filepath" - "sync" - - "github.com/88250/gulu" - "github.com/siyuan-note/filelock" - "github.com/siyuan-note/logging" - "github.com/siyuan-note/siyuan/kernel/util" -) - -var localStorageLock = sync.Mutex{} - -func RemoveLocalStorageVal(key string) (err error) { - localStorageLock.Lock() - defer localStorageLock.Unlock() - - localStorage, err := getLocalStorage() - if nil != err { - return - } - - delete(localStorage, key) - return setLocalStorage(localStorage) -} - -func SetLocalStorageVal(key string, val interface{}) (err error) { - localStorageLock.Lock() - defer localStorageLock.Unlock() - - localStorage, err := getLocalStorage() - if nil != err { - return - } - - localStorage[key] = val - return setLocalStorage(localStorage) -} - -func SetLocalStorage(val interface{}) (err error) { - localStorageLock.Lock() - defer localStorageLock.Unlock() - return setLocalStorage(val) -} - -func GetLocalStorage() (ret map[string]interface{}, err error) { - localStorageLock.Lock() - defer localStorageLock.Unlock() - return getLocalStorage() -} - -func setLocalStorage(val interface{}) (err error) { - dirPath := filepath.Join(util.DataDir, "storage") - if err = os.MkdirAll(dirPath, 0755); nil != err { - logging.LogErrorf("create local storage dir failed: %s", err) - return - } - - data, err := gulu.JSON.MarshalIndentJSON(val, "", " ") - if nil != err { - logging.LogErrorf("marshal local storage failed: %s", err) - return - } - - lsPath := filepath.Join(dirPath, "local.json") - err = filelock.WriteFile(lsPath, data) - if nil != err { - logging.LogErrorf("write local storage failed: %s", err) - return - } - return -} - -func getLocalStorage() (ret map[string]interface{}, err error) { - lsPath := filepath.Join(util.DataDir, "storage/local.json") - if !gulu.File.IsExist(lsPath) { - return - } - - data, err := filelock.ReadFile(lsPath) - if nil != err { - logging.LogErrorf("read local storage failed: %s", err) - return - } - - ret = map[string]interface{}{} - if err = gulu.JSON.UnmarshalJSON(data, &ret); nil != err { - logging.LogErrorf("unmarshal local storage failed: %s", err) - return - } - return -} diff --git a/kernel/model/storage.go b/kernel/model/storage.go new file mode 100644 index 000000000..e539046c6 --- /dev/null +++ b/kernel/model/storage.go @@ -0,0 +1,214 @@ +// SiYuan - Build Your Eternal Digital Garden +// Copyright (c) 2020-present, b3log.org +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package model + +import ( + "os" + "path/filepath" + "sync" + + "github.com/88250/gulu" + "github.com/siyuan-note/filelock" + "github.com/siyuan-note/logging" + "github.com/siyuan-note/siyuan/kernel/util" +) + +type Criterion struct { + Name string `json:"name"` + Sort int `json:"sort"` // 0:按块类型(默认),1:按创建时间升序,2:按创建时间降序,3:按更新时间升序,4:按更新时间降序,5:按内容顺序(仅在按文档分组时) + Group int `json:"group"` // 0:不分组,1:按文档分组 + Layout int `json:"layout"` // 0:上下,1:左右 + HasReplace bool `json:"hasReplace"` // 是否有替换 + Method int `json:"method"` // 0:文本,1:查询语法,2:SQL,3:正则表达式 + HPath string `json:"hPath"` + IDPath []string `json:"idPath"` + K string `json:"k"` // 搜索关键字 + R string `json:"r"` // 替换关键字 + ReplaceList []string `json:"replaceList"` // 替换候选列表 + List []string `json:"list"` // 搜索候选列表 + Types *CriterionTypes `json:"types"` // 类型过滤选项 +} + +type CriterionTypes struct { + MathBlock bool `json:"mathBlock"` + Table bool `json:"table"` + Blockquote bool `json:"blockquote"` + SuperBlock bool `json:"superBlock"` + Paragraph bool `json:"paragraph"` + Document bool `json:"document"` + Heading bool `json:"heading"` + List bool `json:"list"` + ListItem bool `json:"listItem"` + CodeBlock bool `json:"codeBlock"` + HtmlBlock bool `json:"htmlBlock"` +} + +var criteriaLock = sync.Mutex{} + +func SetCriterion(criterion *Criterion) (err error) { + criteriaLock.Lock() + defer criteriaLock.Unlock() + + criteria, err := getCriteria() + if nil != err { + return + } + + update := false + for i, c := range criteria { + if c.Name == criterion.Name { + criteria[i] = criterion + update = true + break + } + } + if !update { + criteria = append(criteria, criterion) + } + + err = setCriteria(criteria) + return +} + +func GetCriteria() (ret []*Criterion, err error) { + criteriaLock.Lock() + defer criteriaLock.Unlock() + return getCriteria() +} + +func setCriteria(criteria []*Criterion) (err error) { + dirPath := filepath.Join(util.DataDir, "storage") + if err = os.MkdirAll(dirPath, 0755); nil != err { + logging.LogErrorf("create storage [criteria] dir failed: %s", err) + return + } + + data, err := gulu.JSON.MarshalIndentJSON(criteria, "", " ") + if nil != err { + logging.LogErrorf("marshal storage [criteria] failed: %s", err) + return + } + + lsPath := filepath.Join(dirPath, "criteria.json") + err = filelock.WriteFile(lsPath, data) + if nil != err { + logging.LogErrorf("write storage [criteria] failed: %s", err) + return + } + return +} + +func getCriteria() (ret []*Criterion, err error) { + dataPath := filepath.Join(util.DataDir, "storage/criteria.json") + if !gulu.File.IsExist(dataPath) { + return + } + + data, err := filelock.ReadFile(dataPath) + if nil != err { + logging.LogErrorf("read storage [criteria] failed: %s", err) + return + } + + if err = gulu.JSON.UnmarshalJSON(data, &ret); nil != err { + logging.LogErrorf("unmarshal storage [criteria] failed: %s", err) + return + } + return +} + +var localStorageLock = sync.Mutex{} + +func RemoveLocalStorageVal(key string) (err error) { + localStorageLock.Lock() + defer localStorageLock.Unlock() + + localStorage, err := getLocalStorage() + if nil != err { + return + } + + delete(localStorage, key) + return setLocalStorage(localStorage) +} + +func SetLocalStorageVal(key string, val interface{}) (err error) { + localStorageLock.Lock() + defer localStorageLock.Unlock() + + localStorage, err := getLocalStorage() + if nil != err { + return + } + + localStorage[key] = val + return setLocalStorage(localStorage) +} + +func SetLocalStorage(val interface{}) (err error) { + localStorageLock.Lock() + defer localStorageLock.Unlock() + return setLocalStorage(val) +} + +func GetLocalStorage() (ret map[string]interface{}, err error) { + localStorageLock.Lock() + defer localStorageLock.Unlock() + return getLocalStorage() +} + +func setLocalStorage(val interface{}) (err error) { + dirPath := filepath.Join(util.DataDir, "storage") + if err = os.MkdirAll(dirPath, 0755); nil != err { + logging.LogErrorf("create storage [local] dir failed: %s", err) + return + } + + data, err := gulu.JSON.MarshalIndentJSON(val, "", " ") + if nil != err { + logging.LogErrorf("marshal storage [local] failed: %s", err) + return + } + + lsPath := filepath.Join(dirPath, "local.json") + err = filelock.WriteFile(lsPath, data) + if nil != err { + logging.LogErrorf("write storage [local] failed: %s", err) + return + } + return +} + +func getLocalStorage() (ret map[string]interface{}, err error) { + lsPath := filepath.Join(util.DataDir, "storage/local.json") + if !gulu.File.IsExist(lsPath) { + return + } + + data, err := filelock.ReadFile(lsPath) + if nil != err { + logging.LogErrorf("read storage [local] failed: %s", err) + return + } + + ret = map[string]interface{}{} + if err = gulu.JSON.UnmarshalJSON(data, &ret); nil != err { + logging.LogErrorf("unmarshal storage [local] failed: %s", err) + return + } + return +}