ferrum_pdf 0.2.0 → 0.4.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 +217 -23
- data/lib/ferrum_pdf/assets_helper.rb +65 -0
- data/lib/ferrum_pdf/controller.rb +27 -0
- data/lib/ferrum_pdf/html_preprocessor.rb +31 -0
- data/lib/ferrum_pdf/railtie.rb +7 -1
- data/lib/ferrum_pdf/version.rb +1 -1
- data/lib/ferrum_pdf.rb +79 -43
- metadata +9 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9b709d6f3d6b9472b389f08891e3ec59f90a2e0a962f034acd31a2ee4efdb79c
|
4
|
+
data.tar.gz: c1353b79300829afd212880fbcb76633e3fe7da2c2facc3b96d8305a7c5fc6ae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a4145a37dc89ac2dbaeb0512fffafbd6056291e0521734ed57affd66a45d32489fd412d0f8fbbde7b53046ffbc8d030f602ee6914224ea76bdb1e95c78adf50f
|
7
|
+
data.tar.gz: 57c44da1352bac877910af6193f7104da77580bd9edaafa1d3dbbb4faa2175d8ec05215bccc40c7f85fa4e93d84089f15c1e2c606bcf886a46625f3c2b3ba61a
|
data/README.md
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
# FerrumPdf
|
2
2
|
|
3
|
-
PDFs for Rails using [Ferrum](https://github.com/rubycdp/ferrum) & headless Chrome
|
3
|
+
PDFs & screentshots for Rails using [Ferrum](https://github.com/rubycdp/ferrum) & headless Chrome.
|
4
|
+
|
5
|
+
Inspired by [Grover](https://github.com/Studiosity/grover).
|
4
6
|
|
5
7
|
## Installation
|
6
8
|
|
9
|
+
First, make sure Chrome is installed.
|
10
|
+
|
7
11
|
Run the following or add the gem to your Gemfile:
|
8
12
|
|
9
13
|
```ruby
|
@@ -12,7 +16,16 @@ bundle add "ferrum_pdf"
|
|
12
16
|
|
13
17
|
## Usage
|
14
18
|
|
15
|
-
|
19
|
+
You can use FerrumPdf to render [PDFs](#-pdfs) and [Screenshots](#-screenshots)
|
20
|
+
|
21
|
+
### 📄 PDFs
|
22
|
+
|
23
|
+
There are two ways to render PDFs:
|
24
|
+
|
25
|
+
* [FerrumPdf.render_pdf](#render-pdfs)
|
26
|
+
* [render_pdf in Rails](#render-pdfs-from-rails-controllers)
|
27
|
+
|
28
|
+
#### Render PDFs from Rails controllers
|
16
29
|
|
17
30
|
Use the `render_pdf` helper in Rails controllers to render a PDF from the current action.
|
18
31
|
|
@@ -20,54 +33,235 @@ Use the `render_pdf` helper in Rails controllers to render a PDF from the curren
|
|
20
33
|
def show
|
21
34
|
respond_to do |format|
|
22
35
|
format.html
|
23
|
-
format.pdf {
|
36
|
+
format.pdf {
|
37
|
+
pdf = render_pdf()
|
38
|
+
send_data pdf, disposition: :inline, filename: "example.pdf"
|
39
|
+
}
|
24
40
|
end
|
25
41
|
end
|
26
42
|
```
|
27
43
|
|
28
|
-
You can also customize which template is rendered:
|
44
|
+
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:
|
29
45
|
|
30
46
|
```ruby
|
31
|
-
render_pdf(
|
47
|
+
render_pdf(
|
48
|
+
layout: "pdf,
|
49
|
+
pdf_options: {
|
50
|
+
display_header_footer: true,
|
51
|
+
header_template: FerrumPdf::DEFAULT_HEADER_TEMPLATE,
|
52
|
+
footer_template: FerrumPdf::DEFAULT_FOOTER_TEMPLATE
|
53
|
+
}
|
54
|
+
)
|
32
55
|
```
|
33
56
|
|
34
|
-
|
57
|
+
#### Render PDFs
|
35
58
|
|
36
|
-
|
59
|
+
FerrumPdf can generate a PDF from HTML or a URL:
|
37
60
|
|
38
61
|
```ruby
|
39
|
-
render_pdf(
|
40
|
-
|
41
|
-
header_template: FerrumPdf::DEFAULT_HEADER_TEMPLATE,
|
42
|
-
footer_template: FerrumPdf::DEFAULT_FOOTER_TEMPLATE
|
43
|
-
})
|
62
|
+
FerrumPdf.render_pdf(html: content)
|
63
|
+
FerrumPdf.render_pdf(url: "https://google.com")
|
44
64
|
```
|
45
65
|
|
46
|
-
|
66
|
+
The full list of options:
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
FerrumPdf.render_pdf(
|
70
|
+
url: "https://example.com/page", # Provide a URL to the content
|
71
|
+
|
72
|
+
html: content, # or provide HTML
|
73
|
+
base_url: request.base_url, # Preprocesses `html` to convert relative paths and protocols. Example: "https://example.org"
|
74
|
+
|
75
|
+
authorize: { user: "username", password: "password" }, # Used for authenticating with basic auth
|
76
|
+
wait_for_idle_options: { connections: 0, duration: 0.05, timeout: 5 }, # Used for setting network wait_for_idle options
|
77
|
+
|
78
|
+
pdf_options: {
|
79
|
+
landscape: false, # paper orientation
|
80
|
+
scale: 1, # Scale of the webpage rendering
|
81
|
+
format: nil,
|
82
|
+
paper_width: 8.5, # Paper width in inches
|
83
|
+
paper_height: 11, # Paper height in inches
|
84
|
+
page_ranges: nil, # Paper ranges to print "1-5, 8 11-13"
|
85
|
+
|
86
|
+
# Margins (in inches, defaults to 1cm)
|
87
|
+
margin_top: 0.4,
|
88
|
+
margin_bottom: 0.4,
|
89
|
+
margin_left: 0.4,
|
90
|
+
margin_right: 0.4,
|
91
|
+
|
92
|
+
# Header, footer, and background options
|
93
|
+
#
|
94
|
+
# Variables can be used with CSS classes. For example <span class="date"></span>
|
95
|
+
# * date: formatted print date
|
96
|
+
# * title: document title
|
97
|
+
# * url: document location
|
98
|
+
# * pageNumber: current page number
|
99
|
+
# *totalPages: total pages in the document
|
100
|
+
|
101
|
+
display_header_footer: false,
|
102
|
+
print_background: false, # Print background graphics
|
103
|
+
header_template: "", # HTML template for the header
|
104
|
+
footer_template: "", # HTML template for the footer
|
105
|
+
}
|
106
|
+
)
|
107
|
+
```
|
108
|
+
|
109
|
+
See [Chrome DevTools Protocol docs](https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-printToPDF) and [Ferrum's `#pdf` docs](https://github.com/rubycdp/ferrum?tab=readme-ov-file#pdfoptions--string--boolean) for the full set of options.
|
110
|
+
|
111
|
+
### 🎆 Screenshots
|
47
112
|
|
48
|
-
|
113
|
+
There are two ways to render Screenshots:
|
114
|
+
|
115
|
+
* [FerrumPdf.render_screenshot](#render-screenshots)
|
116
|
+
* [render_screenshot in Rails](#render-screenshots-from-rails-controllers)
|
117
|
+
|
118
|
+
#### Render Screenshots from Rails controllers
|
119
|
+
|
120
|
+
Use the `render_screenshot` helper in Rails controllers to render a PDF from the current action.
|
49
121
|
|
50
122
|
```ruby
|
51
|
-
|
123
|
+
def show
|
124
|
+
respond_to do |format|
|
125
|
+
format.html
|
126
|
+
format.png {
|
127
|
+
screenshot = render_screenshot()
|
128
|
+
send_data screenshot, disposition: :inline, filename: "example.png"
|
129
|
+
}
|
130
|
+
end
|
131
|
+
end
|
52
132
|
```
|
53
133
|
|
54
|
-
You can also
|
134
|
+
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.
|
55
135
|
|
56
136
|
```ruby
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
137
|
+
render_screenshot(
|
138
|
+
screenshot_options: {
|
139
|
+
format: "png" # or "jpeg"
|
140
|
+
quality: nil # Integer 0-100 works for jpeg only
|
141
|
+
full: true # Boolean whether you need full page screenshot or a viewport
|
142
|
+
selector: nil # String css selector for given element, optional
|
143
|
+
area: nil # Hash area for screenshot, optional. {x: 0, y: 0, width: 100, height: 100}
|
144
|
+
scale: nil # Float zoom in/out
|
145
|
+
background_color: nil # Ferrum::RGBA.new(0, 0, 0, 0.0)
|
146
|
+
}
|
62
147
|
)
|
63
148
|
```
|
64
149
|
|
65
|
-
See
|
66
|
-
|
150
|
+
See [Ferrum screenshot docs](https://github.com/rubycdp/ferrum?tab=readme-ov-file#screenshotoptions--string--integer) for the full set of options.
|
151
|
+
|
152
|
+
#### Render Screenshots
|
153
|
+
|
154
|
+
FerrumPdf can generate a screenshot from HTML or a URL:
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
FerrumPdf.render_screenshot(html: content)
|
158
|
+
FerrumPdf.render_screenshot(url: "https://google.com")
|
159
|
+
```
|
160
|
+
|
161
|
+
The full list of options
|
162
|
+
|
163
|
+
```ruby
|
164
|
+
FerrumPdf.render_screenshot(
|
165
|
+
url: "https://example.com/page", # Provide a URL to the content
|
166
|
+
|
167
|
+
html: content, # or provide HTML
|
168
|
+
base_url: request.base_url, # Preprocesses `html` to convert relative paths and protocols. Example: "https://example.org"
|
169
|
+
|
170
|
+
screenshot_options: {
|
171
|
+
format: "png" # or "jpeg"
|
172
|
+
quality: nil # Integer 0-100 works for jpeg only
|
173
|
+
full: true # Boolean whether you need full page screenshot or a viewport
|
174
|
+
selector: nil # String css selector for given element, optional
|
175
|
+
area: nil # Hash area for screenshot, optional. {x: 0, y: 0, width: 100, height: 100}
|
176
|
+
scale: nil # Float zoom in/out
|
177
|
+
background_color: nil # Ferrum::RGBA.new(0, 0, 0, 0.0)
|
178
|
+
}
|
179
|
+
)
|
180
|
+
```
|
181
|
+
|
182
|
+
## Configuring the Browser
|
183
|
+
|
184
|
+
You can set the default browser options with the configure block.
|
185
|
+
|
186
|
+
See [Ferrum's Customization docs](https://github.com/rubycdp/ferrum?tab=readme-ov-file#customization) for a full list of options.
|
187
|
+
|
188
|
+
```ruby
|
189
|
+
FerrumPdf.configure do |config|
|
190
|
+
config.window_size = [1920, 1080]
|
191
|
+
|
192
|
+
# config.process_timeout = 30 # defaults to 10
|
193
|
+
# config.browser_path = '/usr/bin/chromium'
|
194
|
+
|
195
|
+
# For use with Docker, but ensure you trust any sites visited
|
196
|
+
# config.browser_options = {
|
197
|
+
# "no-sandbox" => true
|
198
|
+
# }
|
199
|
+
end
|
200
|
+
```
|
201
|
+
|
202
|
+
For Docker, `seccomp` is recommend over `--no-sandbox` for security: https://github.com/jlandure/alpine-chrome?tab=readme-ov-file#3-ways-to-securely-use-chrome-headless-with-this-image
|
203
|
+
|
204
|
+
To add Chrome to your Docker image:
|
205
|
+
|
206
|
+
```dockerfile
|
207
|
+
RUN apt-get update && apt-get install gnupg wget -y && \
|
208
|
+
wget --quiet --output-document=- https://dl-ssl.google.com/linux/linux_signing_key.pub | gpg --dearmor > /etc/apt/trusted.gpg.d/google-archive.gpg && \
|
209
|
+
sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' && \
|
210
|
+
apt-get update && \
|
211
|
+
apt-get install google-chrome-stable -y && \
|
212
|
+
rm -rf /var/lib/apt/lists/*
|
213
|
+
```
|
214
|
+
|
215
|
+
### Multiple Browser Support
|
216
|
+
|
217
|
+
```ruby
|
218
|
+
# Create two browsers using the FerrumPdf config, but overriding `window_size`
|
219
|
+
FerrumPdf.add_browser(:small, window_size: [1024, 768]))
|
220
|
+
FerrumPdf.add_browser(:large, window_size: [1920, 1080]))
|
221
|
+
|
222
|
+
FerrumPdf.render_pdf(url: "https://example.org", browser: :small)
|
223
|
+
FerrumPdf.render_pdf(url: "https://example.org", browser: :large)
|
224
|
+
```
|
225
|
+
|
226
|
+
You can also create a `Ferrum::Browser` instance and pass it in as `browser`:
|
227
|
+
|
228
|
+
```ruby
|
229
|
+
FerrumPdf.render_pdf(url: "https://example.org", browser: Ferrum::Browser.new)
|
230
|
+
```
|
231
|
+
|
232
|
+
## Debugging
|
233
|
+
|
234
|
+
One option for debugging is to use Chrome in regular, non-headless mode:
|
235
|
+
|
236
|
+
```ruby
|
237
|
+
FerrumPdf.configure do |config|
|
238
|
+
config.headless = false
|
239
|
+
end
|
240
|
+
```
|
241
|
+
|
242
|
+
FerrumPdf also allows you to pass a block for debugging. This block is executed after loading the page but before rendering the PDF or screenshot.
|
243
|
+
|
244
|
+
```ruby
|
245
|
+
FerrumPdf.render_pdf(url: "https://gooogle.com") do |browser, page|
|
246
|
+
# Open Chrome DevTools to remotely inspect the browser
|
247
|
+
browser.debug
|
248
|
+
|
249
|
+
# Or pause and poke around
|
250
|
+
binding.irb
|
251
|
+
end
|
252
|
+
```
|
253
|
+
|
254
|
+
The block will receive the `Ferrum::Browser` and `Ferrum::Page` objects which you can use for debugging.
|
67
255
|
|
68
256
|
## Contributing
|
69
257
|
|
70
258
|
If you have an issue you'd like to submit, please do so using the issue tracker in GitHub. In order for us to help you in the best way possible, please be as detailed as you can.
|
71
259
|
|
260
|
+
To run the test suite, run:
|
261
|
+
|
262
|
+
```bash
|
263
|
+
bin/test
|
264
|
+
```
|
265
|
+
|
72
266
|
## License
|
73
267
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module FerrumPdf
|
2
|
+
module AssetsHelper
|
3
|
+
class BaseAsset
|
4
|
+
def initialize(asset)
|
5
|
+
@asset = asset
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class PropshaftAsset < BaseAsset
|
10
|
+
def content_type
|
11
|
+
@asset.content_type.to_s
|
12
|
+
end
|
13
|
+
|
14
|
+
def content
|
15
|
+
@asset.content
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class SprocketsAsset < BaseAsset
|
20
|
+
def content_type
|
21
|
+
@asset.content_type
|
22
|
+
end
|
23
|
+
|
24
|
+
def content
|
25
|
+
@asset.source
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
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
|
39
|
+
end
|
40
|
+
|
41
|
+
def propshaft_asset(path)
|
42
|
+
(asset = Rails.application.assets.load_path.find(path)) ? PropshaftAsset.new(asset) : nil
|
43
|
+
end
|
44
|
+
|
45
|
+
def sprockets_asset(path)
|
46
|
+
(asset = Rails.application.assets.find_asset(path)) ? SprocketsAsset.new(asset) : nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def ferrum_pdf_inline_stylesheet(path)
|
52
|
+
(asset = AssetFinder.find(path)) ? "<style>#{asset.content}</style>".html_safe : nil
|
53
|
+
end
|
54
|
+
|
55
|
+
def ferrum_pdf_inline_javascript(path)
|
56
|
+
(asset = AssetFinder.find(path)) ? "<script>#{asset.content}</script>".html_safe : nil
|
57
|
+
end
|
58
|
+
|
59
|
+
def ferrum_pdf_base64_asset(path)
|
60
|
+
return nil unless (asset = AssetFinder.find(path))
|
61
|
+
|
62
|
+
"data:#{asset.content_type};base64,#{Base64.encode64(asset.content).gsub(/\s+/, '')}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,27 @@
|
|
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
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module FerrumPdf
|
2
|
+
# Helper module for preparing HTML for conversion
|
3
|
+
#
|
4
|
+
# Sourced from the PDFKit project
|
5
|
+
# @see https://github.com/pdfkit/pdfkit
|
6
|
+
module HTMLPreprocessor
|
7
|
+
# Change relative paths to absolute, and relative protocols to absolute protocols
|
8
|
+
#
|
9
|
+
# process("Some HTML", "https://example.org")
|
10
|
+
#
|
11
|
+
def self.process(html, base_url)
|
12
|
+
base_url += "/" unless base_url.end_with? "/"
|
13
|
+
protocol = base_url.split("://").first
|
14
|
+
html = translate_relative_paths(html, base_url) if base_url
|
15
|
+
html = translate_relative_protocols(html, protocol) if protocol
|
16
|
+
html
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.translate_relative_paths(html, base_url)
|
20
|
+
# Try out this regexp using rubular http://rubular.com/r/hiAxBNX7KE
|
21
|
+
html.gsub(%r{(href|src)=(['"])/([^/"']([^"']*|[^"']*))?['"]}, "\\1=\\2#{base_url}\\3\\2")
|
22
|
+
end
|
23
|
+
private_class_method :translate_relative_paths
|
24
|
+
|
25
|
+
def self.translate_relative_protocols(body, protocol)
|
26
|
+
# Try out this regexp using rubular http://rubular.com/r/0Ohk0wFYxV
|
27
|
+
body.gsub(%r{(href|src)=(['"])//([^"']*|[^"']*)['"]}, "\\1=\\2#{protocol}://\\3\\2")
|
28
|
+
end
|
29
|
+
private_class_method :translate_relative_protocols
|
30
|
+
end
|
31
|
+
end
|
data/lib/ferrum_pdf/railtie.rb
CHANGED
@@ -1,8 +1,14 @@
|
|
1
1
|
module FerrumPdf
|
2
2
|
class Railtie < ::Rails::Railtie
|
3
|
+
initializer "ferrum_pdf.assets_helper" do
|
4
|
+
ActiveSupport.on_load(:action_view) do
|
5
|
+
include FerrumPdf::AssetsHelper if FerrumPdf.include_assets_helper_module
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
3
9
|
initializer "ferrum_pdf.controller" do
|
4
10
|
ActiveSupport.on_load(:action_controller) do
|
5
|
-
include FerrumPdf::Controller
|
11
|
+
include FerrumPdf::Controller if FerrumPdf.include_controller_module
|
6
12
|
end
|
7
13
|
end
|
8
14
|
end
|
data/lib/ferrum_pdf/version.rb
CHANGED
data/lib/ferrum_pdf.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require "ferrum_pdf/version"
|
2
2
|
require "ferrum_pdf/railtie"
|
3
|
-
|
4
3
|
require "ferrum"
|
5
4
|
|
6
5
|
module FerrumPdf
|
@@ -10,59 +9,96 @@ module FerrumPdf
|
|
10
9
|
<div class='text right'><span class='pageNumber'></span>/<span class='totalPages'></span></div>
|
11
10
|
HTML
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
autoload :AssetsHelper, "ferrum_pdf/assets_helper"
|
13
|
+
autoload :Controller, "ferrum_pdf/controller"
|
14
|
+
autoload :HTMLPreprocessor, "ferrum_pdf/html_preprocessor"
|
16
15
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
16
|
+
mattr_accessor :include_assets_helper_module, default: true
|
17
|
+
mattr_accessor :include_controller_module, default: true
|
18
|
+
mattr_accessor :browsers, default: {}
|
19
|
+
mattr_accessor :config, default: ActiveSupport::OrderedOptions.new.merge(
|
20
|
+
window_size: [ 1920, 1080 ]
|
21
|
+
)
|
22
|
+
|
23
|
+
class << self
|
24
|
+
def configure
|
25
|
+
yield config
|
26
26
|
end
|
27
|
-
end
|
28
27
|
|
29
|
-
|
30
|
-
|
31
|
-
# Sourced from the PDFKit project
|
32
|
-
# @see https://github.com/pdfkit/pdfkit
|
33
|
-
module HTMLPreprocessor
|
34
|
-
# Change relative paths to absolute, and relative protocols to absolute protocols
|
35
|
-
def self.process(html, root_url, protocol)
|
36
|
-
html = translate_relative_paths(html, root_url) if root_url
|
37
|
-
html = translate_relative_protocols(html, protocol) if protocol
|
38
|
-
html
|
28
|
+
def add_browser(name, **options)
|
29
|
+
@@browsers[name] = Ferrum::Browser.new(@@config.merge(options))
|
39
30
|
end
|
40
31
|
|
41
|
-
|
42
|
-
|
43
|
-
|
32
|
+
# Renders HTML or URL to PDF
|
33
|
+
#
|
34
|
+
# render_pdf(url: "https://example.org/receipts/example.pdf")
|
35
|
+
# render_pdf(html: "<h1>Hello world</h1>")
|
36
|
+
#
|
37
|
+
# For rendering HTML, we also need the base_url for preprocessing URLs with relative paths & protocols
|
38
|
+
#
|
39
|
+
# render_pdf(html: "<h1>Hello world</h1>", base_url: "https://example.org/")
|
40
|
+
#
|
41
|
+
def render_pdf(pdf_options: {}, **load_page_args)
|
42
|
+
load_page(**load_page_args) do |browser, page|
|
43
|
+
yield browser, page if block_given?
|
44
|
+
page.pdf(**pdf_options.with_defaults(encoding: :binary))
|
45
|
+
end
|
44
46
|
end
|
45
|
-
private_class_method :translate_relative_paths
|
46
47
|
|
47
|
-
|
48
|
-
|
49
|
-
|
48
|
+
# Renders HTML or URL to Screenshot
|
49
|
+
#
|
50
|
+
# render_screenshot(url: "https://example.org/receipts/example.pdf")
|
51
|
+
# render_screenshot(html: "<h1>Hello world</h1>")
|
52
|
+
#
|
53
|
+
# For rendering HTML, we also need the base_url for preprocessing URLs with relative paths & protocols
|
54
|
+
#
|
55
|
+
# render_screenshot(html: "<h1>Hello world</h1>", base_url: "https://example.org/")
|
56
|
+
#
|
57
|
+
def render_screenshot(screenshot_options: {}, **load_page_args)
|
58
|
+
load_page(**load_page_args) do |browser, page|
|
59
|
+
yield browser, page if block_given?
|
60
|
+
page.screenshot(**screenshot_options.with_defaults(encoding: :binary, full: true))
|
61
|
+
end
|
50
62
|
end
|
51
|
-
private_class_method :translate_relative_protocols
|
52
|
-
end
|
53
63
|
|
54
|
-
|
55
|
-
|
64
|
+
# Loads page into the browser to be used for rendering PDFs or screenshots
|
65
|
+
#
|
66
|
+
# This automatically applies HTML preprocessing if `html:` is present
|
67
|
+
#
|
68
|
+
def load_page(url: nil, html: nil, base_url: nil, authorize: nil, wait_for_idle_options: nil, browser: :default, retries: 1)
|
69
|
+
try = 0
|
70
|
+
|
71
|
+
# Lookup browser if a name was passed
|
72
|
+
browser = @@browsers[browser] || add_browser(browser) if browser.is_a? Symbol
|
73
|
+
|
74
|
+
# Automatically restart the browser if it was disconnected
|
75
|
+
browser.restart unless browser.client.present?
|
76
|
+
|
77
|
+
# Closes page automatically after block finishes
|
78
|
+
# https://github.com/rubycdp/ferrum/blob/main/lib/ferrum/browser.rb#L169
|
79
|
+
browser.create_page do |page|
|
80
|
+
page.network.authorize(**authorize) { |req| req.continue } if authorize
|
56
81
|
|
57
|
-
|
58
|
-
|
82
|
+
# Load content
|
83
|
+
if html
|
84
|
+
page.content = FerrumPdf::HTMLPreprocessor.process(html, base_url)
|
85
|
+
else
|
86
|
+
page.go_to(url)
|
87
|
+
end
|
59
88
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
89
|
+
# Wait for everything to load
|
90
|
+
page.network.wait_for_idle(**wait_for_idle_options)
|
91
|
+
|
92
|
+
yield browser, page
|
93
|
+
end
|
94
|
+
rescue Ferrum::DeadBrowserError
|
95
|
+
try += 1
|
96
|
+
if try <= retries
|
97
|
+
browser.restart
|
98
|
+
retry
|
99
|
+
else
|
100
|
+
raise
|
101
|
+
end
|
66
102
|
end
|
67
103
|
end
|
68
104
|
end
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ferrum_pdf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Oliver
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: rails
|
@@ -38,7 +37,8 @@ dependencies:
|
|
38
37
|
- - "~>"
|
39
38
|
- !ruby/object:Gem::Version
|
40
39
|
version: '0.15'
|
41
|
-
description: Export PDFs from HTML in Rails using Ferrum & headless
|
40
|
+
description: Export PDFs & screenshots from HTML in Rails using Ferrum & headless
|
41
|
+
Chrome
|
42
42
|
email:
|
43
43
|
- excid3@gmail.com
|
44
44
|
executables: []
|
@@ -49,6 +49,9 @@ files:
|
|
49
49
|
- README.md
|
50
50
|
- Rakefile
|
51
51
|
- lib/ferrum_pdf.rb
|
52
|
+
- lib/ferrum_pdf/assets_helper.rb
|
53
|
+
- lib/ferrum_pdf/controller.rb
|
54
|
+
- lib/ferrum_pdf/html_preprocessor.rb
|
52
55
|
- lib/ferrum_pdf/railtie.rb
|
53
56
|
- lib/ferrum_pdf/version.rb
|
54
57
|
- lib/tasks/ferrum_pdf_tasks.rake
|
@@ -59,7 +62,6 @@ metadata:
|
|
59
62
|
homepage_uri: https://github.com/excid3/ferrum_pdf
|
60
63
|
source_code_uri: https://github.com/excid3/ferrum_pdf
|
61
64
|
changelog_uri: https://github.com/excid3/ferrum_pdf/blob/main/CHANGELOG.md
|
62
|
-
post_install_message:
|
63
65
|
rdoc_options: []
|
64
66
|
require_paths:
|
65
67
|
- lib
|
@@ -74,8 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
74
76
|
- !ruby/object:Gem::Version
|
75
77
|
version: '0'
|
76
78
|
requirements: []
|
77
|
-
rubygems_version: 3.
|
78
|
-
signing_key:
|
79
|
+
rubygems_version: 3.6.9
|
79
80
|
specification_version: 4
|
80
|
-
summary: PDFs for Rails using Ferrum & headless Chrome
|
81
|
+
summary: PDFs & screenshots for Rails using Ferrum & headless Chrome
|
81
82
|
test_files: []
|