feat: add cross-platform Linux & Windows OS detection for Ghostscript and Tesseract OCR setup
This commit is contained in:
1 parent
f9706eb740
commit
81336b3f92
4 files changed
+156
-28
No files matched your search
+3
-4
@@ -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');
|
||||
|
||||
@@ -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 };
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
---
|
||||
Reference in new issue
Block a user