ferrum_pdf 2.1.0 → 3.0.1
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 +4 -4
- data/lib/ferrum_pdf/renderers.rb +19 -0
- data/lib/ferrum_pdf/version.rb +1 -1
- data/lib/ferrum_pdf.rb +25 -15
- metadata +4 -6
- data/lib/ferrum_pdf/assets_helper.rb +0 -65
- data/lib/ferrum_pdf/html_preprocessor.rb +0 -33
- data/lib/ferrum_pdf/railtie.rb +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: efe120091d2cc3eaaf6ce3e7fc5ccb3c34d3fabe59570986fa5b08d89295b58a
|
4
|
+
data.tar.gz: b3923cb2306e1cd27023725ddb088ae9f6ed290aab538db1e0d27bdb032d79cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e44f85006fc98e28298c2e3720b3066bc59611c32b439791df54d5b70e4dae5eaa62fabe1499d75f7f85599ff79e52ffee60485556f3b1167a1082aeb381702
|
7
|
+
data.tar.gz: 86ad9105c1a8e2bf3c867a91e0a409d045d5ffdbc6755bdfa5af02a7948271c32ab063a138f3ff09903daa3f100642ef8f328aea154cb4e316add75944d07680
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# 📄 FerrumPdf
|
2
2
|
|
3
|
-
PDFs &
|
3
|
+
PDFs & screenshots for Rails using [Ferrum](https://github.com/rubycdp/ferrum) & headless Chrome.
|
4
4
|
|
5
5
|
Inspired by [Grover](https://github.com/Studiosity/grover), but without the Node.js and puppeteer dependencies. 🎉
|
6
6
|
|
@@ -70,10 +70,11 @@ FerrumPdf.render_pdf(
|
|
70
70
|
url: "https://example.com/page", # Provide a URL to the content
|
71
71
|
|
72
72
|
html: content, # or provide HTML
|
73
|
-
|
73
|
+
display_url: request.original_url, # When supplying content via :html its best to give Chrome a hint of the current url so that it can process relative paths in the document. If you don't provide this, http://example.com will be used instead.
|
74
74
|
|
75
75
|
authorize: { user: "username", password: "password" }, # Used for authenticating with basic auth
|
76
76
|
wait_for_idle_options: { connections: 0, duration: 0.05, timeout: 5 }, # Used for setting network wait_for_idle options
|
77
|
+
timeout_if_open_connections: true,
|
77
78
|
|
78
79
|
pdf_options: {
|
79
80
|
landscape: false, # paper orientation
|
@@ -166,7 +167,7 @@ FerrumPdf.render_screenshot(
|
|
166
167
|
url: "https://example.com/page", # Provide a URL to the content
|
167
168
|
|
168
169
|
html: content, # or provide HTML
|
169
|
-
|
170
|
+
display_url: request.original_url, # When supplying content via :html its best to give Chrome a hint of the current url so that it can process relative paths in the document. If you don't provide this, http://example.com will be used instead.
|
170
171
|
|
171
172
|
screenshot_options: {
|
172
173
|
format: "png" # or "jpeg"
|
@@ -186,7 +187,6 @@ You can set default values for page loads, PDF renders, and screenshot renders w
|
|
186
187
|
|
187
188
|
```ruby
|
188
189
|
FerrumPdf.configure do |config|
|
189
|
-
config.page_options.base_url = "https://example.com/"
|
190
190
|
config.page_options.authorize = { user: "username", password: "password" }
|
191
191
|
config.page_options.wait_for_idle_options = { timeout: 90 }
|
192
192
|
config.page_options.retries = 3
|
@@ -0,0 +1,19 @@
|
|
1
|
+
ActiveSupport.on_load(:action_controller) do
|
2
|
+
# render ferrum_pdf: { pdf options }, template: "whatever", disposition: :inline, filename: "example.pdf"
|
3
|
+
ActionController.add_renderer :ferrum_pdf do |pdf_options, options|
|
4
|
+
send_data_options = options.extract!(:disposition, :filename, :status)
|
5
|
+
url = pdf_options.delete(:url)
|
6
|
+
html = render_to_string(**options.with_defaults(formats: [ :html ])) if url.blank?
|
7
|
+
pdf = FerrumPdf.render_pdf(html: html, display_url: request.original_url, url: url, pdf_options: pdf_options)
|
8
|
+
send_data(pdf, **send_data_options.with_defaults(type: :pdf))
|
9
|
+
end
|
10
|
+
|
11
|
+
# render ferrum_screenshot: { pdf options }, template: "whatever", disposition: :inline, filename: "example.png"
|
12
|
+
ActionController.add_renderer :ferrum_screenshot do |screenshot_options, options|
|
13
|
+
send_data_options = options.extract!(:disposition, :filename, :status)
|
14
|
+
url = screenshot_options.delete(:url)
|
15
|
+
html = render_to_string(**options.with_defaults(formats: [ :html ])) if url.blank?
|
16
|
+
screenshot = FerrumPdf.render_screenshot(url: url, html: html, display_url: request.original_url, screenshot_options: screenshot_options)
|
17
|
+
send_data(screenshot, **send_data_options.with_defaults(type: screenshot_options.fetch(:format, :png)))
|
18
|
+
end
|
19
|
+
end
|
data/lib/ferrum_pdf/version.rb
CHANGED
data/lib/ferrum_pdf.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
require "ferrum_pdf/version"
|
2
|
-
require "ferrum_pdf/railtie"
|
3
1
|
require "ferrum"
|
2
|
+
require "action_controller"
|
3
|
+
|
4
|
+
require "ferrum_pdf/renderers"
|
5
|
+
require "ferrum_pdf/version"
|
4
6
|
|
5
7
|
module FerrumPdf
|
6
8
|
DEFAULT_HEADER_TEMPLATE = "<div class='date text left'></div><div class='title text center'></div>"
|
@@ -9,9 +11,6 @@ module FerrumPdf
|
|
9
11
|
<div class='text right'><span class='pageNumber'></span>/<span class='totalPages'></span></div>
|
10
12
|
HTML
|
11
13
|
|
12
|
-
autoload :AssetsHelper, "ferrum_pdf/assets_helper"
|
13
|
-
autoload :HTMLPreprocessor, "ferrum_pdf/html_preprocessor"
|
14
|
-
|
15
14
|
mattr_accessor :browser_mutex, default: Mutex.new
|
16
15
|
mattr_accessor :config, default: ActiveSupport::OrderedOptions.new.merge(
|
17
16
|
window_size: [ 1920, 1080 ],
|
@@ -57,9 +56,9 @@ module FerrumPdf
|
|
57
56
|
# render_pdf(url: "https://example.org/receipts/example.pdf")
|
58
57
|
# render_pdf(html: "<h1>Hello world</h1>")
|
59
58
|
#
|
60
|
-
# For rendering HTML, we also need
|
59
|
+
# For rendering HTML, we also need display_url for so that Chrome can interpret URLs with relative paths & protocols
|
61
60
|
#
|
62
|
-
# render_pdf(html: "<h1>Hello world</h1>",
|
61
|
+
# render_pdf(html: "<h1>Hello world</h1>", display_url: "https://example.org/hello_world")
|
63
62
|
#
|
64
63
|
def render_pdf(pdf_options: {}, **load_page_args)
|
65
64
|
load_page(**load_page_args) do |browser, page|
|
@@ -73,9 +72,9 @@ module FerrumPdf
|
|
73
72
|
# render_screenshot(url: "https://example.org/receipts/example.pdf")
|
74
73
|
# render_screenshot(html: "<h1>Hello world</h1>")
|
75
74
|
#
|
76
|
-
# For rendering HTML, we also need
|
75
|
+
# For rendering HTML, we also need display_url for so that Chrome can interpret URLs with relative paths & protocols
|
77
76
|
#
|
78
|
-
# render_screenshot(html: "<h1>Hello world</h1>",
|
77
|
+
# render_screenshot(html: "<h1>Hello world</h1>", display_url: "https://example.org/hello_world")
|
79
78
|
#
|
80
79
|
def render_screenshot(screenshot_options: {}, **load_page_args)
|
81
80
|
load_page(**load_page_args) do |browser, page|
|
@@ -84,16 +83,16 @@ module FerrumPdf
|
|
84
83
|
end
|
85
84
|
end
|
86
85
|
|
86
|
+
private
|
87
|
+
|
87
88
|
# Loads page into the browser to be used for rendering PDFs or screenshots
|
88
89
|
#
|
89
|
-
|
90
|
-
#
|
91
|
-
def load_page(url: nil, html: nil, base_url: nil, authorize: nil, wait_for_idle_options: nil, browser: nil, retries: nil)
|
90
|
+
def load_page(url: nil, html: nil, display_url: nil, authorize: nil, wait_for_idle_options: nil, timeout_if_open_connections: nil, browser: nil, retries: nil)
|
92
91
|
try ||= 0
|
93
92
|
authorize ||= config.dig(:page_options, :authorize)
|
94
|
-
base_url ||= config.dig(:page_options, :base_url)
|
95
93
|
retries ||= config.page_options.fetch(:retries, 1)
|
96
94
|
wait_for_idle_options = config.page_options.fetch(:wait_for_idle_options, {}).merge(wait_for_idle_options || {})
|
95
|
+
timeout_if_open_connections = config.page_options.fetch(:timeout_if_open_connections, true) if timeout_if_open_connections.nil?
|
97
96
|
|
98
97
|
with_browser(browser) do |browser|
|
99
98
|
# Closes page automatically after block finishes
|
@@ -103,13 +102,24 @@ module FerrumPdf
|
|
103
102
|
|
104
103
|
# Load content
|
105
104
|
if html
|
106
|
-
|
105
|
+
html_intercepted = false
|
106
|
+
page.network.intercept
|
107
|
+
page.on(:request) do |request|
|
108
|
+
if html_intercepted
|
109
|
+
request.continue
|
110
|
+
else
|
111
|
+
html_intercepted = true
|
112
|
+
request.respond(body: html.blank? ? " " : html)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
page.go_to(display_url || "http://example.com")
|
107
116
|
else
|
108
117
|
page.go_to(url)
|
109
118
|
end
|
110
119
|
|
111
120
|
# Wait for everything to load
|
112
|
-
page.network.wait_for_idle
|
121
|
+
idle = page.network.wait_for_idle(**wait_for_idle_options)
|
122
|
+
raise Ferrum::TimeoutError if timeout_if_open_connections && !idle
|
113
123
|
|
114
124
|
yield browser, page
|
115
125
|
end
|
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:
|
4
|
+
version: 3.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Oliver
|
@@ -10,7 +10,7 @@ cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
|
-
name:
|
13
|
+
name: actionpack
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
15
15
|
requirements:
|
16
16
|
- - ">="
|
@@ -49,9 +49,7 @@ files:
|
|
49
49
|
- README.md
|
50
50
|
- Rakefile
|
51
51
|
- lib/ferrum_pdf.rb
|
52
|
-
- lib/ferrum_pdf/
|
53
|
-
- lib/ferrum_pdf/html_preprocessor.rb
|
54
|
-
- lib/ferrum_pdf/railtie.rb
|
52
|
+
- lib/ferrum_pdf/renderers.rb
|
55
53
|
- lib/ferrum_pdf/version.rb
|
56
54
|
homepage: https://github.com/excid3/ferrum_pdf
|
57
55
|
licenses:
|
@@ -74,7 +72,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
74
72
|
- !ruby/object:Gem::Version
|
75
73
|
version: '0'
|
76
74
|
requirements: []
|
77
|
-
rubygems_version: 3.
|
75
|
+
rubygems_version: 3.6.9
|
78
76
|
specification_version: 4
|
79
77
|
summary: PDFs & screenshots for Rails using Ferrum & headless Chrome
|
80
78
|
test_files: []
|
@@ -1,65 +0,0 @@
|
|
1
|
-
module FerrumPdf
|
2
|
-
class BaseAsset
|
3
|
-
def initialize(asset)
|
4
|
-
@asset = asset
|
5
|
-
end
|
6
|
-
end
|
7
|
-
|
8
|
-
class PropshaftAsset < BaseAsset
|
9
|
-
def content_type
|
10
|
-
@asset.content_type.to_s
|
11
|
-
end
|
12
|
-
|
13
|
-
def content
|
14
|
-
@asset.content
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
class SprocketsAsset < BaseAsset
|
19
|
-
def content_type
|
20
|
-
@asset.content_type
|
21
|
-
end
|
22
|
-
|
23
|
-
def content
|
24
|
-
@asset.source
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
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
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def propshaft_asset(path)
|
41
|
-
(asset = Rails.application.assets.load_path.find(path)) ? PropshaftAsset.new(asset) : nil
|
42
|
-
end
|
43
|
-
|
44
|
-
def sprockets_asset(path)
|
45
|
-
(asset = Rails.application.assets.find_asset(path)) ? SprocketsAsset.new(asset) : nil
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
module AssetsHelper
|
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
|
@@ -1,33 +0,0 @@
|
|
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
|
-
return html if base_url.blank?
|
13
|
-
|
14
|
-
base_url += "/" unless base_url.end_with? "/"
|
15
|
-
protocol = base_url.split("://").first
|
16
|
-
html = translate_relative_paths(html, base_url) if base_url
|
17
|
-
html = translate_relative_protocols(html, protocol) if protocol
|
18
|
-
html
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.translate_relative_paths(html, base_url)
|
22
|
-
# Try out this regexp using rubular http://rubular.com/r/hiAxBNX7KE
|
23
|
-
html.gsub(%r{(href|src)=(['"])/([^/"']([^"']*|[^"']*))?['"]}, "\\1=\\2#{base_url}\\3\\2")
|
24
|
-
end
|
25
|
-
private_class_method :translate_relative_paths
|
26
|
-
|
27
|
-
def self.translate_relative_protocols(body, protocol)
|
28
|
-
# Try out this regexp using rubular http://rubular.com/r/0Ohk0wFYxV
|
29
|
-
body.gsub(%r{(href|src)=(['"])//([^"']*|[^"']*)['"]}, "\\1=\\2#{protocol}://\\3\\2")
|
30
|
-
end
|
31
|
-
private_class_method :translate_relative_protocols
|
32
|
-
end
|
33
|
-
end
|
data/lib/ferrum_pdf/railtie.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
module FerrumPdf
|
2
|
-
class Railtie < ::Rails::Railtie
|
3
|
-
initializer "ferrum_pdf.assets_helper" do
|
4
|
-
ActiveSupport.on_load(:action_view) do
|
5
|
-
include FerrumPdf::AssetsHelper
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
|
-
initializer "ferrum_pdf.controller" do
|
10
|
-
ActiveSupport.on_load(:action_controller) do
|
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
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|