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

Use Ferrum for PDF #547

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ gem "decidim-user_extension", path: "decidim-user_extension"

gem "slack-ruby-client"

gem "ferrum"

group :development, :test do
gem "byebug", "~> 11.0", platform: :mri
gem "figaro"
Expand Down
7 changes: 7 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,11 @@ GEM
multipart-post (~> 2)
faraday-net_http (3.1.0)
net-http
ferrum (0.13)
addressable (~> 2.5)
concurrent-ruby (~> 1.1)
webrick (~> 1.7)
websocket-driver (>= 0.6, < 0.8)
ffi (1.16.3)
figaro (1.2.0)
thor (>= 0.14.0, < 2)
Expand Down Expand Up @@ -900,6 +905,7 @@ GEM
webpush (1.1.0)
hkdf (~> 0.2)
jwt (~> 2.0)
webrick (1.8.1)
websocket-driver (0.7.6)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
Expand Down Expand Up @@ -932,6 +938,7 @@ DEPENDENCIES
dotenv-rails
factory_bot_rails
faker (~> 3.2)
ferrum
figaro
fog-aws
image_processing
Expand Down
1 change: 1 addition & 0 deletions config/initializers/decidim.rb
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@
Decidim.register_assets_path File.expand_path("app/packs", Rails.application.root)

require "decidim/map/provider/static_map/cfj_osm"
require "decidim/exporters/pdf"

## Set default OGP description length limit. It's used in Decidim::Blogs components
Rails.application.config.default_blog_ogp_description_limit = ENV.fetch("DECIDIM_BLOG_OGP_DESCRIPTION_LIMIT", 150).to_i
Expand Down
80 changes: 80 additions & 0 deletions lib/decidim/exporters/pdf.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# frozen_string_literal: true

# To be correctly loaded by Zeitwerk
Decidim::Forms::Admin::QuestionnaireAnswerPresenter # rubocop:disable Lint/Void

module Decidim
module Exporters
# Exports a PDF using the provided hash, given a collection and a
# Serializer. This is an abstract class that should be inherited
# to create PDF exporters, with each PDF exporter class setting
# the desired template, layout and orientation.
#
class PDF < Exporter
# Public: Exports a PDF version of the collection by rendering
# the template into html and then converting it to PDF.
#
# Returns an ExportData instance.
def export
html = controller.render_to_string(
template: template,
layout: layout,
locals: locals
)

document = pdf_from_string(html, orientation: orientation)

ExportData.new(document, "pdf")
end

# may be overwritten if needed
def orientation
"Portrait"
end

# implementing classes should return a valid ERB path here
def template
raise NotImplementedError
end

# implementing classes should return a valid ERB path here
def layout
raise NotImplementedError
end

# This method may be overwritten if the template needs more local variables
def locals
{ collection: collection }
end

protected

def controller
raise NotImplementedError
end

private

def pdf_from_string(html, orientation:)
document = nil

Dir.mktmpdir do |dir|
html_path = File.join(dir, "tmp.html")
File.write(html_path, html)
url = URI::File.build([nil, html_path])

browser = Ferrum::Browser.new
browser.go_to(url)
document = browser.pdf(path: nil,
encoding: :binary,
landscape: orientation != "Portrait",
printBackground: true,
scale: 0.8,
format: :A4)
end

document
end
end
end
end
Loading