Skip to content

Commit

Permalink
Merge pull request gutschilla#6 from gutschilla/xvfb_support
Browse files Browse the repository at this point in the history
  - 0.3.2
  • Loading branch information
gutschilla committed May 3, 2016
2 parents e3ca35f + c7fa41d commit d9a2456
Show file tree
Hide file tree
Showing 10 changed files with 68 additions and 45 deletions.
6 changes: 6 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changes

- 0.3.2
- support for command prefixes, most notabably **xvfb-run** to let a
wkhtmltopdf which was compiled without an unpatched version of qt run on
machines without an x server
- (add in precompiled, patched binaries for wkhtmltopdf and libjpeg8 that are
needed to run wkhtmltopdf without xvfb-run)
- 0.3.1
- implement this as proper application, look for executables at startup (and possibly fail on that)
- save paths in a PfdGenerator.Agent
Expand Down
29 changes: 17 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
A simple wrapper for wkhtmltopdf (HTML to PDF) and PDFTK (adds in encryption) for use in Elixir projects.
It is currently using temporary files instead of pipes or other means of IPC.

# New in 0.3.1
# New in 0.3.2

- 0.3.1
- implement this as proper application, look for executables at startup (and possibly fail on that)
- save paths in a PfdGenerator.Agent
- make paths configurable in `config/ENV.exs` as well
- add some tests (Yay!)
- better README
- 0.3.2
- support for command prefixes, most notabably **xvfb-run** to let a
wkhtmltopdf which was compiled without an unpatched version of qt run on
machines without an x server
- (add in precompiled, patched binaries for wkhtmltopdf and libjpeg8 that are
needed to run wkhtmltopdf without xvfb-run)

For a proper changelog, see [CHANGES](CHANGES.md)

Expand Down Expand Up @@ -53,19 +53,24 @@ html = "<html><body><p>Hi there!</p></body></html>"

# Configuration

This module will automatically try to finde both `wkhtmltopdf` and `pdftk` in your path. But you may override or explicitly set their paths in your config/config.exs:
This module will automatically try to finde both `wkhtmltopdf` and `pdftk` in
your path. But you may override or explicitly set their paths in your
config/config.exs:

```
config :pdf_generator,
wkhtml_path: "/path/to/wkhtmltopdf",
pdftk_path: "/path/to/pdftk",
wkhtml_path: "/usr/bin/wkhtmltopdf",
pdftk_path: "/usr/bin/pdftk",
command_prefix: "xvfb-run"
```

# Documentation

