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 +4 -4
- data/README.md +48 -26
- data/lib/ferrum_pdf/assets_helper.rb +35 -35
- data/lib/ferrum_pdf/railtie.rb +18 -2
- data/lib/ferrum_pdf/version.rb +1 -1
- data/lib/ferrum_pdf.rb +15 -11
- metadata +2 -4
- data/lib/ferrum_pdf/controller.rb +0 -27
- data/lib/tasks/ferrum_pdf_tasks.rake +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e10a66bff6f06cfd7388c12247ca55e92a79bc48ff741e889e0ac0bfde0286e0
|
4
|
+
data.tar.gz: 2a92a79c5a7ca34091644fcd5795d1d1c84d49f7d834f02afd6d9ec462ba892b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
7
|
+
<img src="ferrum_pdf.png" alt="logo" style="width:450px;"/>
|
8
8
|
|
9
|
-
|
9
|
+
## Installation
|
10
10
|
|
11
|
-
|
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 `
|
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
|
-
|
48
|
-
|
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 `
|
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
|
-
|
138
|
-
|
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
|
-
##
|
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
|
-
|
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
|
-
|
3
|
-
|
4
|
-
|
5
|
-
@asset = asset
|
6
|
-
end
|
2
|
+
class BaseAsset
|
3
|
+
def initialize(asset)
|
4
|
+
@asset = asset
|
7
5
|
end
|
6
|
+
end
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
class PropshaftAsset < BaseAsset
|
9
|
+
def content_type
|
10
|
+
@asset.content_type.to_s
|
11
|
+
end
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
end
|
13
|
+
def content
|
14
|
+
@asset.content
|
17
15
|
end
|
16
|
+
end
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
class SprocketsAsset < BaseAsset
|
19
|
+
def content_type
|
20
|
+
@asset.content_type
|
21
|
+
end
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
end
|
23
|
+
def content
|
24
|
+
@asset.source
|
27
25
|
end
|
26
|
+
end
|
28
27
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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
|
-
|
42
|
-
|
43
|
-
|
40
|
+
def propshaft_asset(path)
|
41
|
+
(asset = Rails.application.assets.load_path.find(path)) ? PropshaftAsset.new(asset) : nil
|
42
|
+
end
|
44
43
|
|
45
|
-
|
46
|
-
|
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
|
data/lib/ferrum_pdf/railtie.rb
CHANGED
@@ -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
|
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
|
-
|
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
|
data/lib/ferrum_pdf/version.rb
CHANGED
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:
|
92
|
-
try
|
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
|
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.
|
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
|