bidi2pdf-rails 0.0.1.alpha.1 → 0.0.1.pre.alpha
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/.idea/bidi2pdf-rails.iml +6 -44
- data/.rubocop.yml +0 -3
- data/README.md +4 -31
- data/lib/bidi2pdf_rails/chromedriver_manager_singleton.rb +1 -1
- data/lib/bidi2pdf_rails/log_subscriber.rb +13 -0
- data/lib/bidi2pdf_rails/railtie.rb +45 -10
- data/lib/bidi2pdf_rails/version.rb +1 -1
- data/lib/bidi2pdf_rails.rb +20 -74
- data/lib/generators/bidi2pdf_rails/initializer_generator.rb +6 -7
- data/lib/generators/bidi2pdf_rails/templates/bidi2pdf_rails.rb.tt +28 -60
- data/spec/dummy/app/controllers/reports_controller.rb +0 -4
- data/spec/dummy/config/environments/production.rb +1 -1
- data/spec/dummy/config/initializers/bidi2pdf_rails.rb +16 -20
- data/spec/dummy/config/initializers/cors.rb +1 -1
- data/spec/dummy/config/routes.rb +0 -2
- data/spec/dummy/log/development.log +158 -12719
- data/spec/dummy/tmp/pids/server.pid +1 -1
- metadata +7 -28
- data/lib/bidi2pdf_rails/browser_console_log_subscriber.rb +0 -24
- data/lib/bidi2pdf_rails/main_log_subscriber.rb +0 -33
- data/lib/bidi2pdf_rails/network_log_subscriber.rb +0 -20
- data/lib/bidi2pdf_rails/services/html_renderer.rb +0 -33
- data/lib/bidi2pdf_rails/services/html_to_pdf_converter.rb +0 -28
- data/lib/bidi2pdf_rails/services/pdf_browser_session.rb +0 -39
- data/lib/bidi2pdf_rails/services/pdf_renderer.rb +0 -81
- data/lib/bidi2pdf_rails/services/url_to_pdf_converter.rb +0 -82
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
61431
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bidi2pdf-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.1.alpha
|
4
|
+
version: 0.0.1.pre.alpha
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dieter S.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-04-
|
11
|
+
date: 2025-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -114,20 +114,6 @@ dependencies:
|
|
114
114
|
- - ">="
|
115
115
|
- !ruby/object:Gem::Version
|
116
116
|
version: '0'
|
117
|
-
- !ruby/object:Gem::Dependency
|
118
|
-
name: websocket-native
|
119
|
-
requirement: !ruby/object:Gem::Requirement
|
120
|
-
requirements:
|
121
|
-
- - "~>"
|
122
|
-
- !ruby/object:Gem::Version
|
123
|
-
version: '1.0'
|
124
|
-
type: :development
|
125
|
-
prerelease: false
|
126
|
-
version_requirements: !ruby/object:Gem::Requirement
|
127
|
-
requirements:
|
128
|
-
- - "~>"
|
129
|
-
- !ruby/object:Gem::Version
|
130
|
-
version: '1.0'
|
131
117
|
description: 'Bidi2pdf Rails is a powerful PDF generation tool.
|
132
118
|
|
133
119
|
'
|
@@ -152,16 +138,9 @@ files:
|
|
152
138
|
- Rakefile
|
153
139
|
- lib/bidi2pdf-rails.rb
|
154
140
|
- lib/bidi2pdf_rails.rb
|
155
|
-
- lib/bidi2pdf_rails/browser_console_log_subscriber.rb
|
156
141
|
- lib/bidi2pdf_rails/chromedriver_manager_singleton.rb
|
157
|
-
- lib/bidi2pdf_rails/
|
158
|
-
- lib/bidi2pdf_rails/network_log_subscriber.rb
|
142
|
+
- lib/bidi2pdf_rails/log_subscriber.rb
|
159
143
|
- lib/bidi2pdf_rails/railtie.rb
|
160
|
-
- lib/bidi2pdf_rails/services/html_renderer.rb
|
161
|
-
- lib/bidi2pdf_rails/services/html_to_pdf_converter.rb
|
162
|
-
- lib/bidi2pdf_rails/services/pdf_browser_session.rb
|
163
|
-
- lib/bidi2pdf_rails/services/pdf_renderer.rb
|
164
|
-
- lib/bidi2pdf_rails/services/url_to_pdf_converter.rb
|
165
144
|
- lib/bidi2pdf_rails/version.rb
|
166
145
|
- lib/generators/bidi2pdf_rails/USAGE
|
167
146
|
- lib/generators/bidi2pdf_rails/initializer_generator.rb
|
@@ -223,14 +202,14 @@ files:
|
|
223
202
|
- spec/requests/reports_spec.rb
|
224
203
|
- spec/spec_helper.rb
|
225
204
|
- tasks/bidi2pdf_rails_tasks.rake
|
226
|
-
homepage: https://github.com/dieter-medium/bidi2pdf
|
205
|
+
homepage: https://github.com/dieter-medium/bidi2pdf
|
227
206
|
licenses:
|
228
207
|
- MIT
|
229
208
|
metadata:
|
230
209
|
allowed_push_host: https://rubygems.org
|
231
|
-
homepage_uri: https://github.com/dieter-medium/bidi2pdf
|
232
|
-
source_code_uri: https://github.com/dieter-medium/bidi2pdf
|
233
|
-
changelog_uri: https://github.com/dieter-medium/bidi2pdf
|
210
|
+
homepage_uri: https://github.com/dieter-medium/bidi2pdf
|
211
|
+
source_code_uri: https://github.com/dieter-medium/bidi2pdf
|
212
|
+
changelog_uri: https://github.com/dieter-medium/bidi2pdf/blob/master/CHANGELOG.md
|
234
213
|
rubygems_mfa_required: 'true'
|
235
214
|
post_install_message:
|
236
215
|
rdoc_options: []
|
@@ -1,24 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "bidi2pdf/bidi/browser_console_logger"
|
4
|
-
|
5
|
-
module Bidi2pdfRails
|
6
|
-
class BrowserConsoleLogSubscriber < ActiveSupport::LogSubscriber
|
7
|
-
def browser_console_log_received(event)
|
8
|
-
payload = event.payload
|
9
|
-
timestamp = Bidi2pdf::Bidi::BrowserConsoleLogger.format_timestamp(payload[:timestamp])
|
10
|
-
|
11
|
-
logger.tagged("bidi2pdf_rails", "browser_console", timestamp) do |tagged_logger|
|
12
|
-
verbose_logger = Bidi2pdf::VerboseLogger.new(tagged_logger, Bidi2pdfRails.verbosity)
|
13
|
-
Bidi2pdf::Bidi::BrowserConsoleLogger.new(verbose_logger)
|
14
|
-
.builder
|
15
|
-
.with_level(payload[:level])
|
16
|
-
.with_prefix("")
|
17
|
-
.with_text(payload[:text])
|
18
|
-
.with_args(payload[:args])
|
19
|
-
.with_stack_trace(payload[:stack_trace])
|
20
|
-
.log_event
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Bidi2pdfRails
|
4
|
-
class MainLogSubscriber < ActiveSupport::LogSubscriber
|
5
|
-
@silenced_events = []
|
6
|
-
|
7
|
-
class << self
|
8
|
-
attr_accessor :silenced_events
|
9
|
-
|
10
|
-
def silence(event)
|
11
|
-
self.silenced_events << event
|
12
|
-
end
|
13
|
-
|
14
|
-
def silenced?(event)
|
15
|
-
self.silenced_events.any? { |silenced_event| silenced_event === event }
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
include Bidi2pdf::Notifications::LoggingSubscriberActions
|
20
|
-
|
21
|
-
def handle_printing(event)
|
22
|
-
logger.info "Page rendered and printed: #{event.duration.round(1)}ms"
|
23
|
-
end
|
24
|
-
|
25
|
-
def logger
|
26
|
-
Bidi2pdf::VerboseLogger.new(super.tagged("bidi2pdf_rails"), Bidi2pdfRails.verbosity)
|
27
|
-
end
|
28
|
-
|
29
|
-
def silenced?(event)
|
30
|
-
MainLogSubscriber.silenced?(event) || super(event)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "bidi2pdf/bidi/network_event_formatters/network_event_console_formatter"
|
4
|
-
|
5
|
-
module Bidi2pdfRails
|
6
|
-
class NetworkLogSubscriber < ActiveSupport::LogSubscriber
|
7
|
-
def network_event_received(event)
|
8
|
-
payload = event.payload
|
9
|
-
|
10
|
-
return if payload[:method] == "network.responseStarted" || payload[:method] == "network.beforeRequestSent"
|
11
|
-
|
12
|
-
logger.tagged("bidi2pdf_rails", "network") do |tagged_logger|
|
13
|
-
verbose_logger = Bidi2pdf::VerboseLogger.new(tagged_logger, Bidi2pdfRails.verbosity)
|
14
|
-
formatter = Bidi2pdf::Bidi::NetworkEventFormatters::NetworkEventConsoleFormatter.new(logger: verbose_logger)
|
15
|
-
|
16
|
-
formatter.log [payload[:event]]
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Bidi2pdfRails
|
4
|
-
module Services
|
5
|
-
# app/services/html_renderer.rb
|
6
|
-
class HtmlRenderer
|
7
|
-
def initialize(controller, options)
|
8
|
-
@controller = controller
|
9
|
-
@options = options.dup
|
10
|
-
end
|
11
|
-
|
12
|
-
def render
|
13
|
-
with_overridden_asset_host { @controller.render_to_string(@options.merge(formats: [:html])) }
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def with_overridden_asset_host
|
19
|
-
original_asset_host = ActionController::Base.asset_host
|
20
|
-
|
21
|
-
if @options[:asset_host]
|
22
|
-
ActionController::Base.asset_host = @options[:asset_host]
|
23
|
-
elsif !Rails.application.config.action_controller.asset_host
|
24
|
-
ActionController::Base.asset_host = @controller.request.base_url
|
25
|
-
end
|
26
|
-
|
27
|
-
yield
|
28
|
-
ensure
|
29
|
-
ActionController::Base.asset_host = original_asset_host
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Bidi2pdfRails
|
4
|
-
module Services
|
5
|
-
class HtmlToPdfConverter
|
6
|
-
include PdfBrowserSession
|
7
|
-
|
8
|
-
def initialize(html, print_options: {}, wait_for_network_idle: true, wait_for_page_loaded: true, wait_for_page_check_script: nil)
|
9
|
-
@html = html
|
10
|
-
@print_options = print_options
|
11
|
-
@wait_for_network_idle = wait_for_network_idle
|
12
|
-
@wait_for_page_loaded = wait_for_page_loaded
|
13
|
-
@wait_for_page_check_script = wait_for_page_check_script
|
14
|
-
end
|
15
|
-
|
16
|
-
def generate
|
17
|
-
run_browser_session
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def prepare_tab(tab)
|
23
|
-
tab.render_html_content(@html)
|
24
|
-
wait_for_tab(tab)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Bidi2pdfRails
|
4
|
-
module Services
|
5
|
-
module PdfBrowserSession
|
6
|
-
def run_browser_session
|
7
|
-
pdf_data = nil
|
8
|
-
|
9
|
-
thread = Thread.new do
|
10
|
-
Rails.application.executor.wrap do
|
11
|
-
browser = ChromedriverManagerSingleton.session.browser
|
12
|
-
context = browser.create_user_context
|
13
|
-
window = context.create_browser_window
|
14
|
-
tab = window.create_browser_tab
|
15
|
-
|
16
|
-
begin
|
17
|
-
prepare_tab(tab)
|
18
|
-
pdf_data = tab.print(print_options: @print_options)
|
19
|
-
ensure
|
20
|
-
tab&.close
|
21
|
-
window&.close
|
22
|
-
context&.close
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
thread.join
|
28
|
-
Base64.decode64(pdf_data)
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def wait_for_tab(tab)
|
34
|
-
tab.wait_until_network_idle if @wait_for_network_idle
|
35
|
-
tab.wait_until_page_loaded(check_script: @wait_for_page_check_script) if @wait_for_page_loaded
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,81 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Bidi2pdfRails
|
4
|
-
module Services
|
5
|
-
# PdfRenderer is responsible for rendering a Rails view into a PDF using headless Chrome.
|
6
|
-
#
|
7
|
-
# It accepts a mix of HTML rendering options (passed to `render_to_string`) and PDF generation options.
|
8
|
-
#
|
9
|
-
# @example Basic usage
|
10
|
-
# renderer = Bidi2pdfRails::Services::PdfRenderer.new("invoice", { template: "invoices/show" }, controller)
|
11
|
-
# renderer.render_pdf
|
12
|
-
#
|
13
|
-
# @param filename [String] the base filename for the generated PDF (used for download naming)
|
14
|
-
# @param options [Hash] rendering options including both HTML and PDF-specific options
|
15
|
-
# @option options [String] :template The template to render (or other render_to_string keys like :partial, :layout, etc.)
|
16
|
-
# @option options [String] :asset_host Optional asset host override
|
17
|
-
# @option options [Hash] :print_options Options passed to the Chrome PDF print API
|
18
|
-
# @option options [Boolean] :wait_for_network_idle Wait for network to go idle before generating PDF (default: config default)
|
19
|
-
# @option options [Boolean] :wait_for_page_loaded Wait for page load event before generating PDF (default: config default)
|
20
|
-
# @option options [String] :wait_for_page_check_script JavaScript condition to wait for before generating PDF
|
21
|
-
#
|
22
|
-
class PdfRenderer
|
23
|
-
PDF_OPTIONS = %i[
|
24
|
-
print_options
|
25
|
-
asset_host
|
26
|
-
wait_for_network_idle
|
27
|
-
wait_for_page_loaded
|
28
|
-
wait_for_page_check_script
|
29
|
-
].freeze
|
30
|
-
|
31
|
-
PRINT_URL_OPTIONS = %i[
|
32
|
-
url
|
33
|
-
auth
|
34
|
-
headers
|
35
|
-
cookies
|
36
|
-
].freeze
|
37
|
-
|
38
|
-
def initialize(filename, options, controller)
|
39
|
-
@filename = filename
|
40
|
-
@pdf_options = options.slice(*PDF_OPTIONS)
|
41
|
-
@print_url_options = options.slice(*PRINT_URL_OPTIONS)
|
42
|
-
@html_options = options.except(*(PDF_OPTIONS + PRINT_URL_OPTIONS))
|
43
|
-
@controller = controller
|
44
|
-
end
|
45
|
-
|
46
|
-
def render_pdf
|
47
|
-
ActiveSupport::Notifications.instrument("handle_printing.bidi2pdf_rails") do
|
48
|
-
print_options = Bidi2pdfRails.print_options(@pdf_options[:print_options] || {})
|
49
|
-
wait_for_network_idle = @pdf_options.fetch(:wait_for_network_idle, Bidi2pdfRails.wait_for_network_idle)
|
50
|
-
wait_for_page_loaded = @pdf_options.fetch(:wait_for_page_loaded, Bidi2pdfRails.wait_for_page_loaded)
|
51
|
-
wait_for_page_check_script = @pdf_options.fetch(:wait_for_page_check_script, Bidi2pdfRails.wait_for_page_check_script)
|
52
|
-
|
53
|
-
if @print_url_options[:url]
|
54
|
-
headers = @print_url_options[:headers] || Bidi2pdfRails.headers
|
55
|
-
cookies = @print_url_options[:cookies] || Bidi2pdfRails.cookies
|
56
|
-
auth = @print_url_options[:auth] || Bidi2pdfRails.auth
|
57
|
-
|
58
|
-
UrlToPdfConverter.new(@print_url_options[:url],
|
59
|
-
headers: headers,
|
60
|
-
cookies: cookies,
|
61
|
-
auth: auth,
|
62
|
-
print_options: print_options,
|
63
|
-
wait_for_network_idle: wait_for_network_idle,
|
64
|
-
wait_for_page_loaded: wait_for_page_loaded,
|
65
|
-
wait_for_page_check_script: wait_for_page_check_script
|
66
|
-
).generate
|
67
|
-
else
|
68
|
-
html = HtmlRenderer.new(@controller, @html_options).render
|
69
|
-
|
70
|
-
HtmlToPdfConverter.new(html,
|
71
|
-
print_options: print_options,
|
72
|
-
wait_for_network_idle: wait_for_network_idle,
|
73
|
-
wait_for_page_loaded: wait_for_page_loaded,
|
74
|
-
wait_for_page_check_script: wait_for_page_check_script
|
75
|
-
).generate
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
@@ -1,82 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Bidi2pdfRails
|
4
|
-
module Services
|
5
|
-
class UrlToPdfConverter
|
6
|
-
include PdfBrowserSession
|
7
|
-
|
8
|
-
def initialize(url, headers: {}, cookies: {}, auth: {}, print_options: {}, wait_for_network_idle: true, wait_for_page_loaded: true, wait_for_page_check_script: nil)
|
9
|
-
@url = url
|
10
|
-
@headers = headers || {}
|
11
|
-
@cookies = cookies || {}
|
12
|
-
@auth = auth || {}
|
13
|
-
@print_options = print_options
|
14
|
-
@wait_for_network_idle = wait_for_network_idle
|
15
|
-
@wait_for_page_loaded = wait_for_page_loaded
|
16
|
-
@wait_for_page_check_script = wait_for_page_check_script
|
17
|
-
end
|
18
|
-
|
19
|
-
def generate
|
20
|
-
run_browser_session
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def prepare_tab(tab)
|
26
|
-
add_headers(tab)
|
27
|
-
add_basic_auth(tab)
|
28
|
-
add_cookies(tab)
|
29
|
-
|
30
|
-
tab.navigate_to(@url)
|
31
|
-
wait_for_tab(tab)
|
32
|
-
end
|
33
|
-
|
34
|
-
def add_cookies(tab)
|
35
|
-
@cookies.each do |name, value|
|
36
|
-
tab.set_cookie(
|
37
|
-
name: name,
|
38
|
-
value: value,
|
39
|
-
domain: domain,
|
40
|
-
secure: uri.scheme == "https"
|
41
|
-
)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def add_headers(tab)
|
46
|
-
@headers.each do |name, value|
|
47
|
-
tab.add_headers(
|
48
|
-
url_patterns: url_patterns,
|
49
|
-
headers: [{ name: name, value: value }]
|
50
|
-
)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def add_basic_auth(tab)
|
55
|
-
return unless @auth[:username] && @auth[:password]
|
56
|
-
|
57
|
-
tab.basic_auth(
|
58
|
-
url_patterns: url_patterns,
|
59
|
-
username: @auth[:username],
|
60
|
-
password: @auth[:password]
|
61
|
-
)
|
62
|
-
end
|
63
|
-
|
64
|
-
def uri
|
65
|
-
@uri ||= URI(@url)
|
66
|
-
end
|
67
|
-
|
68
|
-
def domain
|
69
|
-
uri.host
|
70
|
-
end
|
71
|
-
|
72
|
-
def url_patterns
|
73
|
-
[{
|
74
|
-
type: "pattern",
|
75
|
-
protocol: uri.scheme,
|
76
|
-
hostname: uri.host,
|
77
|
-
port: uri.port.to_s
|
78
|
-
}]
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|