Class: Gotenberg::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/gotenberg/client.rb

Overview

Client class for interacting with the Gotenberg API

Instance Method Summary collapse

Constructor Details

#initialize(api_url) ⇒ Client

Initialize a new Client

Parameters:

  • api_url (String)

    The base URL of the Gotenberg API



20
21
22
# File 'lib/gotenberg/client.rb', line 20

def initialize(api_url)
  @api_url = api_url
end

Instance Method Details

#html(htmls, asset_paths, properties = {}) ⇒ String

Convert HTML files to PDF and write it to the output file

Example:

htmls = { index: "<h1>Html</h1>", header: "<h1>Header</h1>", footer: "<h1>Footer</h1>" }
asset_paths = ["path/to/style.css", "path/to/image.png"]
properties = { paperWidth: 8.27, paperHeight: 11.7, marginTop: 1, marginBottom: 1 }
client = Gotenberg::Client.new("http://localhost:3000")
pdf_content = client.html(htmls, asset_paths, properties)

Credit: github.com/jbd0101/ruby-gotenberg-client/blob/master/lib/gotenberg.rb

Parameters:

  • htmls (Hash{Symbol => String})

    A hash with the file name as the key and the HTML content as the value

  • asset_paths (Array<String>)

    Paths to the asset files (like CSS, images) required by the HTML files

  • properties (Hash) (defaults to: {})

    Additional properties for PDF conversion

Options Hash (properties):

  • :paperWidth (Float)

    The width of the paper

  • :paperHeight (Float)

    The height of the paper

  • :marginTop (Float)

    The top margin

  • :marginBottom (Float)

    The bottom margin

  • :marginLeft (Float)

    The left margin

  • :marginRight (Float)

    The right margin

  • :preferCssPageSize (Boolean)

    Whether to prefer CSS page size

  • :printBackground (Boolean)

    Whether to print the background

  • :omitBackground (Boolean)

    Whether to omit the background

  • :landscape (Boolean)

    Whether to use landscape orientation

  • :scale (Float)

    The scale of the PDF

  • :nativePageRanges (String)

    The page ranges to include

Returns:

  • (String)

    The resulting PDF content

Raises:



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/gotenberg/client.rb', line 52

def html(htmls, asset_paths, properties = {})
  raise GotenbergDownError unless up?

  raise IndexFileMissing unless (htmls.keys & ["index", :index]).any?

  dir_name = SecureRandom.uuid
  dir_path = File.join(Dir.tmpdir, dir_name)
  FileUtils.mkdir_p(dir_path)

  htmls.each do |key, value|
    File.write(File.join(dir_path, "#{key}.html"), value)
  end

  uri = URI("#{@api_url}/forms/chromium/convert/html")

  # Gotenberg requires all files to be in the same directory
  asset_paths.each do |path|
    FileUtils.cp(path, dir_path)
    next unless path.split(".").last == "css"

    # This preprocessing is necessary for the gotenberg
    raw_css = File.read(path)
    preprocessed = raw_css.gsub("url(/assets/", "url(").gsub("url(/", "url(")
    File.write(path, preprocessed)
  end

  # Rejecting .. and .
  entries = Dir.entries(dir_path).reject { |f| f.start_with?(".") }

  payload = entries.each_with_object({}).with_index do |(entry, obj), index|
    entry_abs_path = File.join(dir_path, entry)
    mime_type = MIME::Types.type_for(entry_abs_path).first.content_type
    obj["files[#{index}]"] = UploadIO.new(entry_abs_path, mime_type)
  end

  response = multipart_post(uri, payload.merge(properties))
  response.body.dup.force_encoding("utf-8")
ensure
  FileUtils.rm_rf(dir_path) if dir_path
end

#up?Boolean

Check if the Gotenberg API is up and healthy

Returns:

  • (Boolean)

    true if the API is up, false otherwise



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/gotenberg/client.rb', line 96

def up?
  uri = URI("#{@api_url}/health")
  request = Net::HTTP::Get.new(uri)
  request.basic_auth(
    ENV.fetch("GOTENBERG_API_BASIC_AUTH_USERNAME", nil),
    ENV.fetch("GOTENBERG_API_BASIC_AUTH_PASSWORD", nil)
  )

  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = uri.scheme == "https"
  response = http.request(request)

  response.is_a?(Net::HTTPSuccess) && JSON.parse(response.body)["status"] == "up"
rescue StandardError
  false
end