diff --git a/main.ts b/main.ts index 0ce5a9e..732103f 100644 --- a/main.ts +++ b/main.ts @@ -26,9 +26,8 @@ export default class IBookHighlightsPlugin extends Plugin { this.addRibbonIcon('book-open', this.manifest.name, async () => { await this.importAndSaveHighlights().then(() => { new Notice('Apple Books highlights imported successfully'); - }).catch((error) => { - new Notice('Error while importing Apple Books highlights. Check console for details'); - console.error(`Error importing Apple Books highlights: ${error}`); + }).catch(() => { + new Notice(`[${this.manifest.name}]:\nError importing highlights. Check console for details (⌥ ⌘ I)`, 0); }); }); @@ -38,7 +37,11 @@ export default class IBookHighlightsPlugin extends Plugin { id: 'import-all-highlights', name: 'Import all', callback: async () => { - await this.importAndSaveHighlights(); + try { + await this.importAndSaveHighlights(); + } catch (error) { + new Notice(`[${this.manifest.name}]:\nError importing highlights. Check console for details (⌥ ⌘ I)`, 0); + } }, }); @@ -65,46 +68,58 @@ export default class IBookHighlightsPlugin extends Plugin { } async getBooks(): Promise { - const IBOOK_LIBRARY = '~/Library/Containers/com.apple.iBooksX/Data/Documents/BKLibrary/BKLibrary-1-091020131601.sqlite'; - const booksSql = ` - SELECT ZASSETID, ZTITLE, ZAUTHOR, ZGENRE, ZLANGUAGE, ZLASTOPENDATE, ZCOVERURL - FROM ZBKLIBRARYASSET - WHERE ZPURCHASEDATE IS NOT NULL`; - - const command = `echo "${booksSql}" | sqlite3 ${IBOOK_LIBRARY} -json`; - const exec = promisify(child_process.exec); - // Issue #11 - Temporary set maxBuffer to 100MB - // TODO: Need a more efficient solution to handle large data - const { stdout, stderr } = await exec(command, { maxBuffer: 100 * 1024 * 1024 }); - - if (stderr) { - new Notice(stderr); + try { + // const IBOOK_LIBRARY = '~/Library/Containers/com.apple.iBooksX/Data/Documents/BKLibrary/BKLibrary-1-091020131601.sqlite'; + const IBOOK_LIBRARY = '~/Downloads/test-BKLibrary.sqlite'; + // const IBOOK_LIBRARY = '~/Downloads/empty-BKLibrary.sqlite'; + const booksSql = ` + SELECT ZASSETID, ZTITLE, ZAUTHOR, ZGENRE, ZLANGUAGE, ZLASTOPENDATE, ZCOVERURL + FROM ZBKLIBRARYASSET + WHERE ZPURCHASEDATE IS NOT NULL`; + + const command = `echo "${booksSql}" | sqlite3 ${IBOOK_LIBRARY} -json`; + const exec = promisify(child_process.exec); + // Issue #11 - Temporary set maxBuffer to 100MB + // TODO: Need a more efficient solution to handle large data + const { stdout } = await exec(command, { maxBuffer: 100 * 1024 * 1024 }); + + if (!stdout) { + throw('No books found. Looks like your Apple Books library is empty.'); + } + + return JSON.parse(stdout); + } catch (error) { + console.warn(`[${this.manifest.name}]:`, error); return []; } - - return JSON.parse(stdout); } async getAnnotations(): Promise { - const IBOOK_ANNOTATION_DB = '~/Library/Containers/com.apple.iBooksX/Data/Documents/AEAnnotation/AEAnnotation_v10312011_1727_local.sqlite'; - const annotationsSql = ` - SELECT ZANNOTATIONASSETID, ZFUTUREPROOFING5, ZANNOTATIONREPRESENTATIVETEXT, ZANNOTATIONSELECTEDTEXT, ZANNOTATIONNOTE, ZANNOTATIONCREATIONDATE, ZANNOTATIONMODIFICATIONDATE, ZANNOTATIONSTYLE - FROM ZAEANNOTATION - WHERE ZANNOTATIONSELECTEDTEXT IS NOT NULL - AND ZANNOTATIONDELETED IS 0`; - - const command = `echo "${annotationsSql}" | sqlite3 ${IBOOK_ANNOTATION_DB} -json`; - const exec = promisify(child_process.exec); - // Issue #11 - Temporary set maxBuffer to 100MB - // TODO: Need a more efficient solution to handle large data - const { stdout, stderr } = await exec(command, { maxBuffer: 100 * 1024 * 1024 }); - - if (stderr) { - new Notice(stderr); + try { + // const IBOOK_ANNOTATION_DB = '~/Library/Containers/com.apple.iBooksX/Data/Documents/AEAnnotation/AEAnnotation_v10312011_1727_local.sqlite'; + const IBOOK_ANNOTATION_DB = '~/Downloads/empty-AEAnnotation_v10312011_1727_local.sqlite'; + const annotationsSql = ` + SELECT ZANNOTATIONASSETID, ZFUTUREPROOFING5, ZANNOTATIONREPRESENTATIVETEXT, ZANNOTATIONSELECTEDTEXT, ZANNOTATIONNOTE, ZANNOTATIONCREATIONDATE, ZANNOTATIONMODIFICATIONDATE, ZANNOTATIONSTYLE + FROM ZAEANNOTATION + WHERE ZANNOTATIONSELECTEDTEXT IS NOT NULL + AND ZANNOTATIONDELETED IS 0`; + + const command = `echo "${annotationsSql}" | sqlite3 ${IBOOK_ANNOTATION_DB} -json`; + const exec = promisify(child_process.exec); + // Issue #11 - Temporary set maxBuffer to 100MB + // TODO: Need a more efficient solution to handle large data + const { stdout } = await exec(command, { maxBuffer: 100 * 1024 * 1024 }); + + if (stdout.length === 0) { + throw('No highlights found. Make sure you made some highlights in your Apple Books.'); + } + + return JSON.parse(stdout); + } catch (error) { + console.warn(`[${this.manifest.name}]:`, error); return []; } - return JSON.parse(stdout); } async importHighlights(): Promise { const books = await this.getBooks(); @@ -150,6 +165,10 @@ export default class IBookHighlightsPlugin extends Plugin { async importAndSaveHighlights(): Promise { const highlights = await this.importHighlights(); + if (highlights.length === 0) { + throw ('No highlights found. Make sure you made some highlights in your Apple Books.'); + } + await this.saveHighlightsToVault(highlights); } diff --git a/manifest.json b/manifest.json index a594a49..7cef7f7 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "apple-books-import-highlights", "name": "Apple Books - Import Highlights", - "version": "1.2.1", + "version": "1.2.2", "minAppVersion": "0.15.0", "description": "Import your Apple Books highlights and notes to Obsidian.", "author": "bandantonio", diff --git a/package.json b/package.json index 2c14448..7402df0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "obsidian-apple-books-highlights-plugin", - "version": "1.2.1", + "version": "1.2.2", "description": "Import highlights and notes from your Apple Books to Obsidian", "main": "main.js", "scripts": {