wicked_pdf 1.1.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.
@@ -80,7 +80,7 @@ class WickedPdf
80
80
 
81
81
  def set_request_to_render_as_pdf(env)
82
82
  @render_pdf = true
83
- %w(PATH_INFO REQUEST_URI).each { |e| env[e] = env[e].sub(%r{\.pdf\b}, '') }
83
+ %w[PATH_INFO REQUEST_URI].each { |e| env[e] = env[e].sub(%r{\.pdf\b}, '') }
84
84
  env['HTTP_ACCEPT'] = concat(env['HTTP_ACCEPT'], Rack::Mime.mime_type('.html'))
85
85
  env['Rack-Middleware-WickedPdf'] = 'true'
86
86
  end
@@ -8,7 +8,11 @@ class WickedPdf
8
8
  base.class_eval do
9
9
  alias_method_chain :render, :wicked_pdf
10
10
  alias_method_chain :render_to_string, :wicked_pdf
11
- after_filter :clean_temp_files
11
+ if respond_to?(:after_action)
12
+ after_action :clean_temp_files
13
+ else
14
+ after_filter :clean_temp_files
15
+ end
12
16
  end
13
17
  end
14
18
 
@@ -19,47 +23,46 @@ class WickedPdf
19
23
 
20
24
  base.class_eval do
21
25
  after_action :clean_temp_files
26
+ end
27
+ end
22
28
 
23
- alias_method :render_without_wicked_pdf, :render
24
- alias_method :render_to_string_without_wicked_pdf, :render_to_string
25
-
26
- def render(options = nil, *args, &block)
27
- render_with_wicked_pdf(options, *args, &block)
28
- end
29
+ def render(options = nil, *args, &block)
30
+ render_with_wicked_pdf(options, *args, &block)
31
+ end
29
32
 
30
- def render_to_string(options = nil, *args, &block)
31
- render_to_string_with_wicked_pdf(options, *args, &block)
32
- end
33
- end
33
+ def render_to_string(options = nil, *args, &block)
34
+ render_to_string_with_wicked_pdf(options, *args, &block)
34
35
  end
35
36
 
36
37
  def render_with_wicked_pdf(options = nil, *args, &block)
37
38
  if options.is_a?(Hash) && options.key?(:pdf)
38
- log_pdf_creation
39
39
  options[:basic_auth] = set_basic_auth(options)
40
40
  make_and_send_pdf(options.delete(:pdf), (WickedPdf.config || {}).merge(options))
41
- else
41
+ elsif respond_to?(:render_without_wicked_pdf)
42
+ # support alias_method_chain (module included)
42
43
  render_without_wicked_pdf(options, *args, &block)
44
+ else
45
+ # support inheritance (module prepended)
46
+ method(:render).super_method.call(options, *args, &block)
43
47
  end
44
48
  end
45
49
 
46
50
  def render_to_string_with_wicked_pdf(options = nil, *args, &block)
47
51
  if options.is_a?(Hash) && options.key?(:pdf)
48
- log_pdf_creation
49
52
  options[:basic_auth] = set_basic_auth(options)
50
53
  options.delete :pdf
51
54
  make_pdf((WickedPdf.config || {}).merge(options))
52
- else
55
+ elsif respond_to?(:render_to_string_without_wicked_pdf)
56
+ # support alias_method_chain (module included)
53
57
  render_to_string_without_wicked_pdf(options, *args, &block)
58
+ else
59
+ # support inheritance (module prepended)
60
+ method(:render_to_string).super_method.call(options, *args, &block)
54
61
  end
55
62
  end
56
63
 
57
64
  private
58
65
 
59
- def log_pdf_creation
60
- logger.info '*' * 15 + 'WICKED' + '*' * 15 if logger && logger.respond_to?(:info)
61
- end
62
-
63
66
  def set_basic_auth(options = {})
64
67
  options[:basic_auth] ||= WickedPdf.config.fetch(:basic_auth) { false }
