feat: enhance ImageMagick installation process and update documentation
- Added functions to resolve Homebrew and Linux escalation commands for ImageMagick installation. - Improved error handling and logging for manual installation steps. - Updated download URLs for ImageMagick based on the platform. - Enhanced user interface messages to clarify installation steps for different operating systems. - Adjusted CPU worker count in document extraction for better performance.
This commit is contained in:
parent
6a6afc7ab7
commit
691d0f62e8
5 changed files with 115 additions and 16 deletions
9
electron/.gitignore
vendored
9
electron/.gitignore
vendored
|
|
@ -21,6 +21,13 @@ app_dist
|
|||
resources/fastapi
|
||||
resources/nextjs
|
||||
dist
|
||||
eng.traineddata
|
||||
servers/fastapi/build/
|
||||
servers/fastapi/dist/
|
||||
servers/fastapi/fastembed_cache/
|
||||
electron/.cache/
|
||||
electron/.cache/export-runtime/
|
||||
electron/.cache/export-runtime/
|
||||
*.pkg
|
||||
*.toc
|
||||
*.zip
|
||||
*.pyc
|
||||
|
|
@ -20,6 +20,7 @@ import {
|
|||
import { getSetupStatus } from "../utils/setup-dependencies";
|
||||
import {
|
||||
getImageMagickDownloadUrl,
|
||||
getImageMagickManualInstallCommands,
|
||||
isImageMagickInstalled,
|
||||
} from "../utils/imagemagick-check";
|
||||
|
||||
|
|
@ -72,6 +73,33 @@ function commandExists(command: string, versionArgs: string[] = ["--version"]):
|
|||
return result.status === 0;
|
||||
}
|
||||
|
||||
function resolveBrewCommand(): string | null {
|
||||
if (commandExists("brew")) {
|
||||
return "brew";
|
||||
}
|
||||
|
||||
const candidates = ["/opt/homebrew/bin/brew", "/usr/local/bin/brew"];
|
||||
for (const candidate of candidates) {
|
||||
if (fs.existsSync(candidate)) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function resolveLinuxEscalationCommand(): string | null {
|
||||
if (commandExists("pkexec", ["--version"])) return "pkexec";
|
||||
if (commandExists("sudo", ["-V"])) return "sudo";
|
||||
return null;
|
||||
}
|
||||
|
||||
function logManualImageMagickCommands(wc: WebContents) {
|
||||
for (const line of getImageMagickManualInstallCommands()) {
|
||||
const level = line.endsWith(":") ? "info" : "cmd";
|
||||
sendImageMagickLog(wc, level, line);
|
||||
}
|
||||
}
|
||||
|
||||
function runInstallCommand(
|
||||
wc: WebContents,
|
||||
command: string,
|
||||
|
|
@ -210,7 +238,18 @@ export function setupSetupInstallHandlers() {
|
|||
|
||||
if (process.platform === "linux") {
|
||||
if (commandExists("apt-get")) {
|
||||
await runInstallCommand(wc, "pkexec", [
|
||||
const escalator = resolveLinuxEscalationCommand();
|
||||
if (!escalator) {
|
||||
throw new Error(
|
||||
"Neither pkexec nor sudo is available to run apt-get install."
|
||||
);
|
||||
}
|
||||
|
||||
await runInstallCommand(wc, escalator, [
|
||||
"apt-get",
|
||||
"update",
|
||||
]);
|
||||
await runInstallCommand(wc, escalator, [
|
||||
"apt-get",
|
||||
"install",
|
||||
"-y",
|
||||
|
|
@ -218,17 +257,30 @@ export function setupSetupInstallHandlers() {
|
|||
]);
|
||||
} else {
|
||||
throw new Error(
|
||||
"apt-get is unavailable. Install ImageMagick manually from the official download page."
|
||||
"apt-get is unavailable. Install ImageMagick manually using your package manager."
|
||||
);
|
||||
}
|
||||
} else if (process.platform === "darwin") {
|
||||
if (commandExists("brew")) {
|
||||
await runInstallCommand(wc, "brew", ["install", "imagemagick"]);
|
||||
} else {
|
||||
let brewCommand = resolveBrewCommand();
|
||||
if (!brewCommand) {
|
||||
sendImageMagickLog(
|
||||
wc,
|
||||
"info",
|
||||
"Homebrew not found. Installing Homebrew first..."
|
||||
);
|
||||
const installHomebrewCommand =
|
||||
'NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"';
|
||||
await runInstallCommand(wc, "/bin/bash", ["-c", installHomebrewCommand]);
|
||||
brewCommand = resolveBrewCommand();
|
||||
}
|
||||
|
||||
if (!brewCommand) {
|
||||
throw new Error(
|
||||
"Homebrew is not installed. Install ImageMagick manually from the official download page."
|
||||
"Homebrew installation completed, but brew was not found on PATH."
|
||||
);
|
||||
}
|
||||
|
||||
await runInstallCommand(wc, brewCommand, ["install", "imagemagick"]);
|
||||
} else if (process.platform === "win32") {
|
||||
if (commandExists("choco", ["-v"])) {
|
||||
await runInstallCommand(wc, "choco", [
|
||||
|
|
@ -238,7 +290,7 @@ export function setupSetupInstallHandlers() {
|
|||
]);
|
||||
} else {
|
||||
throw new Error(
|
||||
"Chocolatey is not installed. Install ImageMagick manually from the official download page."
|
||||
"Chocolatey is not installed. Falling back to direct installer download."
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -253,14 +305,21 @@ export function setupSetupInstallHandlers() {
|
|||
const message =
|
||||
error instanceof Error ? error.message : "ImageMagick install failed";
|
||||
sendImageMagickLog(wc, "error", message);
|
||||
logManualImageMagickCommands(wc);
|
||||
const downloadUrl = getImageMagickDownloadUrl();
|
||||
sendImageMagickLog(
|
||||
wc,
|
||||
"info",
|
||||
`Falling back to manual install page: ${downloadUrl}`
|
||||
`Opening manual install link: ${downloadUrl}`
|
||||
);
|
||||
await shell.openExternal(downloadUrl);
|
||||
return { ok: true };
|
||||
sendImageMagickProgress(
|
||||
wc,
|
||||
"error",
|
||||
undefined,
|
||||
"Finish manual installation, then click Retry."
|
||||
);
|
||||
return { ok: false, error: message };
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
|
|||
|
|
@ -18,10 +18,34 @@ export function isImageMagickInstalled(): boolean {
|
|||
|
||||
export function getImageMagickDownloadUrl(): string {
|
||||
if (process.platform === "win32") {
|
||||
return "https://imagemagick.org/script/download.php#windows";
|
||||
return "https://imagemagick.org/archive/binaries/ImageMagick-7.1.2-18-Q16-HDRI-x64-dll.exe";
|
||||
}
|
||||
if (process.platform === "darwin") {
|
||||
return "https://imagemagick.org/script/download.php#macosx";
|
||||
return "https://brew.sh/";
|
||||
}
|
||||
return "https://imagemagick.org/script/download.php#linux";
|
||||
}
|
||||
|
||||
export function getImageMagickManualInstallCommands(): string[] {
|
||||
if (process.platform === "win32") {
|
||||
return [
|
||||
"Download and run the installer:",
|
||||
getImageMagickDownloadUrl(),
|
||||
];
|
||||
}
|
||||
|
||||
if (process.platform === "darwin") {
|
||||
return [
|
||||
"Install Homebrew:",
|
||||
'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"',
|
||||
"Install ImageMagick:",
|
||||
"brew install imagemagick",
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
"Install ImageMagick:",
|
||||
"sudo apt-get update",
|
||||
"sudo apt-get install -y imagemagick",
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ const ocrEnabled = parseBool(readArg("--ocr-enabled"), true);
|
|||
const dpi = toNumber(readArg("--dpi"), 150, 72, 600);
|
||||
const numWorkers = toNumber(
|
||||
readArg("--num-workers"),
|
||||
Math.max(os.cpus().length - 4, 1),
|
||||
Math.max(os.cpus().length - 2, 1),
|
||||
1,
|
||||
64
|
||||
);
|
||||
|
|
|
|||
|
|
@ -288,7 +288,7 @@
|
|||
? '<strong>Presenton</strong> uses LibreOffice to generate custom templates from PPTX files.'
|
||||
: step === 'chrome'
|
||||
? '<strong>Presenton</strong> uses Chromium for export and slide rendering. Download it now (~150 MB).'
|
||||
: '<strong>Presenton</strong> uses ImageMagick for OCR/document conversion support. We will try automatic installation first, then open the download page if package manager tools are unavailable.';
|
||||
: '<strong>Presenton</strong> uses ImageMagick for OCR/document conversion support. Linux uses apt, macOS installs Homebrew first (if needed) and then runs brew install imagemagick, and Windows uses Chocolatey with a direct installer fallback.';
|
||||
document.getElementById('btn-install').onclick = () => startInstall(step);
|
||||
document.getElementById('btn-skip').onclick = () => handleSkip();
|
||||
showState('prompt');
|
||||
|
|
@ -315,8 +315,17 @@
|
|||
});
|
||||
} else {
|
||||
document.getElementById('dl-heading').textContent = 'Installing ImageMagick';
|
||||
document.getElementById('dl-phase').textContent = 'Automatic install (apt/brew/choco) with fallback to manual download';
|
||||
window.setupInstaller.installImageMagick().then(() => {
|
||||
document.getElementById('dl-phase').textContent = 'Linux: apt-get | macOS: Homebrew + brew install | Windows: choco or direct installer';
|
||||
window.setupInstaller.installImageMagick().then((installResult) => {
|
||||
if (!installResult || !installResult.ok) {
|
||||
if (currentStep !== 'imagemagick') return;
|
||||
document.getElementById('err-msg').textContent = installResult?.error || 'ImageMagick installation needs manual completion. Follow the shown commands and then click Retry.';
|
||||
showState('error');
|
||||
document.getElementById('btn-retry').onclick = () => startInstall('imagemagick');
|
||||
document.getElementById('btn-skip-error').onclick = () => nextOrDone();
|
||||
return;
|
||||
}
|
||||
|
||||
window.setupInstaller.checkImageMagick().then(res => {
|
||||
if (!res.ok && currentStep === 'imagemagick') {
|
||||
document.getElementById('err-msg').textContent = res.error || 'ImageMagick is not installed yet.';
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue