forked from fitraditya/node-pdf2img
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor the lib to async/await and refactor the tests
- Loading branch information
Showing
5 changed files
with
224 additions
and
241 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
{ | ||
"parser": "babel-eslint", | ||
"rules": { | ||
"strict": [2, "global"], | ||
"indent": ["error", 4], | ||
"quotes": [2, "single"], | ||
"linebreak-style": [2, "unix"], | ||
"semi": [2, "always"], | ||
"array-bracket-spacing": [2, "never"], | ||
"space-in-parens": [2, "never"], | ||
"computed-property-spacing": [2, "never"], | ||
"block-spacing": [2, "never"], | ||
"brace-style": [2], | ||
"camelcase": [2, { "properties": "never" }], | ||
"comma-spacing": [2, { "before": false, "after": true }], | ||
"eol-last": 0, | ||
"key-spacing": [2, { "beforeColon": false, "afterColon": true }], | ||
"new-cap": 2, | ||
"new-parens": 2, | ||
"no-mixed-spaces-and-tabs": [2, "smart-tabs"], | ||
"no-multiple-empty-lines": [2, { "max": 2 }], | ||
"no-trailing-spaces": 2, | ||
"no-spaced-func": 2, | ||
"no-unneeded-ternary": 2, | ||
"one-var": [2, "never"], | ||
"operator-linebreak": [2, "after"], | ||
"padded-blocks": [2, "never"], | ||
"quote-props": [2, "consistent-as-needed"], | ||
"semi-spacing": [2, { "before": false, "after": true }], | ||
"keyword-spacing": 2, | ||
"no-console": "off", | ||
"space-before-blocks": 2, | ||
"space-before-function-paren": [ | ||
0, { "anonymous": "always", "named": "never" } | ||
], | ||
"space-infix-ops": 2, | ||
"space-unary-ops": [1, { "words": true, "nonwords": false }], | ||
"spaced-comment": [2, "always", { "markers": ["!", "*"] }] | ||
}, | ||
"env": { | ||
"es6": true, | ||
"node": true, | ||
"browser": true, | ||
"mocha": true | ||
}, | ||
"extends": "eslint:recommended", | ||
"parserOptions": { | ||
"ecmaVersion": 6, | ||
"ecmaFeatures": { | ||
"experimentalObjectRestSpread": true | ||
} | ||
}, | ||
"plugins": [] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,3 @@ | ||
{ | ||
"esnext" : true, | ||
"node" : true, | ||
"mocha" : true | ||
"esversion": 6 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1 @@ | ||
"use strict"; | ||
|
||
const child = require('child_process'); | ||
const pdf2img = require('./lib/pdf2img'); | ||
|
||
module.exports = (() => { | ||
child.exec(`which graphicsmagick`, (err, stdout, stderr) => { | ||
if (err) { | ||
console.error('Please install graphicsmagick in order to run pdf2img'); | ||
process.exit(1); | ||
} | ||
return pdf2img; | ||
}); | ||
})(); | ||
module.exports = require('./lib/pdf2img'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,185 +1,159 @@ | ||
"use strict"; | ||
|
||
const fs = require('fs'); | ||
const gm = require('gm'); | ||
const path = require('path'); | ||
const util = require('util'); | ||
const stat = util.promisify(fs.stat); | ||
const mkdir = util.promisify(fs.mkdir); | ||
|
||
class Pdf2Img { | ||
constructor() { | ||
this.options = { | ||
type: 'jpg', | ||
size: 1024, | ||
density: 600, | ||
outputdir: null, | ||
outputname: null, | ||
page: null | ||
}; | ||
} | ||
|
||
let options = { | ||
type: 'jpg', | ||
size: 1024, | ||
density: 600, | ||
outputdir: null, | ||
outputname: null, | ||
page: null | ||
}; | ||
|
||
let Pdf2Img = function() {}; | ||
|
||
Pdf2Img.prototype.setOptions = function(opts) { | ||
options.type = opts.type || options.type; | ||
options.size = opts.size || options.size; | ||
options.density = opts.density || options.density; | ||
options.outputdir = opts.outputdir || options.outputdir; | ||
options.outputname = opts.outputname || options.outputname; | ||
options.page = opts.page || options.page; | ||
}; | ||
|
||
Pdf2Img.prototype.convert = function(input, callbackreturn) { | ||
// Make sure it has correct extension | ||
if (path.extname(path.basename(input)) != '.pdf') { | ||
return callbackreturn({ | ||
result: 'error', | ||
message: 'Unsupported file type.' | ||
}); | ||
setOptions(opts) { | ||
this.options.type = opts.type || this.options.type; | ||
this.options.size = opts.size || this.options.size; | ||
this.options.density = opts.density || this.options.density; | ||
this.options.outputdir = opts.outputdir || this.options.outputdir; | ||
this.options.outputname = opts.outputname || this.options.outputname; | ||
this.options.page = opts.page || this.options.page; | ||
} | ||
|
||
// Check if input file exists | ||
if (!isFileExists(input)) { | ||
return callbackreturn({ | ||
result: 'error', | ||
message: 'Input file not found.' | ||
}); | ||
async convert(input) { | ||
try { | ||
await this.validate(input); | ||
let pages = await this.getPagesCount(input); | ||
return this.convertPdf(input, pages); | ||
} catch (err) { | ||
console.error(err); | ||
throw err; | ||
} | ||
} | ||
|
||
let stdout = []; | ||
let output = path.basename(input, path.extname(path.basename(input))); | ||
async validate(input) { | ||
if (!input) { | ||
throw new Error('Invalid input file path.'); | ||
} | ||
|
||
// Set output dir | ||
if (options.outputdir) { | ||
options.outputdir = options.outputdir + path.sep; | ||
} else { | ||
options.outputdir = output + path.sep; | ||
} | ||
if (path.extname(path.basename(input)) != '.pdf') { | ||
throw new Error('Unsupported file type.'); | ||
} | ||
|
||
// Create output dir if it doesn't exists | ||
if (!isDirExists(options.outputdir)) { | ||
fs.mkdirSync(options.outputdir); | ||
} | ||
let statInput = await stat(input); | ||
|
||
// Set output name | ||
if (options.outputname) { | ||
options.outputname = options.outputname; | ||
} else { | ||
options.outputname = output; | ||
if (!statInput.isFile()) { | ||
throw new Error('Input file not found.'); | ||
} | ||
} | ||
|
||
async.waterfall([ | ||
// Get pages count | ||
function(callback) { | ||
gm(input).identify("%p ", function(err, value) { | ||
getPagesCount(input) { | ||
return new Promise((resolve, reject) => { | ||
gm(input).identify('%p ', (err, value) => { | ||
if (err) return reject(err); | ||
|
||
let pageCount = String(value).split(' '); | ||
|
||
if (!pageCount.length) { | ||
callback({ | ||
result: 'error', | ||
message: 'Invalid page number.' | ||
}, null); | ||
return reject('Invalid page number.'); | ||
} else { | ||
// Convert selected page | ||
if (options.page !== null) { | ||
if (options.page < pageCount.length) { | ||
callback(null, [options.page]); | ||
if (this.options.page !== null) { | ||
if (this.options.page < pageCount.length) { | ||
return resolve([this.options.page]); | ||
} else { | ||
callback({ | ||
result: 'error', | ||
message: 'Invalid page number.' | ||
}, null); | ||
return reject('Invalid page number.'); | ||
} | ||
} else { | ||
callback(null, pageCount); | ||
return resolve(pageCount); | ||
} | ||
} | ||
}); | ||
}); | ||
} | ||
|
||
}) | ||
async convertPdf(input, pages) { | ||
try { | ||
let stdout = []; | ||
let output = this.getOutput(input); | ||
await this.setOutDir(output); | ||
this.setOutName(output); | ||
|
||
}, | ||
for (let page of pages) { | ||
let inputStream = fs.createReadStream(input); | ||
let outputFile = `${this.options.outputdir}${this.options.outputname}_${page}.${this.options.type}`; | ||
let result = await this.convertPdf2Img(inputStream, outputFile, parseInt(page)); | ||
stdout.push(result); | ||
} | ||
|
||
return { | ||
result: 'success', | ||
message: stdout | ||
}; | ||
} catch (err) { | ||
throw new Error(err); | ||
} | ||
} | ||
|
||
// Convert pdf file | ||
function(pages, callback) { | ||
// Use eachSeries to make sure that conversion has done page by page | ||
async.eachSeries(pages, function(page, callbackmap) { | ||
let inputStream = fs.createReadStream(input); | ||
let outputFile = options.outputdir + options.outputname + '_' + page + '.' + options.type; | ||
getOutput(input) { | ||
return path.basename(input, path.extname(path.basename(input))); | ||
} | ||
|
||
convertPdf2Img(inputStream, outputFile, parseInt(page), function(error, result) { | ||
if (error) { | ||
return callbackmap(error); | ||
} | ||
async setOutDir(output) { | ||
if (this.options.outputdir) { | ||
this.options.outputdir = this.options.outputdir + path.sep; | ||
} else { | ||
this.options.outputdir = output + path.sep; | ||
} | ||
|
||
stdout.push(result); | ||
return callbackmap(error, result); | ||
}); | ||
}, function(e) { | ||
if (e) callback(e); | ||
let statDir = await stat(this.options.outputdir); | ||
|
||
return callback(null, { | ||
result: 'success', | ||
message: stdout | ||
}); | ||
}); | ||
if (!statDir.isDirectory()) { | ||
await mkdir(this.options.outputdir); | ||
} | ||
], callbackreturn); | ||
}; | ||
|
||
let convertPdf2Img = function(input, output, page, callback) { | ||
if (input.path) { | ||
let filepath = input.path; | ||
} else { | ||
return callback({ | ||
result: 'error', | ||
message: 'Invalid input file path.' | ||
}, null); | ||
} | ||
|
||
let filename = filepath + '[' + (page - 1) + ']'; | ||
|
||
gm(input, filename) | ||
.density(options.density, options.density) | ||
.resize(options.size) | ||
.quality(100) | ||
.write(output, function(err) { | ||
if (err) { | ||
return callback({ | ||
result: 'error', | ||
message: 'Can not write output file.' | ||
}, null); | ||
} | ||
setOutName(output) { | ||
if (this.options.outputname) { | ||
this.options.outputname = this.options.outputname; | ||
} else { | ||
this.options.outputname = output; | ||
} | ||
} | ||
|
||
if (!(fs.statSync(output)['size'] / 1000)) { | ||
return callback({ | ||
result: 'error', | ||
message: 'Zero sized output image detected.' | ||
}, null); | ||
} | ||
async convertPdf2Img(inputStream, output, page) { | ||
return new Promise((resolve, reject) => { | ||
let filename = `${inputStream.path}[${(page - 1)}]`; | ||
gm(inputStream, filename) | ||
.density(this.options.density, this.options.density) | ||
.resize(this.options.size) | ||
.quality(100) | ||
.write(output, (err) => { | ||
if (err) { | ||
return reject('Wasn\'t able to write the output file.'); | ||
} | ||
|
||
let results = { | ||
page: page, | ||
name: path.basename(output), | ||
size: fs.statSync(output)['size'] / 1000.0, | ||
path: output | ||
}; | ||
stat(output).then(statOut => { | ||
if ((statOut.size / 1000) === 0) { | ||
return reject('Zero sized output image detected.'); | ||
} | ||
|
||
return callback(null, results); | ||
return resolve({ | ||
page: page, | ||
name: path.basename(output), | ||
size: statOut.size / 1000.0, | ||
path: output | ||
}); | ||
}); | ||
}); | ||
}); | ||
}; | ||
|
||
// Check if directory is exists | ||
let isDirExists = function(path) { | ||
try { | ||
return fs.statSync(path).isDirectory(); | ||
} catch (e) { | ||
return false; | ||
} | ||
} | ||
|
||
// Check if file is exists | ||
let isFileExists = function(path) { | ||
try { | ||
return fs.statSync(path).isFile(); | ||
} catch (e) { | ||
return false; | ||
} | ||
} | ||
|
||
module.exports = new Pdf2Img; | ||
module.exports = new Pdf2Img(); |
Oops, something went wrong.