mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-19 06:30:10 +08:00
refactor: Extract notes backup and restore logic into separate methods
Extract the notes backup and restore logic from the main backup() and restore() methods into separate private methods for better code clarity and maintainability. - Add backupExternalNotes() method to handle backing up notes from external locations - Add restoreExternalNotes() method to handle restoring notes to configured locations - Both methods properly handle JSON parsing, path expansion, and file operations - Maintains all existing functionality and error handling - All tests pass successfully This refactoring addresses PR review feedback requesting clearer separation of concerns. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
4269a32cfb
commit
6919abf833
@ -248,41 +248,7 @@ class BackupManager {
|
||||
await this.setWritableRecursive(tempDataDir)
|
||||
|
||||
// 检查并备份 notes 目录(如果配置在 Data 目录外)
|
||||
try {
|
||||
const backupData = JSON.parse(data)
|
||||
const persistData = JSON.parse(backupData.localStorage?.['persist:cherry-studio'] || '{}')
|
||||
const noteState = JSON.parse(persistData.note || '{}')
|
||||
const notesPath = noteState.notesPath
|
||||
|
||||
if (notesPath) {
|
||||
// 展开路径获取绝对路径
|
||||
const expandedNotesPath = expandNotesPath(notesPath)
|
||||
const dataPath = path.join(app.getPath('userData'), 'Data')
|
||||
const normalizedDataPath = path.normalize(dataPath)
|
||||
const normalizedNotesPath = path.normalize(expandedNotesPath)
|
||||
|
||||
// 检查 notes 是否在 Data 目录外
|
||||
const isOutsideData =
|
||||
!normalizedNotesPath.startsWith(normalizedDataPath + path.sep) &&
|
||||
normalizedNotesPath !== normalizedDataPath
|
||||
|
||||
if (isOutsideData && fs.existsSync(expandedNotesPath)) {
|
||||
logger.info(`Backing up notes from external location: ${expandedNotesPath}`)
|
||||
const tempNotesDir = path.join(this.tempDir, 'Notes')
|
||||
await this.copyDirWithProgress(expandedNotesPath, tempNotesDir, (size) => {
|
||||
// Notes backup progress from 45% to 50%
|
||||
copiedSize += size
|
||||
const notesProgress = 45 + Math.min(5, Math.floor((size / totalSize) * 5))
|
||||
onProgress({ stage: 'copying_notes', progress: notesProgress, total: 100 })
|
||||
})
|
||||
await this.setWritableRecursive(tempNotesDir)
|
||||
logger.info('External notes directory backed up successfully')
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// 如果解析失败或获取 notes 路径失败,继续备份其他内容
|
||||
logger.warn('Failed to parse notes path from backup data, skipping external notes backup', error as Error)
|
||||
}
|
||||
await this.backupExternalNotes(data, onProgress, totalSize, copiedSize)
|
||||
|
||||
onProgress({ stage: 'preparing_compression', progress: 50, total: 100 })
|
||||
} else {
|
||||
@ -447,42 +413,7 @@ class BackupManager {
|
||||
|
||||
// 检查并恢复外部 Notes 目录
|
||||
logger.debug('step 3.5: check and restore external Notes directory')
|
||||
const notesBackupPath = path.join(this.tempDir, 'Notes')
|
||||
const notesExists = await fs.pathExists(notesBackupPath)
|
||||
|
||||
if (notesExists) {
|
||||
try {
|
||||
// 从 data.json 中获取 notes 路径配置
|
||||
const backupData = JSON.parse(data)
|
||||
const persistData = JSON.parse(backupData.localStorage?.['persist:cherry-studio'] || '{}')
|
||||
const noteState = JSON.parse(persistData.note || '{}')
|
||||
const notesPath = noteState.notesPath
|
||||
|
||||
if (notesPath) {
|
||||
const expandedNotesPath = expandNotesPath(notesPath)
|
||||
logger.info(`Restoring notes to configured location: ${expandedNotesPath}`)
|
||||
|
||||
// 确保目标目录的父目录存在
|
||||
await fs.ensureDir(path.dirname(expandedNotesPath))
|
||||
|
||||
// 如果目标已存在,先删除
|
||||
if (await fs.pathExists(expandedNotesPath)) {
|
||||
await this.setWritableRecursive(expandedNotesPath)
|
||||
await fs.remove(expandedNotesPath)
|
||||
}
|
||||
|
||||
// 复制 Notes 目录
|
||||
await this.copyDirWithProgress(notesBackupPath, expandedNotesPath, (size) => {
|
||||
const progress = Math.min(85, 75 + Math.floor(size / 1000000))
|
||||
onProgress({ stage: 'copying_notes', progress, total: 100 })
|
||||
})
|
||||
|
||||
logger.info('External notes directory restored successfully')
|
||||
}
|
||||
} catch (error) {
|
||||
logger.warn('Failed to restore external notes directory', error as Error)
|
||||
}
|
||||
}
|
||||
await this.restoreExternalNotes(data, onProgress)
|
||||
|
||||
logger.debug('step 4: clean up temp directory')
|
||||
// 清理临时目录
|
||||
@ -592,6 +523,103 @@ class BackupManager {
|
||||
return size
|
||||
}
|
||||
|
||||
/**
|
||||
* Backup external notes directory if configured outside Data folder
|
||||
* @param data - The backup data JSON string
|
||||
* @param onProgress - Progress callback function
|
||||
* @param totalSize - Total size of Data directory for progress calculation
|
||||
* @param copiedSize - Current copied size for progress offset
|
||||
*/
|
||||
private async backupExternalNotes(
|
||||
data: string,
|
||||
onProgress: (processData: { stage: string; progress: number; total: number }) => void,
|
||||
totalSize: number,
|
||||
copiedSize: number
|
||||
): Promise<void> {
|
||||
try {
|
||||
const backupData = JSON.parse(data)
|
||||
const persistData = JSON.parse(backupData.localStorage?.['persist:cherry-studio'] || '{}')
|
||||
const noteState = JSON.parse(persistData.note || '{}')
|
||||
const notesPath = noteState.notesPath
|
||||
|
||||
if (notesPath) {
|
||||
// 展开路径获取绝对路径
|
||||
const expandedNotesPath = expandNotesPath(notesPath)
|
||||
const dataPath = path.join(app.getPath('userData'), 'Data')
|
||||
const normalizedDataPath = path.normalize(dataPath)
|
||||
const normalizedNotesPath = path.normalize(expandedNotesPath)
|
||||
|
||||
// 检查 notes 是否在 Data 目录外
|
||||
const isOutsideData =
|
||||
!normalizedNotesPath.startsWith(normalizedDataPath + path.sep) &&
|
||||
normalizedNotesPath !== normalizedDataPath
|
||||
|
||||
if (isOutsideData && fs.existsSync(expandedNotesPath)) {
|
||||
logger.info(`Backing up notes from external location: ${expandedNotesPath}`)
|
||||
const tempNotesDir = path.join(this.tempDir, 'Notes')
|
||||
await this.copyDirWithProgress(expandedNotesPath, tempNotesDir, (size) => {
|
||||
// Notes backup progress from 45% to 50%
|
||||
copiedSize += size
|
||||
const notesProgress = 45 + Math.min(5, Math.floor((size / totalSize) * 5))
|
||||
onProgress({ stage: 'copying_notes', progress: notesProgress, total: 100 })
|
||||
})
|
||||
await this.setWritableRecursive(tempNotesDir)
|
||||
logger.info('External notes directory backed up successfully')
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// 如果解析失败或获取 notes 路径失败,继续备份其他内容
|
||||
logger.warn('Failed to parse notes path from backup data, skipping external notes backup', error as Error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore external notes directory from backup
|
||||
* @param data - The backup data JSON string
|
||||
* @param onProgress - Progress callback function
|
||||
*/
|
||||
private async restoreExternalNotes(
|
||||
data: string,
|
||||
onProgress: (processData: { stage: string; progress: number; total: number }) => void
|
||||
): Promise<void> {
|
||||
const notesBackupPath = path.join(this.tempDir, 'Notes')
|
||||
const notesExists = await fs.pathExists(notesBackupPath)
|
||||
|
||||
if (notesExists) {
|
||||
try {
|
||||
// 从 data.json 中获取 notes 路径配置
|
||||
const backupData = JSON.parse(data)
|
||||
const persistData = JSON.parse(backupData.localStorage?.['persist:cherry-studio'] || '{}')
|
||||
const noteState = JSON.parse(persistData.note || '{}')
|
||||
const notesPath = noteState.notesPath
|
||||
|
||||
if (notesPath) {
|
||||
const expandedNotesPath = expandNotesPath(notesPath)
|
||||
logger.info(`Restoring notes to configured location: ${expandedNotesPath}`)
|
||||
|
||||
// 确保目标目录的父目录存在
|
||||
await fs.ensureDir(path.dirname(expandedNotesPath))
|
||||
|
||||
// 如果目标已存在,先删除
|
||||
if (await fs.pathExists(expandedNotesPath)) {
|
||||
await this.setWritableRecursive(expandedNotesPath)
|
||||
await fs.remove(expandedNotesPath)
|
||||
}
|
||||
|
||||
// 复制 Notes 目录
|
||||
await this.copyDirWithProgress(notesBackupPath, expandedNotesPath, (size) => {
|
||||
const progress = Math.min(85, 75 + Math.floor(size / 1000000))
|
||||
onProgress({ stage: 'copying_notes', progress, total: 100 })
|
||||
})
|
||||
|
||||
logger.info('External notes directory restored successfully')
|
||||
}
|
||||
} catch (error) {
|
||||
logger.warn('Failed to restore external notes directory', error as Error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async copyDirWithProgress(
|
||||
source: string,
|
||||
destination: string,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user