Advertisement
YaBoiSwayZ

PDF Merger v1

Jul 2nd, 2024
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 5.04 KB | Source Code | 0 0
  1. const PDFMerger = require('pdf-merger-js');
  2. const axios = require('axios');
  3. const axiosRetry = require('axios-retry');
  4. const fs = require('fs');
  5. const path = require('path');
  6. const rfs = require('rotating-file-stream');
  7. const yargs = require('yargs/yargs');
  8. const { hideBin } = require('yargs/helpers');
  9.  
  10. const validateInterval = (interval) => {
  11.   const validUnits = ['s', 'm', 'h', 'd', 'w', 'M', 'y'];
  12.   const unit = interval.slice(-1);
  13.   const number = interval.slice(0, -1);
  14.   if (!validUnits.includes(unit) || isNaN(Number(number))) {
  15.     throw new Error(`Invalid log rotation interval: ${interval}. Must be a number followed by one of 's', 'm', 'h', 'd', 'w', 'M', 'y'.`);
  16.   }
  17. };
  18.  
  19. const argv = yargs(hideBin(process.argv))
  20.   .option('logDirectory', {
  21.     alias: 'd',
  22.     type: 'string',
  23.     description: 'Directory for log files',
  24.     default: path.join(__dirname, 'log'),
  25.     coerce: (arg) => {
  26.       const resolvedPath = path.resolve(arg);
  27.       if (!fs.existsSync(resolvedPath)) {
  28.         fs.mkdirSync(resolvedPath, { recursive: true });
  29.       } else if (!fs.statSync(resolvedPath).isDirectory()) {
  30.         throw new Error(`Invalid log directory: ${resolvedPath} is not a directory.`);
  31.       }
  32.       return resolvedPath;
  33.     },
  34.   })
  35.   .option('logRotationInterval', {
  36.     alias: 'i',
  37.     type: 'string',
  38.     description: 'Log rotation interval',
  39.     default: '1d',
  40.     coerce: (arg) => {
  41.       validateInterval(arg);
  42.       return arg;
  43.     },
  44.   })
  45.   .option('outputFilePath', {
  46.     alias: 'o',
  47.     type: 'string',
  48.     description: 'Path to save the merged PDF',
  49.     default: path.join(__dirname, 'merged.pdf'),
  50.   })
  51.   .option('apiEndpoint', {
  52.     alias: 'e',
  53.     type: 'string',
  54.     description: 'API endpoint to fetch template PDFs',
  55.     default: 'http://localhost:5000/api/upload',
  56.   })
  57.   .option('retryCount', {
  58.     alias: 'r',
  59.     type: 'number',
  60.     description: 'Number of retry attempts for network requests',
  61.     default: 3,
  62.   })
  63.   .option('retryDelay', {
  64.     alias: 't',
  65.     type: 'number',
  66.     description: 'Delay between retry attempts in milliseconds',
  67.     default: 1000,
  68.   })
  69.   .check((argv) => {
  70.     validateInterval(argv.logRotationInterval);
  71.     if (isNaN(argv.retryCount) || argv.retryCount < 0) {
  72.       throw new Error(`Invalid retry count: ${argv.retryCount}. Must be a non-negative number.`);
  73.     }
  74.     if (isNaN(argv.retryDelay) || argv.retryDelay < 0) {
  75.       throw new Error(`Invalid retry delay: ${argv.retryDelay}. Must be a non-negative number.`);
  76.     }
  77.     return true;
  78.   })
  79.   .argv;
  80.  
  81. const config = {
  82.   logDirectory: argv.logDirectory,
  83.   logRotationInterval: argv.logRotationInterval,
  84.   outputFilePath: argv.outputFilePath,
  85.   apiEndpoint: argv.apiEndpoint,
  86.   retryCount: argv.retryCount,
  87.   retryDelay: argv.retryDelay,
  88. };
  89.  
  90. const logStream = rfs.createStream('app.log', {
  91.   interval: config.logRotationInterval,
  92.   path: config.logDirectory,
  93. });
  94.  
  95. const log = (message) => {
  96.   const logMessage = `${new Date().toISOString()} - ${message}\n`;
  97.   logStream.write(logMessage);
  98.   console.log(message);
  99. };
  100.  
  101. axiosRetry(axios, {
  102.   retries: config.retryCount,
  103.   retryDelay: (retryCount) => {
  104.     return config.retryDelay * Math.pow(2, retryCount);
  105.   },
  106. });
  107.  
  108. const fetchPdfByName = async (templateName) => {
  109.   try {
  110.     const response = await axios.get(`${config.apiEndpoint}/${templateName}.pdf`, { responseType: 'arraybuffer' });
  111.     return Buffer.from(response.data);
  112.   } catch (error) {
  113.     const errorMessage = `Error fetching PDF "${templateName}": ${error.message}`;
  114.     log(errorMessage);
  115.     if (error.response) {
  116.       log(`Response status: ${error.response.status}`);
  117.       log(`Response data: ${error.response.data}`);
  118.     }
  119.     throw error;
  120.   }
  121. };
  122.  
  123. const mergePdfs = async (userPdfFilePath, templateName) => {
  124.   const merger = new PDFMerger();
  125.   const tempTemplatePath = path.join(__dirname, 'tempTemplate.pdf');
  126.   try {
  127.     await merger.add(userPdfFilePath);
  128.     log(`Added user PDF: ${userPdfFilePath}`);
  129.  
  130.     const templatePdfBuffer = await fetchPdfByName(templateName);
  131.     fs.writeFileSync(tempTemplatePath, templatePdfBuffer);
  132.     await merger.add(tempTemplatePath);
  133.     log(`Added template PDF: ${templateName}`);
  134.  
  135.     await merger.save(config.outputFilePath);
  136.     log(`PDFs merged successfully: ${config.outputFilePath}`);
  137.   } catch (error) {
  138.     log(`Error merging PDFs: ${error.message}`);
  139.     if (fs.existsSync(tempTemplatePath)) {
  140.       fs.unlinkSync(tempTemplatePath);
  141.       log(`Temporary template PDF deleted due to error: ${tempTemplatePath}`);
  142.     }
  143.     throw error;
  144.   } finally {
  145.     if (fs.existsSync(tempTemplatePath)) {
  146.       fs.unlinkSync(tempTemplatePath);
  147.       log(`Temporary template PDF deleted: ${tempTemplatePath}`);
  148.     }
  149.   }
  150. };
  151.  
  152. mergePdfs('path/to/user/pdf.pdf', 'templateName').catch((error) => {
  153.   log(`Merge process failed: ${error.message}`);
  154. });
  155.  
  156. // Usage: node script.js --logDirectory=/path/to/log --logRotationInterval=1h --outputFilePath=/path/to/merged.pdf --apiEndpoint=http://example.com/api/upload --retryCount=5 --retryDelay=2000
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement