Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SOLVED] If you use windows os with NodeJs and struggling with node-qpdf #17

Open
anusight opened this issue Dec 22, 2020 · 0 comments
Open

Comments

@anusight
Copy link

anusight commented Dec 22, 2020

1. Do not even use node-qpdf. Use the real McCoy, ie. qpdf, the executable that node-qpdf is built on.
2. Download qpdf (https://sourceforge.net/projects/qpdf/files/qpdf/10.0.4/qpdf-10.0.4.tar.gz.asc/download)
3. Go into EnvironmentalVariables and create a path to the bin folder of downloaded & extracted qpdf (#2) above.

4. Here is the code and it works! There is extra code for other stuff I was doing, ie gzip, etc, and was too lazy to separate.

          const zlib = require('zlib');
          const fs = require('fs');
          const path = require('path');
          const router = require('express').Router();
          const multer = require('multer');
          const express = require('express');
          const app = express();
          
          const uploadDir = path.join(__dirname, '../../imageUploads/');
          const uploadPdfDir = path.join(__dirname, '../../pdfUploads/');
          const compressDir = path.join(__dirname, '../../compressedImages/');
          const MAX_SIZE = 20000000;
          
          app.use(function (err, req, res, next) {
            if (err.code === 'LIMIT_FILE_TYPES') {
              res.status(422).json({ error: 'Only images are allowed' });
              return;
            }
            if (err.code === 'LIMIT_FILE_SIZE') {
              res.status(422).json({ error: `Too large. Max Size is ${MAX_SIZE / 1000}kb` });
            }
          });
          
          const fileFilter = function (req, file, cb) {
            const allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'application/pdf'];
            if (!allowedTypes.includes(file.mimetype)) {
              const error = new Error('Wrong file type.');
              error.code = 'LIMIT_FILE_TYPES';
              return cb(error, false);
            }
          
            if (file.size > MAX_SIZE) {
              const error = new Error('File too large.');
              error.code = 'LIMIT_FILE_SIZE';
              return cb(error, false);
            }
            cb(null, true);
          };
          
          const storage = multer.diskStorage({
            destination: (req, file, cb) => {
              if (file.mimetype.includes('pdf')) {
                cb(null, uploadPdfDir);
              } else {
                cb(null, uploadDir);
              }
            },
            filename: (req, file, cb) => {
              const fileName = file.originalname.toLowerCase().split(' ').join('-');
              cb(null, fileName);
            }
          });
          
          function encryptPdf (file, ownerPwd, userPwd) {
            const fullFilePath = uploadPdfDir + file.filename;
            // this line below works without an NodeJs install to package.json because you set qpdf in your environmental variables
            const exec = require('child_process').exec;
             // using --replace-input overwrites existing file and encrypts. If you want a new file
            // remove --replace-input and put the full path of the new file you want encrypted
            const cmd = 'qpdf --encrypt ' + ownerPwd + ' ' + userPwd + ' 40 -- ' + fullFilePath + ' --replace-input';
          
            exec(cmd, function (err) {
              if (err) {
                console.error('Error occured: ' + err);
              } else {
                console.log('PDF encrypted :)');
              }
            });
          }
          
          const upload = multer({
            storage,
            fileFilter,
            limits: {
              fileSize: MAX_SIZE
            }
          });
          
          router.route('/uploadCompress/')
            .post(upload.single('file'), async (req, res) => {
              try {
                const destination = `${compressDir}/${req.file.originalname}.gz`;
                const fileBuffer = req.file.buffer;
                await zlib.gzip(fileBuffer, (err, response) => {
                  if (err) {
                    console.log(err);
                  }
                  fs.writeFile(path.join(__dirname, destination), response, (err, data) => {
                    if (err) {
                      console.log(err);
                    }
                    res.download(path.join(__dirname, destination));
                  });
                });
              } catch (err) {
                console.log(err);
                res.json(err);
              }
            });
          
          router.route('/uploadFiles/')
            .post(upload.single('file'), (req, res) => {
              res.json({ file: req.file });
            });
          
          router.route('/uploadPdfFiles/')
            .post(upload.single('file'), (req, res) => {
              encryptPdf(req.file, 'ownerPWD', 'userPWD');
              res.json({ file: req.file });
            });
          
          module.exports = router;
@anusight anusight changed the title If you use windows os with NodeJs and struggling with this [SOLVED] If you use windows os with NodeJs and struggling with this Dec 22, 2020
@anusight anusight changed the title [SOLVED] If you use windows os with NodeJs and struggling with this [SOLVED] If you use windows os with NodeJs and struggling with node-qpdf Dec 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant