Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optionally track progress #804

Merged
merged 12 commits into from
Mar 16, 2019
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,8 @@ class ThingsController < ApplicationController
disable_links: true,
disable_toc_links: true,
disable_back_links:true,
xsl_style_sheet: 'file.xsl'} # optional XSLT stylesheet to use for styling table of contents
xsl_style_sheet: 'file.xsl'}, # optional XSLT stylesheet to use for styling table of contents
progress: proc { |output| puts output } # proc called when console output changes
end
end
end
Expand Down Expand Up @@ -297,6 +298,22 @@ save_path = Rails.root.join('pdfs','filename.pdf')
File.open(save_path, 'wb') do |file|
file << pdf
end

# you can also track progress on your PDF generation, such as when using it from within a Resque job
class PdfJob
def perform
blk = proc { |output|
match = output.match(/\[.+\] Page (?<current_page>\d+) of (?<total_pages>\d+)/)
if match
current_page = match[:current_page].to_i
total_pages = match[:total_pages].to_i
message = "Generated #{current_page} of #{total_pages} pages"
at current_page, total_pages, message
end
}
WickedPdf.new.pdf_from_string(html, progress: blk)
end
end
```
If you need to display utf encoded characters, add this to your pdf views or layouts:
```html
Expand Down
12 changes: 9 additions & 3 deletions lib/wicked_pdf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
require 'wicked_pdf/railtie'
require 'wicked_pdf/tempfile'
require 'wicked_pdf/middleware'
require 'wicked_pdf/progress'

class WickedPdf
DEFAULT_BINARY_VERSION = Gem::Version.new('0.9.9')
Expand All @@ -36,6 +37,8 @@ class WickedPdf
cattr_accessor :config
attr_accessor :binary_version

include Progress

def initialize(wkhtmltopdf_binary_path = nil)
@exe_path = wkhtmltopdf_binary_path || find_wkhtmltopdf_binary_path
raise "Location of #{EXE_NAME} unknown" if @exe_path.empty?
Expand Down Expand Up @@ -68,15 +71,18 @@ def pdf_from_url(url, options = {})
options.merge!(WickedPdf.config) { |_key, option, _config| option }
generated_pdf_file = WickedPdfTempfile.new('wicked_pdf_generated_file.pdf', options[:temp_path])
command = [@exe_path]
command << '-q' unless on_windows? # suppress errors on stdout
command += parse_options(options)
command << url
command << generated_pdf_file.path.to_s

print_command(command.inspect) if in_development_mode?

err = Open3.popen3(*command) do |_stdin, _stdout, stderr|
stderr.read
if track_progress?(options)
invoke_with_progress(command, options)
else
err = Open3.popen3(*command) do |_stdin, _stdout, stderr|
stderr.read
end
end
if options[:return_file]
return_file = options.delete(:return_file)
Expand Down
33 changes: 33 additions & 0 deletions lib/wicked_pdf/progress.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
class WickedPdf
module Progress
require 'pty' # no support for windows
require 'English'

def track_progress?(options)
options[:progress] && !on_windows?
end

def invoke_with_progress(command, options)
output = []
begin
PTY.spawn(command.join(' ')) do |stdout, _stdin, pid|
begin
stdout.sync
stdout.each_line("\r") do |line|
output << line.chomp
options[:progress].call(line) if options[:progress]
end
rescue Errno::EIO # rubocop:disable Lint/HandleExceptions
# child process is terminated, this is expected behaviour
ensure
::Process.wait pid
end
end
rescue PTY::ChildExited
puts 'The child process exited!'
end
err = output.join('\n')
raise "#{command} failed (exitstatus 0). Output was: #{err}" unless $CHILD_STATUS && $CHILD_STATUS.exitstatus.zero?
end
end
end
13 changes: 12 additions & 1 deletion test/unit/wicked_pdf_test.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
require 'test_helper'

WickedPdf.config = { :exe_path => ENV['WKHTMLTOPDF_BIN'] || '/usr/local/bin/wkhtmltopdf' }
HTML_DOCUMENT = '<html><body>Hello World</body></html>'.freeze

Expand Down Expand Up @@ -226,4 +225,16 @@ def setup
cover_option = @wp.get_valid_option('cover')
assert_equal @wp.get_parsed_options(options), "--disable-javascript --header-center 3 #{cover_option} http://example.org"
end

test 'should output progress when creating pdfs on compatible hosts' do
wp = WickedPdf.new
output = []
options = { :progress => proc { |o| output << o } }
wp.pdf_from_string HTML_DOCUMENT, options
if RbConfig::CONFIG['target_os'] =~ /mswin|mingw/
assert_empty output
else
assert(output.collect { |l| !l.match(/Loading/).nil? }.include?(true)) # should output something like "Loading pages (1/5)"
end
end
end