Skip to content

Commit f448af1

Browse files
committed
Use alternative loading of html.
Also add some nicer error handling.
1 parent 1b23276 commit f448af1

3 files changed

Lines changed: 68 additions & 46 deletions

File tree

lib/index.coffee

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ spawn = require('child_process').spawn
33
path = require('path')
44
phantomjs = require('phantomjs')
55

6-
#
6+
#
77
# phantomjs version 1.8.1 and later should work. Ubuntu has some problems when trying to buffer to /dev/stdout
8-
#
8+
#
99
# Create a PDF file out of an html string.
10-
#
10+
#
1111
# Regions for the PDF page are:
12-
#
12+
#
1313
# - Page Header -> document.getElementById('pageHeader')
1414
# - Page Content -> document.getElementById('pageContent')
1515
# - Page Footer -> document.getElementById('pageFooter')
@@ -22,16 +22,16 @@ exports.create = (string, options, callback) ->
2222
callback = options
2323
options = {}
2424

25-
return callback(new Error("Can't create pdf without content")) unless string?.length
26-
child = spawn(phantomjs.path, [options.script || script, string.length, JSON.stringify(options)])
25+
return callback(new Error("html-pdf: Can't create a pdf without content")) unless string?.length
26+
child = spawn(phantomjs.path, [options.script || script])
2727
stdout = []
2828
stderr = []
2929

3030
timeout = setTimeout ->
3131
child.stdin.end()
3232
child.kill()
33-
stderr = [new Buffer('PDF creation timeout. PDF generation script did not end.')] unless stderr.length
34-
, parseInt(options.timeout) || 10000
33+
stderr = [new Buffer('html-pdf: PDF generation timeout. Phantom.js script did not exit.')] unless stderr.length
34+
, parseInt(options.timeout) || 30000
3535

3636
child.stdout.on 'data', (buffer) ->
3737
stdout.push(buffer)
@@ -45,23 +45,28 @@ exports.create = (string, options, callback) ->
4545
# Clean up the timeout cause the process ended anyways
4646
clearTimeout(timeout)
4747
if (stderr.length || code) > 0
48-
error = new Error(Buffer.concat(stderr).toString())
48+
error = new Error(Buffer.concat(stderr).toString() || 'Unknown Error')
4949
return callback(error)
5050

5151
file = Buffer.concat(stdout)
52-
if isFile = /^\%PDF/.test(file.slice(0, 4).toString())
53-
callback(null, file)
52+
isFileBuffer = /^\%PDF/.test(file.slice(0, 4).toString())
5453

55-
else
54+
if options.filename
55+
callback(null, file.toString())
56+
57+
else if !isFileBuffer
5658
filename = file.toString()
5759
fs.readFile filename, (err, buffer) ->
5860
return callback(err) if err
59-
60-
# Only delete file when options.filename is not defined
61-
unless options.filename
62-
fs.unlink filename, (err) ->
63-
callback(err, buffer)
64-
else
61+
fs.unlink filename, (err) ->
6562
callback(err, buffer)
6663

67-
child.stdin.write(string, 'utf8')
64+
else
65+
callback(null, file)
66+
67+
68+
content =
69+
html: string
70+
options: options
71+
72+
child.stdin.write(JSON.stringify(content)+'\n', 'utf8')

lib/index.js

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,24 @@ phantomjs = require('phantomjs');
1111
script = path.join(__dirname, 'scripts/pdf_a4_portrait.coffee');
1212

