wicked_pdf 1.1.0 → 2.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +5 -5
  2. data/.github/issue_template.md +15 -0
  3. data/.github/workflows/ci.yml +56 -0
  4. data/.rubocop.yml +62 -0
  5. data/.rubocop_todo.yml +81 -39
  6. data/CHANGELOG.md +194 -45
  7. data/README.md +136 -28
  8. data/Rakefile +12 -9
  9. data/gemfiles/5.0.gemfile +3 -1
  10. data/gemfiles/5.1.gemfile +8 -0
  11. data/gemfiles/5.2.gemfile +9 -0
  12. data/gemfiles/6.0.gemfile +10 -0
  13. data/gemfiles/6.1.gemfile +11 -0
  14. data/gemfiles/7.0.gemfile +11 -0
  15. data/generators/wicked_pdf/templates/wicked_pdf.rb +14 -5
  16. data/lib/generators/wicked_pdf_generator.rb +5 -9
  17. data/lib/wicked_pdf/binary.rb +65 -0
  18. data/lib/wicked_pdf/middleware.rb +1 -1
  19. data/lib/wicked_pdf/option_parser.rb +230 -0
  20. data/lib/wicked_pdf/pdf_helper.rb +35 -42
  21. data/lib/wicked_pdf/progress.rb +33 -0
  22. data/lib/wicked_pdf/railtie.rb +6 -44
  23. data/lib/wicked_pdf/tempfile.rb +33 -3
  24. data/lib/wicked_pdf/version.rb +1 -1
  25. data/lib/wicked_pdf/wicked_pdf_helper/assets.rb +200 -17
  26. data/lib/wicked_pdf/wicked_pdf_helper.rb +2 -1
  27. data/lib/wicked_pdf.rb +64 -275
  28. data/test/fixtures/database.yml +4 -0
  29. data/test/fixtures/manifest.js +3 -0
  30. data/test/functional/pdf_helper_test.rb +71 -0
  31. data/test/functional/wicked_pdf_helper_assets_test.rb +61 -0
  32. data/test/test_helper.rb +13 -8
  33. data/test/unit/wicked_pdf_binary_test.rb +26 -0
  34. data/test/unit/wicked_pdf_option_parser_test.rb +133 -0
  35. data/test/unit/wicked_pdf_test.rb +25 -146
  36. data/test/unit/wkhtmltopdf_location_test.rb +48 -0
  37. data/wicked_pdf.gemspec +20 -13
  38. metadata +79 -36
  39. data/.travis.yml +0 -57
  40. data/gemfiles/2.3.gemfile +0 -10
  41. data/gemfiles/3.0.gemfile +0 -12
  42. data/gemfiles/3.1.gemfile +0 -13
  43. data/gemfiles/3.2.gemfile +0 -12
  44. data/gemfiles/4.0.gemfile +0 -6
  45. data/gemfiles/4.1.gemfile +0 -6
  46. data/gemfiles/4.2.gemfile +0 -6
  47. data/gemfiles/rails_edge.gemfile +0 -6
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
- # Wicked PDF [![Build Status](https://secure.travis-ci.org/mileszs/wicked_pdf.png)](http://travis-ci.org/mileszs/wicked_pdf) [![Gem Version](https://badge.fury.io/rb/wicked_pdf.svg)](http://badge.fury.io/rb/wicked_pdf)
1
+ # Wicked PDF [![Gem Version](https://badge.fury.io/rb/wicked_pdf.svg)](http://badge.fury.io/rb/wicked_pdf) [![Build Status](https://github.com/mileszs/wicked_pdf/actions/workflows/ci.yml/badge.svg)](https://github.com/mileszs/wicked_pdf/actions/workflows/ci.yml) [![Code Climate](https://codeclimate.com/github/mileszs/wicked_pdf/badges/gpa.svg)](https://codeclimate.com/github/mileszs/wicked_pdf) [![Open Source Helpers](https://www.codetriage.com/mileszs/wicked_pdf/badges/users.svg)](https://www.codetriage.com/mileszs/wicked_pdf)
2
2
 