65
68
  return unless options[:basic_auth] && request.env['HTTP_AUTHORIZATION']
@@ -76,8 +79,10 @@ class WickedPdf
76
79
  :template => options[:template],
77
80
  :layout => options[:layout],
78
81
  :formats => options[:formats],
79
- :handlers => options[:handlers]
82
+ :handlers => options[:handlers],
83
+ :assigns => options[:assigns]
80
84
  }
85
+ render_opts[:inline] = options[:inline] if options[:inline]
81
86
  render_opts[:locals] = options[:locals] if options[:locals]
82
87
  render_opts[:file] = options[:file] if options[:file]
83
88
  html_string = render_to_string(render_opts)
@@ -97,8 +102,10 @@ class WickedPdf
97
102
  :layout => options[:layout],
98
103
  :formats => options[:formats],
99
104
  :handlers => options[:handlers],
105
+ :assigns => options[:assigns],
100
106
  :content_type => 'text/html'
101
107
  }
108
+ render_opts[:inline] = options[:inline] if options[:inline]
102
109
  render_opts[:locals] = options[:locals] if options[:locals]
103
110
  render_opts[:file] = options[:file] if options[:file]
104
111
  render(render_opts)
@@ -121,7 +128,8 @@ class WickedPdf
121
128
  :template => options[hf][:html][:template],
122
129
  :layout => options[hf][:html][:layout],
123
130
  :formats => options[hf][:html][:formats],
124
- :handlers => options[hf][:html][:handlers]
131
+ :handlers => options[hf][:html][:handlers],
132
+ :assigns => options[hf][:html][:assigns]
125
133
  }
126
134
  render_opts[:locals] = options[hf][:html][:locals] if options[hf][:html][:locals]
127
135
  render_opts[:file] = options[hf][:html][:file] if options[:file]
@@ -0,0 +1,33 @@
1
+ class WickedPdf
2
+ module Progress
3
+ require 'pty' if RbConfig::CONFIG['target_os'] !~ /mswin|mingw/ # no support for windows
4
+ require 'English'
5
+
6
+ def track_progress?(options)
7
+ options[:progress] && !on_windows?
8
+ end
9
+
10
+ def invoke_with_progress(command, options)
11
+ output = []
12
+ begin
13
+ PTY.spawn(command.join(' ')) do |stdout, _stdin, pid|
14
+ begin
15
+ stdout.sync
16
+ stdout.each_line("\r") do |line|
17
+ output << line.chomp
18
+ options[:progress].call(line) if options[:progress]
19
+ end
20
+ rescue Errno::EIO # rubocop:disable Lint/HandleExceptions
21
+ # child process is terminated, this is expected behaviour
22
+ ensure
23
+ ::Process.wait pid
24
+ end
25
+ end
26
+ rescue PTY::ChildExited
27
+ puts 'The child process exited!'
28
+ end
29
+ err = output.join('\n')
30
+ raise "#{command} failed (exitstatus 0). Output was: #{err}" unless $CHILD_STATUS && $CHILD_STATUS.exitstatus.zero?
31
+ end
32
+ end
33
+ end
@@ -3,48 +3,19 @@ require 'wicked_pdf/wicked_pdf_helper'
3
3
  require 'wicked_pdf/wicked_pdf_helper/assets'
4
4
 
5
5
  class WickedPdf
