浏览代码

Merge remote-tracking branch 'origin/dev' into dev

Vanessa 1 年之前
父节点
当前提交
3f70ac1d45

+ 2 - 2
app/appearance/langs/en_US.json

@@ -1307,7 +1307,7 @@
     "102": "Processing completed",
     "103": "The update installation package has been automatically downloaded in the background. When exiting, you will be asked whether to install the new version",
     "104": "The update installation package failed to download, please check the network connection",
-    "105": "Corrupted data repo have been automatically reset",
+    "105": "TODO",
     "106": "Maximum length is limited to 512 characters",
     "107": "Moved document [%s]",
     "108": "Data sync found conflicts, you can view the generated conflict content in [Data History]",
@@ -1358,7 +1358,7 @@
     "153": "Downloaded files %d, chunks %d, received bytes %s",
     "154": "The cloud can only support backup up to 12 snapshots",
     "155": "Cloud sync directory has been reset to [main]",
-    "156": "Access authentication failed, please refresh the page",
+    "156": "Access authentication failed, please refresh or reopen it",
     "157": "The key is not recognized, please confirm that the copied key string is correct",
     "158": "Indexing data repo, walking data %s",
     "159": "Indexing data repo, getting the latest file %v/%v",

+ 2 - 2
app/appearance/langs/es_ES.json

@@ -1307,7 +1307,7 @@
     "102": "Procesamiento completado",
     "103": "El paquete de instalación de la actualización se ha descargado automáticamente en segundo plano. Al salir, se le preguntará si desea instalar la nueva versión",
     "104": "El paquete de instalación de la actualización no se pudo descargar, verifique la conexión de red",
-    "105": "El repositorio de datos corruptos se ha restablecido automáticamente",
+    "105": "TODO",
     "106": "La longitud máxima está limitada a 512 caracteres",
     "107": "Documento movido [%s]",
     "108": "La sincronizaci\u00f3n de datos encontr\u00f3 en conflictos, puede ver el contenido del conflicto generado en [Historial de datos]",
@@ -1358,7 +1358,7 @@
     "153": "Archivos descargados %d, fragmentos %d, bytes recibidos %s",
     "154": "La nube solo admite copias de seguridad de hasta 12 instantáneas",
     "155": "El directorio de sincronización de la nube se ha restablecido a [main]",
-    "156": "Error en la autenticación de acceso, actualice la página",
+    "156": "Error de autenticación de acceso; actualice o vuelva a abrir",
     "157": "No se reconoce la clave, confirme que la cadena de clave copiada es correcta",
     "158": "Indexando repositorio de datos, datos para caminar %s",
     "159": "Indexando repositorio de datos, obteniendo el último archivo %v/%v",

+ 2 - 2
app/appearance/langs/fr_FR.json

@@ -1307,7 +1307,7 @@
     "102": "Traitement terminé",
     "103": "Le package d'installation de la mise à jour a été automatiquement téléchargé en arrière-plan. En quittant, il vous sera demandé si vous souhaitez installer la nouvelle version",
     "104": "Le package d'installation de la mise à jour n'a pas pu être téléchargé, veuillez vérifier la connexion réseau",
-    "105": "Le référentiel de données corrompu a été automatiquement réinitialisé",
+    "105": "TODO",
     "106": "La longueur maximale est limitée à 512 caractères",
     "107": "Document déplacé [%s]",
     "108": "La synchronisation des données a trouvé des conflits, vous pouvez afficher le contenu du conflit généré dans [Historique des données]",
@@ -1358,7 +1358,7 @@
     "153": "Fichiers chargés %d, morceaux %d, octets reçus %s",
     "154": "Le cloud ne peut prendre en charge que la sauvegarde jusqu'à 12 instantanés",
     "155": "Le répertoire de synchronisation du cloud a été réinitialisé sur [main]",
-    "156": "Échec de l'authentification d'accès, veuillez actualiser la page",
+    "156": "Échec de l'authentification d'accès, veuillez actualiser ou rouvrir",
     "157": "La clé n'est pas reconnue, veuillez confirmer que la chaîne de clé copiée est correcte",
     "158": "Indexation du référentiel de données, données de marche %s",
     "159": "Indexation du référentiel de données, obtention du dernier fichier %v/%v",