1313
exports.create = function(string, options, callback) {
14-
var child, stderr, stdout, timeout;
14+
var child, content, stderr, stdout, timeout;
1515
if (arguments.length === 2) {
1616
callback = options;
1717
options = {};
1818
}
1919
if (!(string != null ? string.length : void 0)) {
20-
return callback(new Error("Can't create pdf without content"));
20+
return callback(new Error("html-pdf: Can't create a pdf without content"));
2121
}
22-
child = spawn(phantomjs.path, [options.script || script, string.length, JSON.stringify(options)]);
22+
child = spawn(phantomjs.path, [options.script || script]);
2323
stdout = [];
2424
stderr = [];
2525
timeout = setTimeout(function() {
2626
child.stdin.end();
2727
child.kill();
2828
if (!stderr.length) {
29-
return stderr = [new Buffer('PDF creation timeout. PDF generation script did not end.')];
29+
return stderr = [new Buffer('html-pdf: PDF generation timeout. Phantom.js script did not exit.')];
3030
}
31-
}, parseInt(options.timeout) || 10000);
31+
}, parseInt(options.timeout) || 30000);
3232
child.stdout.on('data', function(buffer) {
3333
return stdout.push(buffer);
3434
});
@@ -38,30 +38,33 @@ exports.create = function(string, options, callback) {
3838
return child.kill();
3939
});
4040
child.on('exit', function(code) {
41-
var error, file, filename, isFile;
41+
var error, file, filename, isFileBuffer;
4242
clearTimeout(timeout);
4343
if ((stderr.length || code) > 0) {
44-
error = new Error(Buffer.concat(stderr).toString());
44+
error = new Error(Buffer.concat(stderr).toString() || 'Unknown Error');
4545
return callback(error);
4646
}
4747
file = Buffer.concat(stdout);
48-
if (isFile = /^\%PDF/.test(file.slice(0, 4).toString())) {
49-
return callback(null, file);
50-
} else {
48+
isFileBuffer = /^\%PDF/.test(file.slice(0, 4).toString());
49+
if (options.filename) {
50+
return callback(null, file.toString());
51+
} else if (!isFileBuffer) {
5152
filename = file.toString();
5253
return fs.readFile(filename, function(err, buffer) {
5354
if (err) {
5455
return callback(err);
5556
}
56-
if (!options.filename) {
57-
return fs.unlink(filename, function(err) {
58-
return callback(err, buffer);
59-
});
60-
} else {
57+
return fs.unlink(filename, function(err) {
6158
return callback(err, buffer);
62-
}
59+
});
6360
});
61+
} else {
62+
return callback(null, file);
6463
}
6564
});
66-
return child.stdin.write(string, 'utf8');
65+
content = {
66+
html: string,
67+
options: options
68+
};
69+
return child.stdin.write(JSON.stringify(content) + '\n', 'utf8');
6770
};

lib/scripts/pdf_a4_portrait.coffee

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,26 @@
1-
sys = require('system')
1+
system = require('system')
22
webpage = require('webpage')
33

4+
# Error handler
5+
exit = (error) ->
6+
message = error if typeof error is 'string'
7+
system.stderr.write("html-pdf: #{message || "Unknown Error #{error}"}\n") if error
8+
phantom.exit(if error then 1 else 0)
9+
10+
11+
# Force cleanup after 2 minutes
12+
setTimeout ->
13+
exit('Force timeout')
14+
, 120000
15+
16+
17+
# Load configurations from stdin
18+
json = JSON.parse(system.stdin.readLine())
19+
exit('Did not receive any html') if !json.html?.trim()
20+
21+
options = json.options
422
page = webpage.create()
5-
bufferSize = sys.args[1]
6-
options = {}
7-
options = JSON.parse(sys.args[2]) if typeof sys.args[2] is 'string'
8-
page.content = sys.stdin.read(bufferSize)
23+
page.content = json.html
924

1025

1126
# Set up content
@@ -74,14 +89,13 @@ page.onLoadFinished = (status) ->
7489
# Option 1: Output file to stdout
7590
# Not working in Ubuntu 12.04 (at least not in my environment)
7691
if options.buffer
92+
system.stderr.write('html-pdf: options.buffer is deprecated. Because of compatibility issues this method will no longer supported.\n')
7793
page.render('/dev/stdout', fileOptions)
7894

79-
8095
# Option 2: Output filename to stdout
8196
else
82-
filename = options.filename || ("#{options.directory || '/tmp'}/html-pdf-#{sys.pid}-#{bufferSize}.#{fileOptions.type}")
97+
filename = options.filename || ("#{options.directory || '/tmp'}/html-pdf-#{system.pid}.#{fileOptions.type}")
8398
page.render(filename, fileOptions)
84-
sys.stdout.write(filename)
85-
99+
system.stdout.write(filename)
86100

87-
phantom.exit(0)
101+
exit(null)

0 commit comments

Comments
 (0)