Dhalang 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 835393ff0f501220a6c71edd20db19897e874b578f0921b37f70b5403840c928
4
- data.tar.gz: 285639cb8e59c0416d82a15c15ef7e656c00e5d2498b19f885d8635dafc05314
3
+ metadata.gz: 4bd71cb9e8eb643b85d2d2e68909db725b088b10ef29cd717634bc5429067ed4
4
+ data.tar.gz: 77b10c45d0c30132e3888c2cc04998502b34ae24a0e363e70b971987ec6a722c
5
5
  SHA512:
6
- metadata.gz: aeacd63e036366dcd4f61da1b06fe65965378c6d4dba61de5401daa67f7f3f06744f01e7e4d24bd0d28a157e052eb5ff597695e978f73b9290594787ef48a482
7
- data.tar.gz: 1888bee0d744f67529fa7927740fbe057ceb73c571c3d06d7de74e24ee028f0769592bc7107bb1696e31e448fd02f7ead676b57f0a94bb2d8ee68192e1382c18
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 configuration
44
- Depending on your use case you may want to change the way Dhalang interacts with Puppeteer. You can do this by passing a Hash with custom configuration parameters as last argument to any calls you make to the library.
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
- So for example:
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
- Below table list the possible configuration parameters you can set:
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
- | navigation_timeout | Amount of milliseconds until Puppeteer while timeout when navigating to the given page | 10000 |
53
- | user_agent | User agent to send with the request | Default Puppeteer one |
54
- | view_port | Custom viewport to use for the request | Default Puppeteer one |
55
- | http_authentication_credentials | Custom HTTP authentication credentials to use for the request | None |
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
@@ -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
- end
13
+ require 'open3'
14
+ end
@@ -0,0 +1 @@
1
+ class DhalangError < StandardError; end
@@ -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
- NAVIGATION_TIMEOUT = 10000
8
- private_constant :NAVIGATION_TIMEOUT
9
-
10
- NAVIGATION_WAIT_UNTIL = 'load'
11
- private_constant :NAVIGATION_WAIT_UNTIL
12
-
13
- USER_AGENT = ''
14
- private_constant :USER_AGENT
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
- DEFAULT_OPTIONS = {
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 :DEFAULT_OPTIONS
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
- Kernel.system("node #{script_path} #{Shellwords.escape(configuration)}")
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
- navigationParameters: {
67
- timeout: options.has_key?(:navigation_timeout) ? options[:navigation_timeout] : NAVIGATION_TIMEOUT,
68
- waitUntil: NAVIGATION_WAIT_UNTIL
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
@@ -1,3 +1,3 @@
1
1
  module Dhalang
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -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
@@ -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 with Puppeteer.
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 {NavigationParameters} navigationParameters - The parameters to use when navigating to pages with Puppeteer.
12
- * @property {string} userAgent - The user agent to send with requests.
13
- * @property {Object} viewPort - The view port to use.
14
- * @property {Object} httpAuthenticationCredentials - The credentials to use for HTTP authentication.
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 {string} puppeteerModulePath - The path puppeteer is under.
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 (puppeteerModulePath) {
39
- module.paths.push(puppeteerModulePath);
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: ['--no-sandbox', '--disable-setuid-sandbox']
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
  }
@@ -6,10 +6,10 @@ const createPdf = async () => {
6
6
 
7
7
  let browser;
8
8
  try {
9
- browser = await dhalang.launchPuppeteer(configuration.puppeteerPath);
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.userOptions.navigationParameters);
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.log(error.message);
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.puppeteerPath);
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.userOptions.navigationParameters);
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
- path: configuration.tempFilePath,
16
- type: configuration.imageType,
17
- fullPage: true
16
+ ...{
17
+ path: configuration.tempFilePath,
18
+ type: configuration.imageType,
19
+ },
20
+ ...screenshotOptions
18
21
  });
19
22
  } catch (error) {
20
- console.log(error.message);
23
+ console.error(error.message);
24
+ process.exit(1);
21
25
  } finally {
22
26
  if (browser) {
23
27
  browser.close();
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dhalang",
3
- "version": "1.0.0",
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": "ISC",
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.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-10-29 00:00:00.000000000 Z
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