pdfgen/routes.js
2025-08-16 07:28:01 +00:00

634 lines
27 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* ROUTES
*/
const { TextEncoder, TextDecoder } = require('util');
const fs = require('fs');
// const fsPromises = require('fs').promises; // Добавим для проверки файла перед отправкой
const path = require('path');
const multer = require('multer');
const {
pdfFillDataXfinity,
pdfFillDataCOX,
pdfFillDataATT,
pdfFillDataSpectrum,
pdfFillDataDukeEnergy,
pdfFillDataAEPOhio,
pdfFillDataEntergy,
pdfFillDataPGE,
pdfFillDataVerizon
} = require('./lib/pdf-fill-data/src');
const appConfig = require('./config');
/**
* API GLOBAL
*/
global.TextEncoder = global.TextEncoder || TextEncoder;
global.TextDecoder = global.TextDecoder || TextDecoder;
/**
* API CONSTANTS
*/
const SECRET_KEY = appConfig.token;
const authenticateToken = (req, res, next) => {
let token = null;
// 1. Сначала ищем токен в заголовке
const authHeader = req.headers['authorization'];
if (authHeader) {
token = authHeader.split(' ')[1];
}
// 2. Если в заголовке нет, ищем в параметрах URL
if (!token && req.query.token) {
token = req.query.token;
}
if (!token) {
return res.status(401).json({ error: 'Token not found' });
}
if (token != SECRET_KEY) {
return res.status(403).json({ error: 'Token is not valid' });
}
next();
};
const storage = multer.diskStorage({
destination: function (req, file, cb) {
const uploadDir = path.join(__dirname, 'public', 'csv');
if (!fs.existsSync(uploadDir)) {
fs.mkdirSync(uploadDir, { recursive: true });
}
cb(null, uploadDir);
},
filename: function (req, file, cb) {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
cb(null, file.fieldname + '-' + uniqueSuffix + path.extname(file.originalname));
}
});
const upload = multer({
storage: storage,
fileFilter: (req, file, cb) => {
if (path.extname(file.originalname) !== '.csv') {
return cb(new Error('Only CSV files are allowed'));
}
cb(null, true);
},
limits: { fileSize: 5 * 1024 * 1024 }
});
// Создание экземпляров всех классов
const pXfinity = new pdfFillDataXfinity();
const pCOX = new pdfFillDataCOX();
const pATT = new pdfFillDataATT();
const pSpectrum = new pdfFillDataSpectrum();
const pDukeEnergy = new pdfFillDataDukeEnergy();
const pEntergy = new pdfFillDataEntergy();
const pAEPOhio = new pdfFillDataAEPOhio();
const pPGE = new pdfFillDataPGE();
const pVerizon = new pdfFillDataVerizon();
/**
* Template path
*/
pXfinity.setTemplatePath(path.join(__dirname, '/public/template/Xfinity.pdf'));
pCOX.setTemplatePath(path.join(__dirname, '/public/template/COX.pdf'));
pATT.setTemplatePath(path.join(__dirname, '/public/template/ATT.pdf'));
pSpectrum.setTemplatePath(path.join(__dirname, '/public/template/SPECTRUM.pdf'));
pDukeEnergy.setTemplatePath(path.join(__dirname, '/public/template/DukeEnergy.pdf'));
pAEPOhio.setTemplatePath(path.join(__dirname, '/public/template/AEPOhio.pdf'));
pEntergy.setTemplatePath(path.join(__dirname, '/public/template/Entergy.pdf'));
pPGE.setTemplatePath(path.join(__dirname, '/public/template/pge_template.pdf'));
pVerizon.setTemplatePath(path.join(__dirname, '/public/template/verizon_template.pdf'));
/**
* CSV path
*/
pXfinity.setTemplateCSVPath(path.join(__dirname, '/public/csv/Xfinity_States_Plans_by_Region.csv'));
pXfinity.setTemplateSocrCSVPath(path.join(__dirname, '/public/csv/Xfinity_socr.csv'));
/**
* API ACTIONS
*/
pXfinity.initTaxClient(appConfig.taxtoken);
pCOX.initTaxClient(appConfig.taxtoken);
pATT.initTaxClient(appConfig.taxtoken);
pSpectrum.initTaxClient(appConfig.taxtoken);
pDukeEnergy.initTaxClient(appConfig.taxtoken);
pAEPOhio.initTaxClient(appConfig.taxtoken);
pPGE.initTaxClient(appConfig.taxtoken);
pVerizon.initTaxClient(appConfig.taxtoken);
pXfinity.loadTariffs();
pXfinity.loadSocr();
// MODULE
// routes.js
// ... (весь код до module.exports остается без изменений) ...
// MODULE
module.exports = function (app) {
app.get('/', function (req, res) {
console.log("==================================");
console.log("HOME");
console.log("==================================");
res.render('home', { title: 'PDFGEN' });
});
app.get('/aep-ohio-form', function (req, res) {
res.render('aep_ohio_form', { title: 'AEP Ohio Form' }); // 'aep_ohio_form' - это имя вашего EJS файла
});
app.get('/entergy-form', function (req, res) {
res.render('entergy_form', { title: 'AEP Ohio Form' });
});
app.get('/pge-form', function (req, res) {
res.render('pge_form', { title: 'PG&E PDF Generation Form' });
});
app.get('/verizon-form', function (req, res) {
res.render('verizon_form', { title: 'PG&E PDF Generation Form' });
});
app.get('/api/v1', function (req, res) {
console.log("==================================");
console.log("API");
console.log("==================================");
res.render('api', { title: 'PDFGEN API' });
});
// --- Xfinity API ---
app.post('/api/v1/Xfinity', authenticateToken, async function (req, res) {
console.log("==================================");
console.log("API Xfinity (Memory Mode)");
console.log("==================================");
try {
await pXfinity.checkAccessTemplate();
await pXfinity.initPdfDoc();
await pXfinity.initBaseFonts();
await pXfinity.initCustomFonts([
path.join(__dirname, '/public/fonts/XfinityBrownTT-Light.ttf'),
path.join(__dirname, '/public/fonts/XfinityBrownTT-Regular.ttf'),
path.join(__dirname, '/public/fonts/XfinityBrownTT-Bold.ttf'),
path.join(__dirname, '/public/fonts/OcrA.ttf')
]);
await pXfinity.initPages();
await pXfinity.setFields(req.body);
await pXfinity.draw();
const pdfBytes = await pXfinity.pdfDoc.save();
const filename = pXfinity.generateFilename('Xfinity');
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
res.setHeader('Content-Length', pdfBytes.length);
res.end(pdfBytes);
console.log(`File ${filename} (Xfinity) has been sent successfully from memory.`);
} catch (error) {
console.error('Error in Xfinity PDF generation:', error);
if (!res.headersSent) {
res.status(500).json({ error: 'Error generating Xfinity PDF: ' + error.message });
}
}
});
app.get('/api/v1/Xfinity/tariffs', (req, res) => {
res.json(pXfinity.getTariffsCache());
});
app.get('/api/v1/Xfinity/socr', (req, res) => {
res.json(pXfinity.getSocrCache());
});
app.post('/api/v1/Xfinity/tariffs/upload', authenticateToken, upload.single('csvFile'), (req, res) => {
if (!req.file) {
return res.status(400).json({ error: 'No file uploaded' });
}
fs.renameSync(req.file.path, pXfinity.getTemplateCSVPath());
pXfinity.loadTariffs();
res.send('OK');
});
// --- COX API ---
app.post('/api/v1/COX', authenticateToken, async function (req, res) {
console.log("==================================");
console.log("API COX (Memory Mode)");
console.log("==================================");
try {
await pCOX.checkAccessTemplate();
await pCOX.initPdfDoc();
await pCOX.initBaseFonts();
await pCOX.initCustomFonts([
path.join(__dirname, '/public/fonts/OpenSans-Regular.ttf'),
path.join(__dirname, '/public/fonts/OpenSans-Bold.ttf'),
path.join(__dirname, '/public/fonts/avenir-lt-std-heavy.ttf'),
path.join(__dirname, '/public/fonts/avenir-lt-std-roman.ttf'),
path.join(__dirname, '/public/fonts/OCRAStd.ttf')
]);
await pCOX.initPages();
await pCOX.setFields(req.body);
await pCOX.draw();
const pdfBytes = await pCOX.pdfDoc.save();
const filename = pCOX.generateFilename('COX');
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
res.setHeader('Content-Length', pdfBytes.length);
res.end(pdfBytes);
console.log(`File ${filename} (COX) has been sent successfully from memory.`);
} catch (error) {
console.error('Error in COX PDF generation:', error);
if (!res.headersSent) {
res.status(500).json({ error: 'Error generating COX PDF: ' + error.message });
}
}
});
// --- ATT API ---
app.post('/api/v1/ATT', authenticateToken, async function (req, res) {
console.log("==================================");
console.log("API ATT (Memory Mode)");
console.log("==================================");
try {
await pATT.checkAccessTemplate();
await pATT.initPdfDoc();
await pATT.initBaseFonts();
await pATT.initCustomFonts([
path.join(__dirname, '/public/fonts/OCRAStd.ttf'),
path.join(__dirname, '/public/fonts/ATT Aleck Sans Regular.ttf'),
path.join(__dirname, '/public/fonts/ATT Aleck Sans Medium Regular.ttf'),
path.join(__dirname, '/public/fonts/ATT Aleck Sans Italic.ttf'),
path.join(__dirname, '/public/fonts/ATT Aleck Sans Black Regular.ttf'),
path.join(__dirname, '/public/fonts/ATT Aleck Sans Black Italic.ttf')
]);
await pATT.initPages();
await pATT.setFields(req.body);
await pATT.draw();
const pdfBytes = await pATT.pdfDoc.save();
const filename = pATT.generateFilename('ATT');
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
res.setHeader('Content-Length', pdfBytes.length);
res.end(pdfBytes);
console.log(`File ${filename} (ATT) has been sent successfully from memory.`);
} catch (error) {
console.error('Error in ATT PDF generation:', error);
if (!res.headersSent) {
res.status(500).json({ error: 'Error generating ATT PDF: ' + error.message });
}
}
});
// --- Spectrum API ---
app.post('/api/v1/Spectrum', authenticateToken, async function (req, res) {
console.log("==================================");
console.log("API Spectrum (Memory Mode)");
console.log("==================================");
try {
await pSpectrum.checkAccessTemplate();
await pSpectrum.initPdfDoc();
await pSpectrum.initBaseFonts();
await pSpectrum.initCustomFonts([
path.join(__dirname, '/public/fonts/OCRAStd.ttf'),
path.join(__dirname, '/public/fonts/ATT Aleck Sans Regular.ttf'),
path.join(__dirname, '/public/fonts/ATT Aleck Sans Medium Regular.ttf'),
path.join(__dirname, '/public/fonts/ATT Aleck Sans Italic.ttf'),
path.join(__dirname, '/public/fonts/ATT Aleck Sans Black Regular.ttf'),
path.join(__dirname, '/public/fonts/ATT Aleck Sans Black Italic.ttf')
]);
await pSpectrum.initPages();
await pSpectrum.setFields(req.body);
// Убедитесь, что для Spectrum есть метод draw. В одном из файлов он был закомментирован.
await pSpectrum.draw();
const pdfBytes = await pSpectrum.pdfDoc.save();
const filename = pSpectrum.generateFilename('Spectrum');
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
res.setHeader('Content-Length', pdfBytes.length);
res.end(pdfBytes);
console.log(`File ${filename} (Spectrum) has been sent successfully from memory.`);
} catch (error) {
console.error('Error in Spectrum PDF generation:', error);
if (!res.headersSent) {
res.status(500).json({ error: 'Error generating Spectrum PDF: ' + error.message });
}
}
});
// --- DukeEnergy API ---
app.post('/api/v1/DukeEnergy', authenticateToken, async function (req, res) {
console.log("==================================");
console.log("API DukeEnergy (Memory Mode)");
console.log("==================================");
try {
await pDukeEnergy.checkAccessTemplate();
await pDukeEnergy.initPdfDoc();
await pDukeEnergy.initBaseFonts();
await pDukeEnergy.initCustomFonts([
path.join(__dirname, '/public/fonts/OpenSans-Bold.ttf'),
path.join(__dirname, '/public/fonts/OpenSans-Regular.ttf')
]);
await pDukeEnergy.initPages();
await pDukeEnergy.setFields(req.body);
await pDukeEnergy.draw();
const pdfBytes = await pDukeEnergy.pdfDoc.save();
const filename = pDukeEnergy.generateFilename('DukeEnergy');
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
res.setHeader('Content-Length', pdfBytes.length);
res.end(pdfBytes);
console.log(`File ${filename} (DukeEnergy) has been sent successfully from memory.`);
} catch (error) {
console.error('Error in DukeEnergy PDF generation:', error);
if (!res.headersSent) {
res.status(500).json({ error: 'Error generating DukeEnergy PDF: ' + error.message });
}
}
});
// --- AEPOhio API ---
app.post('/api/v1/AEPOhio', authenticateToken, async function (req, res) {
console.log("==================================");
console.log("API AEPOhio (Memory Mode)");
console.log("==================================");
try {
await pAEPOhio.checkAccessTemplate();
await pAEPOhio.initPdfDoc();
await pAEPOhio.initBaseFonts();
await pAEPOhio.initCustomFonts([
path.join(__dirname, '/public/fonts/Gotham-Bold.otf'),
path.join(__dirname, '/public/fonts/Gotham-Book.otf'),
path.join(__dirname, '/public/fonts/OcrA.ttf')
]);
await pAEPOhio.initPages();
await pAEPOhio.setFields(req.body);
await pAEPOhio.draw();
const pdfBytes = await pAEPOhio.pdfDoc.save();
const filename = pAEPOhio.generateFilename('AEPOhio');
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
res.setHeader('Content-Length', pdfBytes.length);
res.end(pdfBytes);
console.log(`File ${filename} (AEPOhio) has been sent successfully from memory.`);
} catch (error) {
console.error('Error in AEPOhio PDF generation:', error);
if (!res.headersSent) {
res.status(500).json({ error: 'Error generating AEPOhio PDF: ' + error.message });
}
}
});
// --- Entergy API ---
app.post('/api/v1/Entergy', authenticateToken, async function (req, res) {
console.log("==================================");
console.log("API Entergy (Memory Mode)");
console.log("==================================");
try {
await pEntergy.checkAccessTemplate();
await pEntergy.initPdfDoc();
await pEntergy.initBaseFonts(); // Helvetica
await pEntergy.initCustomFonts([
// Укажите пути к шрифтам, которые будете использовать для Entergy
path.join(__dirname, '/public/fonts/OpenSans-Bold.ttf'),
path.join(__dirname, '/public/fonts/OpenSans-Regular.ttf'),
path.join(__dirname, '/public/fonts/OcrA.ttf') // для штрих-кода, если нужно
]);
await pEntergy.initPages();
await pEntergy.setFields(req.body);
await pEntergy.draw();
const pdfBytes = await pEntergy.pdfDoc.save();
const filename = pEntergy.generateFilename('Entergy');
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
res.setHeader('Content-Length', pdfBytes.length);
res.end(pdfBytes);
console.log(`File ${filename} (Entergy) has been sent successfully from memory.`);
} catch (error) {
console.error('Error in Entergy PDF generation:', error);
if (!res.headersSent) {
res.status(500).json({ error: 'Error generating Entergy PDF: ' + error.message });
}
}
});
app.post('/api/v1/PGE', authenticateToken, async function (req, res) {
console.log("==================================");
console.log("API PGE (SVG Parser Mode)");
console.log("==================================");
try {
await pPGE.checkAccessTemplate();
await pPGE.initPdfDoc(); // Загружаем PDF-основу
await pPGE.initBaseFonts();
// Загрузите шрифты, которые используются в SVG (например, Arial, Myriad Pro)
await pPGE.initCustomFonts([
path.join(__dirname, '/public/fonts/ArialBold.ttf'),
path.join(__dirname, '/public/fonts/Arial.ttf'),
path.join(__dirname, '/public/fonts/ARIALNB.TTF'),
path.join(__dirname, '/public/fonts/ARIALN.TTF'),
path.join(__dirname, '/public/fonts/ArialItalic.ttf'),
// ...
]);
await pPGE.initPages();
await pPGE.setFields(req.body);
await pPGE.draw(); // Этот метод теперь вызывает parseAndDrawSVG
const pdfBytes = await pPGE.pdfDoc.save();
const filename = pPGE.generateFilename('PGE');
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
res.end(pdfBytes);
} catch (error) {
console.error('Error in PGE PDF generation:', error);
if (!res.headersSent) {
res.status(500).json({ error: 'Error generating PGE PDF: ' + error.message });
}
}
});
app.post('/api/v1/Verizon', authenticateToken, async function (req, res) {
console.log("==================================");
console.log("API Verizon (SVG Parser Mode)");
console.log("==================================");
try {
await pVerizon.checkAccessTemplate();
await pVerizon.initPdfDoc();
await pVerizon.initBaseFonts(); // Helvetica (ifont 0)
await pVerizon.initCustomFonts([
path.join(__dirname, '/public/fonts/ArialBold.ttf'),
path.join(__dirname, '/public/fonts/Arial.ttf'),
path.join(__dirname, '/public/fonts/OcrA.ttf'), // для штрих-кода, если нужно
path.join(__dirname, '/public/fonts/kalypsa.ttf')
]);
await pVerizon.initPages();
await pVerizon.setFields(req.body);
await pVerizon.draw(); // Вызывает parseAndDrawSVG
const pdfBytes = await pVerizon.pdfDoc.save();
const filename = pVerizon.generateFilename('Verizon');
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
res.end(pdfBytes);
} catch (error) {
console.error('Error in Verizon PDF generation:', error);
if (!res.headersSent) {
res.status(500).json({ error: 'Error generating Verizon PDF: ' + error.message });
}
}
});
/////////////////////////////////////////////////////////////////////////////////////
// --- AEPOhio API ---
app.get('/api/v1/AEPOhio/random', authenticateToken, async function (req, res) {
console.log("==================================");
console.log("API AEPOhio (Memory Mode)");
console.log("==================================");
try {
await pAEPOhio.checkAccessTemplate();
await pAEPOhio.initPdfDoc();
await pAEPOhio.initBaseFonts();
await pAEPOhio.initCustomFonts([
path.join(__dirname, '/public/fonts/Gotham-Bold.otf'),
path.join(__dirname, '/public/fonts/Gotham-Book.otf'),
path.join(__dirname, '/public/fonts/OcrA.ttf')
]);
await pAEPOhio.initPages();
await pAEPOhio.setFields({});
await pAEPOhio.draw();
const pdfBytes = await pAEPOhio.pdfDoc.save();
const filename = pAEPOhio.generateFilename('AEPOhio');
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
res.setHeader('Content-Length', pdfBytes.length);
res.end(pdfBytes);
console.log(`File ${filename} (AEPOhio) has been sent successfully from memory.`);
} catch (error) {
console.error('Error in AEPOhio PDF generation:', error);
if (!res.headersSent) {
res.status(500).json({ error: 'Error generating AEPOhio PDF: ' + error.message });
}
}
});
// --- Entergy API ---
app.get('/api/v1/Entergy/random', authenticateToken, async function (req, res) {
console.log("==================================");
console.log("API Entergy (Memory Mode)");
console.log("==================================");
try {
await pEntergy.checkAccessTemplate();
await pEntergy.initPdfDoc();
await pEntergy.initBaseFonts(); // Helvetica
await pEntergy.initCustomFonts([
// Укажите пути к шрифтам, которые будете использовать для Entergy
path.join(__dirname, '/public/fonts/OpenSans-Bold.ttf'),
path.join(__dirname, '/public/fonts/OpenSans-Regular.ttf'),
path.join(__dirname, '/public/fonts/OcrA.ttf') // для штрих-кода, если нужно
]);
await pEntergy.initPages();
await pEntergy.setFields({});
await pEntergy.draw();
const pdfBytes = await pEntergy.pdfDoc.save();
const filename = pEntergy.generateFilename('Entergy');
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
res.setHeader('Content-Length', pdfBytes.length);
res.end(pdfBytes);
console.log(`File ${filename} (Entergy) has been sent successfully from memory.`);
} catch (error) {
console.error('Error in Entergy PDF generation:', error);
if (!res.headersSent) {
res.status(500).json({ error: 'Error generating Entergy PDF: ' + error.message });
}
}
});
app.get('/api/v1/PGE/random', authenticateToken, async function (req, res) {
console.log("==================================");
console.log("API PGE (SVG Parser Mode)");
console.log("==================================");
try {
await pPGE.checkAccessTemplate();
await pPGE.initPdfDoc(); // Загружаем PDF-основу
await pPGE.initBaseFonts();
// Загрузите шрифты, которые используются в SVG (например, Arial, Myriad Pro)
await pPGE.initCustomFonts([
path.join(__dirname, '/public/fonts/ArialBold.ttf'),
path.join(__dirname, '/public/fonts/Arial.ttf'),
path.join(__dirname, '/public/fonts/ARIALNB.TTF'),
path.join(__dirname, '/public/fonts/ARIALN.TTF'),
path.join(__dirname, '/public/fonts/ArialItalic.ttf'),
// ...
]);
await pPGE.initPages();
await pPGE.setFields({});
await pPGE.draw(); // Этот метод теперь вызывает parseAndDrawSVG
const pdfBytes = await pPGE.pdfDoc.save();
const filename = pPGE.generateFilename('PGE');
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
res.end(pdfBytes);
} catch (error) {
console.error('Error in PGE PDF generation:', error);
if (!res.headersSent) {
res.status(500).json({ error: 'Error generating PGE PDF: ' + error.message });
}
}
});
app.get('/api/v1/Verizon/random', authenticateToken, async function (req, res) {
console.log("==================================");
console.log("API Verizon (SVG Parser Mode)");
console.log("==================================");
try {
await pVerizon.checkAccessTemplate();
await pVerizon.initPdfDoc();
await pVerizon.initBaseFonts(); // Helvetica (ifont 0)
await pVerizon.initCustomFonts([
path.join(__dirname, '/public/fonts/ArialBold.ttf'),
path.join(__dirname, '/public/fonts/Arial.ttf'),
path.join(__dirname, '/public/fonts/OcrA.ttf'), // для штрих-кода, если нужно
path.join(__dirname, '/public/fonts/kalypsa.ttf')
]);
await pVerizon.initPages();
await pVerizon.setFields({});
await pVerizon.draw(); // Вызывает parseAndDrawSVG
const pdfBytes = await pVerizon.pdfDoc.save();
const filename = pVerizon.generateFilename('Verizon');
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
res.end(pdfBytes);
} catch (error) {
console.error('Error in Verizon PDF generation:', error);
if (!res.headersSent) {
res.status(500).json({ error: 'Error generating Verizon PDF: ' + error.message });
}
}
});
};