ferrum_pdf 1.0.0 → 2.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a1356ce4acb8121982cca17f42a53f88595cdf6004101d60e4192d912fb6a699
4
- data.tar.gz: 12cfdc58b24168b8a45f6239d668ba49f4443ea928b51554189dd565d34c15d8
3
+ metadata.gz: e10a66bff6f06cfd7388c12247ca55e92a79bc48ff741e889e0ac0bfde0286e0
4
+ data.tar.gz: 2a92a79c5a7ca34091644fcd5795d1d1c84d49f7d834f02afd6d9ec462ba892b
5
5
  SHA512:
6
- metadata.gz: e9078a7f52c54d9aed0b6b2840a136853c306a9f4414f92cc3c6ca5649e68b31ead2798ab9a8ec91848709222e67be188bebc570d72e150e56a1d697e19acedd
7
- data.tar.gz: f7947db380dcc18275a9df3a437240d4affe52a4809d7cabdb50a46a34cbf22b93ea67c7278e3cf6a41bf75a7556cf4481f32a5c6e9bc7fd5333a149b52e70d0
6
+ metadata.gz: c6d4472cb10faebb29ab64634f16063c7aac7927baf76e3e58dc72478d3d21819935138e6595a872f9e0766ff51a17303cad51a1857d62110b2e13fd4877234f
7
+ data.tar.gz: 9915cadbed613d26c113a57d5a23268ec3758ef9f566b5f6f387469ed4cce948d5348173a840cf9d36a44d935fda1a3e5f7cb06af5c5f042d73f2fb06707a892
data/README.md CHANGED
@@ -4,11 +4,11 @@ PDFs & screentshots for Rails using [Ferrum](https://github.com/rubycdp/ferrum)
4
4
 
5
5
  Inspired by [Grover](https://github.com/Studiosity/grover), but without the Node.js and puppeteer dependencies. 🎉
6
6
 
7
- ## Installation
7
+ <img src="ferrum_pdf.png" alt="logo" style="width:450px;"/>
8
8
 
9
- First, make sure Chrome is installed.
9
+ ## Installation
10
10
 
11
- Run the following or add the gem to your Gemfile:
11
+ First, make sure Chrome is installed. Then run the following or add the gem to your Gemfile:
12
12
 
13
13
  ```ruby
14
14
  bundle add "ferrum_pdf"
@@ -22,21 +22,18 @@ You can use FerrumPdf to render [PDFs](#-pdfs) and [Screenshots](#-screenshots)
22
22
 
23
23
  There are two ways to render PDFs:
24
24
 
25
+ * [`render ferrum_pdf: {}` in Rails](#render-pdfs-from-rails-controllers)
25
26
  * [FerrumPdf.render_pdf](#render-pdfs)
26
- * [render_pdf in Rails](#render-pdfs-from-rails-controllers)
27
27
 
28
28
  #### Render PDFs from Rails controllers
29
29
 
30
- Use the `render_pdf` helper in Rails controllers to render a PDF from the current action.
30
+ Use the `ferrum_pdf` renderer in Rails controllers to render a PDF from the current action.
31
31
 
32
32
  ```ruby
33
33
  def show
34
34
  respond_to do |format|
35
35
  format.html
36
- format.pdf {
37
- pdf = render_pdf()
38
- send_data pdf, disposition: :inline, filename: "example.pdf"
39
- }
36
+ format.pdf { render ferrum_pdf: {}, disposition: :inline, filename: "example.pdf" }
40
37
  end
41
38
  end
42
39
  ```
@@ -44,14 +41,17 @@ end
44
41
  You can also customize which template is rendered. This will render the template to string with `render_to_string` in Rails, then pass it along to Chrome. For example, you can add headers and footers using `pdf_options` and use a specific layout:
45
42
 
46
43
  ```ruby
47
- render_pdf(
48
- layout: "pdf,
49
- pdf_options: {
44
+ def show
45
+ render ferrum_pdf: {
50
46
  display_header_footer: true,
51
47
  header_template: FerrumPdf::DEFAULT_HEADER_TEMPLATE,
52
48
  footer_template: FerrumPdf::DEFAULT_FOOTER_TEMPLATE
53
- }
54
- )
49
+ },
50
+ layout: "pdf",
51
+ template: "pdf",
52
+ disposition: :inline,
53
+ filename: "example.pdf"
54
+ end
55
55
  ```
56
56
 
57
57
  #### Render PDFs
@@ -112,21 +112,18 @@ See [Chrome DevTools Protocol docs](https://chromedevtools.github.io/devtools-pr
112
112
 
113
113
  There are two ways to render Screenshots:
114
114
 
115
+ * [`render ferrum_screenshot: {}` in Rails](#render-screenshots-from-rails-controllers)
115
116
  * [FerrumPdf.render_screenshot](#render-screenshots)
116
- * [render_screenshot in Rails](#render-screenshots-from-rails-controllers)
117
117
 
118
118
  #### Render Screenshots from Rails controllers
119
119
 
120
- Use the `render_screenshot` helper in Rails controllers to render a PDF from the current action.
120
+ Use the `ferrum_screenshot` renderer in Rails controllers to render a PDF from the current action.
121
121
 
122
122
  ```ruby
123
123
  def show
124
124
  respond_to do |format|
125
125
  format.html
126
- format.png {
127
- screenshot = render_screenshot()
128
- send_data screenshot, disposition: :inline, filename: "example.png"
129
- }
126
+ format.png { render ferrum_screenshot: {}, disposition: :inline, filename: "example.png" }
130
127
  end
131
128
  end
132
129
  ```
@@ -134,8 +131,8 @@ end
134
131
  You can also customize which template is rendered. This will render the template to string with `render_to_string` in Rails, then pass it along to Chrome.
135
132
 
136
133
  ```ruby
137
- render_screenshot(
138
- screenshot_options: {
134
+ def show
135
+ render ferrum_screenshot: {
139
136
  format: "png" # or "jpeg"
140
137
  quality: nil # Integer 0-100 works for jpeg only
141
138
  full: true # Boolean whether you need full page screenshot or a viewport
@@ -143,8 +140,12 @@ render_screenshot(
143
140
  area: nil # Hash area for screenshot, optional. {x: 0, y: 0, width: 100, height: 100}
144
141
  scale: nil # Float zoom in/out
145
142
  background_color: nil # Ferrum::RGBA.new(0, 0, 0, 0.0)
146
- }
147
- )
143
+ },
144
+ layout: "example",
145
+ template: "example",
146
+ disposition: :inline,
147
+ filename: "example.png"
148
+ end
148
149
  ```
149
150
 
150
151
  See [Ferrum screenshot docs](https://github.com/rubycdp/ferrum?tab=readme-ov-file#screenshotoptions--string--integer) for the full set of options.
@@ -179,7 +180,28 @@ FerrumPdf.render_screenshot(
179
180
  )
180
181
  ```
181
182
 
182
- ## Configuring the Browser
183
+ ## Configuration
184
+
185
+ You can set default values for page loads, PDF renders, and screenshot renders with the configure block.
186
+
187
+ ```ruby
188
+ FerrumPdf.configure do |config|
189
+ config.page_options.base_url = "https://example.com/"
190
+ config.page_options.authorize = { user: "username", password: "password" }
191
+ config.page_options.wait_for_idle_options = { timeout: 90 }
192
+ config.page_options.retries = 3
193
+
194
+ config.pdf_options.margin_top = 0.2
195
+ config.pdf_options.margin_bottom = 0.2
196
+ config.pdf_options.margin_left = 0.2
197
+ config.pdf_options.margin_right = 0.2
198
+
199
+ config.screenshot_options.format = :png
200
+ config.screenshot_options.full = false
201
+ end
202
+ ```
203
+
204
+ ### Configuring the Browser
183
205
 
184
206
  You can set the default browser options with the configure block.
185
207
 
@@ -212,7 +234,7 @@ RUN apt-get update && apt-get install gnupg wget -y && \
212
234
  rm -rf /var/lib/apt/lists/*
213
235
  ```
214
236
 
215
- ### Browser Management
237
+ #### Browser Management
216
238
 
217
239
  FerrumPdf uses a single browser instance per Ruby process that is automatically created when needed using your configuration settings:
218
240
 
@@ -1,53 +1,53 @@
1
1
  module FerrumPdf
2
- module AssetsHelper
3
- class BaseAsset
4
- def initialize(asset)
5
- @asset = asset
6
- end
2
+ class BaseAsset
3
+ def initialize(asset)
4
+ @asset = asset
7
5
  end
6
+ end
8
7
 
9
- class PropshaftAsset < BaseAsset
10
- def content_type
11
- @asset.content_type.to_s
12
- end
8
+ class PropshaftAsset < BaseAsset
9
+ def content_type
10
+ @asset.content_type.to_s
11
+ end
13
12
 
14
- def content
15
- @asset.content
16
- end
13
+ def content
14
+ @asset.content
17
15
  end
16
+ end
18
17
 
19
- class SprocketsAsset < BaseAsset
20
- def content_type
21
- @asset.content_type
22
- end
18
+ class SprocketsAsset < BaseAsset
19
+ def content_type
20
+ @asset.content_type
21
+ end
23
22
 
24
- def content
25
- @asset.source
26
- end
23
+ def content
24
+ @asset.source
27
25
  end
26
+ end
28
27
 
29
- class AssetFinder
30
- class << self
31
- def find(path)
32
- if Rails.application.assets.respond_to?(:load_path)
33
- propshaft_asset(path)
34
- elsif Rails.application.assets.respond_to?(:find_asset)
35
- sprockets_asset(path)
36
- else
37
- nil
38
- end
28
+ class AssetFinder
29
+ class << self
30
+ def find(path)
31
+ if Rails.application.assets.respond_to?(:load_path)
32
+ propshaft_asset(path)
33
+ elsif Rails.application.assets.respond_to?(:find_asset)
34
+ sprockets_asset(path)
35
+ else
36
+ nil
39
37
  end
38
+ end
40
39
 
41
- def propshaft_asset(path)
42
- (asset = Rails.application.assets.load_path.find(path)) ? PropshaftAsset.new(asset) : nil
43
- end
40
+ def propshaft_asset(path)
41
+ (asset = Rails.application.assets.load_path.find(path)) ? PropshaftAsset.new(asset) : nil
42
+ end
44
43
 
45
- def sprockets_asset(path)
46
- (asset = Rails.application.assets.find_asset(path)) ? SprocketsAsset.new(asset) : nil
47
- end
44
+ def sprockets_asset(path)
45
+ (asset = Rails.application.assets.find_asset(path)) ? SprocketsAsset.new(asset) : nil
48
46
  end
49
47
  end
48
+ end
50
49
 
50
+ module AssetsHelper
51
51
  def ferrum_pdf_inline_stylesheet(path)
52
52
  (asset = AssetFinder.find(path)) ? "<style>#{asset.content}</style>".html_safe : nil
53
53
  end
@@ -2,13 +2,29 @@ module FerrumPdf
2
2
  class Railtie < ::Rails::Railtie
3
3
  initializer "ferrum_pdf.assets_helper" do
4
4
  ActiveSupport.on_load(:action_view) do
5
- include FerrumPdf::AssetsHelper if FerrumPdf.include_assets_helper_module
5
+ include FerrumPdf::AssetsHelper
6
6
  end
7
7
  end
8
8
 
9
9
  initializer "ferrum_pdf.controller" do
10
10
  ActiveSupport.on_load(:action_controller) do
11
- include FerrumPdf::Controller if FerrumPdf.include_controller_module
11
+ # render ferrum_pdf: { pdf options }, template: "whatever", disposition: :inline, filename: "example.pdf"
12
+ ActionController.add_renderer :ferrum_pdf do |pdf_options, options|
13
+ send_data_options = options.extract!(:disposition, :filename, :status)
14
+ url = pdf_options.delete(:url)
15
+ html = render_to_string(**options.with_defaults(formats: [ :html ])) if url.blank?
16
+ pdf = FerrumPdf.render_pdf(html: html, base_url: request.base_url, url: url, pdf_options: pdf_options)
17
+ send_data(pdf, **send_data_options.with_defaults(type: :pdf))
18
+ end
19
+
20
+ # render ferrum_screenshot: { pdf options }, template: "whatever", disposition: :inline, filename: "example.png"
21
+ ActionController.add_renderer :ferrum_screenshot do |screenshot_options, options|
22
+ send_data_options = options.extract!(:disposition, :filename, :status)
23
+ url = screenshot_options.delete(:url)
24
+ html = render_to_string(**options.with_defaults(formats: [ :html ])) if url.blank?
25
+ screenshot = FerrumPdf.render_screenshot(url: url, html: html, base_url: request.base_url, screenshot_options: screenshot_options)
26
+ send_data(screenshot, **send_data_options.with_defaults(type: screenshot_options.fetch(:format, :png)))
27
+ end
12
28
  end
13
29
  end
14
30
  end
@@ -1,3 +1,3 @@
1
1
  module FerrumPdf
2
- VERSION = "1.0.0"
2
+ VERSION = "2.1.0"
3
3
  end
data/lib/ferrum_pdf.rb CHANGED
@@ -10,14 +10,14 @@ module FerrumPdf
10
10
  HTML
11
11
 
12
12
  autoload :AssetsHelper, "ferrum_pdf/assets_helper"
13
- autoload :Controller, "ferrum_pdf/controller"
14
13
  autoload :HTMLPreprocessor, "ferrum_pdf/html_preprocessor"
15
14
 
16
15
  mattr_accessor :browser_mutex, default: Mutex.new
17
- mattr_accessor :include_assets_helper_module, default: true
18
- mattr_accessor :include_controller_module, default: true
19
16
  mattr_accessor :config, default: ActiveSupport::OrderedOptions.new.merge(
20
- window_size: [ 1920, 1080 ]
17
+ window_size: [ 1920, 1080 ],
18
+ page_options: ActiveSupport::OrderedOptions.new,
19
+ pdf_options: ActiveSupport::OrderedOptions.new,
20
+ screenshot_options: ActiveSupport::OrderedOptions.new
21
21
  )
22
22
 
23
23
  # This doesn't use mattr_accessor because having a `.browser` getter and also
@@ -45,7 +45,7 @@ module FerrumPdf
45
45
  yield browser
46
46
  else
47
47
  browser_mutex.synchronize do
48
- @@browser ||= Ferrum::Browser.new(config)
48
+ @@browser ||= Ferrum::Browser.new(config.except(:page_options, :pdf_options, :screenshot_options))
49
49
  @@browser.restart unless @@browser.client.present?
50
50
  yield @@browser
51
51
  end
@@ -64,7 +64,7 @@ module FerrumPdf
64
64
  def render_pdf(pdf_options: {}, **load_page_args)
65
65
  load_page(**load_page_args) do |browser, page|
66
66
  yield browser, page if block_given?
67
- page.pdf(**pdf_options.with_defaults(encoding: :binary))
67
+ page.pdf(**pdf_options.with_defaults(encoding: :binary, **config.pdf_options))
68
68
  end
69
69
  end
70
70
 
@@ -80,7 +80,7 @@ module FerrumPdf
80
80
  def render_screenshot(screenshot_options: {}, **load_page_args)
81
81
  load_page(**load_page_args) do |browser, page|
82
82
  yield browser, page if block_given?
83
- page.screenshot(**screenshot_options.with_defaults(encoding: :binary, full: true))
83
+ page.screenshot(**screenshot_options.with_defaults(encoding: :binary, full: true, **config.screenshot_options))
84
84
  end
85
85
  end
86
86
 
@@ -88,8 +88,12 @@ module FerrumPdf
88
88
  #
89
89
  # This automatically applies HTML preprocessing if `html:` is present
90
90
  #
91
- def load_page(url: nil, html: nil, base_url: nil, authorize: nil, wait_for_idle_options: nil, browser: nil, retries: 1)
92
- try = 0
91
+ def load_page(url: nil, html: nil, base_url: nil, authorize: nil, wait_for_idle_options: nil, browser: nil, retries: nil)
92
+ try ||= 0
93
+ authorize ||= config.dig(:page_options, :authorize)
94
+ base_url ||= config.dig(:page_options, :base_url)
95
+ retries ||= config.page_options.fetch(:retries, 1)
96
+ wait_for_idle_options = config.page_options.fetch(:wait_for_idle_options, {}).merge(wait_for_idle_options || {})
93
97
 
94
98
  with_browser(browser) do |browser|
95
99
  # Closes page automatically after block finishes
@@ -105,12 +109,12 @@ module FerrumPdf
105
109
  end
106
110
 
107
111
  # Wait for everything to load
108
- page.network.wait_for_idle(**wait_for_idle_options)
112
+ page.network.wait_for_idle!(**wait_for_idle_options)
109
113
 
110
114
  yield browser, page
111
115
  end
112
116
  end
113
- rescue Ferrum::DeadBrowserError
117
+ rescue Ferrum::DeadBrowserError, Ferrum::TimeoutError
114
118
  try += 1
115
119
  if try <= retries
116
120
  with_browser(&:restart)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ferrum_pdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Oliver
@@ -50,11 +50,9 @@ files:
50
50
  - Rakefile
51
51
  - lib/ferrum_pdf.rb
52
52
  - lib/ferrum_pdf/assets_helper.rb
53
- - lib/ferrum_pdf/controller.rb
54
53
  - lib/ferrum_pdf/html_preprocessor.rb
55
54
  - lib/ferrum_pdf/railtie.rb
56
55
  - lib/ferrum_pdf/version.rb
57
- - lib/tasks/ferrum_pdf_tasks.rake
58
56
  homepage: https://github.com/excid3/ferrum_pdf
59
57
  licenses:
60
58
  - MIT
@@ -76,7 +74,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
74
  - !ruby/object:Gem::Version
77
75
  version: '0'
78
76
  requirements: []
79
- rubygems_version: 3.7.0
77
+ rubygems_version: 3.7.1
80
78
  specification_version: 4
81
79
  summary: PDFs & screenshots for Rails using Ferrum & headless Chrome
82
80
  test_files: []
@@ -1,27 +0,0 @@
1
- module FerrumPdf
2
- module Controller
3
- extend ActiveSupport::Concern
4
-
5
- def render_pdf(pdf_options: {}, **rendering, &block)
6
- content = render_to_string(**rendering.with_defaults(formats: [ :html ]))
7
-
8
- FerrumPdf.render_pdf(
9
- html: content,
10
- base_url: request.base_url,
11
- pdf_options: pdf_options,
12
- &block
13
- )
14
- end
15
-
16
- def render_screenshot(screenshot_options: {}, **rendering, &block)
17
- content = render_to_string(**rendering.with_defaults(formats: [ :html ]))
18
-
19
- FerrumPdf.render_screenshot(
20
- html: content,
21
- base_url: request.base_url,
22
- screenshot_options: screenshot_options,
23
- &block
24
- )
25
- end
26
- end
27
- end
@@ -1,4 +0,0 @@
1
- # desc "Explaining what the task does"
2
- # task :ferrum_pdf do
3
- # # Task goes here
4
- # end