Bläddra i källkod

:fire: 移除旧版云端同步和备份功能入口 https://github.com/siyuan-note/siyuan/issues/5405

Liang Ding 3 år sedan
förälder
incheckning
51230a99c3

+ 1 - 0
README.md

@@ -271,6 +271,7 @@ SiYuan is made possible by the following open source projects.
 * [https://github.com/Xuanwo/go-locale](https://github.com/Xuanwo/go-locale) `Apache-2.0 License` 
 * [https://github.com/araddon/dateparse](https://github.com/araddon/dateparse) `MIT License`
 * [https://github.com/common-nighthawk/go-figure](https://github.com/common-nighthawk/go-figure) `MIT License`
+* [https://github.com/denisbrodbeck/machineid](https://github.com/denisbrodbeck/machineid) `MIT License`
 * [https://github.com/dgraph-io/ristretto](https://github.com/dgraph-io/ristretto) `Apache-2.0 License`
 * [https://github.com/dustin/go-humanize](https://github.com/dustin/go-humanize) `MIT License`
 * [https://github.com/emirpasic/gods](https://github.com/emirpasic/gods) `BSD-2-Clause License`

+ 1 - 0
README_zh_CN.md

@@ -280,6 +280,7 @@
 * [https://github.com/Xuanwo/go-locale](https://github.com/Xuanwo/go-locale) `Apache-2.0 License`
 * [https://github.com/araddon/dateparse](https://github.com/araddon/dateparse) `MIT License`
 * [https://github.com/common-nighthawk/go-figure](https://github.com/common-nighthawk/go-figure) `MIT License`
+* [https://github.com/denisbrodbeck/machineid](https://github.com/denisbrodbeck/machineid) `MIT License`
 * [https://github.com/dgraph-io/ristretto](https://github.com/dgraph-io/ristretto) `Apache-2.0 License`
 * [https://github.com/dustin/go-humanize](https://github.com/dustin/go-humanize) `MIT License`
 * [https://github.com/emirpasic/gods](https://github.com/emirpasic/gods) `BSD-2-Clause License`

+ 1 - 1
kernel/api/asset.go

@@ -70,7 +70,7 @@ func setFileAnnotation(c *gin.Context) {
 		ret.Msg = err.Error()
 		return
 	}
-	model.IncWorkspaceDataVer()
+	model.IncSync()
 }
 
 func getFileAnnotation(c *gin.Context) {

+ 0 - 108
kernel/filesys/workspace.go

@@ -1,108 +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 <https://www.gnu.org/licenses/>.
-
-package filesys
-
-import (
-	"os"
-	"path/filepath"
-	"sync"
-
-	"github.com/88250/gulu"
-	"github.com/siyuan-note/filelock"
-	"github.com/siyuan-note/siyuan/kernel/util"
-)
-
-type DataConf struct {
-	Updated int64  `json:"updated"` // 最近一次数据更新时间
-	SyncVer int64  `json:"syncVer"` // 同步版本号
-	Device  string `json:"device"`  // 设备 ID
-}
-
-var incWorkspaceDataVerLock = sync.Mutex{}
-
-func IncWorkspaceDataVer(inc bool, systemID string) {
-	incWorkspaceDataVerLock.Lock()
-	defer incWorkspaceDataVerLock.Unlock()
-
-	confPath := filepath.Join(util.DataDir, ".siyuan")
-	os.MkdirAll(confPath, 0755)
-	confPath = filepath.Join(confPath, "conf.json")
-
-	var data []byte
-	var err error
-	now := util.CurrentTimeMillis()
-	conf := &DataConf{Updated: now, Device: systemID}
-	if !gulu.File.IsExist(confPath) {
-		data, _ = gulu.JSON.MarshalIndentJSON(conf, "", "  ")
-		if err = filelock.LockFileWrite(confPath, data); nil != err {
-			util.LogErrorf("save data conf [%s] failed: %s", confPath, err)
-		}
-
-		t := util.Millisecond2Time(now)
-		if err = os.Chtimes(confPath, t, t); nil != err {
-			util.LogErrorf("change file [%s] mod time failed: %s", confPath, err)
-		}
-		return
-	}
-
-	data, err = filelock.LockFileRead(confPath)
-	if nil != err {
-		data, err = recoverFrom(confPath)
-		if nil != err {
-			return
-		}
-	}
-
-	if err = gulu.JSON.UnmarshalJSON(data, conf); nil != err {
-		data, err = recoverFrom(confPath)
-		if nil != err {
-			return
-		}
-		if err = gulu.JSON.UnmarshalJSON(data, conf); nil != err {
-			util.LogErrorf("parse data conf [%s] failed: %s", confPath, err)
-		}
-	}
-
-	conf.Updated = now
-	conf.Device = systemID
-	if inc {
-		conf.SyncVer++
-	}
-
-	data, _ = gulu.JSON.MarshalIndentJSON(conf, "", "  ")
-	if err = filelock.LockFileWrite(confPath, data); nil != err {
-		util.LogErrorf("save data conf [%s] failed: %s", confPath, err)
-		return
-	}
-}
-
-func recoverFrom(confPath string) (data []byte, err error) {
-	// 尝试从临时文件恢复
-	tmp := util.LatestTmpFile(confPath)
-	if "" == tmp {
-		return
-	}
-
-	data, err = filelock.NoLockFileRead(tmp)
-	if nil != err {
-		util.LogErrorf("read temp data conf [%s] failed: %s", tmp, err)
-		return
-	}
-	util.LogInfof("recovered file [%s] from [%s]", confPath, tmp)
-	os.RemoveAll(tmp)
-	return
-}

+ 2 - 1
kernel/go.mod

@@ -18,6 +18,7 @@ require (
 	github.com/Xuanwo/go-locale v1.1.0
 	github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
 	github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be
+	github.com/denisbrodbeck/machineid v1.0.1
 	github.com/dgraph-io/ristretto v0.1.0
 	github.com/dustin/go-humanize v1.0.0
 	github.com/emirpasic/gods v1.18.1
@@ -103,7 +104,7 @@ require (
 	golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
 	golang.org/x/net v0.0.0-20220708220712-1185a9018129 // indirect
 	golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect
-	golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d // indirect
+	golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e // indirect
 	golang.org/x/tools v0.1.11 // indirect
 	golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect
 	google.golang.org/protobuf v1.28.0 // indirect

+ 4 - 2
kernel/go.sum

@@ -109,6 +109,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMSRhl4D7AQ=
+github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI=
 github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI=
 github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug=
 github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA=
@@ -659,8 +661,8 @@ golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20211023085530-d6a326fbbf70/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d h1:/m5NbqQelATgoSPVC2Z23sR4kVNokFwDDyWh/3rGY+I=
-golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e h1:NHvCuwuS43lGnYhten69ZWqi2QOj/CiDNcKbVqwVoew=
+golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

+ 2 - 2
kernel/model/assets.go

@@ -404,7 +404,7 @@ func RemoveUnusedAssets() (ret []string) {
 		ret = append(ret, unusedAsset)
 	}
 	if 0 < len(ret) {
-		IncWorkspaceDataVer()
+		IncSync()
 	}
 	return
 }
@@ -431,7 +431,7 @@ func RemoveUnusedAsset(p string) (ret string) {
 		util.LogErrorf("remove unused asset [%s] failed: %s", p, err)
 	}
 	ret = p
-	IncWorkspaceDataVer()
+	IncSync()
 	return
 }
 

+ 1 - 1
kernel/model/assets_watcher.go

@@ -76,7 +76,7 @@ func watchAssets() {
 				//util.LogInfof("assets changed: %s", lastEvent)
 				if lastEvent.Op&fsnotify.Write == fsnotify.Write {
 					// 外部修改已有资源文件后纳入云端同步 https://github.com/siyuan-note/siyuan/issues/4694
-					IncWorkspaceDataVer()
+					IncSync()
 				}
 			}
 		}

+ 1 - 1
kernel/model/assets_watcher_darwin.go

@@ -52,7 +52,7 @@ func watchAssets() {
 
 				//util.LogInfof("assets changed: %s", event)
 				if watcher.Write == event.Op {
-					IncWorkspaceDataVer()
+					IncSync()
 				}
 			case err, ok := <-assetsWatcher.Error:
 				if !ok {

+ 1 - 1
kernel/model/backlink.go

@@ -150,7 +150,7 @@ OK:
 		if err = indexWriteJSONQueue(refTree); nil != err {
 			return "", err
 		}
-		IncWorkspaceDataVer()
+		IncSync()
 	}
 	sql.WaitForWritingDatabase()
 	return

+ 3 - 3
kernel/model/blockial.go

@@ -87,7 +87,7 @@ func SetBlockReminder(id string, timed string) (err error) {
 	if err = indexWriteJSONQueue(tree); nil != err {
 		return
 	}
-	IncWorkspaceDataVer()
+	IncSync()
 	cache.PutBlockIAL(id, attrs)
 	return
 }
@@ -124,7 +124,7 @@ func SetBlockAttrs(id string, nameValues map[string]string) (err error) {
 	if err = indexWriteJSONQueue(tree); nil != err {
 		return
 	}
-	IncWorkspaceDataVer()
+	IncSync()
 	cache.PutBlockIAL(id, parse.IAL2Map(node.KramdownIAL))
 	return
 }
@@ -158,7 +158,7 @@ func ResetBlockAttrs(id string, nameValues map[string]string) (err error) {
 	if err = indexWriteJSONQueue(tree); nil != err {
 		return
 	}
-	IncWorkspaceDataVer()
+	IncSync()
 	cache.RemoveBlockIAL(id)
 	return
 }

+ 4 - 4
kernel/model/box.go

@@ -261,7 +261,7 @@ func (box *Box) Mkdir(path string) error {
 		util.LogErrorf("mkdir [path=%s] in box [%s] failed: %s", path, box.ID, err)
 		return errors.New(msg)
 	}
-	IncWorkspaceDataVer()
+	IncSync()
 	return nil
 }
 
@@ -271,7 +271,7 @@ func (box *Box) MkdirAll(path string) error {
 		util.LogErrorf("mkdir all [path=%s] in box [%s] failed: %s", path, box.ID, err)
 		return errors.New(msg)
 	}
-	IncWorkspaceDataVer()
+	IncSync()
 	return nil
 }
 
@@ -292,7 +292,7 @@ func (box *Box) Move(oldPath, newPath string) error {
 			os.Remove(fromDir)
 		}
 	}
-	IncWorkspaceDataVer()
+	IncSync()
 	return nil
 }
 
@@ -305,7 +305,7 @@ func (box *Box) Remove(path string) error {
 		util.LogErrorf("remove [path=%s] in box [%s] failed: %s", path, box.ID, err)
 		return errors.New(msg)
 	}
-	IncWorkspaceDataVer()
+	IncSync()
 	return nil
 }
 

+ 4 - 4
kernel/model/file.go

@@ -1130,7 +1130,7 @@ func MoveDoc(fromBoxID, fromPath, toBoxID, toPath string) (newPath string, err e
 		moveSorts(tree.ID, fromBoxID, toBoxID)
 	}
 	cache.ClearDocsIAL()
-	IncWorkspaceDataVer()
+	IncSync()
 	return
 }
 
@@ -1251,7 +1251,7 @@ func RenameDoc(boxID, p, title string) (err error) {
 		refreshDynamicRefText(changedDefs, changedTrees)
 	}()
 
-	IncWorkspaceDataVer()
+	IncSync()
 	return
 }
 
@@ -1319,7 +1319,7 @@ func CreateDailyNote(boxID string) (p string, err error) {
 			}
 		}
 	}
-	IncWorkspaceDataVer()
+	IncSync()
 
 	b := treenode.GetBlockTree(id)
 	p = b.Path
@@ -1559,7 +1559,7 @@ func ChangeFileTreeSort(boxID string, paths []string) {
 		return
 	}
 
-	IncWorkspaceDataVer()
+	IncSync()
 }
 
 func (box *Box) fillSort(files *[]*File) {

+ 4 - 4
kernel/model/heading.go

@@ -55,7 +55,7 @@ func (tx *Transaction) doFoldHeading(operation *Operation) (ret *TxErr) {
 	if err = tx.writeTree(tree); nil != err {
 		return &TxErr{code: TxErrCodeWriteTree, msg: err.Error(), id: headingID}
 	}
-	IncWorkspaceDataVer()
+	IncSync()
 
 	cache.PutBlockIAL(headingID, parse.IAL2Map(heading.KramdownIAL))
 	for _, child := range children {
@@ -89,7 +89,7 @@ func (tx *Transaction) doUnfoldHeading(operation *Operation) (ret *TxErr) {
 	if err = tx.writeTree(tree); nil != err {
 		return &TxErr{code: TxErrCodeWriteTree, msg: err.Error(), id: headingID}
 	}
-	IncWorkspaceDataVer()
+	IncSync()
 
 	cache.PutBlockIAL(headingID, parse.IAL2Map(heading.KramdownIAL))
 	for _, child := range children {
@@ -208,7 +208,7 @@ func Doc2Heading(srcID, targetID string, after bool) (srcTreeBox, srcTreePath st
 
 	targetTree.Root.SetIALAttr("updated", util.CurrentTimeSecondsStr())
 	err = indexWriteJSONQueue(targetTree)
-	IncWorkspaceDataVer()
+	IncSync()
 	RefreshBacklink(srcTree.ID)
 	RefreshBacklink(targetTree.ID)
 	return
@@ -306,7 +306,7 @@ func Heading2Doc(srcHeadingID, targetBoxID, targetPath string) (srcRootBlockID,
 	if err = indexWriteJSONQueue(newTree); nil != err {
 		return "", "", err
 	}
-	IncWorkspaceDataVer()
+	IncSync()
 	RefreshBacklink(srcTree.ID)
 	RefreshBacklink(newTree.ID)
 	return

+ 3 - 3
kernel/model/history.go

@@ -184,7 +184,7 @@ func RollbackDocHistory(boxID, historyPath string) (err error) {
 	writingDataLock.Unlock()
 
 	RefreshFileTree()
-	IncWorkspaceDataVer()
+	IncSync()
 	return nil
 }
 
@@ -220,7 +220,7 @@ func RollbackAssetsHistory(historyPath string) (err error) {
 		util.LogErrorf("copy file [%s] to [%s] failed: %s", from, to, err)
 		return
 	}
-	IncWorkspaceDataVer()
+	IncSync()
 	return nil
 }
 
@@ -238,7 +238,7 @@ func RollbackNotebookHistory(historyPath string) (err error) {
 	}
 
 	RefreshFileTree()
-	IncWorkspaceDataVer()
+	IncSync()
 	return nil
 }
 

+ 11 - 32
kernel/model/import.go

@@ -284,7 +284,7 @@ func ImportSY(zipPath, boxID, toPath string) (err error) {
 		return
 	}
 
-	IncWorkspaceDataVer()
+	IncSync()
 	RefreshFileTree()
 	return
 }
@@ -303,48 +303,27 @@ func ImportData(zipPath string) (err error) {
 	}
 	defer os.RemoveAll(unzipPath)
 
-	files, err := filepath.Glob(filepath.Join(unzipPath, "*/.siyuan/conf.json"))
+	files, err := filepath.Glob(filepath.Join(unzipPath, "*/*.sy"))
 	if nil != err {
-		util.LogErrorf("glob conf.json failed: %s", err)
-		return errors.New("not found conf.json")
+		util.LogErrorf("check data.zip failed: %s", err)
+		return errors.New("check data.zip failed")
 	}
-	if 1 > len(files) {
-		return errors.New("not found conf.json")
-	}
-
-	confPath := files[0]
-	confData, err := os.ReadFile(confPath)
-	if nil != err {
-		return errors.New("read conf.json failed")
-	}
-	dataConf := &filesys.DataConf{}
-	if err = gulu.JSON.UnmarshalJSON(confData, dataConf); nil != err {
-		util.LogErrorf("unmarshal conf.json failed: %s", err)
-		return errors.New("unmarshal conf.json failed")
-	}
-	dataConf.Device = util.GetDeviceID()
-	confData, err = gulu.JSON.MarshalJSON(dataConf)
-	if nil != err {
-		util.LogErrorf("marshal conf.json failed: %s", err)
-		return errors.New("marshal conf.json failed")
-	}
-	if err = os.WriteFile(confPath, confData, 0644); nil != err {
-		util.LogErrorf("write conf.json failed: %s", err)
-		return errors.New("write conf.json failed")
+	if 0 < len(files) {
+		return errors.New("invalid data.zip")
 	}
 
 	writingDataLock.Lock()
 	defer writingDataLock.Unlock()
 
 	filelock.ReleaseAllFileLocks()
-	tmpDataPath := filepath.Dir(filepath.Dir(confPath))
+	tmpDataPath := unzipPath
 	if err = stableCopy(tmpDataPath, util.DataDir); nil != err {
 		util.LogErrorf("copy data dir from [%s] to [%s] failed: %s", tmpDataPath, util.DataDir, err)
 		err = errors.New("copy data failed")
 		return
 	}
 
-	IncWorkspaceDataVer()
+	IncSync()
 	RefreshFileTree()
 	return
 }
@@ -516,7 +495,7 @@ func ImportFromLocalPath(boxID, localPath string, toPath string) (err error) {
 			return err
 		}
 
-		IncWorkspaceDataVer()
+		IncSync()
 		RefreshFileTree()
 	} else { // 导入单个文件
 		fileName := filepath.Base(localPath)
@@ -588,7 +567,7 @@ func ImportFromLocalPath(boxID, localPath string, toPath string) (err error) {
 		if err = indexWriteJSONQueue(tree); nil != err {
 			return
 		}
-		IncWorkspaceDataVer()
+		IncSync()
 		sql.WaitForWritingDatabase()
 
 		util.PushEndlessProgress(Conf.Language(58))
@@ -598,7 +577,7 @@ func ImportFromLocalPath(boxID, localPath string, toPath string) (err error) {
 		}()
 	}
 	debug.FreeOSMemory()
-	IncWorkspaceDataVer()
+	IncSync()
 	return
 }
 

+ 1 - 1
kernel/model/listitem.go

@@ -105,7 +105,7 @@ func ListItem2Doc(srcListItemID, targetBoxID, targetPath string) (srcRootBlockID
 	if err = indexWriteJSONQueue(newTree); nil != err {
 		return "", "", err
 	}
-	IncWorkspaceDataVer()
+	IncSync()
 	RefreshBacklink(srcTree.ID)
 	RefreshBacklink(newTree.ID)
 	return

+ 3 - 3
kernel/model/mount.go

@@ -48,7 +48,7 @@ func CreateBox(name string) (id string, err error) {
 	boxConf := box.GetConf()
 	boxConf.Name = name
 	box.SaveConf(boxConf)
-	IncWorkspaceDataVer()
+	IncSync()
 	return
 }
 
@@ -66,7 +66,7 @@ func RenameBox(boxID, name string) (err error) {
 	boxConf.Name = name
 	box.Name = name
 	box.SaveConf(boxConf)
-	IncWorkspaceDataVer()
+	IncSync()
 	return
 }
 
@@ -109,7 +109,7 @@ func RemoveBox(boxID string) (err error) {
 	if err = os.RemoveAll(localPath); nil != err {
 		return
 	}
-	IncWorkspaceDataVer()
+	IncSync()
 	return
 }
 

+ 1 - 3
kernel/model/sync.go

@@ -30,7 +30,6 @@ import (
 	"github.com/88250/gulu"
 	"github.com/dustin/go-humanize"
 	"github.com/siyuan-note/dejavu"
-	"github.com/siyuan-note/siyuan/kernel/filesys"
 	"github.com/siyuan-note/siyuan/kernel/sql"
 	"github.com/siyuan-note/siyuan/kernel/treenode"
 	"github.com/siyuan-note/siyuan/kernel/util"
@@ -347,8 +346,7 @@ func getIgnoreLines() (ret []string) {
 	return
 }
 
-func IncWorkspaceDataVer() {
-	filesys.IncWorkspaceDataVer(true, Conf.System.ID)
+func IncSync() {
 	syncSameCount = 0
 	planSyncAfter(30 * time.Second)
 }

+ 1 - 1
kernel/model/transaction.go

@@ -1107,7 +1107,7 @@ func (tx *Transaction) commit() (err error) {
 		}
 	}
 	refreshDynamicRefText(tx.nodes, tx.trees)
-	IncWorkspaceDataVer()
+	IncSync()
 	tx.trees = nil
 	return
 }

+ 2 - 2
kernel/model/upload.go

@@ -92,7 +92,7 @@ func InsertLocalAssets(id string, assetPaths []string) (succMap map[string]inter
 			succMap[baseName] = "assets/" + fName
 		}
 	}
-	IncWorkspaceDataVer()
+	IncSync()
 	return
 }
 
@@ -183,7 +183,7 @@ func Upload(c *gin.Context) {
 		"succMap":  succMap,
 	}
 
-	IncWorkspaceDataVer()
+	IncSync()
 }
 
 func getAssetsDir(boxLocalPath, docDirLocalPath string) (assets string) {

+ 12 - 0
kernel/util/runtime.go

@@ -24,6 +24,7 @@ import (
 	"time"
 
 	"github.com/88250/gulu"
+	"github.com/denisbrodbeck/machineid"
 	"github.com/dustin/go-humanize"
 )
 
@@ -64,6 +65,17 @@ func RandomSleep(minMills, maxMills int) {
 	time.Sleep(time.Duration(r) * time.Millisecond)
 }
 
+func GetDeviceID() string {
+	if "std" == Container {
+		machineID, err := machineid.ID()
+		if nil != err {
+			return gulu.Rand.String(12)
+		}
+		return machineID
+	}
+	return gulu.Rand.String(12)
+}
+
 func SetNetworkProxy(proxyURL string) {
 	if err := os.Setenv("HTTPS_PROXY", proxyURL); nil != err {
 		logger.Errorf("set env [HTTPS_PROXY] failed: %s", err)