+ 2 - 2
app/appearance/langs/zh_CHT.json

@@ -1307,7 +1307,7 @@
     "102": "處理完畢",
     "103": "已經在後台開始自動下載更新安裝檔,退出時將詢問是否安裝新版本",
     "104": "更新安裝檔下載失敗,請檢查網絡連接",
-    "105": "已經自動重置損壞的資料倉庫",
+    "105": "TODO",
     "106": "最大長度限制為 512 字元",
     "107": "已經移動文檔 [%s]",
     "108": "資料同步發現衝突,可在 [資料歷史] 中查看生成的衝突內容",
@@ -1358,7 +1358,7 @@
     "153": "下載文件數 %d 下載分塊數 %d 接收位元組數 %s",
     "154": "雲端最多只能支持備份 12 個快照",
     "155": "雲端同步目錄已經重置為 [main]",
-    "156": "訪問鑑權失敗,請重新整理頁面",
+    "156": "訪問鑑權失敗,請刷新或重新打開",
     "157": "無法識別密鑰,請確認複製的密鑰字串是否正確",
     "158": "正在索引資料倉庫,遍歷資料 %s",
     "159": "正在索引資料倉庫,獲取最新文件 %v/%v",

+ 2 - 2
app/appearance/langs/zh_CN.json

@@ -1307,7 +1307,7 @@
     "102": "处理完毕",
     "103": "已经在后台开始自动下载更新安装包,退出时将询问是否安装新版本",
     "104": "更新安装包下载失败,请检查网络连接",
-    "105": "已经自动重置损坏的数据仓库",
+    "105": "TODO",
     "106": "最大长度限制为 512 字符",
     "107": "已经移动文档 [%s]",
     "108": "数据同步发现冲突,可在 [数据历史] 中查看生成的冲突内容",
@@ -1358,7 +1358,7 @@
     "153": "下载文件数 %d 下载分块数 %d 接收字节数 %s",
     "154": "云端最多只能支持备份 12 个快照",
     "155": "云端同步目录已经重置为 [main]",
-    "156": "访问鉴权失败,请刷新页面",
+    "156": "访问鉴权失败,请刷新或者重新打开",
     "157": "无法识别密钥,请确认复制的密钥字符串是否正确",
     "158": "正在索引数据仓库,遍历数据 %s",
     "159": "正在索引数据仓库,获取最新文件 %v/%v",

+ 1 - 1
kernel/api/extension.go

@@ -121,7 +121,7 @@ func extensionCopy(c *gin.Context) {
 		uploaded[oName] = "assets/" + fName
 	}
 
-	luteEngine := lute.New()
+	luteEngine := util.NewStdLute()
 	md := luteEngine.HTML2Md(dom)
 	md = strings.TrimSpace(md)
 

+ 3 - 3
kernel/go.mod