3
3
  ## A PDF generation plugin for Ruby on Rails
4
4
 
5
5
  Wicked PDF uses the shell utility [wkhtmltopdf](http://wkhtmltopdf.org) to serve a PDF file to a user from HTML. In other words, rather than dealing with a PDF generation DSL of some sort, you simply write an HTML view as you would normally, then let Wicked PDF take care of the hard stuff.
6
6
 
7
- _Wicked PDF has been verified to work on Ruby versions 1.8.7 through 2.3; Rails 2 through 5.0_
7
+ _Wicked PDF has been verified to work on Ruby versions 2.2 through 2.6; Rails 4 through 6.1_
8
8
 
9
9
  ### Installation
10
10
 
@@ -26,8 +26,8 @@ to `config/initializers/mime_types.rb` in older versions of Rails.
26
26
 
27
27
  Because `wicked_pdf` is a wrapper for [wkhtmltopdf](http://wkhtmltopdf.org/), you'll need to install that, too.
28
28
 
29
- The simplest way to install all of the binaries (Linux, OSX, Windows) is through the gem [wkhtmltopdf-binary](https://github.com/steerio/wkhtmltopdf-binary).
30
- To install that, add a second gem
29
+ The simplest way to install all of the binaries on most Linux or OSX systems is through the gem [wkhtmltopdf-binary](https://github.com/zakird/wkhtmltopdf_binary_gem). Builds for other systems are available [here](https://wkhtmltopdf.org/downloads.html)
30
+ To install that gem, add this:
31
31
 
32
32
  ```ruby
33
33
  gem 'wkhtmltopdf-binary'
@@ -35,13 +35,16 @@ gem 'wkhtmltopdf-binary'
35
35
 
36
36
  To your Gemfile and run `bundle install`.
37
37
 
38
- This wrapper may trail in versions, at the moment it wraps the 0.9 version of `wkhtmltopdf` while there is 0.12 version available. Some of the advanced options listed below are not available with 0.9.
38
+ This gem currently installs version 0.12.x of `wkhtmltopdf`. Some of the options listed below are specific 0.9 or below, and others are for 0.12 and up.
39
+
40
+ You can see what flags are supported for the current version in [wkhtmltopdf's auto-generated manual](https://wkhtmltopdf.org/usage/wkhtmltopdf.txt)
39
41
 
40
42
  If your wkhtmltopdf executable is not on your webserver's path, you can configure it in an initializer:
41
43
 
42
44
  ```ruby
43
- WickedPdf.config = {
44
- exe_path: '/usr/local/bin/wkhtmltopdf'
45
+ WickedPdf.configure do |c|
46
+ c.exe_path = '/usr/local/bin/wkhtmltopdf',
47
+ c.enable_local_file_access = true
45
48
  }
46
49
  ```
47
50
 
@@ -83,7 +86,6 @@ The wkhtmltopdf binary is run outside of your Rails application; therefore, your
83
86
  </body>
84
87
  </html>
85
88
  ```
86
-
87
89
  Using wicked_pdf_helpers with asset pipeline raises `Asset names passed to helpers should not include the "/assets/" prefix.` error. To work around this, you can use `wicked_pdf_asset_base64` with the normal Rails helpers, but be aware that this will base64 encode your content and inline it in the page. This is very quick for small assets, but large ones can take a long time.
88
90
 
89
91
  ```html
@@ -106,23 +108,35 @@ Using wicked_pdf_helpers with asset pipeline raises `Asset names passed to helpe
106
108
  </html>
107
109
  ```
108
110
 
111
+ #### Webpacker usage
112
+
113
+ wicked_pdf supports webpack assets.
114
+
115
+ - Use `wicked_pdf_stylesheet_pack_tag` for stylesheets
116
+ - Use `wicked_pdf_javascript_pack_tag` for javascripts
117
+ - Use `wicked_pdf_asset_pack_path` to access an asset directly, for example: `image_tag wicked_pdf_asset_pack_path("media/images/foobar.png")`
118
+
119
+ #### Asset pipeline usage
120
+
121
+ It is best to precompile assets used in PDF views. This will help avoid issues when it comes to deploying, as Rails serves asset files differently between development and production (`config.assets.compile = false`), which can make it look like your PDFs work in development, but fail to load assets in production.
122
+
123
+ config.assets.precompile += ['blueprint/screen.css', 'pdf.css', 'jquery.ui.datepicker.js', 'pdf.js', ...etc...]
124
+
109
125
  #### CDN reference
110
126
 
111
127
  In this case, you can use that standard Rails helpers and point to the current CDN for whichever framework you are using. For jQuery, it would look somethng like this, given the current versions at the time of this writing.
112
128
  ```html
113
- <!doctype html>
114
- <html>
115
- <head>
116
- <%= javascript_include_tag "http://code.jquery.com/jquery-1.10.0.min.js" %>
117
- <%= javascript_include_tag "http://code.jquery.com/ui/1.10.3/jquery-ui.min.js" %>
129
+ <!doctype html>
130
+ <html>
131
+ <head>
132
+ <%= javascript_include_tag "http://code.jquery.com/jquery-1.10.0.min.js" %>
133
+ <%= javascript_include_tag "http://code.jquery.com/ui/1.10.3/jquery-ui.min.js" %>
118
134
  ```
119
- #### Asset pipeline usage
120
135
 
121
- The way to handle this for the asset pipeline on Heroku is to include these files in your asset precompile list, as follows:
136
+ ### Advanced Usage with all available options
122
137
 
123
- config.assets.precompile += ['blueprint/screen.css', 'pdf.css', 'jquery.ui.datepicker.js', 'pdf.js', ...etc...]
138
+ _NOTE: Certain options are only supported in specific versions of wkhtmltopdf._
124
139
 
125
- ### Advanced Usage with all available options
126
140
  ```ruby
127
141
  class ThingsController < ApplicationController
128
142
  def show
@@ -132,8 +146,10 @@ class ThingsController < ApplicationController
132
146
  render pdf: 'file_name',
133
147
  disposition: 'attachment', # default 'inline'
134
148
  template: 'things/show',
135
- file: "#{Rails.root}/files/foo.erb"
136
- layout: 'pdf', # for a pdf.html.erb file
149
+ locals: {foo: @bar},
150
+ file: "#{Rails.root}/files/foo.erb",
151
+ inline: '<!doctype html><html><head></head><body>INLINE HTML</body></html>',
152
+ layout: 'pdf', # for a pdf.pdf.erb file
137
153
  wkhtmltopdf: '/usr/local/bin/wkhtmltopdf', # path to binary
138
154
  show_as_html: params.key?('debug'), # allow debugging based on url param
139
155
  orientation: 'Landscape', # default Portrait
@@ -142,6 +158,7 @@ class ThingsController < ApplicationController
142
158
  page_width: NUMBER,
143
159
  save_to_file: Rails.root.join('pdfs', "#{filename}.pdf"),
144
160
  save_only: false, # depends on :save_to_file being set first
161
+ default_protocol: 'http',
145
162
  proxy: 'TEXT',
146
163
  basic_auth: false # when true username & password are automatically sent from session
147
164
  username: 'TEXT',
@@ -168,13 +185,25 @@ class ThingsController < ApplicationController
168
185
  enable_plugins: true,
169
186
  disable_internal_links: true,
170
187
  disable_external_links: true,
188
+ keep_relative_links: true,
171
189
  print_media_type: true,
190
+
191
+ # define as true the key 'disable_local_file_access' or 'enable_local_file_access', not both
192
+ disable_local_file_access: true,
193
+ enable_local_file_access: false, # must be true when using wkhtmltopdf > 0.12.6
194
+ allow: ["#{Rails.root}/public"], # could be an array or a single string
195
+
172
196
  disable_smart_shrinking: true,
173
197
  use_xserver: true,
174
- background: false, # backround needs to be true to enable background colors to render
198
+ background: false, # background needs to be true to enable background colors to render
175
199
  no_background: true,
200
+ no_stop_slow_scripts: false,
176
201
  viewport_size: 'TEXT', # available only with use_xserver or patched QT
177
202
  extra: '', # directly inserted into the command to wkhtmltopdf
203
+ raise_on_all_errors: nil, # raise error for any stderr output. Such as missing media, image assets
204
+ raise_on_missing_assets: nil, # raise when trying to access a missing asset
205
+ log_level: 'info', # Available values: none, error, warn, or info - only available with wkhtmltopdf 0.12.5+
206
+ quiet: false, # `false` is same as `log_level: 'info'`, `true` is same as `log_level: 'none'`
178
207
  outline: { outline: true,
179
208
  outline_depth: LEVEL },
180
209
  margin: { top: SIZE, # default 10 (mm)
@@ -230,7 +259,9 @@ class ThingsController < ApplicationController
230
259
  disable_links: true,
231
260
  disable_toc_links: true,
232
261
  disable_back_links:true,
233
- xsl_style_sheet: 'file.xsl'} # optional XSLT stylesheet to use for styling table of contents
262
+ xsl_style_sheet: 'file.xsl'}, # optional XSLT stylesheet to use for styling table of contents
263
+ progress: proc { |output| puts output }, # proc called when console output changes
264
+ delete_temporary_files: true # explicitly delete temporary files, default false
234
265
  end
235
266
  end
236
267
  end
@@ -265,11 +296,22 @@ pdf = WickedPdf.new.pdf_from_html_file('/your/absolute/path/here')
265
296
  # create a pdf from a URL
266
297
  pdf = WickedPdf.new.pdf_from_url('https://github.com/mileszs/wicked_pdf')
267
298
 
268
- # create a pdf from string using templates, layouts and content option for header or footer
299
+ # create a pdf from string using templates, layouts, and content option for header or footer
269
300
  pdf = WickedPdf.new.pdf_from_string(
270
- render_to_string('templates/pdf', layout: 'pdfs/layout_pdf'),
301
+ render_to_string('templates/pdf', layout: 'pdfs/layout_pdf.html'),
271
302
  footer: {
272
- content: render_to_string(layout: 'pdfs/layout_pdf')
303
+ content: render_to_string(
304
+ 'templates/footer',
305
+ layout: 'pdfs/layout_pdf.html'
306
+ )
307
+ }
308
+ )
309
+
310
+ # It is possible to use footer/header templates without a layout, in that case you need to provide a valid HTML document
311
+ pdf = WickedPdf.new.pdf_from_string(
312
+ render_to_string('templates/full_pdf_template'),
313
+ header: {
314
+ content: render_to_string('templates/full_header_template')
273
315
  }
274
316
  )
275
317
 
@@ -281,12 +323,33 @@ save_path = Rails.root.join('pdfs','filename.pdf')
281
323
  File.open(save_path, 'wb') do |file|
282
324
  file << pdf
283
325
  end
326
+
327
+ # you can also track progress on your PDF generation, such as when using it from within a Resque job
328
+ class PdfJob
329
+ def perform
330
+ blk = proc { |output|
331
+ match = output.match(/\[.+\] Page (?<current_page>\d+) of (?<total_pages>\d+)/)
332
+ if match
333
+ current_page = match[:current_page].to_i
334
+ total_pages = match[:total_pages].to_i
335
+ message = "Generated #{current_page} of #{total_pages} pages"
336
+ at current_page, total_pages, message
337
+ end
338
+ }
339
+ WickedPdf.new.pdf_from_string(html, progress: blk)
340
+ end
341
+ end
284
342
  ```
285
343
  If you need to display utf encoded characters, add this to your pdf views or layouts:
286
344
  ```html
287
345
  <meta charset="utf-8" />
288
346
  ```
289
-
347
+ If you need to return a PDF in a controller with Rails in API mode:
348
+ ```ruby
349
+ pdf_html = ActionController::Base.new.render_to_string(template: 'controller_name/action_name', layout: 'pdf')
350
+ pdf = WickedPdf.new.pdf_from_string(pdf_html)
351
+ send_data pdf, filename: 'file.pdf'
352
+ ```
290
353
  ### Page Breaks
291
354
 
292
355
  You can control page breaks with CSS.
@@ -340,7 +403,7 @@ If you would like to have WickedPdf automatically generate PDF views for all (or
340
403
  require 'wicked_pdf'
341
404
  config.middleware.use WickedPdf::Middleware
342
405
  ```
343
- If you want to turn on or off the middleware for certain urls, use the `:only` or `:except` conditions like so:
406
+ If you want to turn on or off the middleware for certain URLs, use the `:only` or `:except` conditions like so:
344
407
  ```ruby
345
408
  # conditions can be plain strings or regular expressions, and you can supply only one or an array
346
409
  config.middleware.use WickedPdf::Middleware, {}, only: '/invoice'
@@ -348,6 +411,19 @@ config.middleware.use WickedPdf::Middleware, {}, except: [ %r[^/admin], '/secret
348
411
  ```
349
412
  If you use the standard `render pdf: 'some_pdf'` in your app, you will want to exclude those actions from the middleware.
350
413
 
414
+
415
+ ### Include in an email as an attachment
416
+
417
+ To include a rendered pdf file in an email you can do the following:
418
+
419
+ ```ruby
420
+ attachments['attachment.pdf'] = WickedPdf.new.pdf_from_string(
421
+ render_to_string('link_to_view.pdf.erb', layout: 'pdf')
422
+ )
423
+ ```
424
+
425
+ This will render the pdf to a string and include it in the email. This is very slow so make sure you schedule your email delivery in a job.
426
+
351
427
  ### Further Reading
352
428
 
353
429
  Mike Ackerman's post [How To Create PDFs in Rails](https://www.viget.com/articles/how-to-create-pdfs-in-rails)
@@ -358,8 +434,22 @@ JESii's post [WickedPDF, wkhtmltopdf, and Heroku...a tricky combination](http://
358
434
 
359
435
  Berislav Babic's post [Send PDF attachments from Rails with WickedPdf and ActionMailer](http://berislavbabic.com/send-pdf-attachments-from-rails-with-wickedpdf-and-actionmailer/)
360
436
 
437
+ Corsego's 2021 post [Complete guide to generating PDFs with gem wicked_pdf](https://blog.corsego.com/gem-wicked-pdf)
438
+
439
+ PDFTron's post [How to Generate PDFs With Ruby on Rails](https://www.pdftron.com/blog/rails/how-to-generate-pdf-with-ruby-on-rails/)
440
+
361
441
  StackOverflow [questions with the tag "wicked-pdf"](http://stackoverflow.com/questions/tagged/wicked-pdf)
362
442
 
443
+ ### Screencasts
444
+
445
+ * SupeRails Screencast [EN]
446
+
447
+ [![Ruby on Rails #17 generate, save, send PDFs with gem wicked_pdf](https://i3.ytimg.com/vi/tFvtwEmW-GE/hqdefault.jpg)](https://youtu.be/tFvtwEmW-GE)
448
+
449
+ * codigofacilito Screencast [ES]
450
+
451
+ [![Generar PDF con Ruby on Rails - Tutorial](https://i3.ytimg.com/vi/jeWM_gusmJc/hqdefault.jpg)](https://youtu.be/jeWM_gusmJc)
452
+
363
453
  ### Debugging
364
454
 
365
455
  Now you can use a debug param on the URL that shows you the content of the pdf in plain html to design it faster.
@@ -370,12 +460,30 @@ http://localhost:3001/CONTROLLER/X.pdf?debug
370
460
 
371
461
  However, the wicked_pdf_* helpers will use file:/// paths for assets when using :show_as_html, and your browser's cross-domain safety feature will kick in, and not render them. To get around this, you can load your assets like so in your templates:
372
462
  ```html
373
- <%= params.key?('debug') ? image_tag('foo') : wicked_pdf_image_tag('foo') %>
463
+ <%= params.key?('debug') ? image_tag('foo') : wicked_pdf_image_tag('foo') %>
374
464
  ```
375
465
 
376
466
  #### Gotchas
377
467
 
378
- If one image from your HTML cannot be found (relative or wrong path for ie), others images with right paths **may not** be displayed in the output PDF as well (it seems to be an issue with wkhtmltopdf).
468
+ If one image from your HTML cannot be found (relative or wrong path for example), others images with right paths **may not** be displayed in the output PDF as well (it seems to be an issue with wkhtmltopdf).
469
+
470
+ wkhtmltopdf may render at different resolutions on different platforms. For example, Linux prints at 75 dpi (native for WebKit) while on Windows it's at the desktop's DPI (which is normally 96 dpi). [Use `:zoom => 0.78125`](https://github.com/wkhtmltopdf/wkhtmltopdf/issues/2184) (75/96) to match Linux rendering to Windows.
471
+
472
+ ### Security considerations
473
+
474
+ WickedPdf renders page content on the server by saving HTML and assets to temporary files on disk, then executing `wkhtmltopdf` to convert that HTML to a PDF file.
475
+
476
+ It is highly recommended if you allow user-generated HTML/CSS/JS to be converted to PDF, you sanitize it first, or at least disallow requesting content from internal IP addresses and hostnames.
477
+
478
+ For example, these could potentially leak internal AWS metadata:
479
+ ```html
480
+ <iframe src="http://169.254.169.254/latest/meta-data/"></iframe>
481
+ <object data="http://169.254.169.254/latest/meta-data/" type="text/html">
482
+ ```
483
+
484
+ Thank you to Adam Gold from [Snyk](https://snyk.io) for reporting this.
485
+ We are considering adding host allow & block lists and/or potentially HTML element sanitizing.
486
+ Please open an issue or PR to help us out with this.
379
487
 
380
488
  ### Inspiration
381
489
 
data/Rakefile CHANGED
@@ -5,7 +5,7 @@ require 'rails/version'
5
5
  require 'bundler/gem_tasks'
6
6
 
7
7
  desc 'Default: run unit tests.'
8
- task :default => [:setup_and_run_tests, :rubocop]
8
+ task :default => %i[setup_and_run_tests rubocop]
9
9
 
10
10
  desc 'Test the wicked_pdf plugin.'
11
11
  Rake::TestTask.new(:test) do |t|
@@ -17,16 +17,13 @@ end
17
17
 
18
18
  desc 'Run RuboCop'
19
19
  task :rubocop do
20
- next unless RUBY_VERSION >= '2.0.0'
21
20
  require 'rubocop/rake_task'
22
21
  RuboCop::RakeTask.new
23
22
  end
24
23
 
25
24
  desc 'Setup and run all tests'
26
25
  task :setup_and_run_tests do
27
- unless File.exist?('test/dummy/config/environment.rb')
28
- Rake::Task[:dummy_generate].invoke
29
- end
26
+ Rake::Task[:dummy_generate].invoke unless File.exist?('test/dummy/config/environment.rb')
30
27
  Rake::Task[:test].invoke
31
28
  end
32
29
 
@@ -34,18 +31,24 @@ desc 'Generate dummy application for test cases'
34
31
  task :dummy_generate do
35
32
  Rake::Task[:dummy_remove].invoke
36
33
  puts 'Creating dummy application to run tests'
37
- command = Rails::VERSION::MAJOR == 2 ? '' : 'new'
38
- system("rails #{command} test/dummy")
34
+ system('rails new test/dummy --database=sqlite3')
39
35
  system('touch test/dummy/db/schema.rb')
36
+ FileUtils.cp 'test/fixtures/database.yml', 'test/dummy/config/'
40
37
  FileUtils.rm_r Dir.glob('test/dummy/test/*')
38
+
39
+ # rails 6 needs this to be present before start:
40
+ FileUtils.mkdir_p('test/dummy/app/assets/config')
41
+ FileUtils.mkdir_p('test/dummy/app/assets/javascripts')
42
+ FileUtils.cp 'test/fixtures/manifest.js', 'test/dummy/app/assets/config/'
43
+ FileUtils.cp 'test/fixtures/wicked.js', 'test/dummy/app/assets/javascripts/'
41
44
  end
42
45
 
43
46
  desc 'Remove dummy application'
44
47
  task :dummy_remove do
45
- FileUtils.rm_r Dir.glob('test/dummy/*')
48
+ FileUtils.rm_r Dir.glob('test/dummy/')
46
49
  end
47
50
 
48
- desc 'Generate documentation for the wicked_pdf plugin.'
51
+ desc 'Generate documentation for the wicked_pdf gem.'
49
52
  RDoc::Task.new(:rdoc) do |rdoc|
50
53
  rdoc.rdoc_dir = 'rdoc'
51
54
  rdoc.title = 'WickedPdf'
data/gemfiles/5.0.gemfile CHANGED
@@ -1,6 +1,8 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'rdoc'
4
3
  gem 'rails', '~> 5.0.0'
4
+ gem 'rdoc'
5
+ gem 'sprockets', '~>3.0' # v4 strips newlines from assets causing tests to fail
6
+ gem 'sqlite3', '~> 1.3.6'
5
7
 
6
8
  gemspec path: '../'
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rails', '~> 5.1.0'
4
+ gem 'rdoc'
5
+ gem 'sprockets', '~>3.0' # v4 strips newlines from assets causing tests to fail
6
+ gem 'sqlite3', '~> 1.3.6'
7
+
8
+ gemspec path: '../'
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'bootsnap' # required to run `rake test` in Rails 5.2
4
+ gem 'rails', '~> 5.2'
5
+ gem 'rdoc'
6
+ gem 'sprockets', '~>3.0' # v4 strips newlines from assets causing tests to fail
7
+ gem 'sqlite3', '~> 1.3.6'
8
+
9
+ gemspec path: '../'
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'bootsnap' # required to run `rake test` in Rails 6.0
4
+ gem 'bundler', '~>2'
5
+ gem 'rails', '~>6.0.1'
6
+ gem 'rdoc'
7
+ gem 'sprockets', '~>3.0'
8
+ gem 'sqlite3', '~> 1.4'
9
+
10
+ gemspec path: '../'
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'bootsnap' # required to run `rake test` in Rails 6.1
4
+ gem 'bundler', '~>2'
5
+ gem 'rails', '~>6.1.0'
6
+ gem 'webpacker'
7
+ gem 'rdoc'
8
+ gem 'sprockets', '~>3.0'
9
+ gem 'sqlite3', '~> 1.4'
10
+
11
+ gemspec :path => '../'
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'bootsnap' # required to run `rake test` in Rails 7.0
4
+ gem 'bundler', '~>2'
5
+ gem 'rails', '~>7.0.0'
6
+ gem 'sprockets-rails'
7
+ gem 'rdoc'
8
+ gem 'sprockets', '~>3.0'
9
+ gem 'sqlite3', '~> 1.4'
10
+
11
+ gemspec :path => '../'
@@ -8,14 +8,23 @@
8
8
  #
9
9
  # https://github.com/mileszs/wicked_pdf/blob/master/README.md
10
10
 
11
- WickedPdf.config = {
11
+ WickedPdf.configure do |config|
12
12
  # Path to the wkhtmltopdf executable: This usually isn't needed if using
13
13
  # one of the wkhtmltopdf-binary family of gems.
14
- # exe_path: '/usr/local/bin/wkhtmltopdf',
14
+ # config.exe_path = '/usr/local/bin/wkhtmltopdf',
15
15
  # or
16
- # exe_path: Gem.bin_path('wkhtmltopdf-binary', 'wkhtmltopdf')
16
+ # config.exe_path = Gem.bin_path('wkhtmltopdf-binary', 'wkhtmltopdf')
17
+
18
+ # Needed for wkhtmltopdf 0.12.6+ to use many wicked_pdf asset helpers
19
+ # config.enable_local_file_access = true,
17
20
 
18
21
  # Layout file to be used for all PDFs
19
22
  # (but can be overridden in `render :pdf` calls)
20
- # layout: 'pdf.html',
21
- }
23
+ # config.layout = 'pdf.html',
24
+
25
+ # Using wkhtmltopdf without an X server can be achieved by enabling the
26
+ # 'use_xvfb' flag. This will wrap all wkhtmltopdf commands around the
27
+ # 'xvfb-run' command, in order to simulate an X server.
28
+ #
29
+ # config.use_xvfb = true,
30
+ end
@@ -1,11 +1,7 @@
1
- if defined?(Rails) && Rails::VERSION::MAJOR != 2
2
-
3
- # Rails3 generator invoked with 'rails generate wicked_pdf'
4
- class WickedPdfGenerator < Rails::Generators::Base
5
- source_root(File.expand_path(File.dirname(__FILE__) + '/../../generators/wicked_pdf/templates'))
6
- def copy_initializer
7
- copy_file 'wicked_pdf.rb', 'config/initializers/wicked_pdf.rb'
8
- end
1
+ # Rails generator invoked with 'rails generate wicked_pdf'
2
+ class WickedPdfGenerator < Rails::Generators::Base
3
+ source_root(File.expand_path(File.dirname(__FILE__) + '/../../generators/wicked_pdf/templates'))
4
+ def copy_initializer
5
+ copy_file 'wicked_pdf.rb', 'config/initializers/wicked_pdf.rb'
9
6
  end
10
-
11
7
  end
@@ -0,0 +1,65 @@
1
+ class WickedPdf
2
+ class Binary
3
+ EXE_NAME = 'wkhtmltopdf'.freeze
4
+
5
+ attr_reader :path, :default_version
6
+
7
+ def initialize(binary_path, default_version = WickedPdf::DEFAULT_BINARY_VERSION)
8
+ @path = binary_path || find_binary_path
9
+ @default_version = default_version
10
+
11
+ raise "Location of #{EXE_NAME} unknown" if @path.empty?
12
+ raise "Bad #{EXE_NAME}'s path: #{@path}" unless File.exist?(@path)
13
+ raise "#{EXE_NAME} is not executable" unless File.executable?(@path)
14
+ end
15
+
16
+ def version
17
+ @version ||= retrieve_binary_version
18
+ end
19
+
20
+ def parse_version_string(version_info)
21
+ match_data = /wkhtmltopdf\s*(\d*\.\d*\.\d*\w*)/.match(version_info)
22
+ if match_data && (match_data.length == 2)
23
+ Gem::Version.new(match_data[1])
24
+ else
25
+ default_version
26
+ end
27
+ end
28
+
29
+ def xvfb_run_path
30
+ path = possible_binary_locations.map { |l| File.expand_path("#{l}/xvfb-run") }.find { |location| File.exist?(location) }
31
+ raise StandardError, 'Could not find binary xvfb-run on the system.' unless path
32
+
33
+ path
34
+ end
35
+
36
+ private
37
+
38
+ def retrieve_binary_version
39
+ _stdin, stdout, _stderr = Open3.popen3(@path + ' -V')
40
+ parse_version_string(stdout.gets(nil))
41
+ rescue StandardError
42
+ default_version
43
+ end
44
+
45
+ def find_binary_path
46
+ exe_path ||= WickedPdf.config[:exe_path] unless WickedPdf.config.empty?
47
+ exe_path ||= possible_which_path
48
+ exe_path ||= possible_binary_locations.map { |l| File.expand_path("#{l}/#{EXE_NAME}") }.find { |location| File.exist?(location) }
49
+ exe_path || ''
50
+ end
51
+
52
+ def possible_which_path
53
+ detected_path = (defined?(Bundler) ? Bundler.which('wkhtmltopdf') : `which wkhtmltopdf`).chomp
54
+ detected_path.present? && detected_path
55
+ rescue StandardError
56
+ nil
57
+ end
58
+
59
+ def possible_binary_locations
60
+ possible_locations = (ENV['PATH'].split(':') + %w[/usr/bin /usr/local/bin]).uniq
61
+ possible_locations += %w[~/bin] if ENV.key?('HOME')
62
+ possible_locations
63
+ end
64
+ end
65
+ end
@@ -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