Dhalang 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +35 -10
- data/lib/Dhalang.rb +3 -1
- data/lib/Dhalang/error.rb +1 -0
- data/lib/Dhalang/puppeteer.rb +41 -27
- data/lib/Dhalang/version.rb +1 -1
- data/lib/Screenshot.rb +11 -0
- data/lib/js/dhalang.js +30 -9
- data/lib/js/pdf-generator.js +4 -3
- data/lib/js/screenshot-generator.js +10 -6
- data/package.json +2 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4bd71cb9e8eb643b85d2d2e68909db725b088b10ef29cd717634bc5429067ed4
|
4
|
+
data.tar.gz: 77b10c45d0c30132e3888c2cc04998502b34ae24a0e363e70b971987ec6a722c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d36638644a8b02e167b76f4b943b527fd06dd20cdc6ef4c77ce37af1e41bb24f4f03f13549b0b3cfcd9a1693b7aad535448ebbfd01b6a54cb53be39d32bbd063
|
7
|
+
data.tar.gz: e31806a5c74557130c558eda263a0b72045814db398c1554fe5bfaa5ce0240f14b22b52ce1afd1d8c488936097a8c407ff255c53c166cf346054d57cff749c80
|
data/README.md
CHANGED
@@ -3,11 +3,14 @@
|
|
3
3
|
> Dhalang is a Ruby wrapper for Google's Puppeteer.
|
4
4
|
|
5
5
|
|
6
|
+
|
6
7
|
## Features
|
7
8
|
* Generate PDFs from pages
|
8
9
|
* Generate PDFs from html ( external images/stylesheets supported )
|
9
10
|
* Capture a screenshot of a webpage
|
10
11
|
|
12
|
+
|
13
|
+
|
11
14
|
## Installation
|
12
15
|
Add this line to your application's Gemfile:
|
13
16
|
|
@@ -40,21 +43,43 @@ All methods return a string containing the PDF or JPEG/PNG in binary.
|
|
40
43
|
|
41
44
|
|
42
45
|
|
43
|
-
## Custom
|
44
|
-
|
46
|
+
## Custom PDF/screenshot options
|
47
|
+
To override the default options that are set by Dhalang you can pass as last argument a hash with the custom options you want to set.
|
48
|
+
|
49
|
+
For example to set custom margins for PDFs:
|
50
|
+
|
51
|
+
`Dhalang::PDF.get_from_url("https://www.google.com", {margin: { top: 100, right: 100, bottom: 100, left: 100}})
|
52
|
+
`
|
53
|
+
|
54
|
+
For example to only take a screenshot of the visible part of the page:
|
55
|
+
`Dhalang::Screenshot.get_from_url_as_png("https://www.google.com", {fullPage: false})
|
56
|
+
`
|
57
|
+
|
58
|
+
A list of all possible PDF options that can be set, can be found at: https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#pagepdfoptions
|
45
59
|
|
46
|
-
|
47
|
-
`Dhalang::Screenshot.get_from_url_as_jpeg("https://www.google.com", {navigation_timeout: 20000})`
|
60
|
+
A list of all possible screenshot options that can be set, can be found at: https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#pagescreenshotoptions
|
48
61
|
|
49
|
-
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
## Custom user options
|
66
|
+
You may want to change the way Dhalang interacts with Puppeteer in general. User options can be set by providing them in a hash as last argument to any calls you make to the library. Are you setting both custom PDF and user options? Then they should be passed as a single hash.
|
67
|
+
|
68
|
+
For example to set a custom navigation timeout:
|
69
|
+
`Dhalang::Screenshot.get_from_url_as_jpeg("https://www.google.com", {navigationTimeout: 20000})`
|
70
|
+
|
71
|
+
Below table lists all possible configuration parameters that can be set:
|
50
72
|
| Key | Description | Default |
|
51
73
|
|--------------------|-----------------------------------------------------------------------------------------|---------------------------------|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
74
|
+
| navigationTimeout | Amount of milliseconds until Puppeteer while timeout when navigating to the given page | 10000 |
|
75
|
+
| userAgent | User agent to send with the request | Default Puppeteer one |
|
76
|
+
| isHeadless | Indicates if Chromium should be launched headless | true |
|
77
|
+
| viewPort | Custom viewport to use for the request | Default Puppeteer one |
|
78
|
+
| httpAuthenticationCredentials | Custom HTTP authentication credentials to use for the request | None |
|
79
|
+
|
80
|
+
|
56
81
|
|
57
|
-
## Examples
|
82
|
+
## Examples of using Dhalang
|
58
83
|
To return a PDF from a Rails controller you can do the following:
|
59
84
|
```
|
60
85
|
def example_controller_method
|
data/lib/Dhalang.rb
CHANGED
@@ -4,9 +4,11 @@ module Dhalang
|
|
4
4
|
require_relative 'Dhalang/version'
|
5
5
|
require_relative 'Dhalang/url_utils'
|
6
6
|
require_relative 'Dhalang/file_utils'
|
7
|
+
require_relative 'Dhalang/error'
|
7
8
|
require_relative 'Dhalang/puppeteer'
|
8
9
|
require 'uri'
|
9
10
|
require 'tempfile'
|
10
11
|
require 'shellwords'
|
11
12
|
require 'json'
|
12
|
-
|
13
|
+
require 'open3'
|
14
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
class DhalangError < StandardError; end
|
data/lib/Dhalang/puppeteer.rb
CHANGED
@@ -4,22 +4,17 @@ module Dhalang
|
|
4
4
|
NODE_MODULES_PATH = Dir.pwd + '/node_modules/'.freeze
|
5
5
|
private_constant :NODE_MODULES_PATH
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
VIEW_PORT = ''
|
17
|
-
private_constant :VIEW_PORT
|
18
|
-
|
19
|
-
HTTP_AUTHENTICATION_CREDENTIALS = ''
|
20
|
-
private_constant :HTTP_AUTHENTICATION_CREDENTIALS
|
7
|
+
USER_OPTIONS = {
|
8
|
+
navigationTimeout: 10000,
|
9
|
+
navigationWaitUntil: 'load',
|
10
|
+
userAgent: '',
|
11
|
+
isHeadless: true,
|
12
|
+
viewPort: '',
|
13
|
+
httpAuthenticationCredentials: ''
|
14
|
+
}
|
15
|
+
private_constant :USER_OPTIONS
|
21
16
|
|
22
|
-
|
17
|
+
DEFAULT_PDF_OPTIONS = {
|
23
18
|
scale: 1,
|
24
19
|
displayHeaderFooter: false,
|
25
20
|
headerTemplate: '',
|
@@ -33,7 +28,22 @@ module Dhalang
|
|
33
28
|
margin: { top: 36, right: 36, bottom: 20, left: 36 },
|
34
29
|
preferCSSPageSiz: false
|
35
30
|
}
|
36
|
-
private_constant :
|
31
|
+
private_constant :DEFAULT_PDF_OPTIONS
|
32
|
+
|
33
|
+
DEFAULT_PNG_OPTIONS = {
|
34
|
+
fullPage: true,
|
35
|
+
clip: nil,
|
36
|
+
omitBackground: false
|
37
|
+
}
|
38
|
+
private_constant :DEFAULT_PNG_OPTIONS
|
39
|
+
|
40
|
+
DEFAULT_JPEG_OPTIONS = {
|
41
|
+
quality: 100,
|
42
|
+
fullPage: true,
|
43
|
+
clip: nil,
|
44
|
+
omitBackground: false
|
45
|
+
}
|
46
|
+
private_constant :DEFAULT_JPEG_OPTIONS
|
37
47
|
|
38
48
|
|
39
49
|
# Launches a new Node process, executing the (Puppeteer) script under the given script_path.
|
@@ -45,7 +55,17 @@ module Dhalang
|
|
45
55
|
# @param [Object] options Set of options to use, configurable by the user.
|
46
56
|
def self.visit(page_url, script_path, temp_file_path, temp_file_extension, options)
|
47
57
|
configuration = create_configuration(page_url, script_path, temp_file_path, temp_file_extension, options)
|
48
|
-
|
58
|
+
|
59
|
+
command = "node #{script_path} #{Shellwords.escape(configuration)}"
|
60
|
+
|
61
|
+
Open3.popen2e(command) do |_stdin, stdouterr, wait|
|
62
|
+
return nil if wait.value.success?
|
63
|
+
|
64
|
+
output = stdouterr.read.strip
|
65
|
+
output = nil if output == ''
|
66
|
+
message = output || "Exited with status #{wait.value.exitstatus}"
|
67
|
+
raise DhalangError, message
|
68
|
+
end
|
49
69
|
end
|
50
70
|
|
51
71
|
|
@@ -62,16 +82,10 @@ module Dhalang
|
|
62
82
|
tempFilePath: temp_file_path,
|
63
83
|
puppeteerPath: NODE_MODULES_PATH,
|
64
84
|
imageType: temp_file_extension,
|
65
|
-
userOptions: {
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
},
|
70
|
-
userAgent: options.has_key?(:user_agent) ? options[:user_agent] : USER_AGENT,
|
71
|
-
viewPort: options.has_key?(:view_port) ? options[:view_port] : VIEW_PORT,
|
72
|
-
httpAuthenticationCredentials: options.has_key?(:http_authentication_credentials) ? options[:http_authentication_credentials] : HTTP_AUTHENTICATION_CREDENTIALS
|
73
|
-
},
|
74
|
-
pdfOptions: DEFAULT_OPTIONS.map { |option, value| [option, options.has_key?(option) ? options[option] : value] }.to_h
|
85
|
+
userOptions: USER_OPTIONS.map { |option, value| [option, options.has_key?(option) ? options[option] : value]}.to_h,
|
86
|
+
pdfOptions: DEFAULT_PDF_OPTIONS.map { |option, value| [option, options.has_key?(option) ? options[option] : value] }.to_h,
|
87
|
+
pngOptions: DEFAULT_PNG_OPTIONS.map { |option, value| [option, options.has_key?(option) ? options[option] : value] }.to_h,
|
88
|
+
jpegOptions: DEFAULT_JPEG_OPTIONS.map { |option, value| [option, options.has_key?(option) ? options[option] : value] }.to_h
|
75
89
|
}.to_json
|
76
90
|
end
|
77
91
|
end
|
data/lib/Dhalang/version.rb
CHANGED
data/lib/Screenshot.rb
CHANGED
@@ -33,6 +33,7 @@ module Dhalang
|
|
33
33
|
# @return [String] The screenshot that was taken as binary.
|
34
34
|
private_class_method def self.get(url, image_type, options)
|
35
35
|
UrlUtils.validate(url)
|
36
|
+
validate_options(options)
|
36
37
|
temp_file = FileUtils.create_temp_file(image_type)
|
37
38
|
begin
|
38
39
|
Puppeteer.visit(url, PUPPETEER_SCRIPT_PATH, temp_file.path, image_type, options)
|
@@ -42,5 +43,15 @@ module Dhalang
|
|
42
43
|
end
|
43
44
|
return binary_image_content
|
44
45
|
end
|
46
|
+
|
47
|
+
# Raises an error if the given options might conflict with the Puppeteer configuration.
|
48
|
+
#
|
49
|
+
# @param [Hash] options The options to validate
|
50
|
+
private_class_method def self.validate_options(options)
|
51
|
+
symbolized_options = options.transform_keys(&:to_sym)
|
52
|
+
if symbolized_options.has_key?(:type)
|
53
|
+
raise DhalangError, 'Invalid option set: "type"'
|
54
|
+
end
|
55
|
+
end
|
45
56
|
end
|
46
57
|
end
|
data/lib/js/dhalang.js
CHANGED
@@ -4,14 +4,20 @@
|
|
4
4
|
* @property {string} tempFilePath - The path of the tempfile to write the screenshot/pdf to.
|
5
5
|
* @property {string} puppeteerModulePath - The path of the Puppeteer module.
|
6
6
|
* @property {string} imageType - The type of image to save ( undefined for pdfgenerator ).
|
7
|
-
* @property {UserOptions} userOptions - User defined and default parameters to use when navigating to pages
|
7
|
+
* @property {UserOptions} userOptions - User defined and default parameters to use when navigating to pages.
|
8
|
+
* @property {Object} pdfOptions - User defined and default parameters to use when creating PDFs.
|
9
|
+
* @property {Object} pngOptions - User defined and default parameters to use when creating PNGs.
|
10
|
+
* @property {Object} jpegOptions - User defined and default parameters to use when creating JPEGs.
|
8
11
|
*/
|
12
|
+
|
9
13
|
/**
|
10
14
|
* @typedef {Object} UserOptions
|
11
|
-
* @property {
|
12
|
-
* @property {string}
|
13
|
-
* @property {
|
14
|
-
* @property {
|
15
|
+
* @property {number} navigationTimeout - Maximum in milliseconds until navigation times out, we use a default of 10 seconds as timeout.
|
16
|
+
* @property {string} navigationWaitUntil - Determines when the navigation was finished, we wait here until the Window.load event is fired ( meaning all images, stylesheet, etc was loaded ).
|
17
|
+
* @property {string} userAgent - The user agent to send with requests.
|
18
|
+
* @property {boolean} isHeadless - Indicates if Puppeteer should launch Chromium in headless mode.
|
19
|
+
* @property {Object} viewPort - The view port to use.
|
20
|
+
* @property {Object} httpAuthenticationCredentials - The credentials to use for HTTP authentication.
|
15
21
|
*/
|
16
22
|
|
17
23
|
/**
|
@@ -31,15 +37,17 @@ exports.getConfiguration = function () {
|
|
31
37
|
|
32
38
|
/**
|
33
39
|
* Launches Puppeteer and returns its instance.
|
34
|
-
* @param {
|
40
|
+
* @param {UserOptions} configuration - The configuration to use.
|
35
41
|
* @returns {Promise<Object>}
|
36
42
|
* The launched instance of Puppeteer.
|
37
43
|
*/
|
38
|
-
exports.launchPuppeteer = async function (
|
39
|
-
module.paths.push(
|
44
|
+
exports.launchPuppeteer = async function (configuration) {
|
45
|
+
module.paths.push(configuration.puppeteerPath);
|
40
46
|
const puppeteer = require('puppeteer');
|
47
|
+
const launchArgs = ['--no-sandbox', '--disable-setuid-sandbox'];
|
41
48
|
return await puppeteer.launch({
|
42
|
-
args:
|
49
|
+
args: launchArgs,
|
50
|
+
headless: configuration.userOptions.isHeadless
|
43
51
|
});
|
44
52
|
}
|
45
53
|
|
@@ -60,4 +68,17 @@ exports.configurePage = async function (page, configuration) {
|
|
60
68
|
if (configuration.httpAuthenticationCredentials !== "") {
|
61
69
|
await page.authenticate(configuration.authenticationCredentials)
|
62
70
|
}
|
71
|
+
}
|
72
|
+
|
73
|
+
/**
|
74
|
+
* Extracts the navigation parameters from the configuration in a format that is usable by Puppeteer.
|
75
|
+
* @param {Configuration} configuration - The configuration to extract the navigation parameters from.
|
76
|
+
* @returns {NavigationParameters}
|
77
|
+
* The extracted navigation parameters.
|
78
|
+
*/
|
79
|
+
exports.getNavigationParameters = function (configuration) {
|
80
|
+
return {
|
81
|
+
timeout: configuration.userOptions.navigationTimeout,
|
82
|
+
waituntil: configuration.userOptions.navigationWaitUntil
|
83
|
+
}
|
63
84
|
}
|
data/lib/js/pdf-generator.js
CHANGED
@@ -6,10 +6,10 @@ const createPdf = async () => {
|
|
6
6
|
|
7
7
|
let browser;
|
8
8
|
try {
|
9
|
-
browser = await dhalang.launchPuppeteer(configuration
|
9
|
+
browser = await dhalang.launchPuppeteer(configuration);
|
10
10
|
const page = await browser.newPage();
|
11
11
|
await dhalang.configurePage(page, configuration.userOptions);
|
12
|
-
await page.goto(configuration.webPageUrl, configuration
|
12
|
+
await page.goto(configuration.webPageUrl, dhalang.getNavigationParameters(configuration));
|
13
13
|
await page.waitForTimeout(250);
|
14
14
|
await page.pdf({
|
15
15
|
...{
|
@@ -18,7 +18,8 @@ const createPdf = async () => {
|
|
18
18
|
...configuration.pdfOptions
|
19
19
|
});
|
20
20
|
} catch (error) {
|
21
|
-
console.
|
21
|
+
console.error(error.message);
|
22
|
+
process.exit(1);
|
22
23
|
} finally {
|
23
24
|
if (browser) {
|
24
25
|
browser.close();
|
@@ -6,18 +6,22 @@ const createPdf = async () => {
|
|
6
6
|
|
7
7
|
let browser;
|
8
8
|
try {
|
9
|
-
browser = await dhalang.launchPuppeteer(configuration
|
9
|
+
browser = await dhalang.launchPuppeteer(configuration);
|
10
10
|
const page = await browser.newPage();
|
11
11
|
await dhalang.configurePage(page, configuration.userOptions);
|
12
|
-
await page.goto(configuration.webPageUrl, configuration
|
12
|
+
await page.goto(configuration.webPageUrl, dhalang.getNavigationParameters(configuration));
|
13
13
|
await page.waitForTimeout(250);
|
14
|
+
const screenshotOptions = configuration.imageType === "png" ? configuration.pngOptions : configuration.jpegOptions
|
14
15
|
await page.screenshot({
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
...{
|
17
|
+
path: configuration.tempFilePath,
|
18
|
+
type: configuration.imageType,
|
19
|
+
},
|
20
|
+
...screenshotOptions
|
18
21
|
});
|
19
22
|
} catch (error) {
|
20
|
-
console.
|
23
|
+
console.error(error.message);
|
24
|
+
process.exit(1);
|
21
25
|
} finally {
|
22
26
|
if (browser) {
|
23
27
|
browser.close();
|
data/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "dhalang",
|
3
|
-
"version": "
|
3
|
+
"version": "0.5.0",
|
4
4
|
"description": "",
|
5
5
|
"main": "index.js",
|
6
6
|
"directories": {
|
@@ -14,7 +14,7 @@
|
|
14
14
|
"url": "git+https://github.com/NielsSteensma/Dhalang.git"
|
15
15
|
},
|
16
16
|
"author": "",
|
17
|
-
"license": "
|
17
|
+
"license": "MIT",
|
18
18
|
"bugs": {
|
19
19
|
"url": "https://github.com/NielsSteensma/Dhalang/issues"
|
20
20
|
},
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: Dhalang
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Niels Steensma
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -96,6 +96,7 @@ files:
|
|
96
96
|
- README.md
|
97
97
|
- Rakefile
|
98
98
|
- lib/Dhalang.rb
|
99
|
+
- lib/Dhalang/error.rb
|
99
100
|
- lib/Dhalang/file_utils.rb
|
100
101
|
- lib/Dhalang/puppeteer.rb
|
101
102
|
- lib/Dhalang/url_utils.rb
|