6
- if defined?(Rails)
7
-
8
- if Rails::VERSION::MAJOR >= 5
9
-
10
- class WickedRailtie < Rails::Railtie
11
- initializer 'wicked_pdf.register' do |_app|
12
- ActionController::Base.send :prepend, PdfHelper
13
- ActionView::Base.send :include, WickedPdfHelper::Assets
14
- end
15
- end
16
-
17
- elsif Rails::VERSION::MAJOR == 4
18
-
19
- class WickedRailtie < Rails::Railtie
20
- initializer 'wicked_pdf.register' do |_app|
21
- ActionController::Base.send :include, PdfHelper
22
- ActionView::Base.send :include, WickedPdfHelper::Assets
23
- end
24
- end
25
-
26
- elsif Rails::VERSION::MAJOR == 3
27
-
28
- class WickedRailtie < Rails::Railtie
29
- initializer 'wicked_pdf.register' do |_app|
30
- ActionController::Base.send :include, PdfHelper
31
- if Rails::VERSION::MINOR > 0 && Rails.configuration.assets.enabled
32
- ActionView::Base.send :include, WickedPdfHelper::Assets
6
+ if defined?(Rails.env)
7
+ class WickedRailtie < Rails::Railtie
8
+ initializer 'wicked_pdf.register', :after => 'remotipart.controller_helper' do |_app|
9
+ ActiveSupport.on_load(:action_controller) do
10
+ if ActionController::Base.respond_to?(:prepend) &&
11
+ Object.method(:new).respond_to?(:super_method)
12
+ ActionController::Base.send :prepend, PdfHelper
33
13
  else
34
- ActionView::Base.send :include, WickedPdfHelper
14
+ ActionController::Base.send :include, PdfHelper
35
15
  end
16
+ ActionView::Base.send :include, WickedPdfHelper::Assets
36
17
  end
37
18
  end
38
-
39
- elsif Rails::VERSION::MAJOR == 2
40
-
41
- unless ActionController::Base.instance_methods.include? 'render_with_wicked_pdf'
42
- ActionController::Base.send :include, PdfHelper
43
- end
44
- unless ActionView::Base.instance_methods.include? 'wicked_pdf_stylesheet_link_tag'
45
- ActionView::Base.send :include, WickedPdfHelper
46
- end
47
-
48
19
  end
49
20
 
50
21
  if Mime::Type.lookup_by_extension(:pdf).nil?
@@ -1,3 +1,3 @@
1
1
  class WickedPdf
2
- VERSION = '1.1.0'.freeze
2
+ VERSION = '2.1.0'.freeze
3
3
  end
@@ -23,8 +23,9 @@ class WickedPdf
23
23
 
24
24
  def wicked_pdf_javascript_src_tag(jsfile, options = {})
25
25
  jsfile = WickedPdfHelper.add_extension(jsfile, 'js')
26
+ type = ::Mime.respond_to?(:[]) ? ::Mime[:js] : ::Mime::JS # ::Mime[:js] cannot be used in Rails 2.3.
26
27
  src = "file:///#{WickedPdfHelper.root_path.join('public', 'javascripts', jsfile)}"
27
- content_tag('script', '', { 'type' => Mime::JS, 'src' => path_to_javascript(src) }.merge(options))
28
+ content_tag('script', '', { 'type' => type, 'src' => path_to_javascript(src) }.merge(options))
28
29
  end
29
30
 
30
31
  def wicked_pdf_javascript_include_tag(*sources)
@@ -1,4 +1,6 @@
1
- require 'open-uri'
1
+ require 'net/http'
2
+ # If webpacker is used, need to check for version
3
+ require 'webpacker/version' if defined?(Webpacker)
2
4
 
3
5
  class WickedPdf
4
6
  module WickedPdfHelper
@@ -27,6 +29,32 @@ class WickedPdf
27
29
  end.html_safe
28
30
  end
29
31
 
32
+ def wicked_pdf_stylesheet_pack_tag(*sources)
33
+ return unless defined?(Webpacker)
34
+ if running_in_development?
35
+ stylesheet_pack_tag(*sources)
36
+ else
37
+ css_text = sources.collect do |source|
38
+ source = WickedPdfHelper.add_extension(source, 'css')
39
+ wicked_pdf_stylesheet_link_tag(webpacker_source_url(source))
40
+ end.join("\n")
41
+ css_text.respond_to?(:html_safe) ? css_text.html_safe : css_text
42
+ end
43
+ end
44
+
45
+ def wicked_pdf_javascript_pack_tag(*sources)
46
+ return unless defined?(Webpacker)
47
+
48
+ if running_in_development?
49
+ javascript_pack_tag(*sources)
50
+ else
51
+ sources.collect do |source|
52
+ source = WickedPdfHelper.add_extension(source, 'js')
53
+ "<script type='text/javascript'>#{read_asset(webpacker_source_url(source))}</script>"
54
+ end.join("\n").html_safe
55
+ end
56
+ end
57
+
30
58
  def wicked_pdf_image_tag(img, options = {})
