|
|
|
|
@@ -239,13 +239,13 @@ async function compressPdfWithPs2Pdf(inputFile, outputFile, compression = 'ebook
|
|
|
|
|
// DIAGNOSI COMPLETA DEL PROBLEMA
|
|
|
|
|
async function diagnosePDFProblem() {
|
|
|
|
|
console.log('=== DIAGNOSI COMPLETA SISTEMA ===');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 1. Test ambiente Node.js
|
|
|
|
|
console.log('Node.js version:', process.version);
|
|
|
|
|
console.log('Platform:', process.platform);
|
|
|
|
|
console.log('Architecture:', process.arch);
|
|
|
|
|
console.log('Current working directory:', process.cwd());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 2. Test moduli disponibili
|
|
|
|
|
try {
|
|
|
|
|
console.log('Testing gs module...');
|
|
|
|
|
@@ -253,12 +253,12 @@ async function diagnosePDFProblem() {
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.log('gs module error:', error.message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 3. Test comando di sistema
|
|
|
|
|
const { exec } = require('child_process');
|
|
|
|
|
const util = require('util');
|
|
|
|
|
const execAsync = util.promisify(exec);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
console.log('Testing gs command from system...');
|
|
|
|
|
const { stdout, stderr } = await execAsync('gs -version');
|
|
|
|
|
@@ -267,12 +267,12 @@ async function diagnosePDFProblem() {
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.log('System gs command failed:', error.message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 4. Test scrittura file
|
|
|
|
|
const fs = require('fs').promises;
|
|
|
|
|
const path = require('path');
|
|
|
|
|
const testFile = path.join(process.cwd(), 'test_write.txt');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
await fs.writeFile(testFile, 'test content');
|
|
|
|
|
console.log('File write test: SUCCESS');
|
|
|
|
|
@@ -282,19 +282,18 @@ async function diagnosePDFProblem() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ALTERNATIVA 1: Usando child_process direttamente
|
|
|
|
|
async function convertPDF_ChildProcess(inputFile, outputFile, width, height, compressionLevel = 'screen') {
|
|
|
|
|
const { spawn } = require('child_process');
|
|
|
|
|
const path = require('path');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log('=== CONVERSIONE CON CHILD_PROCESS E COMPRESSIONE ===');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Verifica input
|
|
|
|
|
if (!(await tools.isFileExistsAsync(inputFile))) {
|
|
|
|
|
throw new Error(`File input non trovato: ${inputFile}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Assicurati che la directory output esista
|
|
|
|
|
const outputDir = path.dirname(outputFile);
|
|
|
|
|
const fs = require('fs').promises;
|
|
|
|
|
@@ -303,44 +302,40 @@ async function convertPDF_ChildProcess(inputFile, outputFile, width, height, com
|
|
|
|
|
} catch (error) {
|
|
|
|
|
// Directory già esistente, ok
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const widthPt = Math.round(width * 28.34646);
|
|
|
|
|
// const heightPt = Math.round(height * 28.34646);
|
|
|
|
|
const widthPt = Math.round(width * 28.34646* 10);
|
|
|
|
|
const widthPt = Math.round(width * 28.34646 * 10);
|
|
|
|
|
const heightPt = Math.round(height * 28.34646 * 10);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Parametri di compressione ottimizzati
|
|
|
|
|
const compressionSettings = {
|
|
|
|
|
'maximum': [
|
|
|
|
|
maximum: [
|
|
|
|
|
'-dPDFSETTINGS=/screen',
|
|
|
|
|
'-dDownsampleColorImages=true',
|
|
|
|
|
'-dColorImageResolution=72',
|
|
|
|
|
'-dDownsampleGrayImages=true',
|
|
|
|
|
'-dDownsampleGrayImages=true',
|
|
|
|
|
'-dGrayImageResolution=72',
|
|
|
|
|
'-dDownsampleMonoImages=true',
|
|
|
|
|
'-dMonoImageResolution=72'
|
|
|
|
|
'-dMonoImageResolution=72',
|
|
|
|
|
],
|
|
|
|
|
'high': [
|
|
|
|
|
high: [
|
|
|
|
|
'-dPDFSETTINGS=/ebook',
|
|
|
|
|
'-dDownsampleColorImages=true',
|
|
|
|
|
'-dColorImageResolution=150',
|
|
|
|
|
'-dDownsampleGrayImages=true',
|
|
|
|
|
'-dGrayImageResolution=150'
|
|
|
|
|
'-dGrayImageResolution=150',
|
|
|
|
|
],
|
|
|
|
|
'printer': [
|
|
|
|
|
'-dPDFSETTINGS=/printer',
|
|
|
|
|
'-dDownsampleColorImages=true',
|
|
|
|
|
'-dColorImageResolution=300'
|
|
|
|
|
],
|
|
|
|
|
'screen': [
|
|
|
|
|
printer: ['-dPDFSETTINGS=/printer', '-dDownsampleColorImages=true', '-dColorImageResolution=300'],
|
|
|
|
|
screen: [
|
|
|
|
|
'-dPDFSETTINGS=/screen',
|
|
|
|
|
'-dDownsampleColorImages=true',
|
|
|
|
|
'-dColorImageResolution=96',
|
|
|
|
|
'-dDownsampleGrayImages=true',
|
|
|
|
|
'-dGrayImageResolution=96'
|
|
|
|
|
]
|
|
|
|
|
'-dGrayImageResolution=96',
|
|
|
|
|
],
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
const args = [
|
|
|
|
|
'-sDEVICE=pdfwrite',
|
|
|
|
|
@@ -349,52 +344,53 @@ async function convertPDF_ChildProcess(inputFile, outputFile, width, height, com
|
|
|
|
|
'-dQUIET',
|
|
|
|
|
'-dBATCH',
|
|
|
|
|
'-dSAFER',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Parametri di compressione
|
|
|
|
|
...compressionSettings[compressionLevel] || compressionSettings['screen'],
|
|
|
|
|
...(compressionSettings[compressionLevel] || compressionSettings['screen']),
|
|
|
|
|
'-dCompressFonts=true',
|
|
|
|
|
'-dSubsetFonts=true',
|
|
|
|
|
'-dColorImageFilter=/DCTEncode',
|
|
|
|
|
'-dGrayImageFilter=/DCTEncode',
|
|
|
|
|
'-dEmbedAllFonts=true',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Dimensioni pagina
|
|
|
|
|
`-g${widthPt}x${heightPt}`,
|
|
|
|
|
'-dFIXEDMEDIA',
|
|
|
|
|
// '-dPDFFitPage',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Output
|
|
|
|
|
`-sOutputFile=${outputFile}`,
|
|
|
|
|
inputFile
|
|
|
|
|
inputFile,
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log('Spawning gs with compression args:', args.join(' '));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const gsProcess = spawn('gs', args, {
|
|
|
|
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
|
|
|
shell: process.platform === 'win32'
|
|
|
|
|
shell: process.platform === 'win32',
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let stdout = '';
|
|
|
|
|
let stderr = '';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gsProcess.stdout.on('data', (data) => {
|
|
|
|
|
stdout += data.toString();
|
|
|
|
|
if (stdout.length < 1000) { // Evita log troppo lunghi
|
|
|
|
|
if (stdout.length < 1000) {
|
|
|
|
|
// Evita log troppo lunghi
|
|
|
|
|
console.log('GS OUT:', data.toString().trim());
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gsProcess.stderr.on('data', (data) => {
|
|
|
|
|
stderr += data.toString();
|
|
|
|
|
if (stderr.length < 1000) {
|
|
|
|
|
console.log('GS ERR:', data.toString().trim());
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gsProcess.on('close', async (code) => {
|
|
|
|
|
console.log(`GS process closed with code: ${code}`);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (code === 0) {
|
|
|
|
|
// Attendi e verifica
|
|
|
|
|
setTimeout(async () => {
|
|
|
|
|
@@ -405,8 +401,8 @@ async function convertPDF_ChildProcess(inputFile, outputFile, width, height, com
|
|
|
|
|
try {
|
|
|
|
|
const originalStats = await tools.getFileStatsAsync(inputFile);
|
|
|
|
|
const newStats = await tools.getFileStatsAsync(outputFile);
|
|
|
|
|
const compressionRatio = ((originalStats.size - newStats.size) / originalStats.size * 100).toFixed(1);
|
|
|
|
|
|
|
|
|
|
const compressionRatio = (((originalStats.size - newStats.size) / originalStats.size) * 100).toFixed(1);
|
|
|
|
|
|
|
|
|
|
console.log(`📁 File originale: ${(originalStats.size / 1024 / 1024).toFixed(2)} MB`);
|
|
|
|
|
console.log(`📁 File compresso: ${(newStats.size / 1024 / 1024).toFixed(2)} MB`);
|
|
|
|
|
console.log(`🗜️ Compressione: ${compressionRatio}%`);
|
|
|
|
|
@@ -414,7 +410,7 @@ async function convertPDF_ChildProcess(inputFile, outputFile, width, height, com
|
|
|
|
|
} catch (statsError) {
|
|
|
|
|
console.log('Warning: impossibile calcolare statistiche compressione');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
resolve(outputFile);
|
|
|
|
|
} else {
|
|
|
|
|
console.log('❌ FAIL: File non generato nonostante exit code 0');
|
|
|
|
|
@@ -428,7 +424,7 @@ async function convertPDF_ChildProcess(inputFile, outputFile, width, height, com
|
|
|
|
|
reject(new Error(`Ghostscript failed with code ${code}: ${stderr}`));
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gsProcess.on('error', (error) => {
|
|
|
|
|
console.log('GS process error:', error);
|
|
|
|
|
reject(new Error(`Failed to start Ghostscript: ${error.message}`));
|
|
|
|
|
@@ -631,6 +627,7 @@ router.post('/online-pdf', authenticate, async (req, res) => {
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
let myrec = null;
|
|
|
|
|
|
|
|
|
|
// Aggiorna il PDF OnLine, copiando il file da Generato a OnLine
|
|
|
|
|
if (id_catalog) {
|
|
|
|
|
myrec = await Catalog.findOne({ _id: id_catalog });
|
|
|
|
|
@@ -645,7 +642,7 @@ router.post('/online-pdf', authenticate, async (req, res) => {
|
|
|
|
|
if (stampa) {
|
|
|
|
|
myrec.pdf_online_stampa = myrec.pdf_generato_stampa.replace('_generato', '');
|
|
|
|
|
} else {
|
|
|
|
|
myrec.pdf_online = myrec.pdf_generato.replace('_generato', '');
|
|
|
|
|
myrec.pdf_online = myrec.pdf_generato?.replace('_generato', '');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Aggiorna il PDF OnLine, copiando il file da Generato a OnLine
|
|
|
|
|
@@ -699,17 +696,20 @@ async function JoinPDFCatalogs(cataloghi, options, outputFile, stampa) {
|
|
|
|
|
for (let id_catalog of cataloghi) {
|
|
|
|
|
let catalog = await Catalog.findOne({ _id: id_catalog });
|
|
|
|
|
if (catalog) {
|
|
|
|
|
let filename = stampa ? catalog.pdf_generato_stampa : catalog.pdf_generato;
|
|
|
|
|
let filename = stampa ? catalog.pdf_online_stampa : catalog.pdf_online;
|
|
|
|
|
if (filename) {
|
|
|
|
|
const pdfBytes = await fs.promises.readFile(options.mydir + filename);
|
|
|
|
|
const pdf = await PDFDocument.load(pdfBytes);
|
|
|
|
|
const pages = pdf.getPages();
|
|
|
|
|
const copiedPages = await pdfDoc.copyPages(
|
|
|
|
|
pdf,
|
|
|
|
|
pages.map((p, i) => i)
|
|
|
|
|
);
|
|
|
|
|
for (let page of copiedPages) {
|
|
|
|
|
pdfDoc.addPage(page);
|
|
|
|
|
let myfile = tools.fixFilePath(options.mydir + '/' + filename);
|
|
|
|
|
if (await tools.isFileExistsAsync(myfile)) {
|
|
|
|
|
const pdfBytes = await fs.promises.readFile(myfile);
|
|
|
|
|
const pdf = await PDFDocument.load(pdfBytes);
|
|
|
|
|
const pages = pdf.getPages();
|
|
|
|
|
const copiedPages = await pdfDoc.copyPages(
|
|
|
|
|
pdf,
|
|
|
|
|
pages.map((p, i) => i)
|
|
|
|
|
);
|
|
|
|
|
for (let page of copiedPages) {
|
|
|
|
|
pdfDoc.addPage(page);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
console.log('ATTENZIONE! Catalogo non ancora Generato ! ', catalog.title);
|
|
|
|
|
@@ -725,6 +725,12 @@ async function JoinPDFCatalogs(cataloghi, options, outputFile, stampa) {
|
|
|
|
|
const outputFilename = path.basename(outputFile);
|
|
|
|
|
const outputPath = path.join(options.dir_out, outputFilename);
|
|
|
|
|
|
|
|
|
|
if (await tools.isFileExistsAsync(outputFile)) {
|
|
|
|
|
console.log('✅ Catalogo Completo Generato correttamente ! ', outputFile);
|
|
|
|
|
} else {
|
|
|
|
|
console.log('❌ Catalogo non generato ! ', outputFile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const ris = {
|
|
|
|
|
outputPath,
|
|
|
|
|
};
|
|
|
|
|
@@ -746,7 +752,8 @@ router.post('/join-pdf', authenticate, async (req, res) => {
|
|
|
|
|
options.mydir = tools.getdirByIdApp(idapp);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const full_dir_out = tools.getdirByIdApp(options.idapp) + '/' + options.dir_out;
|
|
|
|
|
const mydirpath = tools.getdirByIdApp(options.idapp);
|
|
|
|
|
const full_dir_out = tools.fixFilePath(path.join(mydirpath, options.dir_out));
|
|
|
|
|
await fs.promises.mkdir(full_dir_out, { recursive: true });
|
|
|
|
|
|
|
|
|
|
// Aggiorna il PDF OnLine, copiando il file da Generato a OnLine
|
|
|
|
|
@@ -767,13 +774,16 @@ router.post('/join-pdf', authenticate, async (req, res) => {
|
|
|
|
|
const ris_stampa = await JoinPDFCatalogs(cataloghi, options, outputFileStampa, true);
|
|
|
|
|
if (ris_stampa) {
|
|
|
|
|
raccolta.pdf_generato_stampa = ris_stampa.outputPath;
|
|
|
|
|
let myfilecheckstampa = path.join(mydirpath, ris_stampa.outputPath);
|
|
|
|
|
raccolta.pdf_generato_stampa_size = await tools.getSizeFile(myfilecheckstampa);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// Creazione file per WEB
|
|
|
|
|
const ris = await JoinPDFCatalogs(cataloghi, options, outputFile, false);
|
|
|
|
|
if (ris) {
|
|
|
|
|
raccolta.pdf_generato = ris.outputPath;
|
|
|
|
|
raccolta.pdf_generato_size = await tools.getSizeFile(ris.outputPath);
|
|
|
|
|
let myfilecheck = path.join(mydirpath, ris.outputPath);
|
|
|
|
|
raccolta.pdf_generato_size = await tools.getSizeFile(myfilecheck);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2663,5 +2673,4 @@ router.post('/generate-pdf', async (req, res) => {
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
module.exports = router;
|
|
|
|
|
|