diff --git a/app/appearance/langs/en_US.json b/app/appearance/langs/en_US.json index 1c2e3042e..08fb9ec50 100644 --- a/app/appearance/langs/en_US.json +++ b/app/appearance/langs/en_US.json @@ -1,4 +1,6 @@ { + "exportAsImage": "Export as image", + "exportBySiYuan": "Export by SiYuan", "featureBetaStage": "This feature support is currently in the free public beta stage, and there is no clear charging plan yet, please know", "syncOfficialProviderIntro": "Currently selected is the cloud storage service officially provided by SiYuan, which only supports paid subscription users", "syncThirdPartyProviderS3Intro": "The current selected is a third-party cloud storage service compatible with the Amazon S3 protocol (eg Qiniu, Aliyun OSS, Cloudflare R2)", diff --git a/app/appearance/langs/es_ES.json b/app/appearance/langs/es_ES.json index ecdea5440..2f1c5bdec 100644 --- a/app/appearance/langs/es_ES.json +++ b/app/appearance/langs/es_ES.json @@ -1,4 +1,6 @@ { + "exportAsImage": "Exportar como imagen", + "exportBySiYuan": "Exportar por SiYuan", "featureBetaStage": "El soporte de esta función se encuentra actualmente en la etapa beta pública gratuita, y aún no hay un plan de carga claro, tenga en cuenta", "syncOfficialProviderIntro": "Actualmente seleccionado es el servicio de almacenamiento en la nube proporcionado oficialmente por SiYuan, que solo admite usuarios de suscripción paga", "syncThirdPartyProviderS3Intro": "El actual seleccionado es un servicio de almacenamiento en la nube de terceros compatible con el protocolo Amazon S3", diff --git a/app/appearance/langs/fr_FR.json b/app/appearance/langs/fr_FR.json index 2c1cdafe4..24c6f5146 100644 --- a/app/appearance/langs/fr_FR.json +++ b/app/appearance/langs/fr_FR.json @@ -1,4 +1,6 @@ { + "exportAsImage": "Exporter en tant qu'image", + "exportBySiYuan": "Exporter par SiYuan", "featureBetaStage": "La prise en charge de cette fonctionnalité est actuellement en phase de bêta publique gratuite et il n'y a pas encore de plan de facturation clair, veuillez savoir", "syncOfficialProviderIntro": "Actuellement sélectionné est le service de stockage en nuage officiellement fourni par SiYuan, qui ne prend en charge que les utilisateurs d'abonnement payant", "syncThirdPartyProviderS3Intro": "L'actuel sélectionné est un service de stockage cloud tiers compatible avec le protocole Amazon S3", diff --git a/app/appearance/langs/zh_CHT.json b/app/appearance/langs/zh_CHT.json index ae05aa916..cbf7b3397 100644 --- a/app/appearance/langs/zh_CHT.json +++ b/app/appearance/langs/zh_CHT.json @@ -1,4 +1,6 @@ { + "exportAsImage": "導出為圖片", + "exportBySiYuan": "由思源筆記導出", "featureBetaStage": "該特性支持目前處於免費公測階段,目前尚未有明確的收費計劃,請悉知", "syncOfficialProviderIntro": "當前選擇的是 SiYuan 官方提供的雲端存儲服務,僅支持付費訂閱用戶使用", "syncThirdPartyProviderS3Intro": "當前選擇的是 Amazon S3 協議兼容的第三方雲端存儲服務(比如七牛雲阿里雲 OSSCloudflare R2)", diff --git a/app/appearance/langs/zh_CN.json b/app/appearance/langs/zh_CN.json index 035756674..506ccb173 100644 --- a/app/appearance/langs/zh_CN.json +++ b/app/appearance/langs/zh_CN.json @@ -1,4 +1,6 @@ { + "exportAsImage": "导出为图片", + "exportBySiYuan": "由思源笔记导出", "featureBetaStage": "该特性支持目前处于免费公测阶段,目前尚未有明确的收费计划,请悉知", "syncOfficialProviderIntro": "当前选择的是 SiYuan 官方提供的云端存储服务,仅支持付费订阅用户使用", "syncThirdPartyProviderS3Intro": "当前选择的是 Amazon S3 协议兼容的第三方云端存储服务(比如七牛云阿里云 OSSCloudflare R2)", diff --git a/app/src/protyle/export/util.ts b/app/src/protyle/export/util.ts index b88ce4b06..35bd648d9 100644 --- a/app/src/protyle/export/util.ts +++ b/app/src/protyle/export/util.ts @@ -33,7 +33,7 @@ declare const html2canvas: (element: Element) => Promise; export const exportImage = (id: string) => { const exportDialog = new Dialog({ - title: window.siyuan.languages.export, + title: window.siyuan.languages.exportAsImage, content: `
-
由思源笔记导出
+
${window.siyuan.languages.exportBySiYuan}
diff --git a/app/src/types/index.d.ts b/app/src/types/index.d.ts index 154d9bb61..4e96fd740 100644 --- a/app/src/types/index.d.ts +++ b/app/src/types/index.d.ts @@ -426,6 +426,8 @@ declare interface IConfig { cBlockCount: number dataSize: number cDataSize: number + assetsSize: number + cAssetsSize: number } } diff --git a/app/src/util/assets.ts b/app/src/util/assets.ts index b8163aae2..bff9042f2 100644 --- a/app/src/util/assets.ts +++ b/app/src/util/assets.ts @@ -145,6 +145,7 @@ export const addGA = () => { cTreeCount: window.siyuan.config.stat.cTreeCount, cBlockCount: window.siyuan.config.stat.cBlockCount, cDataSize: window.siyuan.config.stat.cDataSize, + cAssetsSize: window.siyuan.config.stat.cAssetsSize, }; if (window.siyuan.user) { para.isLoggedIn = true; diff --git a/kernel/conf/stat.go b/kernel/conf/stat.go index 55778ab5c..29825026c 100644 --- a/kernel/conf/stat.go +++ b/kernel/conf/stat.go @@ -23,6 +23,8 @@ type Stat struct { CBlockCount int `json:"cBlockCount"` DataSize int64 `json:"dataSize"` CDataSize int64 `json:"cDataSize"` + AssetsSize int64 `json:"assetsSize"` + CAssetsSize int64 `json:"cAssetsSize"` } func NewStat() *Stat { diff --git a/kernel/model/box.go b/kernel/model/box.go index 173d2e2bb..f37a44878 100644 --- a/kernel/model/box.go +++ b/kernel/model/box.go @@ -26,11 +26,13 @@ import ( "path/filepath" "sort" "strings" + "sync" "time" "github.com/88250/gulu" "github.com/88250/lute/ast" "github.com/88250/lute/parse" + "github.com/dustin/go-humanize" "github.com/facette/natsort" "github.com/siyuan-note/filelock" "github.com/siyuan-note/logging" @@ -52,20 +54,29 @@ type Box struct { } func AutoStat() { + time.Sleep(time.Minute) autoStat() - for range time.Tick(10 * time.Minute) { + for range time.Tick(2 * time.Hour) { autoStat() } } +var statLock = sync.Mutex{} + func autoStat() { + statLock.Lock() + defer statLock.Unlock() + Conf.Stat.TreeCount = treenode.CountTrees() Conf.Stat.CTreeCount = treenode.CeilCount(Conf.Stat.TreeCount) Conf.Stat.BlockCount = treenode.CountBlocks() Conf.Stat.CBlockCount = treenode.CeilCount(Conf.Stat.BlockCount) - Conf.Stat.DataSize, _ = util.SizeOfDirectory(util.DataDir) + Conf.Stat.DataSize, Conf.Stat.AssetsSize = util.DataSize() Conf.Stat.CDataSize = util.CeilSize(Conf.Stat.DataSize) + Conf.Stat.CAssetsSize = util.CeilSize(Conf.Stat.AssetsSize) Conf.Save() + + logging.LogInfof("auto stat [trees=%d, blocks=%d, dataSize=%s, assetsSize=%s]", Conf.Stat.TreeCount, Conf.Stat.BlockCount, humanize.Bytes(uint64(Conf.Stat.DataSize)), humanize.Bytes(uint64(Conf.Stat.AssetsSize))) } func ListNotebooks() (ret []*Box, err error) { diff --git a/kernel/util/file.go b/kernel/util/file.go index c1d788692..f40c1eab4 100644 --- a/kernel/util/file.go +++ b/kernel/util/file.go @@ -17,6 +17,7 @@ package util import ( + "io" "os" "path" "path/filepath" @@ -194,6 +195,27 @@ func SizeOfDirectory(path string) (size int64, err error) { return } +func DataSize() (dataSize, assetsSize int64) { + filepath.Walk(DataDir, func(path string, info os.FileInfo, err error) error { + if nil != err { + logging.LogErrorf("size of data failed: %s", err) + return io.EOF + } + if !info.IsDir() { + s := info.Size() + dataSize += s + + if strings.Contains(strings.TrimPrefix(path, DataDir), "assets") { + assetsSize += s + } + } else { + dataSize += 4096 + } + return nil + }) + return +} + func CeilSize(size int64) int64 { if 100*1024*1024 > size { return 100 * 1024 * 1024 diff --git a/kernel/util/runtime.go b/kernel/util/runtime.go index e9de5cdc9..412bc0ff6 100644 --- a/kernel/util/runtime.go +++ b/kernel/util/runtime.go @@ -25,7 +25,6 @@ import ( "github.com/88250/gulu" "github.com/denisbrodbeck/machineid" - "github.com/dustin/go-humanize" "github.com/siyuan-note/logging" ) @@ -41,9 +40,6 @@ const ( ) func logBootInfo() { - s, _ := SizeOfDirectory(DataDir) - dataDirSize := humanize.Bytes(uint64(s)) - logging.LogInfof("kernel is booting:\n"+ " * ver [%s]\n"+ " * arch [%s]\n"+ @@ -53,8 +49,8 @@ func logBootInfo() { " * read only [%v]\n"+ " * container [%s]\n"+ " * database [ver=%s]\n"+ - " * workspace directory [%s, data %s]", - Ver, runtime.GOARCH, os.Getpid(), Mode, WorkingDir, ReadOnly, Container, DatabaseVer, WorkspaceDir, dataDirSize) + " * workspace directory [%s]", + Ver, runtime.GOARCH, os.Getpid(), Mode, WorkingDir, ReadOnly, Container, DatabaseVer, WorkspaceDir) } func IsMutexLocked(m *sync.Mutex) bool {