31
59
  image_tag wicked_pdf_asset_path(img), options
32
60
  end
@@ -51,6 +79,16 @@ class WickedPdf
51
79
  end
52
80
  end
53
81
 
82
+ def wicked_pdf_asset_pack_path(asset)
83
+ return unless defined?(Webpacker)
84
+
85
+ if running_in_development?
86
+ asset_pack_path(asset)
87
+ else
88
+ wicked_pdf_asset_path webpacker_source_url(asset)
89
+ end
90
+ end
91
+
54
92
  private
55
93
 
56
94
  # borrowed from actionpack/lib/action_view/helpers/asset_url_helper.rb
@@ -68,15 +106,20 @@ class WickedPdf
68
106
  end
69
107
  else
70
108
  asset = find_asset(source)
71
- asset ? asset.pathname : File.join(Rails.public_path, source)
109
+ if asset
110
+ # older versions need pathname, Sprockets 4 supports only filename
111
+ asset.respond_to?(:filename) ? asset.filename : asset.pathname
112
+ else
113
+ File.join(Rails.public_path, source)
114
+ end
72
115
  end
73
116
  end
74
117
 
75
118
  def find_asset(path)
76
119
  if Rails.application.assets.respond_to?(:find_asset)
77
- Rails.application.assets.find_asset(path)
120
+ Rails.application.assets.find_asset(path, :base_path => Rails.application.root.to_s)
78
121
  else
79
- Sprockets::Railtie.build_environment(Rails.application).find_asset(path)
122
+ Sprockets::Railtie.build_environment(Rails.application).find_asset(path, :base_path => Rails.application.root.to_s)
80
123
  end
81
124
  end
82
125
 
@@ -93,7 +136,8 @@ class WickedPdf
93
136
  end
94
137
 
95
138
  def precompiled_or_absolute_asset?(source)
96
- Rails.configuration.assets.compile == false ||
139
+ !Rails.configuration.respond_to?(:assets) ||
140
+ Rails.configuration.assets.compile == false ||
97
141
  source.to_s[0] == '/' ||
98
142
  source.to_s.match(/\Ahttps?\:\/\//)
99
143
  end
@@ -112,8 +156,8 @@ class WickedPdf
112
156
  end
113
157
 
114
158
  def read_from_uri(uri)
115
- encoding = ':UTF-8' if RUBY_VERSION > '1.8'
116
- asset = open(uri, "r#{encoding}", &:read)
159
+ asset = Net::HTTP.get(URI(uri))
160
+ asset.force_encoding('UTF-8') if asset
117
161
  asset = gzip(asset) if WickedPdf.config[:expect_gzipped_remote_assets]
118
162
  asset
119
163
  end
@@ -125,6 +169,28 @@ class WickedPdf
125
169
  rescue Zlib::GzipFile::Error
126
170
  nil
127
171
  end
172
+
173
+ def webpacker_source_url(source)
174
+ return unless defined?(Webpacker) && defined?(Webpacker::VERSION)
175
+ # In Webpacker 3.2.0 asset_pack_url is introduced
176
+ if Webpacker::VERSION >= '3.2.0'
177
+ asset_pack_url(source)
178
+ else
179
+ source_path = asset_pack_path(source)
180
+ # Remove last slash from root path
181
+ root_url[0...-1] + source_path
182
+ end
183
+ end
184
+
185
+ def running_in_development?
186
+ return unless defined?(Webpacker)
187
+ # :dev_server method was added in webpacker 3.0.0
188
+ if Webpacker.respond_to?(:dev_server)
189
+ Webpacker.dev_server.running?
190
+ else
191
+ Rails.env.development? || Rails.env.test?
192
+ end
193
+ end
128
194
  end
129
195
  end
130
196
  end
@@ -0,0 +1,4 @@
1
+ test:
2
+ adapter: sqlite3
3
+ database: ":memory:"
4
+ timeout: 500
@@ -0,0 +1,3 @@
1
+ //= link_tree ../images
2
+ //= link wicked.js
3
+ //= link wicked.css
@@ -5,10 +5,32 @@ module ActionController
5
5
  def render_to_string(opts = {})
6
6
  opts.to_s
7
7
  end
8
+
9
+ def self.alias_method_chain(_target, _feature); end
10
+ end
11
+ end
12
+
13
+ module ActionControllerMock
14
+ class Base
15
+ def render(_)
16
+ [:base]
17
+ end
18
+
19
+ def render_to_string; end
20
+
21
+ def self.after_action(_); end
8
22
  end
9
23
  end
10
24
 
11
25
  class PdfHelperTest < ActionController::TestCase
26
+ module SomePatch
27
+ def render(_)
28
+ super.tap do |s|
29
+ s << :patched
30
+ end
31
+ end
32
+ end
33
+
12
34
  def setup
13
35
  @ac = ActionController::Base.new
14
36
  end
@@ -22,4 +44,53 @@ class PdfHelperTest < ActionController::TestCase
22
44
  :header => { :html => { :template => 'hf.html.erb' } })
