diff --git a/public/i18n/en.yml b/public/i18n/en.yml
index 650917a..caf0374 100644
--- a/public/i18n/en.yml
+++ b/public/i18n/en.yml
@@ -252,6 +252,18 @@ SETTINGS_SYNC_CONFIG_GITEE_BRANCH_PLACEHOLDER: Please enter Gitee branch name
SETTINGS_SYNC_CONFIG_GITHUB_TOKEN_PLACEHOLDER: Please enter GitHub Token
SETTINGS_SYNC_CONFIG_GITEE_TOKEN_PLACEHOLDER: Please enter Gitee Token
SETTINGS_SYNC_CONFIG_PROXY_PLACEHOLDER: Please enter proxy
+SETTINGS_UP_DOWN_DESC: Upload and download configuration files
+SETTINGS_UP_DOWN_TITLE: Please use this after filled the synchronization configuration
+SETTINGS_SYNC_UPLOAD: Upload
+SETTINGS_SYNC_DOWNLOAD: Download
+SETTINGS_SYNC_UPLOAD_ALL: Upload all
+SETTINGS_SYNC_DOWNLOAD_ALL: Download all
+SETTINGS_SYNC_UPLOAD_SUCCESS: Successfully uploaded
+SETTINGS_SYNC_UPLOAD_FAILED: Upload failed
+SETTINGS_SYNC_DOWNLOAD_SUCCESS: Successfully downloaded
+SETTINGS_SYNC_DOWNLOAD_FAILED: Download failed
+SETTINGS_SYNC_COMMON_CONFIG: Common configuration
+SETTINGS_SYNC_MANAGE_CONFIG: Manage configuration
SETTINGS_AUTO_IMPORT: Auto import config in manage page
# shortcut-page
diff --git a/public/i18n/zh-CN.yml b/public/i18n/zh-CN.yml
index 76629ad..f5e4d63 100644
--- a/public/i18n/zh-CN.yml
+++ b/public/i18n/zh-CN.yml
@@ -255,6 +255,18 @@ SETTINGS_SYNC_CONFIG_GITEE_BRANCH_PLACEHOLDER: 请输入Gitee分支名
SETTINGS_SYNC_CONFIG_GITHUB_TOKEN_PLACEHOLDER: 请输入GitHub Token
SETTINGS_SYNC_CONFIG_GITEE_TOKEN_PLACEHOLDER: 请输入Gitee Token
SETTINGS_SYNC_CONFIG_PROXY_PLACEHOLDER: 请输入代理地址
+SETTINGS_UP_DOWN_DESC: 上传下载配置文件
+SETTINGS_UP_DOWN_TITLE: 请在设置完同步配置后使用
+SETTINGS_SYNC_UPLOAD: 上传
+SETTINGS_SYNC_DOWNLOAD: 下载
+SETTINGS_SYNC_UPLOAD_ALL: 上传所有
+SETTINGS_SYNC_DOWNLOAD_ALL: 下载所有
+SETTINGS_SYNC_UPLOAD_SUCCESS: 上传成功
+SETTINGS_SYNC_UPLOAD_FAILED: 上传失败
+SETTINGS_SYNC_DOWNLOAD_SUCCESS: 下载成功
+SETTINGS_SYNC_DOWNLOAD_FAILED: 下载失败
+SETTINGS_SYNC_COMMON_CONFIG: 通用配置
+SETTINGS_SYNC_MANAGE_CONFIG: 管理配置
SETTINGS_AUTO_IMPORT: 管理页面自动导入配置
# shortcut-page
diff --git a/public/i18n/zh-TW.yml b/public/i18n/zh-TW.yml
index 6097b77..394800e 100644
--- a/public/i18n/zh-TW.yml
+++ b/public/i18n/zh-TW.yml
@@ -253,6 +253,18 @@ SETTINGS_SYNC_CONFIG_GITEE_BRANCH_PLACEHOLDER: 請輸入 Gitee 分支名稱
SETTINGS_SYNC_CONFIG_GITHUB_TOKEN_PLACEHOLDER: 請輸入 GitHub Token
SETTINGS_SYNC_CONFIG_GITEE_TOKEN_PLACEHOLDER: 請輸入 Gitee Token
SETTINGS_SYNC_CONFIG_PROXY_PLACEHOLDER: 請輸入代理地址
+SETTINGS_UP_DOWN_DESC: 上傳和下載配置檔案
+SETTINGS_UP_DOWN_TITLE: 請在設置完同步配置後再使用
+SETTINGS_SYNC_UPLOAD: 上傳
+SETTINGS_SYNC_DOWNLOAD: 下載
+SETTINGS_SYNC_UPLOAD_ALL: 上傳全部
+SETTINGS_SYNC_DOWNLOAD_ALL: 下載全部
+SETTINGS_SYNC_UPLOAD_SUCCESS: 上傳成功
+SETTINGS_SYNC_UPLOAD_FAILED: 上傳失敗
+SETTINGS_SYNC_DOWNLOAD_SUCCESS: 下載成功
+SETTINGS_SYNC_DOWNLOAD_FAILED: 下載失敗
+SETTINGS_SYNC_COMMON_CONFIG: 通用配置
+SETTINGS_SYNC_MANAGE_CONFIG: 管理配置
SETTINGS_AUTO_IMPORT: 管理頁面自動導入配置
# shortcut-page
diff --git a/src/main/events/ipcList.ts b/src/main/events/ipcList.ts
index 51f52d4..d4c97b6 100644
--- a/src/main/events/ipcList.ts
+++ b/src/main/events/ipcList.ts
@@ -44,6 +44,7 @@ import { buildMainPageMenu, buildMiniPageMenu, buildPluginPageMenu, buildPicBedL
import path from 'path'
import { T } from '~/main/i18n'
import { generateShortUrl } from '~/universal/utils/common'
+import { uploadFile, downloadFile } from '../utils/syncSettings'
const STORE_PATH = app.getPath('userData')
@@ -164,6 +165,46 @@ export default {
return shortUrl
})
+ ipcMain.handle('uploadCommonConfig', async () => {
+ const dataResult = await uploadFile('data.json')
+ const bakResult = await uploadFile('data.bak.json')
+ return dataResult + bakResult
+ })
+
+ ipcMain.handle('downloadCommonConfig', async () => {
+ const dataResult = await downloadFile('data.json')
+ const bakResult = await downloadFile('data.bak.json')
+ return dataResult + bakResult
+ })
+
+ ipcMain.handle('uploadManageConfig', async () => {
+ const manageResult = await uploadFile('manage.json')
+ const bakResult = await uploadFile('manage.bak.json')
+ return manageResult + bakResult
+ })
+
+ ipcMain.handle('downloadManageConfig', async () => {
+ const manageResult = await downloadFile('manage.json')
+ const bakResult = await downloadFile('manage.bak.json')
+ return manageResult + bakResult
+ })
+
+ ipcMain.handle('uploadAllConfig', async () => {
+ const dataResult = await uploadFile('data.json')
+ const bakResult = await uploadFile('data.bak.json')
+ const manageResult = await uploadFile('manage.json')
+ const manageBakResult = await uploadFile('manage.bak.json')
+ return dataResult + bakResult + manageResult + manageBakResult
+ })
+
+ ipcMain.handle('downloadAllConfig', async () => {
+ const dataResult = await downloadFile('data.json')
+ const bakResult = await downloadFile('data.bak.json')
+ const manageResult = await downloadFile('manage.json')
+ const manageBakResult = await downloadFile('manage.bak.json')
+ return dataResult + bakResult + manageResult + manageBakResult
+ })
+
ipcMain.on('openSettingWindow', () => {
windowManager.get(IWindowList.SETTING_WINDOW)!.show()
if (windowManager.has(IWindowList.MINI_WINDOW)) {
diff --git a/src/main/lifeCycle/index.ts b/src/main/lifeCycle/index.ts
index a0756fc..2db337d 100644
--- a/src/main/lifeCycle/index.ts
+++ b/src/main/lifeCycle/index.ts
@@ -48,7 +48,6 @@ import clipboardPoll from '../utils/clipboardPoll'
import path from 'path'
import { CLIPBOARD_IMAGE_FOLDER } from '~/universal/utils/static'
import fs from 'fs-extra'
-import { syncInterval } from '../utils/syncSettings'
const isDevelopment = process.env.NODE_ENV !== 'production'
const handleStartUpFiles = (argv: string[], cwd: string) => {
@@ -202,7 +201,6 @@ class LifeCycle {
}
const clipboardDir = path.join(picgo.baseDir, CLIPBOARD_IMAGE_FOLDER)
fs.ensureDir(clipboardDir)
- syncInterval()
}
app.whenReady().then(readyFunction)
}
diff --git a/src/main/utils/syncSettings.ts b/src/main/utils/syncSettings.ts
index 6efdd10..ee523c6 100644
--- a/src/main/utils/syncSettings.ts
+++ b/src/main/utils/syncSettings.ts
@@ -46,7 +46,7 @@ function getOctokit (syncConfig: SyncConfig) {
}
function getSyncConfig () {
- const syncConfig = db.get('settings.sync') || {
+ return db.get('settings.sync') || {
type: 'github',
username: '',
repo: '',
@@ -54,7 +54,6 @@ function getSyncConfig () {
token: '',
proxy: ''
}
- return syncConfig
}
function syncConfigValidator (syncConfig: SyncConfig) {
@@ -62,67 +61,6 @@ function syncConfigValidator (syncConfig: SyncConfig) {
return type && username && repo && branch && token
}
-async function getModifiedTime (syncConfig: SyncConfig, filePath: string) {
- const { username, repo, branch, token, type } = syncConfig
- if (type === 'gitee') {
- const url = `https://gitee.com/api/v5/repos/${username}/${repo}/commits`
- const res = await axios.get(url, {
- params: {
- access_token: token,
- ref: branch,
- path: filePath
- }
- })
- const data = res.data
- if (data.length > 0) {
- return data[0].commit.committer.date
- } else {
- return null
- }
- } else {
- const octokit = getOctokit(syncConfig)
- try {
- const res = await octokit.rest.repos.listCommits({
- owner: username,
- repo,
- ref: branch,
- path: filePath,
- per_page: 1
- })
- if (res.status === 200) {
- return res.data.length > 0 ? res.data[0].commit.committer?.date : null
- } else {
- return null
- }
- } catch (error: any) {
- logger.error(error)
- return null
- }
- }
-}
-
-async function getModifiedTimeOfLocal (filePath: string) {
- if (!fs.existsSync(filePath)) {
- return new Date(0)
- }
- const stat = await fs.stat(filePath)
- return stat.mtime
-}
-
-async function compareNewerFile (syncConfig: SyncConfig, fileName: string): Promise<'upload' | 'download' | 'update' | undefined> {
- const localFilePath = path.join(STORE_PATH, fileName)
- const remoteModifiedTime = await getModifiedTime(syncConfig, fileName)
- if (remoteModifiedTime === null) {
- return 'upload'
- }
- const localModifiedTime = await getModifiedTimeOfLocal(localFilePath)
- if (remoteModifiedTime && localModifiedTime) {
- return Date.parse(remoteModifiedTime) > localModifiedTime.getTime() ? 'download' : 'update'
- } else {
- throw new Error('get modified time failed')
- }
-}
-
async function uploadLocalToRemote (syncConfig: SyncConfig, fileName: string) {
const localFilePath = path.join(STORE_PATH, fileName)
if (!fs.existsSync(localFilePath)) {
@@ -130,14 +68,19 @@ async function uploadLocalToRemote (syncConfig: SyncConfig, fileName: string) {
}
const { username, repo, branch, token, type } = syncConfig
if (type === 'gitee') {
- const url = `https://gitee.com/api/v5/repos/${username}/${repo}/contents/${fileName}`
- const res = await axios.post(url, {
- access_token: token,
- branch,
- content: fs.readFileSync(localFilePath, { encoding: 'base64' }),
- message: `upload ${fileName} from PicList`
- })
- return res.status >= 200 && res.status < 300
+ try {
+ const url = `https://gitee.com/api/v5/repos/${username}/${repo}/contents/${fileName}`
+ const res = await axios.post(url, {
+ access_token: token,
+ branch,
+ content: fs.readFileSync(localFilePath, { encoding: 'base64' }),
+ message: `upload ${fileName} from PicList`
+ })
+ return res.status >= 200 && res.status < 300
+ } catch (error: any) {
+ logger.error(error)
+ return false
+ }
} else {
const octokit = getOctokit(syncConfig)
try {
@@ -269,65 +212,78 @@ async function downloadRemoteToLocal (syncConfig: SyncConfig, fileName: string)
}
}
-async function syncFile (syncConfig: SyncConfig, fileName: string) {
- const compareResult = await compareNewerFile(syncConfig, fileName)
- let result = false
- if (compareResult === 'upload') {
- result = await uploadLocalToRemote(syncConfig, fileName)
- } else if (compareResult === 'update') {
- try {
- result = await updateLocalToRemote(syncConfig, fileName)
- } catch (error: any) {
- result = await uploadLocalToRemote(syncConfig, fileName)
- }
- } else if (compareResult === 'download') {
- result = await downloadRemoteToLocal(syncConfig, fileName)
+async function uploadFile (fileName: string, all = false) {
+ const syncConfig = getSyncConfig()
+ if (!syncConfigValidator(syncConfig)) {
+ logger.error('sync config is invalid')
+ return 0
}
- return result
-}
-
-async function syncAllFiles (syncConfig: SyncConfig) {
- for (const file of configFileNames) {
- try {
- const result = await syncFile(syncConfig, file)
+ let successCount = 0
+ if (all) {
+ for (const file of configFileNames) {
+ const result = await uploadFunc(syncConfig, file)
if (result) {
- logger.info(`sync file ${file} success`)
- } else {
- logger.error(`sync file ${file} failed`)
+ successCount++
}
- } catch (error: any) {
- logger.error(`sync file ${file} failed`)
- logger.error(error)
}
+ logger.info(`upload all files at ${new Date().toLocaleString()}`)
+ return successCount
+ } else {
+ const ressult = await uploadFunc(syncConfig, fileName)
+ return ressult ? 1 : 0
}
}
-async function syncFunc () {
- const syncConfig = await getSyncConfig()
- if (!syncConfigValidator(syncConfig)) {
- return
+async function uploadFunc (syncConfig: SyncConfig, fileName: string) {
+ let result = false
+ try {
+ result = await updateLocalToRemote(syncConfig, fileName)
+ } catch (error: any) {
+ result = await uploadLocalToRemote(syncConfig, fileName)
+ }
+ if (!result) {
+ logger.error(`upload ${fileName} failed`)
+ return false
+ } else {
+ logger.info(`upload ${fileName} success`)
+ return true
}
- await syncAllFiles(syncConfig)
- logger.info(`sync all files at ${new Date().toLocaleString()}`)
}
-async function syncInterval () {
- const syncConfig = await getSyncConfig()
+async function downloadFile (fileName: string, all = false) {
+ const syncConfig = getSyncConfig()
if (!syncConfigValidator(syncConfig)) {
- return
+ logger.error('sync config is invalid')
+ return 0
}
- const syncFunc = async () => {
- await syncAllFiles(syncConfig)
- logger.info(`sync all files at ${new Date().toLocaleString()}`)
+ if (all) {
+ let successCount = 0
+ for (const file of configFileNames) {
+ const result = await downloadFunc(syncConfig, file)
+ if (result) {
+ successCount++
+ }
+ }
+ logger.info(`download all files at ${new Date().toLocaleString()}`)
+ return successCount
+ } else {
+ const result = await downloadFunc(syncConfig, fileName)
+ return result ? 1 : 0
+ }
+}
+
+async function downloadFunc (syncConfig: SyncConfig, fileName: string) {
+ const result = await downloadRemoteToLocal(syncConfig, fileName)
+ if (!result) {
+ logger.error(`download ${fileName} failed`)
+ return false
+ } else {
+ logger.info(`download ${fileName} success`)
+ return true
}
- await syncFunc()
- const interval = Number(syncConfig.interval) || 60
- setInterval(async () => {
- syncFunc()
- }, 1000 * 60 * interval)
}
export {
- syncFunc,
- syncInterval
+ uploadFile,
+ downloadFile
}
diff --git a/src/renderer/pages/PicGoSetting.vue b/src/renderer/pages/PicGoSetting.vue
index 20b4e69..fc91dab 100644
--- a/src/renderer/pages/PicGoSetting.vue
+++ b/src/renderer/pages/PicGoSetting.vue
@@ -99,6 +99,18 @@
{{ $T('SETTINGS_CLICK_TO_SET') }}
+
+
+ {{ $T('SETTINGS_CLICK_TO_SET') }}
+
+
@@ -818,15 +830,6 @@
:placeholder="$T('SETTINGS_SYNC_CONFIG_PROXY_PLACEHOLDER')"
/>
-
-
-
+
+
+
+
+
+ {{ $T('SETTINGS_SYNC_COMMON_CONFIG') }}
+
+
+ {{ $T('SETTINGS_SYNC_MANAGE_CONFIG') }}
+
+
+ {{ $T('SETTINGS_SYNC_UPLOAD_ALL') }}
+
+
+
+
+
+
+ {{ $T('SETTINGS_SYNC_COMMON_CONFIG') }}
+
+
+ {{ $T('SETTINGS_SYNC_MANAGE_CONFIG') }}
+
+
+ {{ $T('SETTINGS_SYNC_DOWNLOAD_ALL') }}
+
+
+
+
+
{
- return sync.value.username && sync.value.repo && sync.value.branch && sync.value.token
-})
-
async function cancelSyncSetting () {
syncVisible.value = false
sync.value = await getConfig('settings.sync') || {
@@ -1309,9 +1382,6 @@ function confirmSyncSetting () {
'settings.sync': sync.value
})
syncVisible.value = false
- if (allSynFilled.value) {
- sendRPC(IRPCActionType.RELOAD_APP)
- }
}
const version = pkg.version
@@ -1674,6 +1744,66 @@ async function cancelLogLevelSetting () {
form.logFileSizeLimit = logFileSizeLimit
}
+function DownMessage (failed: number) {
+ if (failed) {
+ $message.error($T('SETTINGS_SYNC_DOWNLOAD_FAILED', { failed }))
+ } else {
+ $message.success($T('SETTINGS_SYNC_DOWNLOAD_SUCCESS'))
+ }
+}
+
+function upMessage (failed: number) {
+ if (failed) {
+ $message.error($T('SETTINGS_SYNC_UPLOAD_FAILED', { failed }))
+ } else {
+ $message.success($T('SETTINGS_SYNC_UPLOAD_SUCCESS'))
+ }
+}
+
+async function uploadCommonConfig () {
+ const result = await invokeToMain('uploadCommonConfig')
+ const failed = 2 - result
+ upMessage(failed)
+}
+
+async function downloadCommonConfig () {
+ const result = await invokeToMain('downloadCommonConfig')
+ const failed = 2 - result
+ DownMessage(failed)
+}
+
+async function uploadManageConfig () {
+ const result = await invokeToMain('uploadManageConfig')
+ const failed = 2 - result
+ upMessage(failed)
+}
+
+async function downloadManageConfig () {
+ const result = await invokeToMain('downloadManageConfig')
+ const failed = 2 - result
+ DownMessage(failed)
+}
+
+async function uploadAll () {
+ const result = await invokeToMain('uploadAllConfig')
+ const failed = 4 - result
+ if (result === 4) {
+ $message.success($T('SETTINGS_SYNC_UPLOAD_SUCCESS'))
+ } else {
+ $message.error($T('SETTINGS_SYNC_UPLOAD_FAILED') + `(${failed})`)
+ }
+}
+
+async function downloadAll () {
+ const result = await invokeToMain('downloadAllConfig')
+ const failed = 4 - result
+ if (result === 4) {
+ $message.success($T('SETTINGS_SYNC_DOWNLOAD_SUCCESS'))
+ } else {
+ $message.error($T('SETTINGS_SYNC_DOWNLOAD_FAILED') + `(${failed})`)
+ }
+}
+
function confirmServerSetting () {
server.value.port = parseInt(server.value.port as unknown as string, 10)
saveConfig({
diff --git a/src/universal/types/i18n.d.ts b/src/universal/types/i18n.d.ts
index df45647..cb6e517 100644
--- a/src/universal/types/i18n.d.ts
+++ b/src/universal/types/i18n.d.ts
@@ -248,6 +248,18 @@ interface ILocales {
SETTINGS_SYNC_CONFIG_GITHUB_TOKEN_PLACEHOLDER: string
SETTINGS_SYNC_CONFIG_GITEE_TOKEN_PLACEHOLDER: string
SETTINGS_SYNC_CONFIG_PROXY_PLACEHOLDER: string
+ SETTINGS_UP_DOWN_DESC: string
+ SETTINGS_UP_DOWN_TITLE: string
+ SETTINGS_SYNC_UPLOAD: string
+ SETTINGS_SYNC_DOWNLOAD: string
+ SETTINGS_SYNC_UPLOAD_ALL: string
+ SETTINGS_SYNC_DOWNLOAD_ALL: string
+ SETTINGS_SYNC_UPLOAD_SUCCESS: string
+ SETTINGS_SYNC_UPLOAD_FAILED: string
+ SETTINGS_SYNC_DOWNLOAD_SUCCESS: string
+ SETTINGS_SYNC_DOWNLOAD_FAILED: string
+ SETTINGS_SYNC_COMMON_CONFIG: string
+ SETTINGS_SYNC_MANAGE_CONFIG: string
SETTINGS_AUTO_IMPORT: string
SHORTCUT_NAME: string
SHORTCUT_BIND: string