feat: add cross-platform Linux & Windows OS detection for Ghostscript and Tesseract OCR setup

This commit is contained in:
ssbg04 committed 2026-07-22 00:28:41 +08:00
1 parent f9706eb740
commit 81336b3f92
4 files changed
+156 -28

No files matched your search

+3 -4
View File
@@ -6,11 +6,10 @@ const path = require('path');
require('dotenv').config();
// ==========================================
// BUNDLED BINARIES FOR OCR (Ghostscript, Tesseract)
// CROSS-PLATFORM SYSTEM SETUP (Ghostscript, Tesseract)
// ==========================================
const gsPath = path.join(__dirname, 'ghostscript', 'bin');
const tessPath = path.join(__dirname, 'tesseract');
process.env.PATH = `${gsPath}${path.delimiter}${tessPath}${path.delimiter}${process.env.PATH}`;
const { setupSystemEnvironment } = require('./src/config/systemSetup');
setupSystemEnvironment();
const { initSchema } = require('./src/models/schema');
+81
View File
@@ -0,0 +1,81 @@
const path = require('path');
const fs = require('fs');
const { execSync } = require('child_process');
/**
* Cross-platform environment setup helper.
* On Windows: Configures bundled Ghostscript and Tesseract binaries from backend directory.
* On Linux (Ubuntu): Checks system binaries, attempts auto-setup if missing, and configures system tessdata.
*/
function setupSystemEnvironment() {
const isWindows = process.platform === 'win32';
const isLinux = process.platform === 'linux';
console.log(`[System Setup] Operating System detected: ${process.platform} (${isWindows ? 'Windows' : isLinux ? 'Linux/Ubuntu' : 'Other'})`);
if (isWindows) {
// WINDOWS: Use bundled binaries inside backend directory
const gsPath = path.join(__dirname, '..', '..', 'ghostscript', 'bin');
const tessPath = path.join(__dirname, '..', '..', 'tesseract');
process.env.PATH = `${gsPath}${path.delimiter}${tessPath}${path.delimiter}${process.env.PATH}`;
const localTessData = path.join(__dirname, '..', '..', 'tesseract', 'tessdata');
if (fs.existsSync(localTessData)) {
process.env.TESSDATA_PREFIX = localTessData;
}
console.log('[System Setup] Windows environment configured using bundled Ghostscript & Tesseract binaries.');
} else if (isLinux) {
// LINUX / UBUNTU: Check and use system installed packages
const ubuntuOneLiner = 'sudo apt-get update && sudo apt-get install -y ghostscript tesseract-ocr tesseract-ocr-eng libtesseract-dev';
let hasGs = false;
let hasTesseract = false;
try {
execSync('which gs', { stdio: 'ignore' });
hasGs = true;
} catch (_) {}
try {
execSync('which tesseract', { stdio: 'ignore' });
hasTesseract = true;
} catch (_) {}
if (!hasGs || !hasTesseract) {
console.warn('[System Setup] WARNING: Missing OCR dependencies on Linux system!');
if (!hasGs) console.warn(' - Ghostscript (gs) is NOT installed.');
if (!hasTesseract) console.warn(' - Tesseract (tesseract) is NOT installed.');
console.log('[System Setup] Attempting auto-setup for Ubuntu/Debian...');
try {
execSync(ubuntuOneLiner, { stdio: 'inherit' });
console.log('[System Setup] Auto-installation of Ghostscript & Tesseract completed successfully.');
} catch (_) {
console.warn('[System Setup] Auto-installation requires root/sudo privileges.');
console.log(`[System Setup] Run this command on your Ubuntu server:\n\n ${ubuntuOneLiner}\n`);
}
} else {
console.log('[System Setup] Linux environment verified: Ghostscript and Tesseract are installed.');
}
// Set TESSDATA_PREFIX for Linux (prioritize system paths, fallback to local tessdata)
const possibleTessDataPaths = [
'/usr/share/tesseract-ocr/4.00/tessdata',
'/usr/share/tesseract-ocr/5/tessdata',
'/usr/share/tessdata',
'/usr/share/tesseract-ocr/tessdata',
path.join(__dirname, '..', '..', 'tesseract', 'tessdata')
];
for (const tessDir of possibleTessDataPaths) {
if (fs.existsSync(tessDir)) {
process.env.TESSDATA_PREFIX = tessDir;
break;
}
}
}
}
module.exports = { setupSystemEnvironment };
+35 -24
View File
@@ -43,30 +43,36 @@ exports.extractOcrData = async (req, res) => {
req.file.path // Input PDF file
];
const isWindows = process.platform === 'win32';
try {
// Try gswin64c first, if it fails, fallback to gs
await execFileAsync('gswin64c', gsArgs);
} catch (err) {
if (err.code === 'ENOENT') {
// Fallback to gs or gswin32c if gswin64c doesn't exist
if (isWindows) {
try {
await execFileAsync('gs', gsArgs);
} catch (fallbackErr) {
try {
await execFileAsync('gswin32c', gsArgs);
} catch (finalErr) {
if (finalErr.code === 'ENOENT') {
return res.status(500).json({
message: 'Missing OCR Program',
error: 'Ghostscript is not installed or not added to PATH. PDF conversion failed.'
});
await execFileAsync('gswin64c', gsArgs);
} catch (err) {
if (err.code === 'ENOENT') {
try {
await execFileAsync('gs', gsArgs);
} catch (fallbackErr) {
await execFileAsync('gswin32c', gsArgs);
}
throw finalErr;
}
} else throw err;
}
} else {
throw err;
// Linux / Ubuntu: Run 'gs' executable directly from system PATH
await execFileAsync('gs', gsArgs);
}
} catch (finalErr) {
if (finalErr.code === 'ENOENT') {
const missingErr = isWindows
? 'Ghostscript is not installed or missing from backend/ghostscript folder.'
: 'Ghostscript (gs) is missing on Linux. Install via: sudo apt-get install -y ghostscript';
return res.status(500).json({
message: 'Missing OCR Program',
error: missingErr
});
}
throw finalErr;
}
console.log('[OCR] Ghostscript successfully generated PNG:', outputPngPath);
@@ -75,14 +81,16 @@ exports.extractOcrData = async (req, res) => {
}
// ==========================================
// 2. READ FILE INTO BUFFER
// ==========================================
// 3. RUN NATIVE TESSERACT EXECUTABLE
// 2. RUN NATIVE TESSERACT EXECUTABLE
// ==========================================
console.log('[OCR] Starting Native Tesseract Engine...');
// Ensure TESSDATA_PREFIX is set to the tesseract folder so it finds eng.traineddata
const tessEnv = { ...process.env, TESSDATA_PREFIX: path.join(__dirname, '..', '..', 'tesseract', 'tessdata') };
// Ensure TESSDATA_PREFIX fallback for both Windows and Linux
const defaultTessData = path.join(__dirname, '..', '..', 'tesseract', 'tessdata');
const tessEnv = {
...process.env,
TESSDATA_PREFIX: process.env.TESSDATA_PREFIX || defaultTessData
};
let stdout;
try {
@@ -94,9 +102,12 @@ exports.extractOcrData = async (req, res) => {
stdout = result.stdout;
} catch (tessErr) {
if (tessErr.code === 'ENOENT') {
const missingErr = process.platform === 'win32'
? 'Tesseract OCR is not installed or missing from backend/tesseract folder.'
: 'Tesseract OCR is missing on Linux. Install via: sudo apt-get install -y tesseract-ocr tesseract-ocr-eng';
return res.status(500).json({
message: 'Missing OCR Program',
error: 'Tesseract OCR is not installed or not added to PATH.'
error: missingErr
});
}
throw tessErr;
+37
View File
@@ -0,0 +1,37 @@
<!-- This markdown file is for making a installation for client and server -->
# Server
## folder directory
1. root: F:\SumbrerongBato\tis_rms_server\backend
2. copy the root files including node module for fully standalone to F:\SumbrerongBato\tis_rms_server\backend_build
- root folder have dummy data for testing, do not add data in the backend_build folder
## installer
- use inno setup compiler
- add save folder path for the installer, default to F:\SumbrerongBato\tis_rms_server\installers
- add checkbox for auto startup
- run in the background
- save on specific location in local example C:\TIS_RMS
- add logo icon on the installer
- add uninstaller
- separate with data and without data installer
## OS Dependency Setup (Ghostscript & Tesseract OCR)
The backend automatically detects the operating system on startup:
### 1. Windows Systems
- Uses the bundled binaries located inside the backend directory:
- `backend/ghostscript/bin`
- `backend/tesseract`
- No manual package installation required.
### 2. Linux / Ubuntu Systems
- Uses system-installed `ghostscript` and `tesseract-ocr`.
- The backend automatically checks for missing binaries on startup and attempts auto-installation if running as root/sudo.
- **One-line manual setup command for Ubuntu**:
```bash
sudo apt-get update && sudo apt-get install -y ghostscript tesseract-ocr tesseract-ocr-eng libtesseract-dev
```
---