saucy/app/lib/letters.rb

68 lines
1.8 KiB
Ruby

require 'zip'
require 'nokogiri'
require 'combine_pdf'
module Letters
def self.apply_template(io, params)
Zip::OutputStream.write_buffer do |out|
Zip::File.open(io) do |zip|
zip.each do |entry|
out.put_next_entry(entry.name)
if entry.name == "content.xml"
out.write apply_template_xml(entry.get_input_stream.read, params)
elsif !entry.directory?
out.write entry.get_input_stream.read
end
end
end
end
end
def self.apply_template_xml(xml, params)
doc = Nokogiri::XML(xml)
doc.xpath("//*[contains(text(), 'DISPLAY_NAME')]").each do |node|
node.content = node.content.gsub("DISPLAY_NAME", params["DISPLAY_NAME"])
end
address_lines = params['ADDRESS'].split("\n")
doc.xpath("//*[contains(text(), 'ADDRESS')]").each do |node|
newnodes = [node] + address_lines[1..].map do |line|
node.clone.tap do |c|
c.content = c.content.gsub("ADDRESS", line)
end
end
node.content = node.content.gsub("ADDRESS", address_lines.first)
newnodes.each_cons(2) do |p, n|
p.add_next_sibling(n)
end
end
doc.to_xml(save_with: 0)
end
def self.generate(template, members)
Dir.mktmpdir do |directory|
members.each do |member|
odt = apply_template(template, {
"DISPLAY_NAME" => member.display_name,
"ADDRESS" => member.address,
})
File.open("#{directory}/#{member.number}.odt", "wb") { |out| out.write(odt.string) }
end
`libreoffice --convert-to pdf --outdir #{directory} #{directory}/*.odt`
pdf = CombinePDF.new
Dir["#{directory}/*.pdf"].each do |file|
pdf << CombinePDF.load(file)
end
pdf.to_pdf
end
end
end