From 32b8b976be4d43ca9ad8825e4f7b4beab0b25b6f Mon Sep 17 00:00:00 2001 From: PiEgg Date: Wed, 30 Sep 2020 17:32:35 +0800 Subject: [PATCH] :sparkles: Feature(config): auto configuration backup & fallback to avoid main process crash ISSUES CLOSED: #568 --- src/main/lifeCycle/index.ts | 12 +++++- src/universal/datastore/dbChecker.ts | 55 ++++++++++++++++++++++++++++ src/universal/datastore/index.ts | 3 ++ src/universal/types/electron.d.ts | 1 + src/universal/types/types.d.ts | 6 +++ 5 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 src/universal/datastore/dbChecker.ts diff --git a/src/main/lifeCycle/index.ts b/src/main/lifeCycle/index.ts index a9c77df30..7650b6e1d 100644 --- a/src/main/lifeCycle/index.ts +++ b/src/main/lifeCycle/index.ts @@ -1,7 +1,9 @@ import { app, globalShortcut, - protocol + protocol, + dialog, + Notification } from 'electron' import { createProtocol, @@ -75,6 +77,14 @@ class LifeCycle { } } } + + if (global.notificationList?.length > 0) { + while (global.notificationList.length) { + const option = global.notificationList.pop() + const notice = new Notification(option!) + notice.show() + } + } }) } private onRunning () { diff --git a/src/universal/datastore/dbChecker.ts b/src/universal/datastore/dbChecker.ts new file mode 100644 index 000000000..ab7830800 --- /dev/null +++ b/src/universal/datastore/dbChecker.ts @@ -0,0 +1,55 @@ +import fs from 'fs-extra' +import path from 'path' +import { app } from 'electron' +import dayjs from 'dayjs' + +const errorMsg = { + broken: 'PicGo 配置文件损坏,已经恢复为默认配置', + brokenButBackup: 'PicGo 配置文件损坏,已经恢复为备份配置' +} + +function dbChecker () { + if (process.type !== 'renderer') { + if (!global.notificationList) global.notificationList = [] + const STORE_PATH = app.getPath('userData') + const configFilePath = path.join(STORE_PATH, 'data.json') + const configFileBackupPath = path.join(STORE_PATH, 'data.bak.json') + if (!fs.existsSync(configFilePath)) { + return + } + let configFile: string = '' + let optionsTpl = { + title: '注意', + body: '' + } + try { + configFile = fs.readFileSync(configFilePath, { encoding: 'utf-8' }) + JSON.parse(configFile) + } catch (e) { + fs.unlinkSync(configFilePath) + if (fs.existsSync(configFileBackupPath)) { + try { + configFile = fs.readFileSync(configFileBackupPath, { encoding: 'utf-8' }) + JSON.parse(configFile) + fs.writeFileSync(configFilePath, configFile, { encoding: 'utf-8' }) + const stats = fs.statSync(configFileBackupPath) + optionsTpl.body = `${errorMsg.brokenButBackup}\n备份文件版本:${dayjs(stats.mtime).format('YYYY-MM-DD HH:mm:ss')}` + global.notificationList.push(optionsTpl) + return + } catch (e) { + optionsTpl.body = errorMsg.broken + global.notificationList.push(optionsTpl) + return + } + } + optionsTpl.body = errorMsg.broken + global.notificationList.push(optionsTpl) + return + } + fs.writeFileSync(configFileBackupPath, configFile, { encoding: 'utf-8' }) + } +} + +export { + dbChecker +} diff --git a/src/universal/datastore/index.ts b/src/universal/datastore/index.ts index 2c1f0399d..e447cbe34 100644 --- a/src/universal/datastore/index.ts +++ b/src/universal/datastore/index.ts @@ -5,6 +5,7 @@ import FileSync from 'lowdb/adapters/FileSync' import path from 'path' import fs from 'fs-extra' import { remote, app } from 'electron' +import { dbChecker } from './dbChecker' const APP = process.type === 'renderer' ? remote.app : app const STORE_PATH = APP.getPath('userData') @@ -15,6 +16,8 @@ if (process.type !== 'renderer') { } } +dbChecker() + class DB { private db: Datastore.LowdbSync constructor () { diff --git a/src/universal/types/electron.d.ts b/src/universal/types/electron.d.ts index 66658b63a..e58312d21 100644 --- a/src/universal/types/electron.d.ts +++ b/src/universal/types/electron.d.ts @@ -27,6 +27,7 @@ declare global { interface Global { PICGO_GUI_VERSION: string PICGO_CORE_VERSION: string + notificationList: IAppNotification[] } } } diff --git a/src/universal/types/types.d.ts b/src/universal/types/types.d.ts index 3d2305ef5..a68a21436 100644 --- a/src/universal/types/types.d.ts +++ b/src/universal/types/types.d.ts @@ -279,3 +279,9 @@ interface IUpYunConfig { } type ILoggerType = string | Error | boolean | number | undefined + +interface IAppNotification { + title: string + body: string + icon?: string +}