For more info, read the [docs on hex](http://hexdocs.pm/pdf_generator) or issue `h PdfGenerator` in your iex shell.
For more info, read the [docs on hex](http://hexdocs.pm/pdf_generator) or issue
`h PdfGenerator` in your iex shell.

TODO
====

- [ ] Pass some useful base path so wkhtmltopdf can resolve static files (styles, images etc) linked in the HTML
- [ ] Pass some useful base path so wkhtmltopdf can resolve static files
(styles, images etc) linked in the HTML
25 changes: 5 additions & 20 deletions config/config.exs
Original file line number Diff line number Diff line change
@@ -1,24 +1,9 @@
# This file is responsible for configuring your application
# and its dependencies with the aid of the Mix.Config module.
use Mix.Config

# This configuration is loaded before any dependency and is restricted
# to this project. If another project depends on this project, this
# file won't be loaded nor affect the parent project. For this reason,
# if you want to provide default values for your application for third-
# party users, it should be done in your mix.exs file.
# config :pdf_generator,
# wkhtml_path: "/usr/bin/wkhtmltopdf",
# pdftk_path: "/usr/bin/pdftk",
# command_prefix: "/usr/bin/xvfb-run"

# Sample configuration:
#
# config :logger, :console,
# level: :info,
# format: "$date $time [$level] $metadata$message\n",
# metadata: [:user_id]
import_config "#{Mix.env}.exs"

# It is also possible to import configuration files, relative to this
# directory. For example, you can emulate configuration per environment
# by uncommenting the line below and defining dev.exs, test.exs and such.
# Configuration from the imported file will override the ones defined
# here (which is why it is important to import them last).
#
# import_config "#{Mix.env}.exs"
2 changes: 2 additions & 0 deletions config/dev.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
use Mix.Config

2 changes: 2 additions & 0 deletions config/pros.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
use Mix.Config

6 changes: 6 additions & 0 deletions config/test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use Mix.Config

config :pdf_generator,
command_prefix: "xvfb-run"


30 changes: 21 additions & 9 deletions lib/pdf_generator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -112,26 +112,38 @@ defmodule PdfGenerator do
File.write html_file, html
pdf_file = Path.join System.tmp_dir, Misc.Random.string <> ".pdf"

shell_params = [
shell_params = [
"--page-size", Keyword.get( options, :page_size ) || "A4",
Keyword.get( options, :shell_params ) || [] # will be flattened
]

%Result{ out: _output, status: status } = Porcelain.exec(
wkhtml_path, List.flatten( [ shell_params, html_file, pdf_file ] )
executable = wkhtml_path
arguments = List.flatten( [ shell_params, html_file, pdf_file ] )
command_prefix = Keyword.get( options, :command_prefix ) || PdfGenerator.PathAgent.get |> Map.get( :command_prefix )

# allow for xvfb-run wkhtmltopdf arg1 arg2
# or sudo wkhtmltopdf ...
{ executable, arguments } =
case command_prefix do
nil -> { executable, arguments }
cmd -> { cmd, [executable] ++ arguments }
end

%Result{ out: _output, status: status, err: error } = Porcelain.exec(
executable, arguments, [in: "", out: :string, err: :string]
)

case status do
0 ->
0 ->
case Keyword.get options, :open_password do
nil -> { :ok, pdf_file }
user_pw -> encrypt_pdf(
pdf_file,
user_pw,
Keyword.get( options, :edit_password )
user_pw -> encrypt_pdf(
pdf_file,
user_pw,
Keyword.get( options, :edit_password )
)
end
_ -> { :error, "wkhtmltopdf returned with nonzero vaule. This is likely du to bad shell_params" }
_ -> { :error, error }
end
end

Expand Down
5 changes: 3 additions & 2 deletions lib/pdf_generator_path_agent.ex
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ defmodule PdfGenerator.PathAgent do
# options override system default paths
options =
[
wkhtml_path: System.find_executable( "wkhtmltopdf" ),
pdftk_path: System.find_executable( "pdftk" ),
wkhtml_path: System.find_executable( "wkhtmltopdf" ),
pdftk_path: System.find_executable( "pdftk" ),
# command_prefix: System.find_executable( "xvfb-run" )
]
++ paths_from_options
|> Enum.filter( fn { _, v } -> v != nil end )
Expand Down
4 changes: 2 additions & 2 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule PdfGenerator.Mixfile do
[
app: :pdf_generator,
name: "PDF Generator",
version: "0.3.1",
version: "0.3.2",
elixir: ">= 1.0.0",
deps: deps,
description: description,
Expand All @@ -27,7 +27,7 @@ defmodule PdfGenerator.Mixfile do

def description do
"""
A simple wrapper for wkhtmltopdf (HTML to PDF) and PDFTK (adds in encryption) for use in Elixir projects.
A wrapper for wkhtmltopdf (HTML to PDF) and PDFTK (adds in encryption) for use in Elixir projects.
"""
end

Expand Down
4 changes: 4 additions & 0 deletions test/pdf_generator_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,8 @@ defmodule PdfGeneratorTest do
assert String.slice( pdf, 0, 6) == "%PDF-1"
end

test "command prefix with noop env" do
{:ok, temp_filename } = PdfGenerator.generate @html, [ command_prefix: "env" ]
end

end

0 comments on commit d9a2456

Please sign in to comment.