@@ -35,7 +35,7 @@ require (
 	github.com/goccy/go-json v0.10.2
 	github.com/gofrs/flock v0.8.1
 	github.com/gorilla/websocket v1.5.1
-	github.com/imroc/req/v3 v3.43.0
+	github.com/imroc/req/v3 v3.43.1
 	github.com/jinzhu/copier v0.4.0
 	github.com/json-iterator/go v1.1.12
 	github.com/klippa-app/go-pdfium v1.11.0
@@ -51,11 +51,11 @@ require (
 	github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
 	github.com/sashabaranov/go-openai v1.20.2
 	github.com/shirou/gopsutil/v3 v3.24.2
-	github.com/siyuan-note/dejavu v0.0.0-20240218075321-a488f36181cc
+	github.com/siyuan-note/dejavu v0.0.0-20240312083319-7cf60efe5c66
 	github.com/siyuan-note/encryption v0.0.0-20231219001248-1e028a4d13b4
 	github.com/siyuan-note/eventbus v0.0.0-20240124091459-8e1b37a55255
 	github.com/siyuan-note/filelock v0.0.0-20240128091141-94d7bb3e0772
-	github.com/siyuan-note/httpclient v0.0.0-20240306121400-b3af777a1f1b
+	github.com/siyuan-note/httpclient v0.0.0-20240312073515-af29be1cfb4e
 	github.com/siyuan-note/logging v0.0.0-20231208035918-61f884c854f0
 	github.com/siyuan-note/riff v0.0.0-20240305012846-494c7fb46c45
 	github.com/spf13/cast v1.6.0

+ 6 - 6
kernel/go.sum

@@ -197,8 +197,8 @@ github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq
 github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
 github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
 github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
-github.com/imroc/req/v3 v3.43.0 h1:TZDLMcuXEUFOvoyjKI2vMeimhq/OWnxvRJDPfEVCEhk=
-github.com/imroc/req/v3 v3.43.0/go.mod h1:SQIz5iYop16MJxbo8ib+4LnostGCok8NQf8ToyQc2xA=
+github.com/imroc/req/v3 v3.43.1 h1:tsWAhvxik4egtHAvMlxcjaWJtHlJL8EpBqJMOm5rmyQ=
+github.com/imroc/req/v3 v3.43.1/go.mod h1:SQIz5iYop16MJxbo8ib+4LnostGCok8NQf8ToyQc2xA=
 github.com/jaytaylor/html2text v0.0.0-20180606194806-57d518f124b0/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
 github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 h1:iCHtR9CQyktQ5+f3dMVZfwD2KWJUgm7M0gdL9NGr8KA=
 github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
@@ -351,16 +351,16 @@ github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFR
 github.com/shurcooL/gofontwoff v0.0.0-20181114050219-180f79e6909d h1:lvCTyBbr36+tqMccdGMwuEU+hjux/zL6xSmf5S9ITaA=
 github.com/shurcooL/gofontwoff v0.0.0-20181114050219-180f79e6909d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw=
 github.com/simplereach/timeutils v1.2.0/go.mod h1:VVbQDfN/FHRZa1LSqcwo4kNZ62OOyqLLGQKYB3pB0Q8=
-github.com/siyuan-note/dejavu v0.0.0-20240218075321-a488f36181cc h1:8Xtg9wp+wvt1Pv/VaaqLkvizT1myUG5yUzoeX/tkMyc=
-github.com/siyuan-note/dejavu v0.0.0-20240218075321-a488f36181cc/go.mod h1:uh+lahK4RdQGlS7AsZ1mAHp6lWI9GR+aNboq4cdaBQU=
+github.com/siyuan-note/dejavu v0.0.0-20240312083319-7cf60efe5c66 h1:9r9Op9nZBHi5IfRQxLoxKOEwajrMVRJCHWQXgt8jsbY=
+github.com/siyuan-note/dejavu v0.0.0-20240312083319-7cf60efe5c66/go.mod h1:lMrCZfigfQNC89yr1UF/PYbFenBQLzSWiWV1TcqUkVY=
 github.com/siyuan-note/encryption v0.0.0-20231219001248-1e028a4d13b4 h1:kJaw5L/evyW6LcB9IQT8PR4ppx8JVqOFP9Ix3rfwSrc=
 github.com/siyuan-note/encryption v0.0.0-20231219001248-1e028a4d13b4/go.mod h1:UYcCCY+0wh+GmUoDOaO63j1sV5lgy7laLAk1XhEiUis=
 github.com/siyuan-note/eventbus v0.0.0-20240124091459-8e1b37a55255 h1:WTAUBlU2v7ISet9ankbjqZrRKo6MLGK1LBmDyNlehPY=
 github.com/siyuan-note/eventbus v0.0.0-20240124091459-8e1b37a55255/go.mod h1:1/nGgthl89FPA7GzAcEWKl6zRRnfgyTjzLZj9bW7kuw=
 github.com/siyuan-note/filelock v0.0.0-20240128091141-94d7bb3e0772 h1:ceX49LJmN8FMwWpkCkZIV9dHG4Ya2ZMrhu9T6VyDiKs=
 github.com/siyuan-note/filelock v0.0.0-20240128091141-94d7bb3e0772/go.mod h1:CYJQjSyKYLhEJJC+5I+R4uNcpyW0X2CaUYwMVbkelDk=
-github.com/siyuan-note/httpclient v0.0.0-20240306121400-b3af777a1f1b h1:t8xkj25nNOQXsS6grX2kpFcNeOydjrT250ahdzWosos=
-github.com/siyuan-note/httpclient v0.0.0-20240306121400-b3af777a1f1b/go.mod h1:mgg/IhCzGQ5h2k6QTTn0kFSR7cCMN/Xb313eTpAedic=
+github.com/siyuan-note/httpclient v0.0.0-20240312073515-af29be1cfb4e h1:2DeWT+8qGw2mqF03Z7R9gwPJ7WTUqDrQSv5Yo/NxxYA=
+github.com/siyuan-note/httpclient v0.0.0-20240312073515-af29be1cfb4e/go.mod h1:v/O6xcc3HomxJR1dLwENGan9RB08WqSPv4kxyzaTSUI=
 github.com/siyuan-note/logging v0.0.0-20231208035918-61f884c854f0 h1:+XjUr9UMXsczdO2bGA72p/k9wa2ShPb8ybi7CDBJ7HQ=
 github.com/siyuan-note/logging v0.0.0-20231208035918-61f884c854f0/go.mod h1:6mRFtAAvYPn3cDzqvyv+t8BVPGqpONDMMb5ywOhY1D4=
 github.com/siyuan-note/riff v0.0.0-20240305012846-494c7fb46c45 h1:/ORGs2Llh98lXSiR3mt/8vZKrAOQAIB4LQkh1aslaow=

+ 18 - 4
kernel/model/assets.go

@@ -103,6 +103,14 @@ func NetImg2LocalAssets(rootID, originalURL string) (err error) {
 		}
 		if ast.NodeImage == n.Type {
 			linkDest := n.ChildByType(ast.NodeLinkDest)
+			linkText := n.ChildByType(ast.NodeLinkText)
+			if nil == linkText {
+				linkText = &ast.Node{Type: ast.NodeLinkText, Tokens: []byte("image")}
+				if openBracket := n.ChildByType(ast.NodeOpenBracket); nil != openBracket {
+					openBracket.InsertAfter(linkText)
+				}
+			}
+
 			dest := linkDest.Tokens
 			if util.IsAssetLinkDest(dest) {
 				return ast.WalkSkipChildren
@@ -122,8 +130,11 @@ func NetImg2LocalAssets(rootID, originalURL string) (err error) {
 				}
 
 				name := filepath.Base(u)
-				name = util.FilterFileName(name)
+				name = util.FilterUploadFileName(name)
 				name = util.TruncateLenFileName(name)
+				if 1 > len(bytes.TrimSpace(linkText.Tokens)) {
+					linkText.Tokens = []byte(name)
+				}
 				name = "net-img-" + name
 				name = util.AssetName(name)
 				writePath := filepath.Join(assetsDirPath, name)
@@ -198,8 +209,11 @@ func NetImg2LocalAssets(rootID, originalURL string) (err error) {
 					}
 				}
 				name = strings.TrimSuffix(name, ext)
-				name = util.FilterFileName(name)
+				name = util.FilterUploadFileName(name)
 				name = util.TruncateLenFileName(name)
+				if 1 > len(bytes.TrimSpace(linkText.Tokens)) {
+					linkText.Tokens = []byte(name)
+				}
 				name = "net-img-" + name + "-" + ast.NewNodeID() + ext
 				writePath := filepath.Join(assetsDirPath, name)
 				if err = filelock.WriteFile(writePath, data); nil != err {
@@ -285,7 +299,7 @@ func NetAssets2LocalAssets(rootID string) (err error) {
 			}
 
 			name := filepath.Base(u)
-			name = util.FilterFileName(name)
+			name = util.FilterUploadFileName(name)
 			name = util.TruncateLenFileName(name)
 			name = "network-asset-" + name
 			name = util.AssetName(name)
@@ -375,7 +389,7 @@ func NetAssets2LocalAssets(rootID string) (err error) {
 				}
 			}
 			name = strings.TrimSuffix(name, ext)
-			name = util.FilterFileName(name)
+			name = util.FilterUploadFileName(name)
 			name = util.TruncateLenFileName(name)
 			name = "network-asset-" + name + "-" + ast.NewNodeID() + ext
 			writePath := filepath.Join(assetsDirPath, name)

+ 1 - 1
kernel/model/import.go

@@ -951,7 +951,7 @@ func processBase64Img(n *ast.Node, dest string, assetDirPath string, err error)
 	if nil != alt {
 		name = alt.TokensStr() + ext
 	}
-	name = util.FilterFileName(name)
+	name = util.FilterUploadFileName(name)
 	name = util.AssetName(name)
 
 	tmp := filepath.Join(base64TmpDir, name)

+ 44 - 53
kernel/model/repository.go

@@ -1019,17 +1019,18 @@ func syncRepoDownload() (err error) {
 	_, _, err = indexRepoBeforeCloudSync(repo)
 	if nil != err {
 		planSyncAfter(fixSyncInterval)
+
+		logging.LogErrorf("sync data repo download failed: %s", err)
+		msg := fmt.Sprintf(Conf.Language(80), formatRepoErrorMsg(err))
+		Conf.Sync.Stat = msg
+		Conf.Save()
+		util.PushStatusBar(msg)
+		util.PushErrMsg(msg, 0)
 		return
 	}
 
 	syncContext := map[string]interface{}{eventbus.CtxPushMsg: eventbus.CtxPushMsgToStatusBar}
 	mergeResult, trafficStat, err := repo.SyncDownload(syncContext)
-	if errors.Is(err, dejavu.ErrRepoFatal) {
-		// 重置仓库并再次尝试同步
-		if _, resetErr := resetRepository(repo); nil == resetErr {
-			mergeResult, trafficStat, err = repo.SyncDownload(syncContext)
-		}
-	}
 	elapsed := time.Since(start)
 	if nil != err {
 		planSyncAfter(fixSyncInterval)
@@ -1089,17 +1090,18 @@ func syncRepoUpload() (err error) {
 	_, _, err = indexRepoBeforeCloudSync(repo)
 	if nil != err {
 		planSyncAfter(fixSyncInterval)
+
+		logging.LogErrorf("sync data repo upload failed: %s", err)
+		msg := fmt.Sprintf(Conf.Language(80), formatRepoErrorMsg(err))
+		Conf.Sync.Stat = msg
+		Conf.Save()
+		util.PushStatusBar(msg)
+		util.PushErrMsg(msg, 0)
 		return
 	}
 
 	syncContext := map[string]interface{}{eventbus.CtxPushMsg: eventbus.CtxPushMsgToStatusBar}
 	trafficStat, err := repo.SyncUpload(syncContext)
-	if errors.Is(err, dejavu.ErrRepoFatal) {
-		// 重置仓库并再次尝试同步
-		if _, resetErr := resetRepository(repo); nil == resetErr {
-			trafficStat, err = repo.SyncUpload(syncContext)
-		}
-	}
 	elapsed := time.Since(start)
 	if nil != err {
 		planSyncAfter(fixSyncInterval)
@@ -1165,6 +1167,13 @@ func bootSyncRepo() (err error) {
 	if nil != err {
 		autoSyncErrCount++
 		planSyncAfter(fixSyncInterval)
+
+		msg := fmt.Sprintf(Conf.Language(80), formatRepoErrorMsg(err))
+		Conf.Sync.Stat = msg
+		Conf.Save()
+		util.PushStatusBar(msg)
+		util.PushErrMsg(msg, 0)
+		BootSyncSucc = 1
 		isBootSyncing.Store(false)
 		return
 	}
@@ -1172,10 +1181,17 @@ func bootSyncRepo() (err error) {
 	syncContext := map[string]interface{}{eventbus.CtxPushMsg: eventbus.CtxPushMsgToStatusBar}
 	fetchedFiles, err := repo.GetSyncCloudFiles(syncContext)
 	if errors.Is(err, dejavu.ErrRepoFatal) {
-		// 重置仓库并再次尝试同步
-		if _, resetErr := resetRepository(repo); nil == resetErr {
-			fetchedFiles, err = repo.GetSyncCloudFiles(syncContext)
-		}
+		autoSyncErrCount++
+		planSyncAfter(fixSyncInterval)
+
+		msg := fmt.Sprintf(Conf.Language(80), formatRepoErrorMsg(err))
+		Conf.Sync.Stat = msg
+		Conf.Save()
+		util.PushStatusBar(msg)
+		util.PushErrMsg(msg, 0)
+		BootSyncSucc = 1
+		isBootSyncing.Store(false)
+		return
 	}
 
 	syncingFiles = sync.Map{}
@@ -1261,17 +1277,23 @@ func syncRepo(exit, byHand bool) (dataChanged bool, err error) {
 	if nil != err {
 		autoSyncErrCount++
 		planSyncAfter(fixSyncInterval)
+
+		logging.LogErrorf("sync data repo failed: %s", err)
+		msg := fmt.Sprintf(Conf.Language(80), formatRepoErrorMsg(err))
+		Conf.Sync.Stat = msg
+		Conf.Save()
+		util.PushStatusBar(msg)
+		if 1 > autoSyncErrCount || byHand {
+			util.PushErrMsg(msg, 0)
+		}
+		if exit {
+			ExitSyncSucc = 1
+		}
 		return
 	}
 
 	syncContext := map[string]interface{}{eventbus.CtxPushMsg: eventbus.CtxPushMsgToStatusBar}
 	mergeResult, trafficStat, err := repo.Sync(syncContext)
-	if errors.Is(err, dejavu.ErrRepoFatal) {
-		// 重置仓库并再次尝试同步
-		if _, resetErr := resetRepository(repo); nil == resetErr {
-			mergeResult, trafficStat, err = repo.Sync(syncContext)
-		}
-	}
 	elapsed := time.Since(start)
 	if nil != err {
 		autoSyncErrCount++
@@ -1528,19 +1550,7 @@ func indexRepoBeforeCloudSync(repo *dejavu.Repo) (beforeIndex, afterIndex *entit
 	afterIndex, err = repo.Index("[Sync] Cloud sync", map[string]interface{}{
 		eventbus.CtxPushMsg: eventbus.CtxPushMsgToStatusBar,
 	})
-	if errors.Is(err, dejavu.ErrNotFoundObject) {
-		var resetErr error
-		afterIndex, resetErr = resetRepository(repo)
-		if nil != resetErr {
-			return
-		}
-		err = nil
-	}
-
 	if nil != err {
-		msg := fmt.Sprintf(Conf.Language(140), formatRepoErrorMsg(err))
-		util.PushStatusBar(msg)
-		util.PushErrMsg(msg, 12000)
 		logging.LogErrorf("index data repo before cloud sync failed: %s", err)
 		return
 	}
@@ -1579,25 +1589,6 @@ func indexRepoBeforeCloudSync(repo *dejavu.Repo) (beforeIndex, afterIndex *entit
 	return
 }
 
-func resetRepository(repo *dejavu.Repo) (index *entity.Index, err error) {
-	logging.LogWarnf("data repo is corrupted, try to reset it")
-	err = os.RemoveAll(filepath.Join(repo.Path))
-	if nil != err {
-		logging.LogErrorf("remove data repo failed: %s", err)
-		return
-	}
-	index, err = repo.Index("[Sync] Cloud sync", map[string]interface{}{
-		eventbus.CtxPushMsg: eventbus.CtxPushMsgToStatusBar,
-	})
-	logging.LogWarnf("data repo has been reset")
-
-	go func() {
-		time.Sleep(5 * time.Second)
-		util.PushMsg(Conf.Language(105), 5000)
-	}()
-	return
-}
-
 func newRepository() (ret *dejavu.Repo, err error) {
 	cloudConf, err := buildCloudConf()
 	if nil != err {

+ 0 - 1
kernel/model/sync.go

@@ -221,7 +221,6 @@ func syncData(exit, byHand bool) {
 			logging.LogErrorf("write websocket message failed: %v", writeErr)
 		}
 	}
-
 	return
 }