From 4a64f5592feb90c8723c6744e217a49dd83fb948 Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Fri, 15 Jul 2022 09:25:02 +0800 Subject: [PATCH 1/3] =?UTF-8?q?:art:=20`/=E8=B5=84=E6=BA=90`=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=90=9C=E7=B4=A2=E6=9C=AA=E7=B4=A2=E5=BC=95=E7=9A=84?= =?UTF-8?q?=E6=96=87=E4=BB=B6=20https://github.com/siyuan-note/siyuan/issu?= =?UTF-8?q?es/5416?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/cache/asset.go | 59 +++++++++++++++++++++++++++ kernel/main.go | 2 + kernel/mobile/kernel.go | 2 + kernel/model/assets.go | 42 +++++++++++-------- kernel/model/assets_watcher.go | 4 ++ kernel/model/assets_watcher_darwin.go | 4 ++ kernel/sql/aseet.go | 16 -------- 7 files changed, 96 insertions(+), 33 deletions(-) create mode 100644 kernel/cache/asset.go diff --git a/kernel/cache/asset.go b/kernel/cache/asset.go new file mode 100644 index 000000000..d66fd6a95 --- /dev/null +++ b/kernel/cache/asset.go @@ -0,0 +1,59 @@ +// 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 cache + +import ( + "io/fs" + "path/filepath" + "strings" + "sync" + + "github.com/siyuan-note/siyuan/kernel/util" +) + +type Asset struct { + HName string `json:"hName"` + Path string `json:"path"` + Updated int64 `json:"updated"` +} + +var Assets = sync.Map{} + +func LoadAssets() { + Assets = sync.Map{} + assets := filepath.Join(util.DataDir, "assets") + filepath.Walk(assets, func(path string, info fs.FileInfo, err error) error { + if info.IsDir() { + if strings.HasPrefix(info.Name(), ".") { + return filepath.SkipDir + } + return nil + } + if strings.HasSuffix(info.Name(), ".sya") { + return nil + } + + hName := util.RemoveID(info.Name()) + path = filepath.ToSlash(strings.TrimPrefix(path, util.DataDir))[1:] + Assets.Store(path, &Asset{ + HName: hName, + Path: path, + Updated: info.ModTime().UnixMilli(), + }) + return nil + }) +} diff --git a/kernel/main.go b/kernel/main.go index 493bd2e1f..3f39a34ae 100644 --- a/kernel/main.go +++ b/kernel/main.go @@ -19,6 +19,7 @@ package main import ( + "github.com/siyuan-note/siyuan/kernel/cache" "github.com/siyuan-note/siyuan/kernel/model" "github.com/siyuan-note/siyuan/kernel/server" "github.com/siyuan-note/siyuan/kernel/sql" @@ -48,6 +49,7 @@ func main() { go model.AutoFlushTx() go sql.AutoFlushTreeQueue() go treenode.AutoFlushBlockTree() + go cache.LoadAssets() model.WatchAssets() model.HandleSignal() } diff --git a/kernel/mobile/kernel.go b/kernel/mobile/kernel.go index b93e7731c..edfc00dfb 100644 --- a/kernel/mobile/kernel.go +++ b/kernel/mobile/kernel.go @@ -23,6 +23,7 @@ import ( "strings" "time" + "github.com/siyuan-note/siyuan/kernel/cache" "github.com/siyuan-note/siyuan/kernel/model" "github.com/siyuan-note/siyuan/kernel/server" "github.com/siyuan-note/siyuan/kernel/sql" @@ -61,6 +62,7 @@ func StartKernel(container, appDir, workspaceDir, nativeLibDir, privateDataDir, go model.AutoFlushTx() go sql.AutoFlushTreeQueue() go treenode.AutoFlushBlockTree() + go cache.LoadAssets() }() } diff --git a/kernel/model/assets.go b/kernel/model/assets.go index 0d0bd2bbe..05474f7b1 100644 --- a/kernel/model/assets.go +++ b/kernel/model/assets.go @@ -37,6 +37,7 @@ import ( "github.com/gabriel-vasile/mimetype" "github.com/siyuan-note/filelock" "github.com/siyuan-note/httpclient" + "github.com/siyuan-note/siyuan/kernel/cache" "github.com/siyuan-note/siyuan/kernel/search" "github.com/siyuan-note/siyuan/kernel/sql" "github.com/siyuan-note/siyuan/kernel/treenode" @@ -161,25 +162,32 @@ func NetImg2LocalAssets(rootID string) (err error) { return } -type Asset struct { - HName string `json:"hName"` - Name string `json:"name"` - Path string `json:"path"` -} +func SearchAssetsByName(keyword string) (ret []*cache.Asset) { + ret = []*cache.Asset{} -func SearchAssetsByName(keyword string) (ret []*Asset) { - ret = []*Asset{} - sqlAssets := sql.QueryAssetsByName(keyword) - for _, sqlAsset := range sqlAssets { - hName := util.RemoveID(sqlAsset.Name) - _, hName = search.MarkText(hName, keyword, 64, Conf.Search.CaseSensitive) - asset := &Asset{ - HName: hName, - Name: sqlAsset.Name, - Path: sqlAsset.Path, + count := 0 + cache.Assets.Range(func(k, v interface{}) bool { + asset := v.(*cache.Asset) + if !strings.Contains(strings.ToLower(asset.HName), strings.ToLower(keyword)) { + return true } - ret = append(ret, asset) - } + + _, hName := search.MarkText(asset.HName, keyword, 64, Conf.Search.CaseSensitive) + ret = append(ret, &cache.Asset{ + HName: hName, + Path: asset.Path, + Updated: asset.Updated, + }) + count++ + if Conf.Search.Limit <= count { + return false + } + return true + }) + + sort.Slice(ret, func(i, j int) bool { + return ret[i].Updated > ret[j].Updated + }) return } diff --git a/kernel/model/assets_watcher.go b/kernel/model/assets_watcher.go index 01fff5209..a1163971e 100644 --- a/kernel/model/assets_watcher.go +++ b/kernel/model/assets_watcher.go @@ -23,6 +23,7 @@ import ( "time" "github.com/fsnotify/fsnotify" + "github.com/siyuan-note/siyuan/kernel/cache" "github.com/siyuan-note/siyuan/kernel/util" ) @@ -78,6 +79,9 @@ func watchAssets() { // 外部修改已有资源文件后纳入云端同步 https://github.com/siyuan-note/siyuan/issues/4694 IncSync() } + + // 重新缓存资源文件,以便使用 /资源 搜索 + cache.LoadAssets() } } }() diff --git a/kernel/model/assets_watcher_darwin.go b/kernel/model/assets_watcher_darwin.go index 706d3ffc0..8ad177e8e 100644 --- a/kernel/model/assets_watcher_darwin.go +++ b/kernel/model/assets_watcher_darwin.go @@ -23,6 +23,7 @@ import ( "time" "github.com/radovskyb/watcher" + "github.com/siyuan-note/siyuan/kernel/cache" "github.com/siyuan-note/siyuan/kernel/util" ) @@ -54,6 +55,9 @@ func watchAssets() { if watcher.Write == event.Op { IncSync() } + + // 重新缓存资源文件,以便使用 /资源 搜索 + cache.LoadAssets() case err, ok := <-assetsWatcher.Error: if !ok { return diff --git a/kernel/sql/aseet.go b/kernel/sql/aseet.go index 1d5daadd9..c15db8058 100644 --- a/kernel/sql/aseet.go +++ b/kernel/sql/aseet.go @@ -93,22 +93,6 @@ func docTitleImgAsset(root *ast.Node) *Asset { return nil } -func QueryAssetsByName(name string) (ret []*Asset) { - ret = []*Asset{} - sqlStmt := "SELECT * FROM assets WHERE name LIKE ? GROUP BY id ORDER BY id DESC LIMIT 32" - rows, err := query(sqlStmt, "%"+name+"%") - if nil != err { - util.LogErrorf("sql query [%s] failed: %s", sqlStmt, err) - return - } - defer rows.Close() - for rows.Next() { - asset := scanAssetRows(rows) - ret = append(ret, asset) - } - return -} - func QueryAssetByHash(hash string) (ret *Asset) { sqlStmt := "SELECT * FROM assets WHERE hash = ?" row := queryRow(sqlStmt, hash) From e0af974bf8be9333121f313fd0d568761cf10a3f Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Fri, 15 Jul 2022 09:30:37 +0800 Subject: [PATCH 2/3] =?UTF-8?q?:art:=20`/=E8=B5=84=E6=BA=90`=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=90=9C=E7=B4=A2=E6=9C=AA=E7=B4=A2=E5=BC=95=E7=9A=84?= =?UTF-8?q?=E6=96=87=E4=BB=B6=20https://github.com/siyuan-note/siyuan/issu?= =?UTF-8?q?es/5416?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../20200924100744-br924ar.sy | 80 +++++++++++++++++- .../20200915214115-42b8zma.sy | 62 +++++++++++++- .../20211226123038-4umgpxy.sy | 84 +++++++++++++++---- 3 files changed, 201 insertions(+), 25 deletions(-) diff --git a/app/guide/20210808180117-6v0mkxr/20200923234011-ieuun1p/20210808180303-xaduj2o/20200924100744-br924ar.sy b/app/guide/20210808180117-6v0mkxr/20200923234011-ieuun1p/20210808180303-xaduj2o/20200924100744-br924ar.sy index 318111700..b8fb93db4 100644 --- a/app/guide/20210808180117-6v0mkxr/20200923234011-ieuun1p/20210808180303-xaduj2o/20200924100744-br924ar.sy +++ b/app/guide/20210808180117-6v0mkxr/20200923234011-ieuun1p/20210808180303-xaduj2o/20200924100744-br924ar.sy @@ -5,7 +5,7 @@ "id": "20200924100744-br924ar", "title": "Assets", "type": "doc", - "updated": "20220711122005" + "updated": "20220715092808" }, "Children": [ { @@ -625,7 +625,7 @@ "ListData": {}, "Properties": { "id": "20220503122349-o26mvnq", - "updated": "20220503122616" + "updated": "20220715092808" }, "Children": [ { @@ -650,7 +650,23 @@ "Children": [ { "Type": "NodeText", - "Data": "When deleting the notebook, in order to ensure that cross-notebook asset references work properly, the assets under the notebook will be copied to the global assets in batches" + "Data": "When deleting the notebook, in order to ensure that cross-notebook asset references work properly, the " + }, + { + "Type": "NodeText", + "Data": "assets" + }, + { + "Type": "NodeText", + "Data": " under the notebook will be copied to the global " + }, + { + "Type": "NodeText", + "Data": "assets" + }, + { + "Type": "NodeText", + "Data": " in batches" } ] } @@ -678,7 +694,63 @@ "Children": [ { "Type": "NodeText", - "Data": "Does not support viewing notebook-level assets history in data history" + "Data": "Does not support viewing notebook-level " + }, + { + "Type": "NodeText", + "Data": "assets" + }, + { + "Type": "NodeText", + "Data": " history in " + }, + { + "Type": "NodeText", + "Data": "data history" + } + ] + } + ] + }, + { + "ID": "20220715092756-f5azf15", + "Type": "NodeListItem", + "ListData": { + "BulletChar": 42, + "Marker": "Kg==" + }, + "Properties": { + "id": "20220715092756-f5azf15", + "updated": "20220715092808" + }, + "Children": [ + { + "ID": "20220715092756-4bzibji", + "Type": "NodeParagraph", + "Properties": { + "id": "20220715092756-4bzibji", + "updated": "20220715092808" + }, + "Children": [ + { + "Type": "NodeText", + "Data": "Dose not support search by " + }, + { + "Type": "NodeCodeSpan", + "Data": "code", + "Children": [ + { + "Type": "NodeCodeSpanOpenMarker" + }, + { + "Type": "NodeCodeSpanContent", + "Data": "/Assets" + }, + { + "Type": "NodeCodeSpanCloseMarker" + } + ] } ] } diff --git a/app/guide/20210808180117-czj9bvb/20200812220555-lj3enxa/20210808180321-hbvl5c2/20200915214115-42b8zma.sy b/app/guide/20210808180117-czj9bvb/20200812220555-lj3enxa/20210808180321-hbvl5c2/20200915214115-42b8zma.sy index ffb7604a0..5d5c9916a 100644 --- a/app/guide/20210808180117-czj9bvb/20200812220555-lj3enxa/20210808180321-hbvl5c2/20200915214115-42b8zma.sy +++ b/app/guide/20210808180117-czj9bvb/20200812220555-lj3enxa/20210808180321-hbvl5c2/20200915214115-42b8zma.sy @@ -5,7 +5,7 @@ "id": "20200915214115-42b8zma", "title": "资源文件", "type": "doc", - "updated": "20220711122042" + "updated": "20220715092726" }, "Children": [ { @@ -547,7 +547,7 @@ "ListData": {}, "Properties": { "id": "20220503121213-afjyt05", - "updated": "20220503121834" + "updated": "20220715092726" }, "Children": [ { @@ -600,7 +600,63 @@ "Children": [ { "Type": "NodeText", - "Data": "不支持在数据历史中查看笔记本级资源文件历史" + "Data": "不支持在" + }, + { + "Type": "NodeText", + "Data": "数据历史" + }, + { + "Type": "NodeText", + "Data": "中查看笔记本级资源文件历史" + } + ] + } + ] + }, + { + "ID": "20220715092717-dbd9ih9", + "Type": "NodeListItem", + "ListData": { + "BulletChar": 42, + "Marker": "Kg==" + }, + "Properties": { + "id": "20220715092717-dbd9ih9", + "updated": "20220715092726" + }, + "Children": [ + { + "ID": "20220715092717-btrw2bk", + "Type": "NodeParagraph", + "Properties": { + "id": "20220715092717-btrw2bk", + "updated": "20220715092726" + }, + "Children": [ + { + "Type": "NodeText", + "Data": "不支持使用 " + }, + { + "Type": "NodeCodeSpan", + "Data": "code", + "Children": [ + { + "Type": "NodeCodeSpanOpenMarker" + }, + { + "Type": "NodeCodeSpanContent", + "Data": "/资源" + }, + { + "Type": "NodeCodeSpanCloseMarker" + } + ] + }, + { + "Type": "NodeText", + "Data": " 搜索" } ] } diff --git a/app/guide/20211226090932-5lcq56f/20211226115423-d5z1joq/20211226121203-rjjngpz/20211226123038-4umgpxy.sy b/app/guide/20211226090932-5lcq56f/20211226115423-d5z1joq/20211226121203-rjjngpz/20211226123038-4umgpxy.sy index fc5739eb3..7642567f9 100644 --- a/app/guide/20211226090932-5lcq56f/20211226115423-d5z1joq/20211226121203-rjjngpz/20211226123038-4umgpxy.sy +++ b/app/guide/20211226090932-5lcq56f/20211226115423-d5z1joq/20211226121203-rjjngpz/20211226123038-4umgpxy.sy @@ -4,7 +4,7 @@ "Properties": { "id": "20211226123038-4umgpxy", "title": "資料文件", - "updated": "20220711122031" + "updated": "20220715092951" }, "Children": [ { @@ -242,7 +242,7 @@ }, "Properties": { "id": "20211226123051-1qp7a9g", - "updated": "20220711121953" + "updated": "20220715092951" }, "Children": [ { @@ -256,7 +256,7 @@ }, "Properties": { "id": "20211226123051-mmn60x5", - "updated": "20220711121953" + "updated": "20220715092951" }, "Children": [ { @@ -264,12 +264,12 @@ "Type": "NodeParagraph", "Properties": { "id": "20211226123051-p8dr1dy", - "updated": "20220711121953" + "updated": "20220715092951" }, "Children": [ { "Type": "NodeText", - "Data": "引用具體的資料文件,比如圖片或者文件。如果資源文件是 PDF 且做過" + "Data": "引用具體的資料文件,比如圖片或者文件。如果資料文件是 PDF 且做過" }, { "Type": "NodeBlockRef", @@ -511,12 +511,12 @@ "HeadingLevel": 2, "Properties": { "id": "20220503122338-a69glac", - "updated": "20220503122338" + "updated": "20220715092913" }, "Children": [ { "Type": "NodeText", - "Data": "筆記本級資源文件" + "Data": "筆記本級資料文件" } ] }, @@ -525,12 +525,12 @@ "Type": "NodeParagraph", "Properties": { "id": "20220503122338-re7pyhf", - "updated": "20220503122338" + "updated": "20220715092933" }, "Children": [ { "Type": "NodeText", - "Data": "如果需要默認將插入的資源文件放置在文檔同級 assets 文件夾下,則需要先手動創建名為 assets 的文件夾,這樣思源會優先選擇該 assets 文件夾來存放資源文件。" + "Data": "如果需要默認將插入的資料文件放置在文檔同級 assets 文件夾下,則需要先手動創建名為 assets 的文件夾,這樣思源會優先選擇該 assets 文件夾來存放資料文件。" } ] }, @@ -539,12 +539,12 @@ "Type": "NodeParagraph", "Properties": { "id": "20220503122338-gxfzjcm", - "updated": "20220503122338" + "updated": "20220715092934" }, "Children": [ { "Type": "NodeText", - "Data": "建議盡量不要使用筆記本級資源文件,因為這會帶來一些副作用:" + "Data": "建議盡量不要使用筆記本級資料文件,因為這會帶來一些副作用:" } ] }, @@ -554,7 +554,7 @@ "ListData": {}, "Properties": { "id": "20220503122338-jmr7c2k", - "updated": "20220503122338" + "updated": "20220715092938" }, "Children": [ { @@ -566,7 +566,7 @@ }, "Properties": { "id": "20220503122338-4zg71qe", - "updated": "20220503122338" + "updated": "20220715092936" }, "Children": [ { @@ -574,12 +574,12 @@ "Type": "NodeParagraph", "Properties": { "id": "20220503122338-t6apzrh", - "updated": "20220503122338" + "updated": "20220715092936" }, "Children": [ { "Type": "NodeText", - "Data": "刪除該筆記本時,為保證跨筆記本資源文件引用正常工作,該筆記本下的資源文件會被批量複製到全局 assets 中" + "Data": "刪除該筆記本時,為保證跨筆記本資料文件引用正常工作,該筆記本下的資料文件會被批量複製到全局 assets 中" } ] } @@ -594,7 +594,7 @@ }, "Properties": { "id": "20220503122338-64cnjli", - "updated": "20220503122338" + "updated": "20220715092938" }, "Children": [ { @@ -602,12 +602,60 @@ "Type": "NodeParagraph", "Properties": { "id": "20220503122338-e5zlrvp", - "updated": "20220503122338" + "updated": "20220715092938" }, "Children": [ { "Type": "NodeText", - "Data": "不支持在數據歷史中查看筆記本級資源文件歷史" + "Data": "不支持在數據歷史中查看筆記本級資料文件歷史" + } + ] + } + ] + }, + { + "ID": "20220715092849-nxblvyk", + "Type": "NodeListItem", + "ListData": { + "BulletChar": 42, + "Marker": "Kg==" + }, + "Properties": { + "id": "20220715092849-nxblvyk", + "updated": "20220715092907" + }, + "Children": [ + { + "ID": "20220715092849-n45ydou", + "Type": "NodeParagraph", + "Properties": { + "id": "20220715092849-n45ydou", + "updated": "20220715092907" + }, + "Children": [ + { + "Type": "NodeText", + "Data": "不支持使用 " + }, + { + "Type": "NodeCodeSpan", + "Data": "code", + "Children": [ + { + "Type": "NodeCodeSpanOpenMarker" + }, + { + "Type": "NodeCodeSpanContent", + "Data": "/資料" + }, + { + "Type": "NodeCodeSpanCloseMarker" + } + ] + }, + { + "Type": "NodeText", + "Data": " 搜索" } ] } From d62d929a18611b7fb3ad7ce8577508d181940f21 Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Fri, 15 Jul 2022 09:39:25 +0800 Subject: [PATCH 3/3] =?UTF-8?q?:art:=20`/=E8=B5=84=E6=BA=90`=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=90=9C=E7=B4=A2=E6=9C=AA=E7=B4=A2=E5=BC=95=E7=9A=84?= =?UTF-8?q?=E6=96=87=E4=BB=B6=20https://github.com/siyuan-note/siyuan/issu?= =?UTF-8?q?es/5416?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/cache/asset.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kernel/cache/asset.go b/kernel/cache/asset.go index d66fd6a95..c958561b5 100644 --- a/kernel/cache/asset.go +++ b/kernel/cache/asset.go @@ -21,6 +21,7 @@ import ( "path/filepath" "strings" "sync" + "time" "github.com/siyuan-note/siyuan/kernel/util" ) @@ -34,6 +35,7 @@ type Asset struct { var Assets = sync.Map{} func LoadAssets() { + start := time.Now() Assets = sync.Map{} assets := filepath.Join(util.DataDir, "assets") filepath.Walk(assets, func(path string, info fs.FileInfo, err error) error { @@ -56,4 +58,8 @@ func LoadAssets() { }) return nil }) + elapsed := time.Since(start) + if 2000 < elapsed.Milliseconds() { + util.LogInfof("loaded assets [%s]", elapsed) + } }