Skip to content

Commit

Permalink
Ensure pdfannots is executable; scope name to platform
Browse files Browse the repository at this point in the history
  • Loading branch information
mgmeyers committed Jul 20, 2023
1 parent 7530da2 commit 05f9bfa
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 33 deletions.
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "obsidian-zotero-desktop-connector",
"name": "Zotero Integration",
"version": "3.0.5",
"version": "3.0.6",
"minAppVersion": "1.1.1",
"description": "Insert and import citations, bibliographies, notes, and PDF annotations from Zotero.",
"author": "mgmeyers",
Expand Down
54 changes: 31 additions & 23 deletions src/bbt/export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -725,17 +725,21 @@ export async function exportToMarkdown(

if (canExtract) {
try {
const res = await extractAnnotations(pdfInputPath, {
imageBaseName: imageBaseName,
imageDPI: settings.pdfExportImageDPI,
imageFormat: settings.pdfExportImageFormat,
imageOutputPath: imageOutputPath,
imageQuality: settings.pdfExportImageQuality,
attemptOCR: settings.pdfExportImageOCR,
ocrLang: settings.pdfExportImageOCRLang,
tesseractPath: settings.pdfExportImageTesseractPath,
tessDataDir: settings.pdfExportImageTessDataDir,
});
const res = await extractAnnotations(
pdfInputPath,
{
imageBaseName: imageBaseName,
imageDPI: settings.pdfExportImageDPI,
imageFormat: settings.pdfExportImageFormat,
imageOutputPath: imageOutputPath,
imageQuality: settings.pdfExportImageQuality,
attemptOCR: settings.pdfExportImageOCR,
ocrLang: settings.pdfExportImageOCRLang,
tesseractPath: settings.pdfExportImageTesseractPath,
tessDataDir: settings.pdfExportImageTessDataDir,
},
settings.exeOverridePath
);

let extracted = JSON.parse(res);

Expand Down Expand Up @@ -922,18 +926,22 @@ export async function dataExplorerPrompt(settings: ZoteroConnectorSettings) {

if (canExtract) {
try {
const res = await extractAnnotations(pdfInputPath, {
noWrite: true,
imageBaseName: 'base_name',
imageDPI: settings.pdfExportImageDPI,
imageFormat: settings.pdfExportImageFormat,
imageOutputPath: path.join(vaultRoot, 'output_path'),
imageQuality: settings.pdfExportImageQuality,
attemptOCR: settings.pdfExportImageOCR,
ocrLang: settings.pdfExportImageOCRLang,
tesseractPath: settings.pdfExportImageTesseractPath,
tessDataDir: settings.pdfExportImageTessDataDir,
});
const res = await extractAnnotations(
pdfInputPath,
{
noWrite: true,
imageBaseName: 'base_name',
imageDPI: settings.pdfExportImageDPI,
imageFormat: settings.pdfExportImageFormat,
imageOutputPath: path.join(vaultRoot, 'output_path'),
imageQuality: settings.pdfExportImageQuality,
attemptOCR: settings.pdfExportImageOCR,
ocrLang: settings.pdfExportImageOCRLang,
tesseractPath: settings.pdfExportImageTesseractPath,
tessDataDir: settings.pdfExportImageTessDataDir,
},
settings.exeOverridePath
);

let extracted = JSON.parse(res);

Expand Down
20 changes: 17 additions & 3 deletions src/bbt/extractAnnotations.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { execa } from 'execa';
import { Notice } from 'obsidian';
import path from 'path';
import { getExeName, getExeRoot } from 'src/helpers';
import { ensureExecutableSync, getExeName, getExeRoot } from 'src/helpers';

import { LoadingModal } from './LoadingModal';

Expand Down Expand Up @@ -33,7 +33,11 @@ const paramMap: Record<keyof ExtractParams, string> = {
tessDataDir: '--tess-data-dir',
};

export async function extractAnnotations(input: string, params: ExtractParams) {
export async function extractAnnotations(
input: string,
params: ExtractParams,
overridePath?: string
) {
const modal = new LoadingModal(app, 'Extracting annotations...');
modal.open();

Expand Down Expand Up @@ -61,7 +65,17 @@ export async function extractAnnotations(input: string, params: ExtractParams) {
});

try {
const result = await execa(path.join(getExeRoot(), getExeName()), args);
const isExecutable = ensureExecutableSync(overridePath);

if (!isExecutable) {
new Notice(`Error: PDF utility is not executable`, 10000);
return '[]';
}

const result = await execa(
overridePath || path.join(getExeRoot(), getExeName()),
args
);

modal.close();

Expand Down
65 changes: 63 additions & 2 deletions src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,27 @@ export function getExeRoot() {
}

export function getExeName() {
return os.platform() === 'win32' ? 'pdfannots2json.exe' : 'pdfannots2json';
return os.platform() === 'win32'
? 'pdfannots2json.exe'
: `pdfannots2json-${os.platform()}-${os.arch()}`;
}

export function scopeExe() {
if (os.platform() === 'win32') {
return;
}

fs.renameSync(
path.join(getExeRoot(), getLegacyExeName()),
path.join(getExeRoot(), getExeName())
);
}

export function getLegacyExeName() {
return os.platform() === 'win32' ? 'pdfannots2json.exe' : 'pdfannots2json';
}

export function getLegacyExeName2() {
return os.platform() === 'win32' ? 'pdf-annots2json.exe' : 'pdf-annots2json';
}

Expand All @@ -36,10 +53,15 @@ export function doesEXEExist(override?: string) {
return fs.existsSync(path.join(getExeRoot(), getExeName()));
}

export function doesLegacyEXEExist() {
export function doesLegacyEXEExist(override?: string) {
if (override) return fs.existsSync(override);
return fs.existsSync(path.join(getExeRoot(), getLegacyExeName()));
}

export function doesLegacyEXEExist2() {
return fs.existsSync(path.join(getExeRoot(), getLegacyExeName2()));
}

export function removeEXE() {
fs.rmSync(path.join(getExeRoot(), getExeName()));
}
Expand All @@ -48,6 +70,10 @@ export function removeLegacyEXE() {
fs.rmSync(path.join(getExeRoot(), getLegacyExeName()));
}

export function removeLegacyEXE2() {
fs.rmSync(path.join(getExeRoot(), getLegacyExeName2()));
}

export async function checkEXEVersion(override?: string) {
try {
const result = await execa(
Expand All @@ -67,3 +93,38 @@ export async function checkEXEVersion(override?: string) {
throw e;
}
}

export function getExecutableMode(mode = 0) {
return (
mode | fs.constants.S_IXUSR | fs.constants.S_IXGRP | fs.constants.S_IXOTH
);
}

function handleError(err: any) {
console.error('Error: pdfannots2json not executable', err);

if (err.code === 'ENOENT') {
return false;
} else {
return undefined;
}
}

export function ensureExecutableSync(override?: string) {
const file = override || path.join(getExeRoot(), getExeName());

try {
fs.accessSync(file, fs.constants.X_OK);
return true;
} catch {
//
}

try {
const stats = fs.statSync(file);
fs.chmodSync(file, getExecutableMode(stats.mode));
return true;
} catch (err) {
return handleError(err);
}
}
16 changes: 12 additions & 4 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ import {
noteExportPrompt,
} from './bbt/exportNotes';
import './bbt/template.helpers';
import { currentVersion, downloadAndExtract } from './settings/AssetDownloader';
import {
currentVersion,
downloadAndExtract,
internalVersion,
} from './settings/AssetDownloader';
import { ZoteroConnectorSettingsTab } from './settings/settings';
import {
CitationFormat,
Expand Down Expand Up @@ -284,10 +288,13 @@ export default class ZoteroConnector extends Plugin {
}

async updatePDFUtility() {
const { exeOverridePath, _exeInternalVersion, exeVersion } = this.settings;
if (exeOverridePath || !exeVersion) return;

if (
!this.settings.exeOverridePath &&
this.settings.exeVersion &&
this.settings.exeVersion !== currentVersion
exeVersion !== currentVersion ||
!_exeInternalVersion ||
_exeInternalVersion !== internalVersion
) {
const modal = new LoadingModal(
app,
Expand All @@ -300,6 +307,7 @@ export default class ZoteroConnector extends Plugin {

if (success) {
this.settings.exeVersion = currentVersion;
this.settings._exeInternalVersion = internalVersion;
this.saveSettings();
}
} catch {
Expand Down
10 changes: 10 additions & 0 deletions src/settings/AssetDownloader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,20 @@ import {
checkEXEVersion,
doesEXEExist,
doesLegacyEXEExist,
doesLegacyEXEExist2,
getExeRoot,
removeEXE,
removeLegacyEXE,
removeLegacyEXE2,
scopeExe,
} from 'src/helpers';
import { ZoteroConnectorSettings } from 'src/types';

import { Icon } from './Icon';
import { SettingItem } from './SettingItem';

export const currentVersion = '1.0.15';
export const internalVersion = 1;

const options: Record<string, Record<string, string>> = {
darwin: {
Expand Down Expand Up @@ -50,6 +54,10 @@ export async function downloadAndExtract() {
if (!url) return false;

try {
if (doesLegacyEXEExist2()) {
removeLegacyEXE2();
}

if (doesLegacyEXEExist()) {
removeLegacyEXE();
}
Expand All @@ -61,6 +69,8 @@ export async function downloadAndExtract() {
await download(url, getExeRoot(), {
extract: true,
});

scopeExe();
} catch (e) {
console.error(e);
new Notice(
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export interface ZoteroConnectorSettings {
database: Database;
port?: string;
exeVersion?: string;
_exeInternalVersion?: number;
exeOverridePath?: string;
exportFormats: ExportFormat[];
noteImportFolder: string;
Expand Down

0 comments on commit 05f9bfa

Please sign in to comment.