Last active
January 3, 2016 06:38
-
-
Save swistak/8423518 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'fileutils' | |
require 'logger' | |
require 'erb' | |
# Pdf generation service based on wkhtmltopdf. | |
class PdfGenerator | |
class WkhtmltopdfError < RuntimeError; end | |
DPI = 96 # Pixels in inch | |
DPC = (DPI / 2.54) # = 37.795 Pixels in centimeter | |
# See http://madalgo.au.dk/~jakobt/wkhtmltoxdoc/wkhtmltopdf-0.9.9-doc.html | |
# | |
# Options without argument just take true, rest should have string as value. | |
# To disable option set it to false. | |
PDF_OPTIONS = { | |
'quiet' => true, | |
# Header is disabled. | |
# 'header-html' => 'header.html', | |
# 'footer-html' => 'footer.html', | |
'print-media-type' => true, | |
# 'disable-smart-shrinking' => true, | |
'page-size' => 'A4', | |
'margin-top' => '0.5cm', | |
'margin-right' => '0.5cm', | |
'margin-bottom' => '1cm', | |
'margin-left' => '0.5cm', | |
'encoding' => "UTF-8", | |
} | |
PDF_DIR = 'pdfs' | |
FileUtils.mkdir_p(PDF_DIR) | |
attr_accessor :error_message | |
attr_accessor :note | |
def logger | |
defined?(Rails) ? Rails.logger : (@logger ||= Logger.new($stdout)) | |
end | |
def pdf_options | |
PDF_OPTIONS | |
end | |
def note_url | |
'index.html' | |
end | |
def pdf_path | |
File.join(PDF_DIR, "ramki.pdf") | |
end | |
def wkhtmltopdf | |
@wkhtmltopdf ||= begin | |
pdf_command = [ | |
`ls -1 bin/wkhtmltopdf* 2>/dev/null`.split("\n").last, | |
`which wkhtmltopdf` | |
].detect{|c| !c.nil? } | |
raise("Cannot locate wkhtmltopdf in #{Dir.pwd} or $PATH") if pdf_command.nil? | |
pdf_command.strip | |
end | |
end | |
def xvfb_wrapper | |
"" #'xvfb-run -s "-screen 0, 1600x1200x24"' | |
end | |
# wkhtmltopdf [OPTIONS]... <input file> [More input files] <output file> | |
def pdf_command | |
normalized_options = pdf_options.map{|k, v| | |
v ? "--#{k} #{v == true ? "" : v}" : nil | |
}.compact.join(" ") | |
"#{xvfb_wrapper} #{wkhtmltopdf} #{normalized_options} #{note_url} #{pdf_path}" | |
end | |
def render | |
File.open('index.html', 'w') do |f| | |
f.write ERB.new(File.read('index.html.erb')).result | |
end | |
end | |
# Generates a pdf. | |
def generate | |
render | |
perform | |
end | |
# Performs a pdf generation. | |
def perform | |
logger.debug "Running: " + pdf_command | |
# See http://mentalized.net/journal/2010/03/08/5_ways_to_run_commands_from_ruby/ | |
redirection = " 2>&1" | |
@out = IO.popen(pdf_command + redirection, "wb+") do |pdf| | |
pdf.close_write | |
pdf.gets(nil) | |
end | |
unless $? == 0 | |
self.error_message = "Failed to generate pdf via: #{wkhtmltopdf}. Exit code: #{$?}." | |
raise(WkhtmltopdfError, error_message, caller[1..-1]) | |
end | |
end | |
end | |
if __FILE__ == $0 | |
PdfGenerator.new.generate | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment