wicked_pdf 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/issue_template.md +15 -0
- data/.rubocop.yml +5 -0
- data/.rubocop_todo.yml +2 -2
- data/.travis.yml +45 -26
- data/CHANGELOG.md +37 -2
- data/README.md +73 -19
- data/Rakefile +7 -3
- data/gemfiles/3.1.gemfile +0 -1
- data/gemfiles/5.1.gemfile +6 -0
- data/gemfiles/5.2.gemfile +9 -0
- data/gemfiles/rails_edge.gemfile +5 -2
- data/lib/wicked_pdf.rb +41 -29
- data/lib/wicked_pdf/middleware.rb +1 -1
- data/lib/wicked_pdf/pdf_helper.rb +29 -21
- data/lib/wicked_pdf/progress.rb +33 -0
- data/lib/wicked_pdf/railtie.rb +1 -1
- data/lib/wicked_pdf/version.rb +1 -1
- data/lib/wicked_pdf/wicked_pdf_helper.rb +2 -1
- data/lib/wicked_pdf/wicked_pdf_helper/assets.rb +8 -3
- data/test/fixtures/database.yml +4 -0
- data/test/functional/pdf_helper_test.rb +71 -0
- data/test/unit/wicked_pdf_test.rb +22 -3
- data/test/unit/wkhtmltopdf_location_test.rb +50 -0
- data/wicked_pdf.gemspec +16 -12
- metadata +45 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9b2b03398c3ff6b7c63f7b35289653d9227ff19bcc1e473e06880ba1c8414c67
|
4
|
+
data.tar.gz: 17c06db62266b781714242e9b9bede0f528646257ebefda4f681b76314fd1f3f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a2787ffaf69e82aeb6970880d49769a3f1d5b9ab254b8f9162f6bac0d0af58004d8dfc82bfff17b0f84f2b074a1221949b5de2b765e10692a6ea9537119f56ae
|
7
|
+
data.tar.gz: 9b13a953a42f28c2509f777d0a16ef25922f4b81661167c3196aa91442d8179c9f2a3aec1e5c55893be0d1103d19bc42f08903ec3060eca62754d9d2d8be38ed
|
@@ -0,0 +1,15 @@
|
|
1
|
+
## Issue description
|
2
|
+
|
3
|
+
## Expected or desired behavior
|
4
|
+
|
5
|
+
## System specifications
|
6
|
+
|
7
|
+
wicked_pdf gem version (output of `cat Gemfile.lock | grep wicked_pdf`):
|
8
|
+
|
9
|
+
wkhtmltopdf version (output of `wkhtmltopdf --version`):
|
10
|
+
|
11
|
+
whtmltopdf [provider gem](https://rubygems.org/search?utf8=%E2%9C%93&query=wkhtmltopdf) and version if one is used:
|
12
|
+
|
13
|
+
platform/distribution and version (e.g. Windows 10 / Ubuntu 16.04 / Heroku cedar):
|
14
|
+
|
15
|
+
|
data/.rubocop.yml
CHANGED
@@ -1,9 +1,14 @@
|
|
1
1
|
inherit_from: .rubocop_todo.yml
|
2
2
|
|
3
3
|
AllCops:
|
4
|
+
TargetRubyVersion: 1.9
|
4
5
|
Exclude:
|
5
6
|
- 'test/dummy/**/*'
|
6
7
|
|
8
|
+
Metrics/BlockLength:
|
9
|
+
Exclude:
|
10
|
+
- 'wicked_pdf.gemspec'
|
11
|
+
|
7
12
|
# I'd like wicked_pdf to keep Ruby 1.8 compatibility for now
|
8
13
|
Style/HashSyntax:
|
9
14
|
EnforcedStyle: hash_rockets
|
data/.rubocop_todo.yml
CHANGED
@@ -24,7 +24,7 @@ Metrics/ModuleLength:
|
|
24
24
|
|
25
25
|
# Offense count: 5
|
26
26
|
Metrics/CyclomaticComplexity:
|
27
|
-
Max:
|
27
|
+
Max: 11
|
28
28
|
|
29
29
|
# Offense count: 92
|
30
30
|
# Configuration parameters: AllowURI, URISchemes.
|
@@ -41,7 +41,7 @@ Metrics/PerceivedComplexity:
|
|
41
41
|
Max: 12
|
42
42
|
|
43
43
|
# Offense count: 2
|
44
|
-
|
44
|
+
Naming/AccessorMethodName:
|
45
45
|
Enabled: false
|
46
46
|
|
47
47
|
# Offense count: 1
|
data/.travis.yml
CHANGED
@@ -1,22 +1,12 @@
|
|
1
1
|
language:
|
2
2
|
- ruby
|
3
|
+
git:
|
4
|
+
depth: 1
|
5
|
+
quiet: true
|
3
6
|
before_install:
|
4
7
|
- sudo apt-get update -qq
|
5
|
-
- gem update bundler
|
6
8
|
bundler_args: --verbose
|
7
9
|
sudo: required
|
8
|
-
rvm:
|
9
|
-
- 1.9.2
|
10
|
-
- 1.9.3
|
11
|
-
- 2.0
|
12
|
-
- 2.1
|
13
|
-
- 2.2
|
14
|
-
- 2.3.0
|
15
|
-
- ruby-head
|
16
|
-
gemfile:
|
17
|
-
- gemfiles/3.0.gemfile
|
18
|
-
- gemfiles/3.1.gemfile
|
19
|
-
- gemfiles/3.2.gemfile
|
20
10
|
before_script:
|
21
11
|
- bundle list
|
22
12
|
- sudo apt-get install -y wkhtmltopdf
|
@@ -33,25 +23,54 @@ matrix:
|
|
33
23
|
- gem update --system 1.8.25
|
34
24
|
- gem --version
|
35
25
|
gemfile: gemfiles/2.3.gemfile
|
36
|
-
- rvm:
|
26
|
+
- rvm: 1.9.2
|
27
|
+
gemfile: gemfiles/3.0.gemfile
|
28
|
+
- rvm: 1.9.3
|
29
|
+
gemfile: gemfiles/3.1.gemfile
|
30
|
+
- rvm: 2.0
|
31
|
+
gemfile: gemfiles/3.2.gemfile
|
32
|
+
- rvm: 2.0
|
37
33
|
gemfile: gemfiles/4.0.gemfile
|
38
|
-
- rvm: 2.
|
34
|
+
- rvm: 2.1
|
39
35
|
gemfile: gemfiles/4.1.gemfile
|
40
|
-
- rvm: 2.2
|
36
|
+
- rvm: 2.2
|
41
37
|
gemfile: gemfiles/4.2.gemfile
|
42
|
-
- rvm: 2.3
|
38
|
+
- rvm: 2.3
|
43
39
|
gemfile: gemfiles/5.0.gemfile
|
44
|
-
|
40
|
+
before_install:
|
41
|
+
# https://github.com/danmayer/coverband/issues/162
|
42
|
+
- "find /home/travis/.rvm/rubies -wholename '*default/bundler-*.gemspec' -delete"
|
43
|
+
- rvm @global do gem uninstall bundler -a -x -I || true
|
44
|
+
- gem install bundler -v '< 2'
|
45
|
+
- rvm: 2.4
|
46
|
+
gemfile: gemfiles/5.1.gemfile
|
47
|
+
- rvm: 2.5
|
48
|
+
gemfile: gemfiles/5.2.gemfile
|
49
|
+
- rvm: 2.5
|
45
50
|
gemfile: gemfiles/rails_edge.gemfile
|
46
|
-
- rvm: 2.
|
51
|
+
- rvm: 2.6
|
52
|
+
gemfile: gemfiles/5.2.gemfile
|
53
|
+
before_install:
|
54
|
+
- gem update --system
|
55
|
+
- gem install bundler
|
56
|
+
- rvm: 2.6
|
57
|
+
gemfile: gemfiles/rails_edge.gemfile
|
58
|
+
before_install:
|
59
|
+
- gem update --system
|
60
|
+
- gem install bundler
|
61
|
+
- rvm: ruby-head
|
62
|
+
gemfile: gemfiles/5.2.gemfile
|
63
|
+
before_install:
|
64
|
+
- gem install bundler -v '~> 2'
|
65
|
+
- rvm: ruby-head
|
47
66
|
gemfile: gemfiles/rails_edge.gemfile
|
67
|
+
before_install:
|
68
|
+
- gem install bundler -v '~> 2'
|
48
69
|
allow_failures:
|
49
|
-
- rvm:
|
70
|
+
- rvm: 2.5
|
71
|
+
gemfile: gemfiles/rails_edge.gemfile
|
72
|
+
- rvm: 2.6
|
73
|
+
gemfile: gemfiles/rails_edge.gemfile
|
74
|
+
- rvm: 2.5.3
|
50
75
|
gemfile: gemfiles/3.0.gemfile
|
51
|
-
- rvm: 1.9.2
|
52
|
-
gemfile: gemfiles/3.1.gemfile
|
53
|
-
- rvm: 1.9.2
|
54
|
-
gemfile: gemfiles/3.2.gemfile
|
55
|
-
- rvm: 1.9.3
|
56
|
-
gemfile: gemfiles/4.0.gemfile
|
57
76
|
- rvm: ruby-head
|
data/CHANGELOG.md
CHANGED
@@ -2,7 +2,41 @@
|
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
4
4
|
|
5
|
-
## [1.
|
5
|
+
## [1.2.0] - 2019-03-16
|
6
|
+
### Added
|
7
|
+
- [Add `raise_on_all_errors: true` option to raise on any error that prints to STDOUT during PDF generation](https://github.com/mileszs/wicked_pdf/pull/751)
|
8
|
+
- [Add ability to use the `assigns` option to `render` to assign instance variables to a PDF template](https://github.com/mileszs/wicked_pdf/pull/801)
|
9
|
+
- [Add ability to track console progress](https://github.com/mileszs/wicked_pdf/pull/804) with `progress: -> (output) { puts output }`. This is useful to add reporting hooks to show your frontend what page number is being generated.
|
10
|
+
|
11
|
+
### Changed
|
12
|
+
- [Fix conflict with other gems that hook into `render`](https://github.com/mileszs/wicked_pdf/pull/574) and avoid using `alias_method_chain` where possible
|
13
|
+
- [Fix issue using the shell to locate `wkhtmltopdf` in a Bundler environment](https://github.com/mileszs/wicked_pdf/pull/728)
|
14
|
+
- [Fix `wkhtmltopdf` path detection when HOME environment variable is unset](https://github.com/mileszs/wicked_pdf/pull/568)
|
15
|
+
- [Fix error when the `Rails` constant is defined but not actually using Rails](https://github.com/mileszs/wicked_pdf/pull/613)
|
16
|
+
- [Fix compatibility issue with Sprockets 4](https://github.com/mileszs/wicked_pdf/pull/615)
|
17
|
+
- [Fix compatibility issue with `Mime::JS` in Rails 5.1+](https://github.com/mileszs/wicked_pdf/pull/627)
|
18
|
+
- [Fix deprecation warning by using `after_action` instead of `after_filter` when available](https://github.com/mileszs/wicked_pdf/pull/663)
|
19
|
+
- [Provide Rails `base_path` to `find_asset` calls for Sprockets file lookup](https://github.com/mileszs/wicked_pdf/pull/688)
|
20
|
+
- Logger changes:
|
21
|
+
- [Use `Rails.logger.debug` instead of `p`](https://github.com/mileszs/wicked_pdf/pull/575)
|
22
|
+
- [Change logger message to prepend `[wicked_pdf]` instead of nonstandard `****************WICKED****************`](https://github.com/mileszs/wicked_pdf/pull/589)
|
23
|
+
- Documentation changes:
|
24
|
+
- [Update link to wkhtmltopdf homepage](https://github.com/mileszs/wicked_pdf/pull/582)
|
25
|
+
- [Update link to `wkhtmltopdf_binary_gem`](https://github.com/mileszs/wicked_pdf/commit/59e6c5fca3985f2fa2f345089596250df5da2682)
|
26
|
+
- [Update documentation for usage with the Asset Pipeline](https://github.com/mileszs/wicked_pdf/commit/690d00157706699a71b7dcd71834759f4d84702f)
|
27
|
+
- [Document `default_protocol` option](https://github.com/mileszs/wicked_pdf/pull/585)
|
28
|
+
- [Document `image` and `no_image` options](https://github.com/mileszs/wicked_pdf/pull/689)
|
29
|
+
- [Document issue with DPI/scaling on various platforms](https://github.com/mileszs/wicked_pdf/pull/715)
|
30
|
+
- [Document creating and attaching a PDF in a mailer](https://github.com/mileszs/wicked_pdf/pull/746)
|
31
|
+
- [Document dependency on `wkhtmltopdf` with RubyGems](https://github.com/mileszs/wicked_pdf/pull/656)
|
32
|
+
- [Add example using WickedPDF with Rails in an API-only configuration](https://github.com/mileszs/wicked_pdf/pull/796)
|
33
|
+
- [Add example for rending a template as a header/footer](https://github.com/mileszs/wicked_pdf/pull/603)
|
34
|
+
- [Add GitHub issue template](https://github.com/mileszs/wicked_pdf/pull/805)
|
35
|
+
- [Add CodeClimate Badge](https://github.com/mileszs/wicked_pdf/pull/646)
|
36
|
+
- RuboCop cleanup
|
37
|
+
- Updates to Travis CI pipeline to support newer versions of Ruby & Rails
|
38
|
+
|
39
|
+
## [1.1.0] - 2016-08-30
|
6
40
|
### Added
|
7
41
|
- Support Rails 5.x and Sprockets 3.x
|
8
42
|
- Support `window_status: 'somestring'` option, to instruct wkhtmltopdf to wait until the browser `window.status` is equal to the supplied string. This can be useful to force rendering to wait [as explained quite well here](https://spin.atomicobject.com/2015/08/29/ember-app-done-loading/)
|
@@ -80,7 +114,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
80
114
|
- Asset helpers no longer add a file extension if it already is specified with one
|
81
115
|
|
82
116
|
# Compare Releases
|
83
|
-
- [1.
|
117
|
+
- [1.2.0...HEAD](https://github.com/mileszs/wicked_pdf/compare/1.2.0...HEAD)
|
118
|
+
- [1.1.0...1.2.0](https://github.com/mileszs/wicked_pdf/compare/1.1.0...1.2.0)
|
84
119
|
- [1.0.6...1.1.0](https://github.com/mileszs/wicked_pdf/compare/1.0.6...1.1.0)
|
85
120
|
- [1.0.5...1.0.6](https://github.com/mileszs/wicked_pdf/compare/1.0.5...1.0.6)
|
86
121
|
- [1.0.4...1.0.5](https://github.com/mileszs/wicked_pdf/compare/1.0.4...1.0.5)
|
data/README.md
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
# Wicked PDF [![Build Status](https://secure.travis-ci.org/mileszs/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://secure.travis-ci.org/mileszs/wicked_pdf.svg)](http://travis-ci.org/mileszs/wicked_pdf) [![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.
|
7
|
+
_Wicked PDF has been verified to work on Ruby versions 1.8.7 through 2.6; Rails 2 through 5.2_
|
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
|
30
|
-
To install that, add
|
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,7 +35,9 @@ gem 'wkhtmltopdf-binary'
|
|
35
35
|
|
36
36
|
To your Gemfile and run `bundle install`.
|
37
37
|
|
38
|
-
This
|
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
|
|
@@ -106,6 +108,12 @@ Using wicked_pdf_helpers with asset pipeline raises `Asset names passed to helpe
|
|
106
108
|
</html>
|
107
109
|
```
|
108
110
|
|
111
|
+
#### Asset pipeline usage
|
112
|
+
|
113
|
+
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.
|
114
|
+
|
115
|
+
config.assets.precompile += ['blueprint/screen.css', 'pdf.css', 'jquery.ui.datepicker.js', 'pdf.js', ...etc...]
|
116
|
+
|
109
117
|
#### CDN reference
|
110
118
|
|
111
119
|
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.
|
@@ -116,11 +124,6 @@ In this case, you can use that standard Rails helpers and point to the current C
|
|
116
124
|
<%= javascript_include_tag "http://code.jquery.com/jquery-1.10.0.min.js" %>
|
117
125
|
<%= javascript_include_tag "http://code.jquery.com/ui/1.10.3/jquery-ui.min.js" %>
|
118
126
|
```
|
119
|
-
#### Asset pipeline usage
|
120
|
-
|
121
|
-
The way to handle this for the asset pipeline on Heroku is to include these files in your asset precompile list, as follows:
|
122
|
-
|
123
|
-
config.assets.precompile += ['blueprint/screen.css', 'pdf.css', 'jquery.ui.datepicker.js', 'pdf.js', ...etc...]
|
124
127
|
|
125
128
|
### Advanced Usage with all available options
|
126
129
|
```ruby
|
@@ -132,8 +135,9 @@ class ThingsController < ApplicationController
|
|
132
135
|
render pdf: 'file_name',
|
133
136
|
disposition: 'attachment', # default 'inline'
|
134
137
|
template: 'things/show',
|
135
|
-
file: "#{Rails.root}/files/foo.erb"
|
136
|
-
|
138
|
+
file: "#{Rails.root}/files/foo.erb",
|
139
|
+
inline: '<!doctype html><html><head></head><body>INLINE HTML</body></html>',
|
140
|
+
layout: 'pdf', # for a pdf.pdf.erb file
|
137
141
|
wkhtmltopdf: '/usr/local/bin/wkhtmltopdf', # path to binary
|
138
142
|
show_as_html: params.key?('debug'), # allow debugging based on url param
|
139
143
|
orientation: 'Landscape', # default Portrait
|
@@ -142,6 +146,7 @@ class ThingsController < ApplicationController
|
|
142
146
|
page_width: NUMBER,
|
143
147
|
save_to_file: Rails.root.join('pdfs', "#{filename}.pdf"),
|
144
148
|
save_only: false, # depends on :save_to_file being set first
|
149
|
+
default_protocol: 'http',
|
145
150
|
proxy: 'TEXT',
|
146
151
|
basic_auth: false # when true username & password are automatically sent from session
|
147
152
|
username: 'TEXT',
|
@@ -171,10 +176,11 @@ class ThingsController < ApplicationController
|
|
171
176
|
print_media_type: true,
|
172
177
|
disable_smart_shrinking: true,
|
173
178
|
use_xserver: true,
|
174
|
-
background: false, #
|
179
|
+
background: false, # background needs to be true to enable background colors to render
|
175
180
|
no_background: true,
|
176
181
|
viewport_size: 'TEXT', # available only with use_xserver or patched QT
|
177
182
|
extra: '', # directly inserted into the command to wkhtmltopdf
|
183
|
+
raise_on_all_errors: nil, # raise error for any stderr output. Such as missing media, image assets
|
178
184
|
outline: { outline: true,
|
179
185
|
outline_depth: LEVEL },
|
180
186
|
margin: { top: SIZE, # default 10 (mm)
|
@@ -230,7 +236,8 @@ class ThingsController < ApplicationController
|
|
230
236
|
disable_links: true,
|
231
237
|
disable_toc_links: true,
|
232
238
|
disable_back_links:true,
|
233
|
-
xsl_style_sheet: 'file.xsl'} # optional XSLT stylesheet to use for styling table of contents
|
239
|
+
xsl_style_sheet: 'file.xsl'}, # optional XSLT stylesheet to use for styling table of contents
|
240
|
+
progress: proc { |output| puts output } # proc called when console output changes
|
234
241
|
end
|
235
242
|
end
|
236
243
|
end
|
@@ -267,9 +274,20 @@ pdf = WickedPdf.new.pdf_from_url('https://github.com/mileszs/wicked_pdf')
|
|
267
274
|
|
268
275
|
# create a pdf from string using templates, layouts and content option for header or footer
|
269
276
|
pdf = WickedPdf.new.pdf_from_string(
|
270
|
-
render_to_string('templates/pdf', layout: 'pdfs/layout_pdf'),
|
277
|
+
render_to_string('templates/pdf', layout: 'pdfs/layout_pdf.html'),
|
271
278
|
footer: {
|
272
|
-
content: render_to_string(
|
279
|
+
content: render_to_string(
|
280
|
+
'templates/footer',
|
281
|
+
layout: 'pdfs/layout_pdf.html'
|
282
|
+
)
|
283
|
+
}
|
284
|
+
)
|
285
|
+
|
286
|
+
# It is possible to use footer/header templates without a layout, in that case you need to provide a valid HTML document
|
287
|
+
pdf = WickedPdf.new.pdf_from_string(
|
288
|
+
render_to_string('templates/full_pdf_template'),
|
289
|
+
header: {
|
290
|
+
content: render_to_string('templates/full_header_template')
|
273
291
|
}
|
274
292
|
)
|
275
293
|
|
@@ -281,12 +299,33 @@ save_path = Rails.root.join('pdfs','filename.pdf')
|
|
281
299
|
File.open(save_path, 'wb') do |file|
|
282
300
|
file << pdf
|
283
301
|
end
|
302
|
+
|
303
|
+
# you can also track progress on your PDF generation, such as when using it from within a Resque job
|
304
|
+
class PdfJob
|
305
|
+
def perform
|
306
|
+
blk = proc { |output|
|
307
|
+
match = output.match(/\[.+\] Page (?<current_page>\d+) of (?<total_pages>\d+)/)
|
308
|
+
if match
|
309
|
+
current_page = match[:current_page].to_i
|
310
|
+
total_pages = match[:total_pages].to_i
|
311
|
+
message = "Generated #{current_page} of #{total_pages} pages"
|
312
|
+
at current_page, total_pages, message
|
313
|
+
end
|
314
|
+
}
|
315
|
+
WickedPdf.new.pdf_from_string(html, progress: blk)
|
316
|
+
end
|
317
|
+
end
|
284
318
|
```
|
285
319
|
If you need to display utf encoded characters, add this to your pdf views or layouts:
|
286
320
|
```html
|
287
321
|
<meta charset="utf-8" />
|
288
322
|
```
|
289
|
-
|
323
|
+
If you need to return a PDF in a controller with Rails in API mode:
|
324
|
+
```ruby
|
325
|
+
pdf_html = ActionController::Base.new.render_to_string(template: 'controller_name/action_name', layout: 'pdf')
|
326
|
+
pdf = WickedPdf.new.pdf_from_string(pdf_html)
|
327
|
+
send_data pdf, filename: 'file.pdf'
|
328
|
+
```
|
290
329
|
### Page Breaks
|
291
330
|
|
292
331
|
You can control page breaks with CSS.
|
@@ -340,7 +379,7 @@ If you would like to have WickedPdf automatically generate PDF views for all (or
|
|
340
379
|
require 'wicked_pdf'
|
341
380
|
config.middleware.use WickedPdf::Middleware
|
342
381
|
```
|
343
|
-
If you want to turn on or off the middleware for certain
|
382
|
+
If you want to turn on or off the middleware for certain URLs, use the `:only` or `:except` conditions like so:
|
344
383
|
```ruby
|
345
384
|
# conditions can be plain strings or regular expressions, and you can supply only one or an array
|
346
385
|
config.middleware.use WickedPdf::Middleware, {}, only: '/invoice'
|
@@ -348,6 +387,19 @@ config.middleware.use WickedPdf::Middleware, {}, except: [ %r[^/admin], '/secret
|
|
348
387
|
```
|
349
388
|
If you use the standard `render pdf: 'some_pdf'` in your app, you will want to exclude those actions from the middleware.
|
350
389
|
|
390
|
+
|
391
|
+
### Include in an email as an attachment
|
392
|
+
|
393
|
+
To include a rendered pdf file in an email you can do the following:
|
394
|
+
|
395
|
+
```ruby
|
396
|
+
attachments['attachment.pdf'] = WickedPdf.new.pdf_from_string(
|
397
|
+
render_to_string('link_to_view.pdf.erb', layout: 'pdf')
|
398
|
+
)
|
399
|
+
```
|
400
|
+
|
401
|
+
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.
|
402
|
+
|
351
403
|
### Further Reading
|
352
404
|
|
353
405
|
Mike Ackerman's post [How To Create PDFs in Rails](https://www.viget.com/articles/how-to-create-pdfs-in-rails)
|
@@ -375,7 +427,9 @@ However, the wicked_pdf_* helpers will use file:/// paths for assets when using
|
|
375
427
|
|
376
428
|
#### Gotchas
|
377
429
|
|
378
|
-
If one image from your HTML cannot be found (relative or wrong path for
|
430
|
+
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).
|
431
|
+
|
432
|
+
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.
|
379
433
|
|
380
434
|
### Inspiration
|
381
435
|
|
data/Rakefile
CHANGED
@@ -34,9 +34,13 @@ desc 'Generate dummy application for test cases'
|
|
34
34
|
task :dummy_generate do
|
35
35
|
Rake::Task[:dummy_remove].invoke
|
36
36
|
puts 'Creating dummy application to run tests'
|
37
|
-
|
38
|
-
|
37
|
+
if Rails::VERSION::MAJOR > 2
|
38
|
+
system('rails new test/dummy --database=sqlite3')
|
39
|
+
else
|
40
|
+
system('rails test/dummy')
|
41
|
+
end
|
39
42
|
system('touch test/dummy/db/schema.rb')
|
43
|
+
FileUtils.cp 'test/fixtures/database.yml', 'test/dummy/config/'
|
40
44
|
FileUtils.rm_r Dir.glob('test/dummy/test/*')
|
41
45
|
end
|
42
46
|
|
@@ -45,7 +49,7 @@ task :dummy_remove do
|
|
45
49
|
FileUtils.rm_r Dir.glob('test/dummy/*')
|
46
50
|
end
|
47
51
|
|
48
|
-
desc 'Generate documentation for the wicked_pdf
|
52
|
+
desc 'Generate documentation for the wicked_pdf gem.'
|
49
53
|
RDoc::Task.new(:rdoc) do |rdoc|
|
50
54
|
rdoc.rdoc_dir = 'rdoc'
|
51
55
|
rdoc.title = 'WickedPdf'
|
data/gemfiles/3.1.gemfile
CHANGED
data/gemfiles/rails_edge.gemfile
CHANGED
@@ -1,6 +1,9 @@
|
|
1
|
-
source
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
|
3
3
|
gem 'rdoc'
|
4
|
-
gem 'rails', git:
|
4
|
+
gem 'rails', git: 'https://github.com/rails/rails.git'
|
5
|
+
gem 'sqlite3', '~> 1.3.6'
|
6
|
+
gem 'bootsnap' # required to run `rake test` in Rails 6.0
|
7
|
+
gem 'mocha', '= 1.3' # newer versions blow up
|
5
8
|
|
6
9
|
gemspec path: '../'
|
data/lib/wicked_pdf.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# wkhtml2pdf Ruby interface
|
2
|
-
# http://
|
2
|
+
# http://wkhtmltopdf.org/
|
3
3
|
|
4
4
|
require 'logger'
|
5
5
|
require 'digest/md5'
|
@@ -27,6 +27,7 @@ require 'wicked_pdf/version'
|
|
27
27
|
require 'wicked_pdf/railtie'
|
28
28
|
require 'wicked_pdf/tempfile'
|
29
29
|
require 'wicked_pdf/middleware'
|
30
|
+
require 'wicked_pdf/progress'
|
30
31
|
|
31
32
|
class WickedPdf
|
32
33
|
DEFAULT_BINARY_VERSION = Gem::Version.new('0.9.9')
|
@@ -36,6 +37,8 @@ class WickedPdf
|
|
36
37
|
cattr_accessor :config
|
37
38
|
attr_accessor :binary_version
|
38
39
|
|
40
|
+
include Progress
|
41
|
+
|
39
42
|
def initialize(wkhtmltopdf_binary_path = nil)
|
40
43
|
@exe_path = wkhtmltopdf_binary_path || find_wkhtmltopdf_binary_path
|
41
44
|
raise "Location of #{EXE_NAME} unknown" if @exe_path.empty?
|
@@ -68,15 +71,18 @@ class WickedPdf
|
|
68
71
|
options.merge!(WickedPdf.config) { |_key, option, _config| option }
|
69
72
|
generated_pdf_file = WickedPdfTempfile.new('wicked_pdf_generated_file.pdf', options[:temp_path])
|
70
73
|
command = [@exe_path]
|
71
|
-
command << '-q' unless on_windows? # suppress errors on stdout
|
72
74
|
command += parse_options(options)
|
73
75
|
command << url
|
74
76
|
command << generated_pdf_file.path.to_s
|
75
77
|
|
76
78
|
print_command(command.inspect) if in_development_mode?
|
77
79
|
|
78
|
-
|
79
|
-
|
80
|
+
if track_progress?(options)
|
81
|
+
invoke_with_progress(command, options)
|
82
|
+
else
|
83
|
+
err = Open3.popen3(*command) do |_stdin, _stdout, stderr|
|
84
|
+
stderr.read
|
85
|
+
end
|
80
86
|
end
|
81
87
|
if options[:return_file]
|
82
88
|
return_file = options.delete(:return_file)
|
@@ -85,9 +91,10 @@ class WickedPdf
|
|
85
91
|
generated_pdf_file.rewind
|
86
92
|
generated_pdf_file.binmode
|
87
93
|
pdf = generated_pdf_file.read
|
94
|
+
raise "Error generating PDF\n Command Error: #{err}" if options[:raise_on_all_errors] && !err.empty?
|
88
95
|
raise "PDF could not be generated!\n Command Error: #{err}" if pdf && pdf.rstrip.empty?
|
89
96
|
pdf
|
90
|
-
rescue => e
|
97
|
+
rescue StandardError => e
|
91
98
|
raise "Failed to execute:\n#{command}\nError: #{e}"
|
92
99
|
ensure
|
93
100
|
generated_pdf_file.close! if generated_pdf_file && !return_file
|
@@ -96,7 +103,7 @@ class WickedPdf
|
|
96
103
|
private
|
97
104
|
|
98
105
|
def in_development_mode?
|
99
|
-
return Rails.env == 'development' if defined?(Rails)
|
106
|
+
return Rails.env == 'development' if defined?(Rails.env)
|
100
107
|
RAILS_ENV == 'development' if defined?(RAILS_ENV)
|
101
108
|
end
|
102
109
|
|
@@ -105,19 +112,19 @@ class WickedPdf
|
|
105
112
|
end
|
106
113
|
|
107
114
|
def print_command(cmd)
|
108
|
-
|
115
|
+
Rails.logger.debug '[wicked_pdf]: ' + cmd
|
109
116
|
end
|
110
117
|
|
111
118
|
def retrieve_binary_version
|
112
119
|
_stdin, stdout, _stderr = Open3.popen3(@exe_path + ' -V')
|
113
120
|
@binary_version = parse_version(stdout.gets(nil))
|
114
|
-
rescue
|
121
|
+
rescue StandardError
|
115
122
|
DEFAULT_BINARY_VERSION
|
116
123
|
end
|
117
124
|
|
118
125
|
def parse_version(version_info)
|
119
126
|
match_data = /wkhtmltopdf\s*(\d*\.\d*\.\d*\w*)/.match(version_info)
|
120
|
-
if match_data && (
|
127
|
+
if match_data && (match_data.length == 2)
|
121
128
|
Gem::Version.new(match_data[1])
|
122
129
|
else
|
123
130
|
DEFAULT_BINARY_VERSION
|
@@ -195,24 +202,26 @@ class WickedPdf
|
|
195
202
|
|
196
203
|
def parse_header_footer(options)
|
197
204
|
r = []
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
205
|
+
unless options.blank?
|
206
|
+
[:header, :footer].collect do |hf|
|
207
|
+
next if options[hf].blank?
|
208
|
+
opt_hf = options[hf]
|
209
|
+
r += make_options(opt_hf, [:center, :font_name, :left, :right], hf.to_s)
|
210
|
+
r += make_options(opt_hf, [:font_size, :spacing], hf.to_s, :numeric)
|
211
|
+
r += make_options(opt_hf, [:line], hf.to_s, :boolean)
|
212
|
+
if options[hf] && options[hf][:content]
|
213
|
+
@hf_tempfiles = [] unless defined?(@hf_tempfiles)
|
214
|
+
@hf_tempfiles.push(tf = WickedPdfTempfile.new("wicked_#{hf}_pdf.html"))
|
215
|
+
tf.write options[hf][:content]
|
216
|
+
tf.flush
|
217
|
+
options[hf][:html] = {}
|
218
|
+
options[hf][:html][:url] = "file:///#{tf.path}"
|
219
|
+
end
|
220
|
+
unless opt_hf[:html].blank?
|
221
|
+
r += make_option("#{hf}-html", opt_hf[:html][:url]) unless opt_hf[:html][:url].blank?
|
222
|
+
end
|
214
223
|
end
|
215
|
-
end
|
224
|
+
end
|
216
225
|
r
|
217
226
|
end
|
218
227
|
|
@@ -322,18 +331,21 @@ class WickedPdf
|
|
322
331
|
:disable_smart_shrinking,
|
323
332
|
:use_xserver,
|
324
333
|
:no_background,
|
334
|
+
:images,
|
335
|
+
:no_images,
|
325
336
|
:no_stop_slow_scripts], '', :boolean)
|
326
337
|
end
|
327
338
|
r
|
328
339
|
end
|
329
340
|
|
330
341
|
def find_wkhtmltopdf_binary_path
|
331
|
-
possible_locations = (ENV['PATH'].split(':') + %w
|
342
|
+
possible_locations = (ENV['PATH'].split(':') + %w[/usr/bin /usr/local/bin]).uniq
|
343
|
+
possible_locations += %w[~/bin] if ENV.key?('HOME')
|
332
344
|
exe_path ||= WickedPdf.config[:exe_path] unless WickedPdf.config.empty?
|
333
345
|
exe_path ||= begin
|
334
|
-
detected_path = (defined?(Bundler) ?
|
346
|
+
detected_path = (defined?(Bundler) ? Bundler.which('wkhtmltopdf') : `which wkhtmltopdf`).chomp
|
335
347
|
detected_path.present? && detected_path
|
336
|
-
rescue
|
348
|
+
rescue StandardError
|
337
349
|
nil
|
338
350
|
end
|
339
351
|
exe_path ||= possible_locations.map { |l| File.expand_path("#{l}/#{EXE_NAME}") }.find { |location| File.exist?(location) }
|
@@ -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
|
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
|
-
|
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
|
-
|
24
|
-
|
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
|
-
|
31
|
-
|
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
|
-
|
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
|
-
|
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' # 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
|
data/lib/wicked_pdf/railtie.rb
CHANGED
data/lib/wicked_pdf/version.rb
CHANGED
@@ -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' =>
|
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)
|
@@ -68,15 +68,20 @@ class WickedPdf
|
|
68
68
|
end
|
69
69
|
else
|
70
70
|
asset = find_asset(source)
|
71
|
-
|
71
|
+
if asset
|
72
|
+
# older versions need pathname, Sprockets 4 supports only filename
|
73
|
+
asset.respond_to?(:filename) ? asset.filename : asset.pathname
|
74
|
+
else
|
75
|
+
File.join(Rails.public_path, source)
|
76
|
+
end
|
72
77
|
end
|
73
78
|
end
|
74
79
|
|
75
80
|
def find_asset(path)
|
76
81
|
if Rails.application.assets.respond_to?(:find_asset)
|
77
|
-
Rails.application.assets.find_asset(path)
|
82
|
+
Rails.application.assets.find_asset(path, :base_path => Rails.application.root.to_s)
|
78
83
|
else
|
79
|
-
Sprockets::Railtie.build_environment(Rails.application).find_asset(path)
|
84
|
+
Sprockets::Railtie.build_environment(Rails.application).find_asset(path, :base_path => Rails.application.root.to_s)
|
80
85
|
end
|
81
86
|
end
|
82
87
|
|
@@ -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
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'test_helper'
|
2
|
-
|
3
2
|
WickedPdf.config = { :exe_path => ENV['WKHTMLTOPDF_BIN'] || '/usr/local/bin/wkhtmltopdf' }
|
4
3
|
HTML_DOCUMENT = '<html><body>Hello World</body></html>'.freeze
|
5
4
|
|
@@ -7,7 +6,10 @@ HTML_DOCUMENT = '<html><body>Hello World</body></html>'.freeze
|
|
7
6
|
# Also, smash the returned array of options into a single string for
|
8
7
|
# convenience in testing below.
|
9
8
|
class WickedPdf
|
9
|
+
undef :binary_version
|
10
|
+
undef :binary_version=
|
10
11
|
attr_accessor :binary_version
|
12
|
+
|
11
13
|
def get_parsed_options(opts)
|
12
14
|
parse_options(opts).join(' ')
|
13
15
|
end
|
@@ -131,6 +133,11 @@ class WickedPdfTest < ActiveSupport::TestCase
|
|
131
133
|
assert_equal '--outline-depth 5', @wp.get_parsed_options(:outline => { :outline_depth => 5 }).strip
|
132
134
|
end
|
133
135
|
|
136
|
+
test 'should parse no_images option' do
|
137
|
+
assert_equal '--no-images', @wp.get_parsed_options(:no_images => true).strip
|
138
|
+
assert_equal '--images', @wp.get_parsed_options(:images => true).strip
|
139
|
+
end
|
140
|
+
|
134
141
|
test 'should parse margins options' do
|
135
142
|
[:top, :bottom, :left, :right].each do |o|
|
136
143
|
assert_equal "--margin-#{o} 12", @wp.get_parsed_options(:margin => { o => '12' }).strip
|
@@ -200,7 +207,7 @@ class WickedPdfTest < ActiveSupport::TestCase
|
|
200
207
|
test 'should not use double dash options for version without dashes' do
|
201
208
|
@wp.binary_version = WickedPdf::BINARY_VERSION_WITHOUT_DASHES
|
202
209
|
|
203
|
-
%w
|
210
|
+
%w[toc cover].each do |name|
|
204
211
|
assert_equal @wp.get_valid_option(name), name
|
205
212
|
end
|
206
213
|
end
|
@@ -208,7 +215,7 @@ class WickedPdfTest < ActiveSupport::TestCase
|
|
208
215
|
test 'should use double dash options for version with dashes' do
|
209
216
|
@wp.binary_version = Gem::Version.new('0.11.0')
|
210
217
|
|
211
|
-
%w
|
218
|
+
%w[toc cover].each do |name|
|
212
219
|
assert_equal @wp.get_valid_option(name), "--#{name}"
|
213
220
|
end
|
214
221
|
end
|
@@ -218,4 +225,16 @@ class WickedPdfTest < ActiveSupport::TestCase
|
|
218
225
|
cover_option = @wp.get_valid_option('cover')
|
219
226
|
assert_equal @wp.get_parsed_options(options), "--disable-javascript --header-center 3 #{cover_option} http://example.org"
|
220
227
|
end
|
228
|
+
|
229
|
+
test 'should output progress when creating pdfs on compatible hosts' do
|
230
|
+
wp = WickedPdf.new
|
231
|
+
output = []
|
232
|
+
options = { :progress => proc { |o| output << o } }
|
233
|
+
wp.pdf_from_string HTML_DOCUMENT, options
|
234
|
+
if RbConfig::CONFIG['target_os'] =~ /mswin|mingw/
|
235
|
+
assert_empty output
|
236
|
+
else
|
237
|
+
assert(output.collect { |l| !l.match(/Loading/).nil? }.include?(true)) # should output something like "Loading pages (1/5)"
|
238
|
+
end
|
239
|
+
end
|
221
240
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
class WkhtmltopdfLocationTest < ActiveSupport::TestCase
|
4
|
+
setup do
|
5
|
+
@saved_config = WickedPdf.config
|
6
|
+
WickedPdf.config = {}
|
7
|
+
end
|
8
|
+
|
9
|
+
teardown do
|
10
|
+
WickedPdf.config = @saved_config
|
11
|
+
end
|
12
|
+
|
13
|
+
test 'should correctly locate wkhtmltopdf without bundler' do
|
14
|
+
bundler_module = Bundler
|
15
|
+
Object.send(:remove_const, :Bundler)
|
16
|
+
|
17
|
+
assert_nothing_raised do
|
18
|
+
WickedPdf.new
|
19
|
+
end
|
20
|
+
|
21
|
+
Object.const_set(:Bundler, bundler_module)
|
22
|
+
end
|
23
|
+
|
24
|
+
test 'should correctly locate wkhtmltopdf with bundler' do
|
25
|
+
assert_nothing_raised do
|
26
|
+
WickedPdf.new
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class LocationNonWritableTest < ActiveSupport::TestCase
|
31
|
+
setup do
|
32
|
+
@saved_config = WickedPdf.config
|
33
|
+
WickedPdf.config = {}
|
34
|
+
|
35
|
+
@old_home = ENV['HOME']
|
36
|
+
ENV['HOME'] = '/not/a/writable/directory'
|
37
|
+
end
|
38
|
+
|
39
|
+
teardown do
|
40
|
+
WickedPdf.config = @saved_config
|
41
|
+
ENV['HOME'] = @old_home
|
42
|
+
end
|
43
|
+
|
44
|
+
test 'should correctly locate wkhtmltopdf with bundler while HOME is set to a non-writable directory' do
|
45
|
+
assert_nothing_raised do
|
46
|
+
WickedPdf.new
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/wicked_pdf.gemspec
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
4
|
require 'wicked_pdf/version'
|
@@ -7,28 +7,32 @@ require 'English'
|
|
7
7
|
Gem::Specification.new do |spec|
|
8
8
|
spec.name = 'wicked_pdf'
|
9
9
|
spec.version = WickedPdf::VERSION
|
10
|
-
spec.authors = ['Miles Z. Sterrett']
|
11
|
-
spec.email = 'miles.sterrett@gmail.com'
|
10
|
+
spec.authors = ['Miles Z. Sterrett', 'David Jones']
|
11
|
+
spec.email = ['miles.sterrett@gmail.com', 'unixmonkey1@gmail.com']
|
12
12
|
spec.summary = 'PDF generator (from HTML) gem for Ruby on Rails'
|
13
13
|
spec.homepage = 'https://github.com/mileszs/wicked_pdf'
|
14
14
|
spec.license = 'MIT'
|
15
15
|
spec.date = Time.now.strftime('%Y-%m-%d')
|
16
|
-
spec.description = <<
|
17
|
-
Wicked PDF uses the shell utility wkhtmltopdf to serve a PDF file to a user from HTML.
|
18
|
-
In other words, rather than dealing with a PDF generation DSL of some sort,
|
19
|
-
you simply write an HTML view as you would normally, and let Wicked take care of the hard stuff.
|
20
|
-
|
16
|
+
spec.description = <<DESC.gsub(/^\s+/, '')
|
17
|
+
Wicked PDF uses the shell utility wkhtmltopdf to serve a PDF file to a user from HTML.
|
18
|
+
In other words, rather than dealing with a PDF generation DSL of some sort,
|
19
|
+
you simply write an HTML view as you would normally, and let Wicked take care of the hard stuff.
|
20
|
+
DESC
|
21
21
|
|
22
22
|
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
23
23
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
24
24
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
25
25
|
spec.require_paths = ['lib']
|
26
26
|
|
27
|
+
spec.requirements << 'wkhtmltopdf'
|
28
|
+
|
29
|
+
spec.add_dependency 'activesupport'
|
30
|
+
|
27
31
|
spec.add_development_dependency 'rails'
|
28
|
-
spec.add_development_dependency 'bundler', '~> 1.3'
|
32
|
+
spec.add_development_dependency 'bundler', RUBY_VERSION >= '2.5' ? '~> 2' : '~> 1.3'
|
29
33
|
spec.add_development_dependency 'rake'
|
30
|
-
spec.add_development_dependency 'rubocop' if RUBY_VERSION >= '2.0.0'
|
31
|
-
spec.add_development_dependency 'sqlite3'
|
32
|
-
spec.add_development_dependency 'mocha'
|
34
|
+
spec.add_development_dependency 'rubocop', '~> 0.50.0' if RUBY_VERSION >= '2.0.0'
|
35
|
+
spec.add_development_dependency 'sqlite3', '~> 1.3.6'
|
36
|
+
spec.add_development_dependency 'mocha', '= 1.3'
|
33
37
|
spec.add_development_dependency 'test-unit'
|
34
38
|
end
|
metadata
CHANGED
@@ -1,15 +1,30 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wicked_pdf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Miles Z. Sterrett
|
8
|
+
- David Jones
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2019-03-16 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
13
28
|
- !ruby/object:Gem::Dependency
|
14
29
|
name: rails
|
15
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -30,14 +45,14 @@ dependencies:
|
|
30
45
|
requirements:
|
31
46
|
- - "~>"
|
32
47
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
48
|
+
version: '2'
|
34
49
|
type: :development
|
35
50
|
prerelease: false
|
36
51
|
version_requirements: !ruby/object:Gem::Requirement
|
37
52
|
requirements:
|
38
53
|
- - "~>"
|
39
54
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
55
|
+
version: '2'
|
41
56
|
- !ruby/object:Gem::Dependency
|
42
57
|
name: rake
|
43
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -56,44 +71,44 @@ dependencies:
|
|
56
71
|
name: rubocop
|
57
72
|
requirement: !ruby/object:Gem::Requirement
|
58
73
|
requirements:
|
59
|
-
- - "
|
74
|
+
- - "~>"
|
60
75
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
76
|
+
version: 0.50.0
|
62
77
|
type: :development
|
63
78
|
prerelease: false
|
64
79
|
version_requirements: !ruby/object:Gem::Requirement
|
65
80
|
requirements:
|
66
|
-
- - "
|
81
|
+
- - "~>"
|
67
82
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
83
|
+
version: 0.50.0
|
69
84
|
- !ruby/object:Gem::Dependency
|
70
85
|
name: sqlite3
|
71
86
|
requirement: !ruby/object:Gem::Requirement
|
72
87
|
requirements:
|
73
|
-
- - "
|
88
|
+
- - "~>"
|
74
89
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
90
|
+
version: 1.3.6
|
76
91
|
type: :development
|
77
92
|
prerelease: false
|
78
93
|
version_requirements: !ruby/object:Gem::Requirement
|
79
94
|
requirements:
|
80
|
-
- - "
|
95
|
+
- - "~>"
|
81
96
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
97
|
+
version: 1.3.6
|
83
98
|
- !ruby/object:Gem::Dependency
|
84
99
|
name: mocha
|
85
100
|
requirement: !ruby/object:Gem::Requirement
|
86
101
|
requirements:
|
87
|
-
- -
|
102
|
+
- - '='
|
88
103
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
104
|
+
version: '1.3'
|
90
105
|
type: :development
|
91
106
|
prerelease: false
|
92
107
|
version_requirements: !ruby/object:Gem::Requirement
|
93
108
|
requirements:
|
94
|
-
- -
|
109
|
+
- - '='
|
95
110
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
111
|
+
version: '1.3'
|
97
112
|
- !ruby/object:Gem::Dependency
|
98
113
|
name: test-unit
|
99
114
|
requirement: !ruby/object:Gem::Requirement
|
@@ -112,11 +127,14 @@ description: |
|
|
112
127
|
Wicked PDF uses the shell utility wkhtmltopdf to serve a PDF file to a user from HTML.
|
113
128
|
In other words, rather than dealing with a PDF generation DSL of some sort,
|
114
129
|
you simply write an HTML view as you would normally, and let Wicked take care of the hard stuff.
|
115
|
-
email:
|
130
|
+
email:
|
131
|
+
- miles.sterrett@gmail.com
|
132
|
+
- unixmonkey1@gmail.com
|
116
133
|
executables: []
|
117
134
|
extensions: []
|
118
135
|
extra_rdoc_files: []
|
119
136
|
files:
|
137
|
+
- ".github/issue_template.md"
|
120
138
|
- ".gitignore"
|
121
139
|
- ".rubocop.yml"
|
122
140
|
- ".rubocop_todo.yml"
|
@@ -134,6 +152,8 @@ files:
|
|
134
152
|
- gemfiles/4.1.gemfile
|
135
153
|
- gemfiles/4.2.gemfile
|
136
154
|
- gemfiles/5.0.gemfile
|
155
|
+
- gemfiles/5.1.gemfile
|
156
|
+
- gemfiles/5.2.gemfile
|
137
157
|
- gemfiles/rails_edge.gemfile
|
138
158
|
- generators/wicked_pdf/templates/wicked_pdf.rb
|
139
159
|
- generators/wicked_pdf/wicked_pdf_generator.rb
|
@@ -142,11 +162,13 @@ files:
|
|
142
162
|
- lib/wicked_pdf.rb
|
143
163
|
- lib/wicked_pdf/middleware.rb
|
144
164
|
- lib/wicked_pdf/pdf_helper.rb
|
165
|
+
- lib/wicked_pdf/progress.rb
|
145
166
|
- lib/wicked_pdf/railtie.rb
|
146
167
|
- lib/wicked_pdf/tempfile.rb
|
147
168
|
- lib/wicked_pdf/version.rb
|
148
169
|
- lib/wicked_pdf/wicked_pdf_helper.rb
|
149
170
|
- lib/wicked_pdf/wicked_pdf_helper/assets.rb
|
171
|
+
- test/fixtures/database.yml
|
150
172
|
- test/fixtures/document_with_long_line.html
|
151
173
|
- test/fixtures/wicked.css
|
152
174
|
- test/fixtures/wicked.js
|
@@ -155,6 +177,7 @@ files:
|
|
155
177
|
- test/functional/wicked_pdf_helper_test.rb
|
156
178
|
- test/test_helper.rb
|
157
179
|
- test/unit/wicked_pdf_test.rb
|
180
|
+
- test/unit/wkhtmltopdf_location_test.rb
|
158
181
|
- wicked_pdf.gemspec
|
159
182
|
homepage: https://github.com/mileszs/wicked_pdf
|
160
183
|
licenses:
|
@@ -174,13 +197,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
174
197
|
- - ">="
|
175
198
|
- !ruby/object:Gem::Version
|
176
199
|
version: '0'
|
177
|
-
requirements:
|
178
|
-
|
179
|
-
rubygems_version:
|
200
|
+
requirements:
|
201
|
+
- wkhtmltopdf
|
202
|
+
rubygems_version: 3.0.1
|
180
203
|
signing_key:
|
181
204
|
specification_version: 4
|
182
205
|
summary: PDF generator (from HTML) gem for Ruby on Rails
|
183
206
|
test_files:
|
207
|
+
- test/fixtures/database.yml
|
184
208
|
- test/fixtures/document_with_long_line.html
|
185
209
|
- test/fixtures/wicked.css
|
186
210
|
- test/fixtures/wicked.js
|
@@ -189,3 +213,4 @@ test_files:
|
|
189
213
|
- test/functional/wicked_pdf_helper_test.rb
|
190
214
|
- test/test_helper.rb
|
191
215
|
- test/unit/wicked_pdf_test.rb
|
216
|
+
- test/unit/wkhtmltopdf_location_test.rb
|