23
45
  assert_match %r{^file:\/\/\/.*wicked_header_pdf.*\.html}, options[:header][:html][:url]
24
46
  end
47
+
48
+ test 'should not interfere with already prepended patches' do
49
+ # Emulate railtie
50
+ if Rails::VERSION::MAJOR >= 5
51
+ # this spec tests the following:
52
+ # if another gem prepends a render method to ActionController::Base
53
+ # before wicked_pdf does, does calling render trigger an infinite loop?
54
+ # this spec fails with 6392bea1fe3a41682dfd7c20fd9c179b5a758f59 because PdfHelper
55
+ # aliases the render method prepended by the other gem to render_without_pdf, then
56
+ # base_evals its own definition of render, which calls render_with_pdf -> render_without_pdf.
57
+ # If the other gem uses the prepend inhertinance pattern (calling super instead of aliasing),
58
+ # when it calls super it calls the base_eval'd version of render instead of going up the
59
+ # inheritance chain, causing an infinite loop.
60
+
61
+ # This fiddling with consts is required to get around the fact that PdfHelper checks
62
+ # that it is being prepended to ActionController::Base
63
+ OriginalBase = ActionController::Base
64
+ ActionController.send(:remove_const, :Base)
65
+ ActionController.const_set(:Base, ActionControllerMock::Base)
66
+
67
+ # Emulate another gem being loaded before wicked
68
+ ActionController::Base.prepend(SomePatch)
69
+ ActionController::Base.prepend(::WickedPdf::PdfHelper)
70
+
71
+ begin
72
+ # test that wicked's render method is actually called
73
+ ac = ActionController::Base.new
74
+ ac.expects(:render_with_wicked_pdf)
75
+ ac.render(:cats)
76
+
77
+ # test that calling render does not trigger infinite loop
78
+ ac = ActionController::Base.new
79
+ assert_equal [:base, :patched], ac.render(:cats)
80
+ rescue SystemStackError
81
+ assert_equal true, false # force spec failure
82
+ ensure
83
+ ActionController.send(:remove_const, :Base)
84
+ ActionController.const_set(:Base, OriginalBase)
85
+ end
86
+ end
87
+ end
88
+
89
+ test 'should call after_action instead of after_filter when able' do
90
+ ActionController::Base.expects(:after_filter).with(:clean_temp_files).never
91
+ ActionController::Base.expects(:after_action).with(:clean_temp_files).once
92
+ ActionController::Base.class_eval do
93
+ include ::WickedPdf::PdfHelper
94
+ end
95
+ end
25
96
  end