From 1cdfcbbb3174e3990065713c9dcbdebd9db245a8 Mon Sep 17 00:00:00 2001 From: novov Date: Fri, 20 Oct 2023 17:28:28 +1300 Subject: [PATCH 01/10] Add support for relative attachment paths --- src/formats/apple-notes.ts | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/formats/apple-notes.ts b/src/formats/apple-notes.ts index d24f16f..ef46703 100644 --- a/src/formats/apple-notes.ts +++ b/src/formats/apple-notes.ts @@ -3,7 +3,7 @@ import { NoteConverter } from './apple-notes/convert-note'; import { ANAccount, ANAttachment, ANConverter, ANConverterType, ANFolderType } from './apple-notes/models'; import { descriptor } from './apple-notes/descriptor'; import { ImportContext } from '../main'; -import { fsPromises, os, path, splitext, zlib } from '../filesystem'; +import { fsPromises, os, path, parseFilePath, splitext, zlib } from '../filesystem'; import { FormatImporter } from '../format-importer'; import { Root } from 'protobufjs'; import SQLiteTag from './apple-notes/sqlite/index'; @@ -16,7 +16,7 @@ const CORETIME_OFFSET = 978307200; export class AppleNotesImporter extends FormatImporter { ctx: ImportContext; - attachmentPath: string; + cachedAttachmentPath: string; rootFolder: TFolder; database: SQLiteTagSpawned; @@ -101,7 +101,6 @@ export class AppleNotesImporter extends FormatImporter { this.ctx = ctx; this.protobufRoot = Root.fromJSON(descriptor); this.rootFolder = await this.getOutputFolder() as TFolder; - this.attachmentPath = this.getAttachmentPath(); if (!this.rootFolder) { new Notice('Please select a location to export to.'); @@ -252,7 +251,7 @@ export class AppleNotesImporter extends FormatImporter { // A PDF only seems to be generated when you modify the scan :( row = await this.database.get` SELECT - zidentifier, zfallbackpdfgeneration, zcreationdate, zmodificationdate, zaccount1 + zidentifier, zfallbackpdfgeneration, zcreationdate, zmodificationdate, zaccount1, znote FROM (SELECT *, NULL AS zfallbackpdfgeneration FROM ziccloudsyncingobject) WHERE @@ -271,7 +270,7 @@ export class AppleNotesImporter extends FormatImporter { case ANAttachment.Scan: row = await this.database.get` SELECT - zidentifier, zsizeheight, zsizewidth, zcreationdate, zmodificationdate, zaccount1 + zidentifier, zsizeheight, zsizewidth, zcreationdate, zmodificationdate, zaccount1, znote FROM ziccloudsyncingobject WHERE z_ent = ${this.keys.ICAttachment} @@ -289,7 +288,7 @@ export class AppleNotesImporter extends FormatImporter { case ANAttachment.Drawing: row = await this.database.get` SELECT - zidentifier, zfallbackimagegeneration, zcreationdate, zmodificationdate, zaccount1 + zidentifier, zfallbackimagegeneration, zcreationdate, zmodificationdate, zaccount1, znote FROM (SELECT *, NULL AS zfallbackimagegeneration FROM ziccloudsyncingobject) WHERE @@ -318,7 +317,7 @@ export class AppleNotesImporter extends FormatImporter { row = await this.database.get` SELECT a.zidentifier, a.zfilename, a.zaccount6, a.zaccount5, - a.zgeneration1, b.zcreationdate, b.zmodificationdate + a.zgeneration1, b.zcreationdate, b.zmodificationdate, b.znote FROM (SELECT *, NULL AS zaccount6, NULL AS zgeneration1 FROM ziccloudsyncingobject) AS a, ziccloudsyncingobject AS b @@ -338,9 +337,11 @@ export class AppleNotesImporter extends FormatImporter { } try { + const attachmentPath = await this.getAttachmentPath(this.resolvedFiles[row.ZNOTE]); + file = await this.vault.createBinary( //@ts-ignore - this.app.vault.getAvailablePath(`${this.attachmentPath}/${outName}`, outExt), + this.app.vault.getAvailablePath(`${attachmentPath}/${outName}`, outExt), await fsPromises.readFile(sourcePath), { ctime: this.decodeTime(row.ZCREATIONDATE), mtime: this.decodeTime(row.ZMODIFICATIONDATE) } ); @@ -365,13 +366,21 @@ export class AppleNotesImporter extends FormatImporter { return Math.floor((timestamp + CORETIME_OFFSET) * 1000); } - getAttachmentPath(): string { - let attachmentPath = this.app.vault.getConfig('attachmentFolderPath'); - if (attachmentPath.startsWith('/')) attachmentPath = attachmentPath.substring(1); + async getAttachmentPath(note: TFile): Promise { + if (this.cachedAttachmentPath) return this.cachedAttachmentPath; + + let attachmentSetting = this.app.vault.getConfig('attachmentFolderPath'); + let attachmentPath = parseFilePath( + //@ts-ignore + await this.app.vault.getAvailablePathForAttachments(note.basename, note.extension, note) + ).parent; - const outPath = path.join(attachmentPath, `${this.outputLocation} Attachments`); + if (!attachmentSetting.startsWith('./')) { + attachmentPath = path.join(attachmentSetting, `${this.outputLocation} Attachments`); + this.cachedAttachmentPath = attachmentPath; + } - this.createFolders(outPath); - return outPath; + this.createFolders(attachmentPath); + return attachmentPath; } } From c88296678f78bb390c0d373f1d65e61002611e87 Mon Sep 17 00:00:00 2001 From: novov Date: Fri, 20 Oct 2023 18:05:23 +1300 Subject: [PATCH 02/10] Handle folder errors better and escape bad folder names --- src/formats/apple-notes.ts | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/formats/apple-notes.ts b/src/formats/apple-notes.ts index ef46703..03fc99f 100644 --- a/src/formats/apple-notes.ts +++ b/src/formats/apple-notes.ts @@ -4,6 +4,7 @@ import { ANAccount, ANAttachment, ANConverter, ANConverterType, ANFolderType } f import { descriptor } from './apple-notes/descriptor'; import { ImportContext } from '../main'; import { fsPromises, os, path, parseFilePath, splitext, zlib } from '../filesystem'; +import { sanitizeFileName } from '../util'; import { FormatImporter } from '../format-importer'; import { Root } from 'protobufjs'; import SQLiteTag from './apple-notes/sqlite/index'; @@ -118,11 +119,19 @@ export class AppleNotesImporter extends FormatImporter { SELECT z_pk FROM ziccloudsyncingobject WHERE z_ent = ${this.keys.ICAccount} `; const noteFolders = await this.database.all` - SELECT z_pk FROM ziccloudsyncingobject WHERE z_ent = ${this.keys.ICFolder} + SELECT z_pk, ztitle2 FROM ziccloudsyncingobject WHERE z_ent = ${this.keys.ICFolder} `; for (let a of noteAccounts) await this.resolveAccount(a.Z_PK); - for (let f of noteFolders) await this.resolveFolder(f.Z_PK); + + for (let f of noteFolders) { + try { + await this.resolveFolder(f.Z_PK); + } + catch (e) { + this.ctx.reportFailed(f.ZTITLE2, e?.message); + } + } const notes = await this.database.all` SELECT @@ -194,7 +203,7 @@ export class AppleNotesImporter extends FormatImporter { if (folder.ZIDENTIFIER !== 'DefaultFolder-CloudKit') { // Notes in the default "Notes" folder are placed in the main directory - prefix += folder.ZTITLE2; + prefix += sanitizeFileName(folder.ZTITLE2); } const resolved = await this.createFolders(prefix); @@ -223,7 +232,7 @@ export class AppleNotesImporter extends FormatImporter { return null; } - const folder = this.resolvedFolders[row.ZFOLDER] as TFolder; + const folder = this.resolvedFolders[row.ZFOLDER] || this.rootFolder; const title = `${row.ZTITLE1}.md`; const file = await this.saveAsMarkdownFile(folder, title, ''); From 79876a772c6040c70eaadee87da3c4f9a2167b2d Mon Sep 17 00:00:00 2001 From: novov Date: Sat, 21 Oct 2023 13:27:43 +1300 Subject: [PATCH 03/10] Add option to include handwriting text --- src/formats/apple-notes.ts | 20 ++++++++++++++++++-- src/formats/apple-notes/convert-note.ts | 11 ++++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/formats/apple-notes.ts b/src/formats/apple-notes.ts index 03fc99f..9ddbdce 100644 --- a/src/formats/apple-notes.ts +++ b/src/formats/apple-notes.ts @@ -34,7 +34,10 @@ export class AppleNotesImporter extends FormatImporter { omitFirstLine = true; importTrashed = false; + includeHandwriting = false; + trashFolder = -1; + handwriting: Record = {}; init(): void { if (!Platform.isMacOS || !Platform.isDesktop) { @@ -70,6 +73,16 @@ export class AppleNotesImporter extends FormatImporter { .setValue(true) .onChange(async v => this.omitFirstLine = v) ); + + new Setting(this.modal.contentEl) + .setName('Include handwriting text') + .setDesc( + 'When Apple Notes has detected handwriting in drawings, include it as text before the drawing.' + ) + .addToggle(t => t + .setValue(false) + .onChange(async v => this.includeHandwriting = v) + ); } async getNotesDatabase(): Promise { @@ -297,9 +310,10 @@ export class AppleNotesImporter extends FormatImporter { case ANAttachment.Drawing: row = await this.database.get` SELECT - zidentifier, zfallbackimagegeneration, zcreationdate, zmodificationdate, zaccount1, znote + zidentifier, zfallbackimagegeneration, zcreationdate, zmodificationdate, zaccount1, + znote, zhandwritingsummary FROM - (SELECT *, NULL AS zfallbackimagegeneration FROM ziccloudsyncingobject) + (SELECT *, NULL AS zfallbackimagegeneration, NULL AS zhandwritingsummary FROM ziccloudsyncingobject) WHERE z_ent = ${this.keys.ICAttachment} AND z_pk = ${id} @@ -318,6 +332,8 @@ export class AppleNotesImporter extends FormatImporter { ); } + if (this.includeHandwriting) this.handwriting[id] = row.ZHANDWRITINGSUMMARY || ''; + outName = 'Drawing'; outExt = 'png'; break; diff --git a/src/formats/apple-notes/convert-note.ts b/src/formats/apple-notes/convert-note.ts index 9b115e1..3b83aa3 100644 --- a/src/formats/apple-notes/convert-note.ts +++ b/src/formats/apple-notes/convert-note.ts @@ -364,9 +364,14 @@ export class NoteConverter extends ANConverter { } const attachment = await this.importer.resolveAttachment(id, attr.attachmentInfo!.typeUti); - if (!attachment) return ` **(error reading attachment)**`; - - return `\n${this.app.fileManager.generateMarkdownLink(attachment, '/')}\n`; + let link = attachment + ? `\n${this.app.fileManager.generateMarkdownLink(attachment, '/')}\n` + : ` **(error reading attachment)**`; + + const handwriting = this.importer.handwriting[id]; + if (handwriting) link = `\n> [!Handwriting]-\n> ${handwriting.replace('\n', '\n> ')}${link}`; + + return link; } async getInternalLink(uri: string, name: string | undefined = undefined): Promise { From 51fabc1e9858edd50292739d121f1630c5fca3bf Mon Sep 17 00:00:00 2001 From: novov Date: Sat, 21 Oct 2023 14:12:02 +1300 Subject: [PATCH 04/10] Fix issues with recently deleted on multi-account notes --- src/formats/apple-notes.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/formats/apple-notes.ts b/src/formats/apple-notes.ts index 9ddbdce..07e5574 100644 --- a/src/formats/apple-notes.ts +++ b/src/formats/apple-notes.ts @@ -36,7 +36,7 @@ export class AppleNotesImporter extends FormatImporter { importTrashed = false; includeHandwriting = false; - trashFolder = -1; + trashFolders: number[] = []; handwriting: Record = {}; init(): void { @@ -152,7 +152,7 @@ export class AppleNotesImporter extends FormatImporter { WHERE z_ent = ${this.keys.ICNote} AND ztitle1 IS NOT NULL - AND zfolder != ${this.trashFolder} + AND zfolder NOT IN (${this.trashFolders}) `; this.noteCount = notes.length; @@ -199,7 +199,7 @@ export class AppleNotesImporter extends FormatImporter { return null; } else if (!this.importTrashed && folder.ZFOLDERTYPE == ANFolderType.Trash) { - this.trashFolder = id; + this.trashFolders.push(id); return null; } else if (folder.ZPARENT !== null) { @@ -214,7 +214,7 @@ export class AppleNotesImporter extends FormatImporter { prefix = `${this.rootFolder.path}/`; } - if (folder.ZIDENTIFIER !== 'DefaultFolder-CloudKit') { + if (!folder.ZIDENTIFIER.startsWith('DefaultFolder')) { // Notes in the default "Notes" folder are placed in the main directory prefix += sanitizeFileName(folder.ZTITLE2); } @@ -246,6 +246,7 @@ export class AppleNotesImporter extends FormatImporter { } const folder = this.resolvedFolders[row.ZFOLDER] || this.rootFolder; + const title = `${row.ZTITLE1}.md`; const file = await this.saveAsMarkdownFile(folder, title, ''); From 106dc47f49e8ea57acd92fdb08d1f80beba58119 Mon Sep 17 00:00:00 2001 From: novov Date: Sat, 21 Oct 2023 14:54:57 +1300 Subject: [PATCH 05/10] Make import more robust for changes in future versions --- src/formats/apple-notes.ts | 45 +++++++++---------------- src/formats/apple-notes/convert-note.ts | 10 +++--- 2 files changed, 21 insertions(+), 34 deletions(-) diff --git a/src/formats/apple-notes.ts b/src/formats/apple-notes.ts index 07e5574..6956772 100644 --- a/src/formats/apple-notes.ts +++ b/src/formats/apple-notes.ts @@ -24,6 +24,7 @@ export class AppleNotesImporter extends FormatImporter { protobufRoot: Root; keys: Record; + owners: Record = {}; resolvedAccounts: Record = {}; resolvedFiles: Record = {}; resolvedFolders: Record = {}; @@ -35,9 +36,7 @@ export class AppleNotesImporter extends FormatImporter { omitFirstLine = true; importTrashed = false; includeHandwriting = false; - trashFolders: number[] = []; - handwriting: Record = {}; init(): void { if (!Platform.isMacOS || !Platform.isDesktop) { @@ -221,6 +220,7 @@ export class AppleNotesImporter extends FormatImporter { const resolved = await this.createFolders(prefix); this.resolvedFolders[id] = resolved; + this.owners[id] = folder.ZOWNER; return resolved; } @@ -252,6 +252,7 @@ export class AppleNotesImporter extends FormatImporter { this.ctx.status(`Importing note ${title}`); this.resolvedFiles[id] = file; + this.owners[id] = this.owners[row.ZFOLDER]; // Notes may reference other notes, so we want them in resolvedFiles before we parse to avoid cycles const converter = this.decodeData(row.zhexdata, NoteConverter); @@ -274,7 +275,7 @@ export class AppleNotesImporter extends FormatImporter { // A PDF only seems to be generated when you modify the scan :( row = await this.database.get` SELECT - zidentifier, zfallbackpdfgeneration, zcreationdate, zmodificationdate, zaccount1, znote + zidentifier, zfallbackpdfgeneration, zcreationdate, zmodificationdate, znote FROM (SELECT *, NULL AS zfallbackpdfgeneration FROM ziccloudsyncingobject) WHERE @@ -282,10 +283,7 @@ export class AppleNotesImporter extends FormatImporter { AND z_pk = ${id} `; - sourcePath = path.join( - this.resolvedAccounts[row.ZACCOUNT1].path, - 'FallbackPDFs', row.ZIDENTIFIER, row.ZFALLBACKPDFGENERATION || '', 'FallbackPDF.pdf' - ); + sourcePath = path.join('FallbackPDFs', row.ZIDENTIFIER, row.ZFALLBACKPDFGENERATION || '', 'FallbackPDF.pdf'); outName = 'Scan'; outExt = 'pdf'; break; @@ -293,17 +291,14 @@ export class AppleNotesImporter extends FormatImporter { case ANAttachment.Scan: row = await this.database.get` SELECT - zidentifier, zsizeheight, zsizewidth, zcreationdate, zmodificationdate, zaccount1, znote + zidentifier, zsizeheight, zsizewidth, zcreationdate, zmodificationdate, znote FROM ziccloudsyncingobject WHERE z_ent = ${this.keys.ICAttachment} AND z_pk = ${id} `; - sourcePath = path.join( - this.resolvedAccounts[row.ZACCOUNT1].path, - 'Previews', `${row.ZIDENTIFIER}-1-${row.ZSIZEWIDTH}x${row.ZSIZEHEIGHT}-0.jpeg` - ); + sourcePath = path.join('Previews', `${row.ZIDENTIFIER}-1-${row.ZSIZEWIDTH}x${row.ZSIZEHEIGHT}-0.jpeg`); outName = 'Scan Page'; outExt = 'jpg'; break; @@ -311,10 +306,10 @@ export class AppleNotesImporter extends FormatImporter { case ANAttachment.Drawing: row = await this.database.get` SELECT - zidentifier, zfallbackimagegeneration, zcreationdate, zmodificationdate, zaccount1, + zidentifier, zfallbackimagegeneration, zcreationdate, zmodificationdate, znote, zhandwritingsummary FROM - (SELECT *, NULL AS zfallbackimagegeneration, NULL AS zhandwritingsummary FROM ziccloudsyncingobject) + (SELECT *, NULL AS zfallbackimagegeneration FROM ziccloudsyncingobject) WHERE z_ent = ${this.keys.ICAttachment} AND z_pk = ${id} @@ -322,19 +317,12 @@ export class AppleNotesImporter extends FormatImporter { if (row.ZFALLBACKIMAGEGENERATION) { // macOS 14/iOS 17 and above - sourcePath = path.join( - this.resolvedAccounts[row.ZACCOUNT1].path, - 'FallbackImages', row.ZIDENTIFIER, row.ZFALLBACKIMAGEGENERATION, 'FallbackImage.png' - ); + sourcePath = path.join('FallbackImages', row.ZIDENTIFIER, row.ZFALLBACKIMAGEGENERATION, 'FallbackImage.png'); } else { - sourcePath = path.join( - this.resolvedAccounts[row.ZACCOUNT1].path, 'FallbackImages', `${row.ZIDENTIFIER}.jpg` - ); + sourcePath = path.join('FallbackImages', `${row.ZIDENTIFIER}.jpg`); } - if (this.includeHandwriting) this.handwriting[id] = row.ZHANDWRITINGSUMMARY || ''; - outName = 'Drawing'; outExt = 'png'; break; @@ -342,10 +330,10 @@ export class AppleNotesImporter extends FormatImporter { default: row = await this.database.get` SELECT - a.zidentifier, a.zfilename, a.zaccount6, a.zaccount5, + a.zidentifier, a.zfilename, a.zgeneration1, b.zcreationdate, b.zmodificationdate, b.znote FROM - (SELECT *, NULL AS zaccount6, NULL AS zgeneration1 FROM ziccloudsyncingobject) AS a, + (SELECT *, NULL AS zgeneration1 FROM ziccloudsyncingobject) AS a, ziccloudsyncingobject AS b WHERE a.z_ent = ${this.keys.ICMedia} @@ -353,17 +341,14 @@ export class AppleNotesImporter extends FormatImporter { AND a.z_pk = b.zmedia `; - const account = row.ZACCOUNT6 || row.ZACCOUNT5; - sourcePath = path.join( - this.resolvedAccounts[account].path, - 'Media', row.ZIDENTIFIER, row.ZGENERATION1 || '', row.ZFILENAME - ); + sourcePath = path.join('Media', row.ZIDENTIFIER, row.ZGENERATION1 || '', row.ZFILENAME); [outName, outExt] = splitext(row.ZFILENAME); break; } try { const attachmentPath = await this.getAttachmentPath(this.resolvedFiles[row.ZNOTE]); + sourcePath = path.join(this.resolvedAccounts[this.owners[row.ZNOTE]].path, sourcePath); file = await this.vault.createBinary( //@ts-ignore diff --git a/src/formats/apple-notes/convert-note.ts b/src/formats/apple-notes/convert-note.ts index 3b83aa3..501da25 100644 --- a/src/formats/apple-notes/convert-note.ts +++ b/src/formats/apple-notes/convert-note.ts @@ -341,7 +341,8 @@ export class NoteConverter extends ANConverter { case ANAttachment.ModifiedScan: case ANAttachment.Drawing: row = await this.importer.database.get` - SELECT z_pk FROM ziccloudsyncingobject + SELECT z_pk, zhandwritingsummary + FROM (SELECT *, NULL AS zhandwritingsummary FROM ziccloudsyncingobject) WHERE zidentifier = ${attr.attachmentInfo.attachmentIdentifier}`; id = row?.Z_PK; @@ -368,9 +369,10 @@ export class NoteConverter extends ANConverter { ? `\n${this.app.fileManager.generateMarkdownLink(attachment, '/')}\n` : ` **(error reading attachment)**`; - const handwriting = this.importer.handwriting[id]; - if (handwriting) link = `\n> [!Handwriting]-\n> ${handwriting.replace('\n', '\n> ')}${link}`; - + if (this.importer.includeHandwriting && row.ZHANDWRITINGSUMMARY) { + link = `\n> [!Handwriting]-\n> ${row.ZHANDWRITINGSUMMARY.replace('\n', '\n> ')}${link}`; + } + return link; } From 31a584cbe1818a120c0faa04500937c8886b44cb Mon Sep 17 00:00:00 2001 From: novov Date: Sat, 21 Oct 2023 16:56:09 +1300 Subject: [PATCH 06/10] Print errors to console even when caught --- src/formats/apple-notes.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/formats/apple-notes.ts b/src/formats/apple-notes.ts index 6956772..56d5655 100644 --- a/src/formats/apple-notes.ts +++ b/src/formats/apple-notes.ts @@ -142,6 +142,7 @@ export class AppleNotesImporter extends FormatImporter { } catch (e) { this.ctx.reportFailed(f.ZTITLE2, e?.message); + console.error(e); } } @@ -161,6 +162,7 @@ export class AppleNotesImporter extends FormatImporter { } catch (e) { this.ctx.reportFailed(n.ZTITLE1, e?.message); + console.error(e); } } @@ -357,7 +359,8 @@ export class AppleNotesImporter extends FormatImporter { { ctime: this.decodeTime(row.ZCREATIONDATE), mtime: this.decodeTime(row.ZMODIFICATIONDATE) } ); } - catch { + catch (e) { + console.error(e); return null; } From 0b87a6bbc204afc51adcb3a6fc5645e3986974e9 Mon Sep 17 00:00:00 2001 From: novov Date: Sun, 22 Oct 2023 14:56:49 +1300 Subject: [PATCH 07/10] Fallback to root attachments folder when account folder doesn't have attachment --- src/formats/apple-notes.ts | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/formats/apple-notes.ts b/src/formats/apple-notes.ts index 56d5655..d28055b 100644 --- a/src/formats/apple-notes.ts +++ b/src/formats/apple-notes.ts @@ -349,13 +349,14 @@ export class AppleNotesImporter extends FormatImporter { } try { - const attachmentPath = await this.getAttachmentPath(this.resolvedFiles[row.ZNOTE]); - sourcePath = path.join(this.resolvedAccounts[this.owners[row.ZNOTE]].path, sourcePath); + const binary = await this.getAttachmentSource(this.resolvedAccounts[this.owners[row.ZNOTE]], sourcePath); + //@ts-ignore + const outPath = this.app.vault.getAvailablePath( + `${await this.getAttachmentPath(this.resolvedFiles[row.ZNOTE])}/${outName}`, outExt + ); file = await this.vault.createBinary( - //@ts-ignore - this.app.vault.getAvailablePath(`${attachmentPath}/${outName}`, outExt), - await fsPromises.readFile(sourcePath), + outPath, binary, { ctime: this.decodeTime(row.ZCREATIONDATE), mtime: this.decodeTime(row.ZMODIFICATIONDATE) } ); } @@ -380,6 +381,15 @@ export class AppleNotesImporter extends FormatImporter { return Math.floor((timestamp + CORETIME_OFFSET) * 1000); } + async getAttachmentSource(account: ANAccount, sourcePath: string): Promise { + try { + return await fsPromises.readFile(path.join(account.path, sourcePath)); + } + catch (e) { + return await fsPromises.readFile(path.join(NOTE_FOLDER_PATH, sourcePath)); + } + } + async getAttachmentPath(note: TFile): Promise { if (this.cachedAttachmentPath) return this.cachedAttachmentPath; From 816212ac4d483462f5dc73cc8bed41801f5f0df9 Mon Sep 17 00:00:00 2001 From: novov Date: Sun, 22 Oct 2023 18:46:46 +1300 Subject: [PATCH 08/10] Minor bug fixes --- src/formats/apple-notes.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/formats/apple-notes.ts b/src/formats/apple-notes.ts index d28055b..d205420 100644 --- a/src/formats/apple-notes.ts +++ b/src/formats/apple-notes.ts @@ -36,7 +36,7 @@ export class AppleNotesImporter extends FormatImporter { omitFirstLine = true; importTrashed = false; includeHandwriting = false; - trashFolders: number[] = []; + trashFolders: number[] = [-1]; init(): void { if (!Platform.isMacOS || !Platform.isDesktop) { @@ -386,7 +386,7 @@ export class AppleNotesImporter extends FormatImporter { return await fsPromises.readFile(path.join(account.path, sourcePath)); } catch (e) { - return await fsPromises.readFile(path.join(NOTE_FOLDER_PATH, sourcePath)); + return await fsPromises.readFile(path.join(os.homedir(), NOTE_FOLDER_PATH, sourcePath)); } } From 7cd498f15608e4d6d088489116faa439b05f1c6e Mon Sep 17 00:00:00 2001 From: novov Date: Sun, 22 Oct 2023 23:05:46 +1300 Subject: [PATCH 09/10] Fix issues with empty array SQL params instead of working around it --- package.json | 1 - src/formats/apple-notes.ts | 2 +- .../apple-notes/sqlite/static-params.js | 31 +++++++++++++++++++ src/formats/apple-notes/sqlite/utils.js | 2 +- 4 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 src/formats/apple-notes/sqlite/static-params.js diff --git a/package.json b/package.json index 37230e9..8727503 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,6 @@ "joplin-turndown-plugin-gfm": "1.0.12", "plain-tag": "0.1.3", "protobufjs": "7.2.5", - "static-params": "0.3.0", "xml-flow": "1.0.4" } } diff --git a/src/formats/apple-notes.ts b/src/formats/apple-notes.ts index d205420..b7b024f 100644 --- a/src/formats/apple-notes.ts +++ b/src/formats/apple-notes.ts @@ -36,7 +36,7 @@ export class AppleNotesImporter extends FormatImporter { omitFirstLine = true; importTrashed = false; includeHandwriting = false; - trashFolders: number[] = [-1]; + trashFolders: number[] = []; init(): void { if (!Platform.isMacOS || !Platform.isDesktop) { diff --git a/src/formats/apple-notes/sqlite/static-params.js b/src/formats/apple-notes/sqlite/static-params.js new file mode 100644 index 0000000..85168d0 --- /dev/null +++ b/src/formats/apple-notes/sqlite/static-params.js @@ -0,0 +1,31 @@ +class Static extends String {} + +export const asParams = (template, ...values) => { + const t = [template[0]]; + const v = [t]; + + for (let i = 0; i < values.length; i++) { + if (values[i] instanceof Static) { + t[t.length - 1] += values[i] + template[i + 1]; + } + else { + if (Array.isArray(values[i])) { + t.push(...values[i].slice(1).map(_ => ',')); + + v.push(...values[i]); + if (values[i].length == 0) v.push(''); + } + else v.push(values[i]); + + t.push(template[i + 1]); + } + } + + return v; +}; + +export const asStatic = _ => new Static(_); + +export const asTag = fn => function() { + return fn.apply(this, asParams.apply(null, arguments)); +}; diff --git a/src/formats/apple-notes/sqlite/utils.js b/src/formats/apple-notes/sqlite/utils.js index 9a79bff..34af53f 100644 --- a/src/formats/apple-notes/sqlite/utils.js +++ b/src/formats/apple-notes/sqlite/utils.js @@ -1,5 +1,5 @@ import plain from 'plain-tag'; -import { asStatic, asParams } from 'static-params/sql'; +import { asStatic, asParams } from './static-params'; export const error = (rej, reason) => { const code = 'SQLITE_ERROR'; From 2b530850a91ff04c351d48edd0bda124132c7507 Mon Sep 17 00:00:00 2001 From: novov Date: Tue, 24 Oct 2023 11:51:12 +1300 Subject: [PATCH 10/10] Address PR feedback --- package.json | 1 + src/formats/apple-notes.ts | 7 ++--- .../apple-notes/sqlite/static-params.js | 31 ------------------- src/formats/apple-notes/sqlite/utils.js | 2 +- 4 files changed, 5 insertions(+), 36 deletions(-) delete mode 100644 src/formats/apple-notes/sqlite/static-params.js diff --git a/package.json b/package.json index 8727503..485fe4e 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "joplin-turndown-plugin-gfm": "1.0.12", "plain-tag": "0.1.3", "protobufjs": "7.2.5", + "static-params": "0.4.0", "xml-flow": "1.0.4" } } diff --git a/src/formats/apple-notes.ts b/src/formats/apple-notes.ts index b7b024f..2c76f6b 100644 --- a/src/formats/apple-notes.ts +++ b/src/formats/apple-notes.ts @@ -350,10 +350,9 @@ export class AppleNotesImporter extends FormatImporter { try { const binary = await this.getAttachmentSource(this.resolvedAccounts[this.owners[row.ZNOTE]], sourcePath); + const attachmentFolder = await this.getAttachmentFolder(this.resolvedFiles[row.ZNOTE]); //@ts-ignore - const outPath = this.app.vault.getAvailablePath( - `${await this.getAttachmentPath(this.resolvedFiles[row.ZNOTE])}/${outName}`, outExt - ); + const outPath = this.app.vault.getAvailablePath(`${attachmentFolder}/${outName}`, outExt); file = await this.vault.createBinary( outPath, binary, @@ -390,7 +389,7 @@ export class AppleNotesImporter extends FormatImporter { } } - async getAttachmentPath(note: TFile): Promise { + async getAttachmentFolder(note: TFile): Promise { if (this.cachedAttachmentPath) return this.cachedAttachmentPath; let attachmentSetting = this.app.vault.getConfig('attachmentFolderPath'); diff --git a/src/formats/apple-notes/sqlite/static-params.js b/src/formats/apple-notes/sqlite/static-params.js deleted file mode 100644 index 85168d0..0000000 --- a/src/formats/apple-notes/sqlite/static-params.js +++ /dev/null @@ -1,31 +0,0 @@ -class Static extends String {} - -export const asParams = (template, ...values) => { - const t = [template[0]]; - const v = [t]; - - for (let i = 0; i < values.length; i++) { - if (values[i] instanceof Static) { - t[t.length - 1] += values[i] + template[i + 1]; - } - else { - if (Array.isArray(values[i])) { - t.push(...values[i].slice(1).map(_ => ',')); - - v.push(...values[i]); - if (values[i].length == 0) v.push(''); - } - else v.push(values[i]); - - t.push(template[i + 1]); - } - } - - return v; -}; - -export const asStatic = _ => new Static(_); - -export const asTag = fn => function() { - return fn.apply(this, asParams.apply(null, arguments)); -}; diff --git a/src/formats/apple-notes/sqlite/utils.js b/src/formats/apple-notes/sqlite/utils.js index 34af53f..9a79bff 100644 --- a/src/formats/apple-notes/sqlite/utils.js +++ b/src/formats/apple-notes/sqlite/utils.js @@ -1,5 +1,5 @@ import plain from 'plain-tag'; -import { asStatic, asParams } from './static-params'; +import { asStatic, asParams } from 'static-params/sql'; export const error = (rej, reason) => { const code = 'SQLITE_ERROR';