From adbfae9e07870e1562b9fb509df90e4941664ae5 Mon Sep 17 00:00:00 2001 From: JackGruber <24863925+JackGruber@users.noreply.github.com> Date: Mon, 21 Nov 2022 21:43:47 +0100 Subject: [PATCH 01/15] don't create subfolder when original backup basepath does not exist --- src/Backup.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Backup.ts b/src/Backup.ts index 43be5dc..c956ebd 100644 --- a/src/Backup.ts +++ b/src/Backup.ts @@ -225,8 +225,12 @@ class Backup { if (this.createSubfolder) { this.log.verbose("append subFolder"); + const orgBackupBasePath = this.backupBasePath; this.backupBasePath = path.join(this.backupBasePath, "JoplinBackup"); - if (!fs.existsSync(this.backupBasePath)) { + if ( + fs.existsSync(orgBackupBasePath) && + !fs.existsSync(this.backupBasePath) + ) { try { fs.mkdirSync(this.backupBasePath); } catch (e) { From a07ec18f3eb31dcc5988eb00e30dccf2f1681bd0 Mon Sep 17 00:00:00 2001 From: JackGruber <24863925+JackGruber@users.noreply.github.com> Date: Tue, 22 Nov 2022 20:00:20 +0100 Subject: [PATCH 02/15] Fix async calls --- src/Backup.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Backup.ts b/src/Backup.ts index c956ebd..a532a0c 100644 --- a/src/Backup.ts +++ b/src/Backup.ts @@ -265,7 +265,7 @@ class Backup { (await helper.validFileName(this.backupSetName)) === false ) { this.backupSetName = "{YYYYMMDDHHmm}"; - this.showError( + await this.showError( 'Backup set name does contain not allowed characters ( \\/:*?"<>| )!' ); } @@ -708,7 +708,7 @@ class Backup { file ); } catch (e) { - this.showError("Backup error", format + ": " + e.message); + await this.showError("Backup error", format + ": " + e.message); throw e; } } @@ -990,7 +990,7 @@ class Backup { recursive: true, }); } catch (e) { - this.showError("moveFinishedBackup: " + e.message); + await this.showError("moveFinishedBackup: " + e.message); throw e; } } From 791e0c0493299b9569e3891de4ddce9abfcbe8a1 Mon Sep 17 00:00:00 2001 From: JackGruber <24863925+JackGruber@users.noreply.github.com> Date: Tue, 22 Nov 2022 20:04:30 +0100 Subject: [PATCH 03/15] Fix #47 Suppress repeating error message during automatic execution --- src/Backup.ts | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/Backup.ts b/src/Backup.ts index a532a0c..9bf15b9 100644 --- a/src/Backup.ts +++ b/src/Backup.ts @@ -28,6 +28,7 @@ class Backup { private backupSetName: string; private exportFormat: string; private execFinishCmd: string; + private suppressErrorMsgUntil: number; constructor() { this.log = backupLogging; @@ -50,6 +51,7 @@ class Backup { await sevenZip.updateBinPath(); await sevenZip.setExecutionFlag(); this.backupStartTime = null; + this.suppressErrorMsgUntil = 0; } private async upgradeBackupPluginVersion() { @@ -442,13 +444,32 @@ class Backup { this.log.info("Backup completed"); this.moveLogFile(backupDst); + this.suppressErrorMsgUntil = 0; + if (showDoneMsg === true) { await this.showMsg(`Backup completed`); } } else { - await this.showError( - `The Backup path '${this.backupBasePath}' does not exist!` - ); + const now = new Date(); + + // Show error msg only every x hours on automatic runs + if ( + showDoneMsg === false && + this.suppressErrorMsgUntil > now.getTime() + ) { + this.log.error( + `The Backup path '${this.backupBasePath}' does not exist!` + ); + this.log.info("Error dialog suppressed"); + } else { + await this.showError( + `The Backup path '${this.backupBasePath}' does not exist!` + ); + + if (showDoneMsg === false) { + this.suppressErrorMsgUntil = now.getTime() + 6 * 60 * 60 * 1000; + } + } } this.backupStartTime = null; From dbf9024bb1189a0fdd736cc657b1f47b66ee9022 Mon Sep 17 00:00:00 2001 From: JackGruber <24863925+JackGruber@users.noreply.github.com> Date: Tue, 22 Nov 2022 20:08:17 +0100 Subject: [PATCH 04/15] Add changelog error msg supressing --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2848750..e55e10d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## not released +- Fix: #47 Suppress repeating error message during automatic execution if the backup path is not accessible + ## v1.2.0 (2022-11-20) - Add: Option to select export format between JEX, MD with Frontmatter and RAW (Only supported with Joplin > 2.9.12) From 54712fe73fbcfb6b0092205d2d0f9e325b8a535a Mon Sep 17 00:00:00 2001 From: JackGruber <24863925+JackGruber@users.noreply.github.com> Date: Tue, 6 Dec 2022 20:32:27 +0100 Subject: [PATCH 05/15] Add Settings to logging --- src/Backup.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Backup.ts b/src/Backup.ts index 9bf15b9..2fd6668 100644 --- a/src/Backup.ts +++ b/src/Backup.ts @@ -374,6 +374,8 @@ class Backup { "backupVersion", "backupPlugins", "createSubfolder", + "createSubfolder", + "exportFormat", ]; this.log.verbose("Plugin settings:"); From 32189ea66389fb795254d69e6cf0ea1dbbc91956 Mon Sep 17 00:00:00 2001 From: JackGruber <24863925+JackGruber@users.noreply.github.com> Date: Tue, 6 Dec 2022 20:42:13 +0100 Subject: [PATCH 06/15] add logging infp --- src/Backup.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Backup.ts b/src/Backup.ts index 2fd6668..7bbc6e9 100644 --- a/src/Backup.ts +++ b/src/Backup.ts @@ -1003,6 +1003,11 @@ class Backup { ); } catch (e) { await this.showError("moveFinishedBackup: " + e.message); + this.log.error( + path.join(this.activeBackupPath, file) + + " => " + + path.join(backupDestination, file) + ); throw e; } } From ac94529d49a1fcf3537d4fc5fc115eb899b17c23 Mon Sep 17 00:00:00 2001 From: JackGruber <24863925+JackGruber@users.noreply.github.com> Date: Tue, 6 Dec 2022 20:59:06 +0100 Subject: [PATCH 07/15] add test for existing folder and files --- __test__/backup.test.ts | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/__test__/backup.test.ts b/__test__/backup.test.ts index e7142eb..4a48cae 100644 --- a/__test__/backup.test.ts +++ b/__test__/backup.test.ts @@ -298,6 +298,44 @@ describe("Backup", function () { expect(fs.existsSync(expected)).toBe(true); }); + it(`retention = 1, folder exist with same files and folder`, async () => { + const emptyFolder = path.join(testPath.activeBackupJob, "emptyFolder"); + const emptyFolderCheck = path.join( + testPath.backupBasePath, + "emptyFolder" + ); + const folder = path.join(testPath.activeBackupJob, "folder"); + const folderCheck = path.join(testPath.backupBasePath, "folder"); + const file1 = path.join(folder, "file.txt"); + const file1Check = path.join(folderCheck, "file.txt"); + const file2 = path.join(testPath.activeBackupJob, "file.txt"); + const file2Check = path.join(testPath.backupBasePath, "file.txt"); + backup.backupBasePath = testPath.backupBasePath; + backup.activeBackupPath = testPath.activeBackupJob; + + fs.emptyDirSync(testPath.backupBasePath); + fs.emptyDirSync(emptyFolderCheck); + fs.emptyDirSync(folderCheck); + fs.writeFileSync(file1Check, "old file"); + fs.writeFileSync(file2Check, "old file"); + + fs.emptyDirSync(testPath.activeBackupJob); + fs.emptyDirSync(emptyFolder); + fs.emptyDirSync(folder); + fs.writeFileSync(file1, "new file"); + fs.writeFileSync(file2, "new file"); + + backup.backupRetention = 1; + + expect(await backup.moveFinishedBackup()).toBe(testPath.backupBasePath); + expect(fs.existsSync(folderCheck)).toBe(true); + expect(fs.existsSync(emptyFolderCheck)).toBe(true); + expect(fs.existsSync(file1Check)).toBe(true); + expect(fs.existsSync(file2Check)).toBe(true); + expect(backup.log.error).toHaveBeenCalledTimes(0); + expect(backup.log.warn).toHaveBeenCalledTimes(0); + }); + it(`retention > 1, file exist`, async () => { backup.backupBasePath = testPath.backupBasePath; backup.activeBackupPath = testPath.activeBackupJob; From 775de505112075c660eecfca4528e7413daf40a6 Mon Sep 17 00:00:00 2001 From: JackGruber <24863925+JackGruber@users.noreply.github.com> Date: Tue, 6 Dec 2022 21:13:53 +0100 Subject: [PATCH 08/15] overwrite file --- src/Backup.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Backup.ts b/src/Backup.ts index 7bbc6e9..ab5c27a 100644 --- a/src/Backup.ts +++ b/src/Backup.ts @@ -999,7 +999,8 @@ class Backup { try { fs.moveSync( path.join(this.activeBackupPath, file), - path.join(backupDestination, file) + path.join(backupDestination, file), + { overwrite: true } ); } catch (e) { await this.showError("moveFinishedBackup: " + e.message); From 1b4e4d1b7e485daf52c7fd8d4538225809421ffa Mon Sep 17 00:00:00 2001 From: JackGruber <24863925+JackGruber@users.noreply.github.com> Date: Wed, 7 Dec 2022 16:59:53 +0100 Subject: [PATCH 09/15] better naming --- src/Backup.ts | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/Backup.ts b/src/Backup.ts index ab5c27a..d7614da 100644 --- a/src/Backup.ts +++ b/src/Backup.ts @@ -992,22 +992,18 @@ class Backup { } } else { backupDestination = this.backupBasePath; - const oldBackupData = fs + const backupData = fs .readdirSync(this.activeBackupPath, { withFileTypes: true }) .map((dirent) => dirent.name); - for (const file of oldBackupData) { + console.log(backupData); + for (const file of backupData) { + let dst = path.join(backupDestination, file); try { - fs.moveSync( - path.join(this.activeBackupPath, file), - path.join(backupDestination, file), - { overwrite: true } - ); + fs.moveSync(path.join(this.activeBackupPath, file), dst); } catch (e) { await this.showError("moveFinishedBackup: " + e.message); this.log.error( - path.join(this.activeBackupPath, file) + - " => " + - path.join(backupDestination, file) + path.join(this.activeBackupPath, file) + " => " + dst ); throw e; } @@ -1029,7 +1025,6 @@ class Backup { private async clearBackupTarget(backupPath: string) { this.log.verbose(`Clear backup target`); - // Remove only files const oldBackupData = fs .readdirSync(backupPath, { withFileTypes: true }) @@ -1044,7 +1039,7 @@ class Backup { try { fs.removeSync(path.join(backupPath, file)); } catch (e) { - await this.showError("" + e.message); + await this.showError("clearBackupTarget " + e.message); throw e; } } @@ -1053,14 +1048,14 @@ class Backup { try { fs.removeSync(path.join(backupPath, "templates")); } catch (e) { - await this.showError("deleteOldBackupSets" + e.message); + await this.showError("clearBackupTarget " + e.message); throw e; } try { fs.removeSync(path.join(backupPath, "profile")); } catch (e) { - await this.showError("deleteOldBackupSets" + e.message); + await this.showError("clearBackupTarget " + e.message); throw e; } } From 7a1ebc79462545813e2ef00140f98a91533bf8d9 Mon Sep 17 00:00:00 2001 From: JackGruber <24863925+JackGruber@users.noreply.github.com> Date: Sat, 10 Dec 2022 10:17:49 +0100 Subject: [PATCH 10/15] More test cases --- __test__/backup.test.ts | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/__test__/backup.test.ts b/__test__/backup.test.ts index 4a48cae..7d154b4 100644 --- a/__test__/backup.test.ts +++ b/__test__/backup.test.ts @@ -304,34 +304,41 @@ describe("Backup", function () { testPath.backupBasePath, "emptyFolder" ); - const folder = path.join(testPath.activeBackupJob, "folder"); - const folderCheck = path.join(testPath.backupBasePath, "folder"); - const file1 = path.join(folder, "file.txt"); - const file1Check = path.join(folderCheck, "file.txt"); + const folderNotes = path.join(testPath.activeBackupJob, "notes"); + const folderNotesCheck = path.join(testPath.backupBasePath, "notes"); + const file1 = path.join(folderNotes, "file.txt"); + const file1Check = path.join(folderNotesCheck, "file.txt"); const file2 = path.join(testPath.activeBackupJob, "file.txt"); const file2Check = path.join(testPath.backupBasePath, "file.txt"); + const file3Check = path.join(testPath.backupBasePath, "fileStay.txt"); + const file4Check = path.join(folderNotesCheck, "fileNo.txt"); backup.backupBasePath = testPath.backupBasePath; backup.activeBackupPath = testPath.activeBackupJob; fs.emptyDirSync(testPath.backupBasePath); fs.emptyDirSync(emptyFolderCheck); - fs.emptyDirSync(folderCheck); + fs.emptyDirSync(folderNotesCheck); fs.writeFileSync(file1Check, "old file"); fs.writeFileSync(file2Check, "old file"); + fs.writeFileSync(file3Check, "old file"); + fs.writeFileSync(file4Check, "old file"); fs.emptyDirSync(testPath.activeBackupJob); fs.emptyDirSync(emptyFolder); - fs.emptyDirSync(folder); + fs.emptyDirSync(folderNotes); fs.writeFileSync(file1, "new file"); fs.writeFileSync(file2, "new file"); backup.backupRetention = 1; expect(await backup.moveFinishedBackup()).toBe(testPath.backupBasePath); - expect(fs.existsSync(folderCheck)).toBe(true); + expect(fs.existsSync(folderNotes)).toBe(false); + expect(fs.existsSync(folderNotesCheck)).toBe(true); expect(fs.existsSync(emptyFolderCheck)).toBe(true); expect(fs.existsSync(file1Check)).toBe(true); expect(fs.existsSync(file2Check)).toBe(true); + expect(fs.existsSync(file3Check)).toBe(true); + expect(fs.existsSync(file4Check)).toBe(false); expect(backup.log.error).toHaveBeenCalledTimes(0); expect(backup.log.warn).toHaveBeenCalledTimes(0); }); From d1c8143c357b82be8832f64a0d5e13320c7ccb8a Mon Sep 17 00:00:00 2001 From: JackGruber <24863925+JackGruber@users.noreply.github.com> Date: Sat, 10 Dec 2022 10:18:11 +0100 Subject: [PATCH 11/15] Remove logging --- src/Backup.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Backup.ts b/src/Backup.ts index d7614da..d039016 100644 --- a/src/Backup.ts +++ b/src/Backup.ts @@ -995,7 +995,6 @@ class Backup { const backupData = fs .readdirSync(this.activeBackupPath, { withFileTypes: true }) .map((dirent) => dirent.name); - console.log(backupData); for (const file of backupData) { let dst = path.join(backupDestination, file); try { From 372ab4aa29f788235569b0804a6e79bc710bbb9b Mon Sep 17 00:00:00 2001 From: JackGruber <24863925+JackGruber@users.noreply.github.com> Date: Sat, 10 Dec 2022 10:19:59 +0100 Subject: [PATCH 12/15] Overwrite files --- src/Backup.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Backup.ts b/src/Backup.ts index d039016..08c0b97 100644 --- a/src/Backup.ts +++ b/src/Backup.ts @@ -998,7 +998,9 @@ class Backup { for (const file of backupData) { let dst = path.join(backupDestination, file); try { - fs.moveSync(path.join(this.activeBackupPath, file), dst); + fs.moveSync(path.join(this.activeBackupPath, file), dst, { + overwrite: true, + }); } catch (e) { await this.showError("moveFinishedBackup: " + e.message); this.log.error( From 2466c320bf7552fbc5b71c0d98c70d7fc94f3239 Mon Sep 17 00:00:00 2001 From: JackGruber <24863925+JackGruber@users.noreply.github.com> Date: Sat, 10 Dec 2022 10:20:27 +0100 Subject: [PATCH 13/15] Remove notes folder from RAW and MD export --- src/Backup.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Backup.ts b/src/Backup.ts index 08c0b97..00a40c8 100644 --- a/src/Backup.ts +++ b/src/Backup.ts @@ -1046,6 +1046,13 @@ class Backup { } } + try { + fs.removeSync(path.join(backupPath, "notes")); + } catch (e) { + await this.showError("clearBackupTarget " + e.message); + throw e; + } + try { fs.removeSync(path.join(backupPath, "templates")); } catch (e) { From 39fb38686bccbeded1b0b04cc59b991592e44a13 Mon Sep 17 00:00:00 2001 From: JackGruber <24863925+JackGruber@users.noreply.github.com> Date: Sat, 10 Dec 2022 10:20:57 +0100 Subject: [PATCH 14/15] Add changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e55e10d..cbc9efb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## not released - Fix: #47 Suppress repeating error message during automatic execution if the backup path is not accessible +- Fix: #48 File already exists when a RAW or MD Frontmatter backup with no revisions is made ## v1.2.0 (2022-11-20) From c836fe1aa4307476d8c3805a83d24be874eab39d Mon Sep 17 00:00:00 2001 From: JackGruber <24863925+JackGruber@users.noreply.github.com> Date: Sat, 10 Dec 2022 10:25:28 +0100 Subject: [PATCH 15/15] bump version 1.2.1 --- CHANGELOG.md | 2 ++ package-lock.json | 4 ++-- package.json | 2 +- src/manifest.json | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cbc9efb..efa143d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## not released +## v1.2.1 (2022-12-10) + - Fix: #47 Suppress repeating error message during automatic execution if the backup path is not accessible - Fix: #48 File already exists when a RAW or MD Frontmatter backup with no revisions is made diff --git a/package-lock.json b/package-lock.json index bd1a1b9..9cf391f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "joplin-plugin-backup", - "version": "1.2.0", + "version": "1.2.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "joplin-plugin-backup", - "version": "1.2.0", + "version": "1.2.1", "license": "MIT", "dependencies": { "7zip-bin": "^5.1.1", diff --git a/package.json b/package.json index efc7cbd..ee87663 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "joplin-plugin-backup", - "version": "1.2.0", + "version": "1.2.1", "scripts": { "dist": "webpack --joplin-plugin-config buildMain && webpack --joplin-plugin-config buildExtraScripts && webpack --joplin-plugin-config createArchive", "prepare": "npm run dist && husky install", diff --git a/src/manifest.json b/src/manifest.json index b620c50..ef044e3 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 1, "id": "io.github.jackgruber.backup", "app_min_version": "2.1.3", - "version": "1.2.0", + "version": "1.2.1", "name": "Simple Backup", "description": "Plugin to create manual and automatic backups.", "author": "JackGruber",