Compare commits

...

20 Commits
6.1.2 ... 6.2.1

Author SHA1 Message Date
Julien Neuhart
876f0f9a14 Improving error message when the removing of a user profile directory fails 2020-05-01 15:14:42 +02:00
Julien Neuhart
f9f0fc1d67 Removing user profile directory when an Office conversion is over 2020-05-01 15:12:51 +02:00
Julien Neuhart
42e357341a Updating dependencies and fixing lint issues 2020-05-01 14:22:42 +02:00
Julien Neuhart
edc5402aad Adding new badge for Docker pulls in README 2020-05-01 14:22:10 +02:00
Julien Neuhart
3f61ffa6fb Updating CONTRIBUTING.md (Go version) + Rebuilding documentation 2020-05-01 13:08:53 +02:00
Julien Neuhart
1c22b889fe Merge branch 'master' of https://github.com/thecodingmachine/gotenberg 2020-05-01 12:58:15 +02:00
Julien Neuhart
e80f5939b2 Updating markdown files according to some users PRs 2020-05-01 12:58:11 +02:00
Julien Neuhart
c068088cc1 Merge pull request #182 from sdawka/patch-1
Update index.html
2020-05-01 12:53:07 +02:00
Julien Neuhart
1767f371f7 Merge branch 'master' of https://github.com/thecodingmachine/gotenberg 2020-05-01 12:52:14 +02:00
Julien Neuhart
5d5caf64fa Merge pull request #148 from thecodingmachine/bugfix/typo-in-readme
Fixing documentation typo
2020-05-01 12:52:06 +02:00
Julien Neuhart
e095b9419a Updating go version 2020-05-01 12:48:48 +02:00
Sahil Dawka
a5ef072f56 Update index.html 2020-03-18 17:26:22 -04:00
Julien Neuhart
5f6a2456d4 Merge pull request #177 from thecodingmachine/dependabot/go_modules/github.com/stretchr/testify-1.5.1
Bump github.com/stretchr/testify from 1.4.0 to 1.5.1
2020-03-06 14:01:58 +01:00
dependabot-preview[bot]
b0f24889f4 Bump github.com/stretchr/testify from 1.4.0 to 1.5.1
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.4.0 to 1.5.1.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.4.0...v1.5.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-06 08:44:44 +00:00
Julien Neuhart
0a69f0fd51 Merge pull request #176 from pgrimaud/master
Fix typo in README.md
2020-03-05 14:47:53 +01:00
Pierre Grimaud
43c0142682 Fix typo in README.md 2020-03-05 14:43:34 +01:00
Julien Neuhart
1ff16cc54b minor refactoring: using default scale from default options 2020-02-10 10:10:49 +01:00
Julien Neuhart
3609cf54c0 Merge pull request #168 from mdjward/feature/chrome-scaling-support
Add support for Chrome scaling.
2020-02-10 10:03:24 +01:00
Matt Ward
198038f5ea Add support for Chrome scaling. 2020-02-01 19:10:40 +00:00
David Négrier
9e9b369dc2 Fixing documentation typo
s/others/other/g
2019-11-20 19:03:17 +01:00
27 changed files with 247 additions and 155 deletions

View File

@@ -8,7 +8,7 @@ find below useful information about how to contribute to the Gotenberg project.
### Install from sources ### Install from sources
1. Install and run the latest version of Docker 1. Install and run the latest version of Docker
2. Verify your Go version (>= 1.13) 2. Verify your Go version (>= 1.14)
3. Fork this repository 3. Fork this repository
4. Clone it outside of your `GOPATH` (we're using Go modules) 4. Clone it outside of your `GOPATH` (we're using Go modules)

View File

@@ -1,13 +1,13 @@
GOLANG_VERSION=1.13 GOLANG_VERSION=1.14
VERSION=snapshot VERSION=snapshot
DOCKER_USER= DOCKER_USER=
DOCKER_PASSWORD= DOCKER_PASSWORD=
DOCKER_REGISTRY=thecodingmachine DOCKER_REGISTRY=thecodingmachine
GOTENBERG_USER_GID=1001 GOTENBERG_USER_GID=1001
GOTENBERG_USER_UID=1001 GOTENBERG_USER_UID=1001
GOLANGCI_LINT_VERSION=1.20.1 GOLANGCI_LINT_VERSION=1.25.1
CODE_COVERAGE=0 CODE_COVERAGE=0
TINI_VERSION=0.18.0 TINI_VERSION=0.19.0
MAXIMUM_WAIT_TIMEOUT=30.0 MAXIMUM_WAIT_TIMEOUT=30.0
MAXIMUM_WAIT_DELAY=10.0 MAXIMUM_WAIT_DELAY=10.0
MAXIMUM_WEBHOOK_URL_TIMEOUT=30.0 MAXIMUM_WEBHOOK_URL_TIMEOUT=30.0
@@ -36,7 +36,6 @@ fmt:
# run all linters. # run all linters.
lint: lint:
make workspace
docker build --build-arg GOLANGCI_LINT_VERSION=$(GOLANGCI_LINT_VERSION) -t $(DOCKER_REGISTRY)/gotenberg:lint -f build/lint/Dockerfile . docker build --build-arg GOLANGCI_LINT_VERSION=$(GOLANGCI_LINT_VERSION) -t $(DOCKER_REGISTRY)/gotenberg:lint -f build/lint/Dockerfile .
docker run --rm $(DOCKER_REGISTRY)/gotenberg:lint docker run --rm $(DOCKER_REGISTRY)/gotenberg:lint

View File

@@ -13,7 +13,7 @@ At TheCodingMachine, we build a lot of web applications (intranets, extranets an
* HTML and Markdown conversions using Google Chrome headless * HTML and Markdown conversions using Google Chrome headless
* Office conversions (.txt, .rtf, .docx, .doc, .odt, .pptx, .ppt, .odp and so on) using [unoconv](https://github.com/dagwieers/unoconv) * Office conversions (.txt, .rtf, .docx, .doc, .odt, .pptx, .ppt, .odp and so on) using [unoconv](https://github.com/dagwieers/unoconv)
* Assets :package:: send your header, footer, images, fonts, stylesheets and so on for converting your HTML and Markdown to beaufitul PDFs! * Assets :package:: send your header, footer, images, fonts, stylesheets and so on for converting your HTML and Markdown to beautiful PDFs!
* Easily interact with the API using our [Go](https://github.com/thecodingmachine/gotenberg-go-client) and [PHP](https://github.com/thecodingmachine/gotenberg-php-client) libraries * Easily interact with the API using our [Go](https://github.com/thecodingmachine/gotenberg-go-client) and [PHP](https://github.com/thecodingmachine/gotenberg-php-client) libraries
## Quick start ## Quick start
@@ -31,6 +31,7 @@ to learn how to interact with it!
## Badges ## Badges
[![Docker pulls](https://img.shields.io/docker/pulls/thecodingmachine/gotenberg)](https://hub.docker.com/r/thecodingmachine/gotenberg)
[![Docker image layers](https://images.microbadger.com/badges/image/thecodingmachine/gotenberg:6.svg)](https://microbadger.com/images/thecodingmachine/gotenberg:6) [![Docker image layers](https://images.microbadger.com/badges/image/thecodingmachine/gotenberg:6.svg)](https://microbadger.com/images/thecodingmachine/gotenberg:6)
[![Travis CI](https://travis-ci.org/thecodingmachine/gotenberg.svg?branch=master)](https://travis-ci.org/thecodingmachine/gotenberg) [![Travis CI](https://travis-ci.org/thecodingmachine/gotenberg.svg?branch=master)](https://travis-ci.org/thecodingmachine/gotenberg)
[![GoDoc](https://godoc.org/github.com/thecodingmachine/gotenberg?status.svg)](https://godoc.org/github.com/thecodingmachine/gotenberg) [![GoDoc](https://godoc.org/github.com/thecodingmachine/gotenberg?status.svg)](https://godoc.org/github.com/thecodingmachine/gotenberg)

View File

@@ -24,7 +24,7 @@ For instance:
```bash ```bash
$ git clone https://github.com/thecodingmachine/gotenberg.git $ git clone https://github.com/thecodingmachine/gotenberg.git
$ make publish GOTENBERG_USER_GID=your_custom_gid GOTENBERG_USER_UID=your_custom_uid DOCKER_REGISTRY=your_registry DOCKER_USER=registry_user DOCKER_PASSWORD=registry_password VERSION=6.1.0 $ make publish GOTENBERG_USER_GID=your_custom_gid GOTENBERG_USER_UID=your_custom_uid DOCKER_REGISTRY=your_registry DOCKER_USER=registry_user DOCKER_PASSWORD=registry_password VERSION=6.2.0
``` ```
> `master` branch is always up-to-date with the latest version of the API. > `master` branch is always up-to-date with the latest version of the API.
@@ -38,7 +38,7 @@ version: '3'
services: services:
# your others services # your other services
gotenberg: gotenberg:
image: thecodingmachine/gotenberg:6 image: thecodingmachine/gotenberg:6
@@ -65,6 +65,7 @@ securityContext:
## Cloud Run (Google Cloud) ## Cloud Run (Google Cloud)
If you're looking for cost savings, you might be interested by [Cloud Run](https://cloud.google.com/run). If you're looking for cost savings, you might be interested by [Cloud Run](https://cloud.google.com/run).
However, according to some users, doing asynchronous conversion (with a webhook) might not working.
In the following examples, we will assume your In the following examples, we will assume your
Gotenberg API is available at [http://localhost:3000](http://localhost:3000). Gotenberg API is available at [http://localhost:3000](http://localhost:3000).

View File

@@ -157,7 +157,7 @@ You may also send additional files. For instance: images, fonts, stylesheets and
The only requirement is to make sure that their paths The only requirement is to make sure that their paths
are on the same level as the `index.html` file. are on the same level as the `index.html` file.
In others words, this will work: In other words, this will work:
```html ```html
<!doctype html> <!doctype html>
@@ -243,11 +243,11 @@ $dest = 'result.pdf';
$client->store($request, $dest); $client->store($request, $dest);
``` ```
## Paper size, margins, orientation ## Paper size, margins, orientation, scaling
You may also customize the resulting PDF format. You may also customize the resulting PDF format.
By default, it will be rendered with `A4` size, `1 inch` margins and `portrait` orientation. By default, it will be rendered with `A4` size, `1 inch` margins and `portrait` orientation and 100% (`1.0`) page scale.
> Paper size and margins have to be provided in `inches`. Same for margins. > Paper size and margins have to be provided in `inches`. Same for margins.
@@ -265,6 +265,7 @@ $ curl --request POST \
--form marginLeft=0 \ --form marginLeft=0 \
--form marginRight=0 \ --form marginRight=0 \
--form landscape=true \ --form landscape=true \
--form scale=0.75 \
-o result.pdf -o result.pdf
``` ```
@@ -279,6 +280,7 @@ req := gotenberg.NewHTMLRequest(index)
req.PaperSize(gotenberg.A4) req.PaperSize(gotenberg.A4)
req.Margins(gotenberg.NoMargins) req.Margins(gotenberg.NoMargins)
req.Landscape(true) req.Landscape(true)
req.Scale(0.75)
dest := "result.pdf" dest := "result.pdf"
c.Store(req, dest) c.Store(req, dest)
``` ```
@@ -297,6 +299,7 @@ $request = new HTMLRequest($index);
$request->setPaperSize(Request::A4); $request->setPaperSize(Request::A4);
$request->setMargins(Request::NO_MARGINS); $request->setMargins(Request::NO_MARGINS);
$request->setLandscape(true); $request->setLandscape(true);
$request->setScale(0.75);
$dest = 'result.pdf'; $dest = 'result.pdf';
$client->store($request, $dest); $client->store($request, $dest);
``` ```

View File

@@ -37,7 +37,7 @@ version: '3'
services: services:
# your others services # your other services
gotenberg: gotenberg:
image: thecodingmachine/gotenberg:6 image: thecodingmachine/gotenberg:6

View File

@@ -1,17 +1,6 @@
FROM thecodingmachine/gotenberg:workspace
# |--------------------------------------------------------------------------
# | GolangCI-Lint
# |--------------------------------------------------------------------------
# |
# | Installs GolangCI-Lint, a linters Runner for Go. 5x faster
# | than gometalinter.
# |
ARG GOLANGCI_LINT_VERSION ARG GOLANGCI_LINT_VERSION
RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b /usr/local/bin v${GOLANGCI_LINT_VERSION} &&\ FROM golangci/golangci-lint:v$GOLANGCI_LINT_VERSION
golangci-lint --version
# |-------------------------------------------------------------------------- # |--------------------------------------------------------------------------
# | Final touch # | Final touch
@@ -21,16 +10,13 @@ RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.s
# | # |
# Define our working directory outside of $GOPATH (we're using go modules). # Define our working directory outside of $GOPATH (we're using go modules).
USER gotenberg
WORKDIR /gotenberg/lint WORKDIR /gotenberg/lint
# Install module dependencies. # Copy our code source.
COPY --chown=gotenberg:gotenberg go.mod go.sum ./ COPY . .
# Install module dependencies.
RUN go mod download &&\ RUN go mod download &&\
go mod verify go mod verify
# Copy our code source. CMD ["golangci-lint", "run" ,"--tests=false", "--enable-all", "--disable=dupl", "--disable=funlen", "--disable=wsl", "--disable=gocognit", "--disable=gomnd" ]
COPY --chown=gotenberg:gotenberg . .
CMD ["golangci-lint", "run" ,"--tests=false", "--enable-all", "--disable=dupl", "--disable=funlen", "--disable=wsl", "--disable=gocognit" ]

View File

@@ -24,8 +24,8 @@ func main() {
if err != nil { if err != nil {
systemLogger.FatalOp(op, err) systemLogger.FatalOp(op, err)
} }
systemLogger.InfofOp(op, "Gotenberg %s", version) systemLogger.InfoOpf(op, "Gotenberg %s", version)
systemLogger.DebugfOp(op, "configuration: %+v", config) systemLogger.DebugOpf(op, "configuration: %+v", config)
if !config.DisableGoogleChrome() { if !config.DisableGoogleChrome() {
// start Google Chrome headless. // start Google Chrome headless.
if err := chrome.Start(systemLogger); err != nil { if err := chrome.Start(systemLogger); err != nil {
@@ -36,7 +36,7 @@ func main() {
srv := xhttp.New(config) srv := xhttp.New(config)
// run our API in a goroutine so that it doesn't block. // run our API in a goroutine so that it doesn't block.
go func() { go func() {
systemLogger.InfofOp(op, "http server started on port '%d'", config.DefaultListenPort()) systemLogger.InfoOpf(op, "http server started on port '%d'", config.DefaultListenPort())
if err := srv.Start(fmt.Sprintf(":%d", config.DefaultListenPort())); err != nil { if err := srv.Start(fmt.Sprintf(":%d", config.DefaultListenPort())); err != nil {
if err != http.ErrServerClosed { if err != http.ErrServerClosed {
systemLogger.FatalOp(op, err) systemLogger.FatalOp(op, err)

View File

@@ -154,7 +154,7 @@
<p>For instance:</p> <p>For instance:</p>
<pre class="chroma">$ git clone https://github.com/thecodingmachine/gotenberg.git <pre class="chroma">$ git clone https://github.com/thecodingmachine/gotenberg.git
$ make publish <span class="nv">GOTENBERG_USER_GID</span><span class="o">=</span>your_custom_gid <span class="nv">GOTENBERG_USER_UID</span><span class="o">=</span>your_custom_uid <span class="nv">DOCKER_REGISTRY</span><span class="o">=</span>your_registry <span class="nv">DOCKER_USER</span><span class="o">=</span>registry_user <span class="nv">DOCKER_PASSWORD</span><span class="o">=</span>registry_password <span class="nv">VERSION</span><span class="o">=</span>6.1.0 $ make publish <span class="nv">GOTENBERG_USER_GID</span><span class="o">=</span>your_custom_gid <span class="nv">GOTENBERG_USER_UID</span><span class="o">=</span>your_custom_uid <span class="nv">DOCKER_REGISTRY</span><span class="o">=</span>your_registry <span class="nv">DOCKER_USER</span><span class="o">=</span>registry_user <span class="nv">DOCKER_PASSWORD</span><span class="o">=</span>registry_password <span class="nv">VERSION</span><span class="o">=</span>6.2.0
</pre> </pre>
<blockquote> <blockquote>
@@ -171,7 +171,7 @@ $ make publish <span class="nv">GOTENBERG_USER_GID</span><span class="o">=</span
</span><span class="w"> </span><span class="w">
</span><span class="w"></span><span class="k">services</span><span class="p">:</span><span class="w"> </span><span class="w"></span><span class="k">services</span><span class="p">:</span><span class="w">
</span><span class="w"> </span><span class="w">
</span><span class="w"> </span><span class="c"># your others services</span><span class="w"> </span><span class="w"> </span><span class="c"># your other services</span><span class="w">
</span><span class="w"> </span><span class="w">
</span><span class="w"> </span><span class="k">gotenberg</span><span class="p">:</span><span class="w"> </span><span class="w"> </span><span class="k">gotenberg</span><span class="p">:</span><span class="w">
</span><span class="w"> </span><span class="k">image</span><span class="p">:</span><span class="w"> </span>thecodingmachine/gotenberg<span class="p">:</span><span class="m">6</span><span class="w"> </span><span class="w"> </span><span class="k">image</span><span class="p">:</span><span class="w"> </span>thecodingmachine/gotenberg<span class="p">:</span><span class="m">6</span><span class="w">
@@ -204,7 +204,8 @@ $ make publish <span class="nv">GOTENBERG_USER_GID</span><span class="o">=</span
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>
</a>Cloud Run (Google Cloud)</h2> </a>Cloud Run (Google Cloud)</h2>
<p>If youre looking for cost savings, you might be interested by <a href="https://cloud.google.com/run">Cloud Run</a>.</p> <p>If youre looking for cost savings, you might be interested by <a href="https://cloud.google.com/run">Cloud Run</a>.
However, according to some users, doing asynchronous conversion (with a webhook) might not working.</p>
<p>In the following examples, we will assume your <p>In the following examples, we will assume your
Gotenberg API is available at <a href="http://localhost:3000">http://localhost:3000</a>.</p> Gotenberg API is available at <a href="http://localhost:3000">http://localhost:3000</a>.</p>
@@ -586,7 +587,7 @@ $client-&gt;store($request, $dest);
<p>The only requirement is to make sure that their paths <p>The only requirement is to make sure that their paths
are on the same level as the <code>index.html</code> file.</p> are on the same level as the <code>index.html</code> file.</p>
<p>In others words, this will work:</p> <p>In other words, this will work:</p>
<pre class="chroma"><span class="cp">&lt;!doctype html&gt;</span> <pre class="chroma"><span class="cp">&lt;!doctype html&gt;</span>
<span class="p">&lt;</span><span class="nt">html</span> <span class="na">lang</span><span class="o">=</span><span class="s">&#34;en&#34;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">html</span> <span class="na">lang</span><span class="o">=</span><span class="s">&#34;en&#34;</span><span class="p">&gt;</span>
@@ -675,19 +676,19 @@ $dest = &#39;result.pdf&#39;;
$client-&gt;store($request, $dest); $client-&gt;store($request, $dest);
</pre> </pre>
<h2 class="Heading"><a class="Anchor" aria-hidden="true" id="html.paper_size_margins_orientation" href="#html.paper_size_margins_orientation"> <h2 class="Heading"><a class="Anchor" aria-hidden="true" id="html.paper_size_margins_orientation_scaling" href="#html.paper_size_margins_orientation_scaling">
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>
</a>Paper size, margins, orientation</h2> </a>Paper size, margins, orientation, scaling</h2>
<p>You may also customize the resulting PDF format.</p> <p>You may also customize the resulting PDF format.</p>
<p>By default, it will be rendered with <code>A4</code> size, <code>1 inch</code> margins and <code>portrait</code> orientation.</p> <p>By default, it will be rendered with <code>A4</code> size, <code>1 inch</code> margins and <code>portrait</code> orientation and 100% (<code>1.0</code>) page scale.</p>
<blockquote> <blockquote>
<p>Paper size and margins have to be provided in <code>inches</code>. Same for margins.</p> <p>Paper size and margins have to be provided in <code>inches</code>. Same for margins.</p>
</blockquote> </blockquote>
<h3 class="Heading"><a class="Anchor" aria-hidden="true" id="html.paper_size_margins_orientation.c_url" href="#html.paper_size_margins_orientation.c_url"> <h3 class="Heading"><a class="Anchor" aria-hidden="true" id="html.paper_size_margins_orientation_scaling.c_url" href="#html.paper_size_margins_orientation_scaling.c_url">
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>
</a>cURL</h3> </a>cURL</h3>
@@ -702,10 +703,11 @@ $client-&gt;store($request, $dest);
</span><span class="se"></span> --form <span class="nv">marginLeft</span><span class="o">=</span><span class="m">0</span> <span class="se">\ </span><span class="se"></span> --form <span class="nv">marginLeft</span><span class="o">=</span><span class="m">0</span> <span class="se">\
</span><span class="se"></span> --form <span class="nv">marginRight</span><span class="o">=</span><span class="m">0</span> <span class="se">\ </span><span class="se"></span> --form <span class="nv">marginRight</span><span class="o">=</span><span class="m">0</span> <span class="se">\
</span><span class="se"></span> --form <span class="nv">landscape</span><span class="o">=</span><span class="nb">true</span> <span class="se">\ </span><span class="se"></span> --form <span class="nv">landscape</span><span class="o">=</span><span class="nb">true</span> <span class="se">\
</span><span class="se"></span> --form <span class="nv">scale</span><span class="o">=</span>0.75 <span class="se">\
</span><span class="se"></span> -o result.pdf </span><span class="se"></span> -o result.pdf
</pre> </pre>
<h3 class="Heading"><a class="Anchor" aria-hidden="true" id="html.paper_size_margins_orientation.go" href="#html.paper_size_margins_orientation.go"> <h3 class="Heading"><a class="Anchor" aria-hidden="true" id="html.paper_size_margins_orientation_scaling.go" href="#html.paper_size_margins_orientation_scaling.go">
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>
</a>Go</h3> </a>Go</h3>
@@ -717,11 +719,12 @@ $client-&gt;store($request, $dest);
<span class="nx">req</span><span class="p">.</span><span class="nf">PaperSize</span><span class="p">(</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">A4</span><span class="p">)</span> <span class="nx">req</span><span class="p">.</span><span class="nf">PaperSize</span><span class="p">(</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">A4</span><span class="p">)</span>
<span class="nx">req</span><span class="p">.</span><span class="nf">Margins</span><span class="p">(</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">NoMargins</span><span class="p">)</span> <span class="nx">req</span><span class="p">.</span><span class="nf">Margins</span><span class="p">(</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">NoMargins</span><span class="p">)</span>
<span class="nx">req</span><span class="p">.</span><span class="nf">Landscape</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span> <span class="nx">req</span><span class="p">.</span><span class="nf">Landscape</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
<span class="nx">req</span><span class="p">.</span><span class="nf">Scale</span><span class="p">(</span><span class="mf">0.75</span><span class="p">)</span>
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">&#34;result.pdf&#34;</span> <span class="nx">dest</span> <span class="o">:=</span> <span class="s">&#34;result.pdf&#34;</span>
<span class="nx">c</span><span class="p">.</span><span class="nf">Store</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">dest</span><span class="p">)</span> <span class="nx">c</span><span class="p">.</span><span class="nf">Store</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">dest</span><span class="p">)</span>
</pre> </pre>
<h3 class="Heading"><a class="Anchor" aria-hidden="true" id="html.paper_size_margins_orientation.php" href="#html.paper_size_margins_orientation.php"> <h3 class="Heading"><a class="Anchor" aria-hidden="true" id="html.paper_size_margins_orientation_scaling.php" href="#html.paper_size_margins_orientation_scaling.php">
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>
</a>PHP</h3> </a>PHP</h3>
@@ -736,6 +739,7 @@ $request = new HTMLRequest($index);
$request-&gt;setPaperSize(Request::A4); $request-&gt;setPaperSize(Request::A4);
$request-&gt;setMargins(Request::NO_MARGINS); $request-&gt;setMargins(Request::NO_MARGINS);
$request-&gt;setLandscape(true); $request-&gt;setLandscape(true);
$request-&gt;setScale(0.75);
$dest = &#39;result.pdf&#39;; $dest = &#39;result.pdf&#39;;
$client-&gt;store($request, $dest); $client-&gt;store($request, $dest);
</pre> </pre>
@@ -1700,7 +1704,7 @@ if the API is under heavy load.</p>
</span><span class="w"> </span><span class="w">
</span><span class="w"></span><span class="k">services</span><span class="p">:</span><span class="w"> </span><span class="w"></span><span class="k">services</span><span class="p">:</span><span class="w">
</span><span class="w"> </span><span class="w">
</span><span class="w"> </span><span class="c"># your others services</span><span class="w"> </span><span class="w"> </span><span class="c"># your other services</span><span class="w">
</span><span class="w"> </span><span class="w">
</span><span class="w"> </span><span class="k">gotenberg</span><span class="p">:</span><span class="w"> </span><span class="w"> </span><span class="k">gotenberg</span><span class="p">:</span><span class="w">
</span><span class="w"> </span><span class="k">image</span><span class="p">:</span><span class="w"> </span>thecodingmachine/gotenberg<span class="p">:</span><span class="m">6</span><span class="w"> </span><span class="w"> </span><span class="k">image</span><span class="p">:</span><span class="w"> </span>thecodingmachine/gotenberg<span class="p">:</span><span class="m">6</span><span class="w">

33
go.mod
View File

@@ -1,30 +1,27 @@
module github.com/thecodingmachine/gotenberg module github.com/thecodingmachine/gotenberg
go 1.13 go 1.14
require ( require (
github.com/dustin/go-humanize v1.0.0 github.com/dustin/go-humanize v1.0.0
github.com/google/go-cmp v0.3.1 // indirect github.com/konsorten/go-windows-terminal-sequences v1.0.3 // indirect
github.com/gorilla/websocket v1.4.1 // indirect github.com/kr/text v0.2.0 // indirect
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect github.com/labstack/echo/v4 v4.1.16
github.com/kr/pretty v0.1.0 // indirect
github.com/labstack/echo/v4 v4.1.11
github.com/labstack/gommon v0.3.0 github.com/labstack/gommon v0.3.0
github.com/mafredri/cdp v0.25.0 github.com/mafredri/cdp v0.28.0
github.com/mattn/go-colorable v0.1.4 // indirect github.com/mattn/go-isatty v0.0.12
github.com/mattn/go-isatty v0.0.11
github.com/microcosm-cc/bluemonday v1.0.2 github.com/microcosm-cc/bluemonday v1.0.2
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2
github.com/russross/blackfriday/v2 v2.0.1 github.com/russross/blackfriday/v2 v2.0.1
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
github.com/sirupsen/logrus v1.4.2 github.com/sirupsen/logrus v1.5.0
github.com/stretchr/testify v1.4.0 github.com/stretchr/testify v1.5.1
github.com/valyala/fasttemplate v1.1.0 // indirect golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79 // indirect
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 // indirect golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5 // indirect
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 // indirect golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e golang.org/x/sys v0.0.0-20200501052902-10377860bb8e // indirect
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449 // indirect
golang.org/x/text v0.3.2 golang.org/x/text v0.3.2
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/yaml.v2 v2.2.7 // indirect gopkg.in/yaml.v2 v2.2.8 // indirect
) )

96
go.sum
View File

@@ -1,41 +1,40 @@
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/labstack/echo/v4 v4.1.11 h1:z0BZoArY4FqdpUEl+wlHp4hnr/oSR6MTmQmv8OHSoww= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/labstack/echo/v4 v4.1.16 h1:8swiwjE5Jkai3RPfZoahp8kjVCRNq+y7Q0hPji2Kz0o=
github.com/labstack/echo/v4 v4.1.16/go.mod h1:awO+5TzAjvL8XpibdsfXxPgHr+orhtXZJZIQCVjogKI=
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0= github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/mafredri/cdp v0.25.0 h1:nXhdpjP8Nrhw+9jnMlljEF6xs2B3vXI/wSiKDOvOXGs= github.com/mafredri/cdp v0.28.0 h1:v/LWC3GpactA1EaS737bl+eNUhvOaDh+FzvyoDxNM5o=
github.com/mafredri/cdp v0.25.0/go.mod h1:hgdiA0yp1uqhSaDOHJWPgXpMbh+LAfUdD9vbN2AM8gE= github.com/mafredri/cdp v0.28.0/go.mod h1:11586MgpyJuQR4qiXQ/7HBame2FtGIBzymaUHZcQ0PY=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= github.com/mafredri/go-lint v0.0.0-20180911205320-920981dfc79e/go.mod h1:k/zdyxI3q6dup24o8xpYjJKTCf2F7rfxLp6w/efTiWs=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/microcosm-cc/bluemonday v1.0.2 h1:5lPfLTTAvAbtS0VqT+94yOtFnGfUWYyx0+iToC3Os3s= github.com/microcosm-cc/bluemonday v1.0.2 h1:5lPfLTTAvAbtS0VqT+94yOtFnGfUWYyx0+iToC3Os3s=
github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc=
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -44,47 +43,58 @@ github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/valyala/fasttemplate v1.1.0 h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy1Ocw4= github.com/valyala/fasttemplate v1.1.0 h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy1Ocw4=
github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g= golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79 h1:IaQbIIB2X/Mp/DKctl6ROxz1KyMlKp4uyvL6+kQ7C88=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5 h1:WQ8q63x+f/zpC8Ac1s9wLElVoHhm32p6tudrU72n1QA=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a h1:WXEvlFVvvGxCJLG6REjsT03iWnKLEWinaScsxF2Vm2o=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449 h1:gSbV7h1NRL2G1xTg/owz62CST1oJBmxy4QpMMregXVQ= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e h1:hq86ru83GdWTlfQFZGO4nZJTU4Bs2wfHl8oFHRaXsfc=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200330183114-f8bfb4ee3038/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@@ -239,13 +239,13 @@ func convert(ctx context.Context, p printer.Printer) error {
// and directly return the resulting PDF file // and directly return the resulting PDF file
// or an error. // or an error.
if !r.HasArg(resource.WebhookURLArgKey) { if !r.HasArg(resource.WebhookURLArgKey) {
logger.DebugfOp(op, "no '%s' found, converting synchronously", resource.WebhookURLArgKey) logger.DebugOpf(op, "no '%s' found, converting synchronously", resource.WebhookURLArgKey)
return convertSync(ctx, p, filename, fpath) return convertSync(ctx, p, filename, fpath)
} }
// as a webhook URL has been given, we // as a webhook URL has been given, we
// run the following lines in a goroutine so that // run the following lines in a goroutine so that
// it doesn't block. // it doesn't block.
logger.DebugfOp(op, "'%s' found, converting asynchronously", resource.WebhookURLArgKey) logger.DebugOpf(op, "'%s' found, converting asynchronously", resource.WebhookURLArgKey)
return convertAsync(ctx, p, filename, fpath) return convertAsync(ctx, p, filename, fpath)
} }
if err := resolver(); err != nil { if err := resolver(); err != nil {
@@ -264,7 +264,7 @@ func convertSync(ctx context.Context, p printer.Printer, filename, fpath string)
return err return err
} }
if !r.HasArg(resource.ResultFilenameArgKey) { if !r.HasArg(resource.ResultFilenameArgKey) {
logger.DebugfOp( logger.DebugOpf(
op, op,
"no '%s' found, using generated filename '%s'", "no '%s' found, using generated filename '%s'",
resource.RemoteURLArgKey, resource.RemoteURLArgKey,
@@ -275,7 +275,7 @@ func convertSync(ctx context.Context, p printer.Printer, filename, fpath string)
} }
return nil return nil
} }
logger.DebugfOp( logger.DebugOpf(
op, op,
"'%s' found, so not using generated filename", "'%s' found, so not using generated filename",
resource.ResultFilenameArgKey, resource.ResultFilenameArgKey,
@@ -321,7 +321,7 @@ func convertAsync(ctx context.Context, p printer.Printer, filename, fpath string
return return
} }
defer f.Close() // nolint: errcheck defer f.Close() // nolint: errcheck
logger.DebugfOp( logger.DebugOpf(
op, op,
"preparing to send result file '%s' to '%s'...", "preparing to send result file '%s' to '%s'...",
filename, filename,
@@ -342,13 +342,13 @@ func convertAsync(ctx context.Context, p printer.Printer, filename, fpath string
if len(customHTTPHeaders) > 0 { if len(customHTTPHeaders) > 0 {
for key, value := range customHTTPHeaders { for key, value := range customHTTPHeaders {
req.Header.Set(key, value) req.Header.Set(key, value)
logger.DebugfOp(op, "set '%s' to custom HTTP header '%s'", value, key) logger.DebugOpf(op, "set '%s' to custom HTTP header '%s'", value, key)
} }
} else { } else {
logger.DebugOp(op, "skipping custom HTTP headers as none have been provided...") logger.DebugOp(op, "skipping custom HTTP headers as none have been provided...")
} }
// send the result file. // send the result file.
logger.DebugfOp( logger.DebugOpf(
op, op,
"sending result file '%s' to '%s'...", "sending result file '%s' to '%s'...",
filename, filename,
@@ -361,7 +361,7 @@ func convertAsync(ctx context.Context, p printer.Printer, filename, fpath string
return return
} }
defer resp.Body.Close() // nolint: errcheck defer resp.Body.Close() // nolint: errcheck
logger.DebugfOp( logger.DebugOpf(
op, op,
"result file '%s' sent to '%s'", "result file '%s' sent to '%s'",
filename, filename,

View File

@@ -56,6 +56,10 @@ func chromePrinterOptions(r resource.Resource, config conf.Config) (printer.Chro
if err != nil { if err != nil {
return printer.ChromePrinterOptions{}, err return printer.ChromePrinterOptions{}, err
} }
scale, err := resource.ScaleArg(r, config)
if err != nil {
return printer.ChromePrinterOptions{}, err
}
return printer.ChromePrinterOptions{ return printer.ChromePrinterOptions{
WaitTimeout: waitTimeout, WaitTimeout: waitTimeout,
WaitDelay: waitDelay, WaitDelay: waitDelay,
@@ -71,6 +75,7 @@ func chromePrinterOptions(r resource.Resource, config conf.Config) (printer.Chro
PageRanges: pageRanges, PageRanges: pageRanges,
RpccBufferSize: googleChromeRpccBufferSize, RpccBufferSize: googleChromeRpccBufferSize,
CustomHTTPHeaders: make(map[string]string), CustomHTTPHeaders: make(map[string]string),
Scale: scale,
}, nil }, nil
} }
opts, err := resolver() opts, err := resolver()

View File

@@ -167,14 +167,14 @@ func (ctx Context) LogRequestResult(err error, isDebug bool) error {
"bytes_out": bytesOut(resp), "bytes_out": bytesOut(resp),
} }
if err != nil { if err != nil {
ctx.logger.WithFields(fields).ErrorfOp(op, "request failed") ctx.logger.WithFields(fields).ErrorOpf(op, "request failed")
return err return err
} }
if isDebug { if isDebug {
ctx.logger.WithFields(fields).DebugfOp(op, "request handled") ctx.logger.WithFields(fields).DebugOpf(op, "request handled")
return nil return nil
} }
ctx.logger.WithFields(fields).InfofOp(op, "request handled") ctx.logger.WithFields(fields).InfoOpf(op, "request handled")
return nil return nil
} }

View File

@@ -57,6 +57,9 @@ const (
// GoogleChromeRpccBufferSizeArgKey is the key // GoogleChromeRpccBufferSizeArgKey is the key
// of the argument "googleChromeRpccBufferSize". // of the argument "googleChromeRpccBufferSize".
GoogleChromeRpccBufferSizeArgKey ArgKey = "googleChromeRpccBufferSize" GoogleChromeRpccBufferSizeArgKey ArgKey = "googleChromeRpccBufferSize"
// ScaleArgKey is the key
// of the argument "scale".
ScaleArgKey ArgKey = "scale"
) )
/* /*
@@ -81,6 +84,7 @@ func ArgKeys() []ArgKey {
LandscapeArgKey, LandscapeArgKey,
PageRangesArgKey, PageRangesArgKey,
GoogleChromeRpccBufferSizeArgKey, GoogleChromeRpccBufferSizeArgKey,
ScaleArgKey,
} }
} }
@@ -294,3 +298,22 @@ func GoogleChromeRpccBufferSizeArg(r Resource, config conf.Config) (int64, error
} }
return result, nil return result, nil
} }
/*
ScaleArg is a helper for retrieving
the "scale" argument as float64.
*/
func ScaleArg(r Resource, config conf.Config) (float64, error) {
const op string = "resource.ScaleArg"
opts := printer.DefaultChromePrinterOptions(config)
result, err := r.Float64Arg(
ScaleArgKey,
opts.Scale,
xassert.Float64NotInferiorTo(0.1),
xassert.Float64NotSuperiorTo(2.0),
)
if err != nil {
return result, xerror.New(op, err)
}
return result, nil
}

View File

@@ -26,6 +26,7 @@ func TestArgKeys(t *testing.T) {
LandscapeArgKey, LandscapeArgKey,
PageRangesArgKey, PageRangesArgKey,
GoogleChromeRpccBufferSizeArgKey, GoogleChromeRpccBufferSizeArgKey,
ScaleArgKey,
} }
assert.Equal(t, expected, ArgKeys()) assert.Equal(t, expected, ArgKeys())
} }
@@ -346,3 +347,50 @@ func TestGoogleChromeRpccBufferSizeArg(t *testing.T) {
err = r.Close() err = r.Close()
assert.Nil(t, err) assert.Nil(t, err)
} }
func TestScaleArg(t *testing.T) {
const (
resourceDirectoryName string = "foo"
defaultValue float64 = 1.0
)
var expected float64
logger := test.DebugLogger()
config := conf.DefaultConfig()
r, err := New(logger, resourceDirectoryName)
assert.Nil(t, err)
// argument does not exist.
expected = defaultValue
v, err := ScaleArg(r, config)
assert.Nil(t, err)
assert.Equal(t, expected, v)
// argument exist.
expected = 0.5
r.WithArg(ScaleArgKey, "0.5")
v, err = ScaleArg(r, config)
assert.Nil(t, err)
assert.Equal(t, expected, v)
// should not be OK as argument
// value is < 0.1.
expected = defaultValue
r.WithArg(ScaleArgKey, "-1.0")
v, err = ScaleArg(r, config)
test.AssertError(t, err)
assert.Equal(t, expected, v)
// should not be OK as argument
// value is > 2.0.
expected = defaultValue
r.WithArg(ScaleArgKey, "2.1")
v, err = ScaleArg(r, config)
test.AssertError(t, err)
assert.Equal(t, expected, v)
// should not be OK as
// argument value is invalid.
expected = defaultValue
r.WithArg(ScaleArgKey, "foo")
v, err = ScaleArg(r, config)
test.AssertError(t, err)
assert.Equal(t, expected, v)
// finally...
err = r.Close()
assert.Nil(t, err)
}

View File

@@ -25,7 +25,7 @@ func (f file) write(in io.Reader) error {
return err return err
} }
defer out.Close() // nolint: errcheck defer out.Close() // nolint: errcheck
if err := out.Chmod(0644); err != nil { if err := out.Chmod(0600); err != nil {
return err return err
} }
if _, err := io.Copy(out, in); err != nil { if _, err := io.Copy(out, in); err != nil {

View File

@@ -50,7 +50,7 @@ func New(logger xlog.Logger, directoryName string) (Resource, error) {
if err != nil { if err != nil {
return Resource{}, xerror.New(op, err) return Resource{}, xerror.New(op, err)
} }
logger.DebugfOp(op, "resource directory '%s' created", directoryName) logger.DebugOpf(op, "resource directory '%s' created", directoryName)
return Resource{ return Resource{
logger: logger, logger: logger,
dirPath: dirPath, dirPath: dirPath,
@@ -65,13 +65,13 @@ func New(logger xlog.Logger, directoryName string) (Resource, error) {
func (r Resource) Close() error { func (r Resource) Close() error {
const op string = "resource.Resource.Close" const op string = "resource.Resource.Close"
if _, err := os.Stat(r.dirPath); os.IsNotExist(err) { if _, err := os.Stat(r.dirPath); os.IsNotExist(err) {
r.logger.DebugfOp(op, "resource directory '%s' does not exist, nothing to remove", r.dirPath) r.logger.DebugOpf(op, "resource directory '%s' does not exist, nothing to remove", r.dirPath)
return nil return nil
} }
if err := os.RemoveAll(r.dirPath); err != nil { if err := os.RemoveAll(r.dirPath); err != nil {
return xerror.New(op, err) return xerror.New(op, err)
} }
r.logger.DebugfOp(op, "resource directory '%s' removed", r.dirPath) r.logger.DebugOpf(op, "resource directory '%s' removed", r.dirPath)
return nil return nil
} }
@@ -84,17 +84,17 @@ func (r *Resource) WithCustomHTTPHeader(key string, value string) {
if strings.Contains(canonicalKey, RemoteURLCustomHTTPHeaderCanonicalBaseKey) || if strings.Contains(canonicalKey, RemoteURLCustomHTTPHeaderCanonicalBaseKey) ||
strings.Contains(canonicalKey, WebhookURLCustomHTTPHeaderCanonicalBaseKey) { strings.Contains(canonicalKey, WebhookURLCustomHTTPHeaderCanonicalBaseKey) {
r.customHeaders[canonicalKey] = value r.customHeaders[canonicalKey] = value
r.logger.DebugfOp(op, "added '%s' with value '%s' to resource custom HTTP headers", canonicalKey, value) r.logger.DebugOpf(op, "added '%s' with value '%s' to resource custom HTTP headers", canonicalKey, value)
return return
} }
r.logger.DebugfOp(op, "skipping '%s' as it is not a custom HTTP header...", canonicalKey) r.logger.DebugOpf(op, "skipping '%s' as it is not a custom HTTP header...", canonicalKey)
} }
// WithArg add a new argument to the Resource. // WithArg add a new argument to the Resource.
func (r *Resource) WithArg(key ArgKey, value string) { func (r *Resource) WithArg(key ArgKey, value string) {
const op string = "resource.Resource.WithArg" const op string = "resource.Resource.WithArg"
r.args[key] = value r.args[key] = value
r.logger.DebugfOp(op, "added '%s' with value '%s' to resource args", key, value) r.logger.DebugOpf(op, "added '%s' with value '%s' to resource args", key, value)
} }
// WithFile add a new file to the Resource. // WithFile add a new file to the Resource.
@@ -112,7 +112,7 @@ func (r *Resource) WithFile(filename string, in io.Reader) error {
return err return err
} }
r.files[filename] = file r.files[filename] = file
r.logger.DebugfOp(op, "resource file '%s' created", filename) r.logger.DebugOpf(op, "resource file '%s' created", filename)
return nil return nil
} }
if err := resolver(); err != nil { if err := resolver(); err != nil {

View File

@@ -132,21 +132,21 @@ func isViable(logger xlog.Logger) bool {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()
endpoint := "http://localhost:9222" endpoint := "http://localhost:9222"
logger.DebugfOp( logger.DebugOpf(
op, op,
"checking Google Chrome headless process viability via endpoint '%s/json/version'", "checking Google Chrome headless process viability via endpoint '%s/json/version'",
endpoint, endpoint,
) )
v, err := devtool.New(endpoint).Version(ctx) v, err := devtool.New(endpoint).Version(ctx)
if err != nil { if err != nil {
logger.DebugfOp( logger.DebugOpf(
op, op,
"Google Chrome headless is not viable as endpoint returned '%v'", "Google Chrome headless is not viable as endpoint returned '%v'",
err.Error(), err.Error(),
) )
return false return false
} }
logger.DebugfOp( logger.DebugOpf(
op, op,
"Google Chrome headless is viable as endpoint returned '%v'", "Google Chrome headless is viable as endpoint returned '%v'",
v, v,
@@ -162,9 +162,12 @@ func isViable(logger xlog.Logger) bool {
} }
func warmup(logger xlog.Logger) { func warmup(logger xlog.Logger) {
const op string = "chrome.warmup" const (
warmupTime := xtime.Duration(0.5) op string = "chrome.warmup"
logger.DebugfOp( seconds float64 = 0.5
)
warmupTime := xtime.Duration(seconds)
logger.DebugOpf(
op, op,
"waiting '%v' for allowing Google Chrome to warmup", "waiting '%v' for allowing Google Chrome to warmup",
warmupTime, warmupTime,

View File

@@ -45,6 +45,7 @@ type ChromePrinterOptions struct {
PageRanges string PageRanges string
RpccBufferSize int64 RpccBufferSize int64
CustomHTTPHeaders map[string]string CustomHTTPHeaders map[string]string
Scale float64
} }
// DefaultChromePrinterOptions returns the default // DefaultChromePrinterOptions returns the default
@@ -66,6 +67,7 @@ func DefaultChromePrinterOptions(config conf.Config) ChromePrinterOptions {
PageRanges: "", PageRanges: "",
RpccBufferSize: config.DefaultGoogleChromeRpccBufferSize(), RpccBufferSize: config.DefaultGoogleChromeRpccBufferSize(),
CustomHTTPHeaders: make(map[string]string), CustomHTTPHeaders: make(map[string]string),
Scale: 1.0,
} }
} }
@@ -95,7 +97,8 @@ func (p chromePrinter) Print(destination string) error {
defer devtConn.Close() // nolint: errcheck defer devtConn.Close() // nolint: errcheck
// create a new CDP Client that uses conn. // create a new CDP Client that uses conn.
devtClient := cdp.NewClient(devtConn) devtClient := cdp.NewClient(devtConn)
newContextTarget, err := devtClient.Target.CreateBrowserContext(ctx) createBrowserContextArgs := target.NewCreateBrowserContextArgs()
newContextTarget, err := devtClient.Target.CreateBrowserContext(ctx, createBrowserContextArgs)
if err != nil { if err != nil {
return err return err
} }
@@ -160,7 +163,7 @@ func (p chromePrinter) Print(destination string) error {
// apply a wait delay (if any). // apply a wait delay (if any).
if p.opts.WaitDelay > 0.0 { if p.opts.WaitDelay > 0.0 {
// wait for a given amount of time (useful for javascript delay). // wait for a given amount of time (useful for javascript delay).
p.logger.DebugfOp(op, "applying a wait delay of '%.2fs'...", p.opts.WaitDelay) p.logger.DebugOpf(op, "applying a wait delay of '%.2fs'...", p.opts.WaitDelay)
time.Sleep(xtime.Duration(p.opts.WaitDelay)) time.Sleep(xtime.Duration(p.opts.WaitDelay))
} else { } else {
p.logger.DebugOp(op, "no wait delay to apply, moving on...") p.logger.DebugOp(op, "no wait delay to apply, moving on...")
@@ -176,12 +179,13 @@ func (p chromePrinter) Print(destination string) error {
SetDisplayHeaderFooter(true). SetDisplayHeaderFooter(true).
SetHeaderTemplate(p.opts.HeaderHTML). SetHeaderTemplate(p.opts.HeaderHTML).
SetFooterTemplate(p.opts.FooterHTML). SetFooterTemplate(p.opts.FooterHTML).
SetPrintBackground(true) SetPrintBackground(true).
SetScale(p.opts.Scale)
if p.opts.PageRanges != "" { if p.opts.PageRanges != "" {
printToPdfArgs.SetPageRanges(p.opts.PageRanges) printToPdfArgs.SetPageRanges(p.opts.PageRanges)
} }
// print the page to PDF. // printToPDF the page to PDF.
print, err := targetClient.Page.PrintToPDF( printToPDF, err := targetClient.Page.PrintToPDF(
ctx, ctx,
printToPdfArgs, printToPdfArgs,
) )
@@ -206,7 +210,7 @@ func (p chromePrinter) Print(destination string) error {
} }
return err return err
} }
if err := ioutil.WriteFile(destination, print.Data, 0644); err != nil { if err := ioutil.WriteFile(destination, printToPDF.Data, 0600); err != nil {
return err return err
} }
return nil return nil
@@ -279,7 +283,7 @@ func (p chromePrinter) setCustomHTTPHeaders(ctx context.Context, client *cdp.Cli
// useless but for the logs. // useless but for the logs.
for key, value := range p.opts.CustomHTTPHeaders { for key, value := range p.opts.CustomHTTPHeaders {
customHTTPHeaders[key] = value customHTTPHeaders[key] = value
p.logger.DebugfOp(op, "set '%s' to custom HTTP header '%s'", value, key) p.logger.DebugOpf(op, "set '%s' to custom HTTP header '%s'", value, key)
} }
b, err := json.Marshal(customHTTPHeaders) b, err := json.Marshal(customHTTPHeaders)
if err != nil { if err != nil {
@@ -354,7 +358,7 @@ func (p chromePrinter) listenEvents(ctx context.Context, client *cdp.Client) err
if err != nil { if err != nil {
return err return err
} }
p.logger.DebugfOp(op, "event '%s' received", ev.Name) p.logger.DebugOpf(op, "event '%s' received", ev.Name)
if ev.Name == networkIdleEventName { if ev.Name == networkIdleEventName {
break break
} }

View File

@@ -36,7 +36,7 @@ func NewMarkdownPrinter(logger xlog.Logger, fpath string, opts ChromePrinterOpti
baseFilename := xrand.Get() baseFilename := xrand.Get()
dst := fmt.Sprintf("%s/%s.html", dirPath, baseFilename) dst := fmt.Sprintf("%s/%s.html", dirPath, baseFilename)
logger.DebugOp(op, "writing the HTML from previous conversion(s) into new file...") logger.DebugOp(op, "writing the HTML from previous conversion(s) into new file...")
if err := ioutil.WriteFile(dst, buffer.Bytes(), 0644); err != nil { if err := ioutil.WriteFile(dst, buffer.Bytes(), 0600); err != nil {
return "", err return "", err
} }
return fmt.Sprintf("file://%s", dst), nil return fmt.Sprintf("file://%s", dst), nil

View File

@@ -57,7 +57,7 @@ func (p mergePrinter) Print(destination string) error {
} }
// see https://github.com/thecodingmachine/gotenberg/issues/139. // see https://github.com/thecodingmachine/gotenberg/issues/139.
sort.Strings(p.fpaths) sort.Strings(p.fpaths)
p.logger.DebugfOp(op, "merging '%v'...", p.fpaths) p.logger.DebugOpf(op, "merging '%v'...", p.fpaths)
resolver := func() error { resolver := func() error {
var args []string var args []string
args = append(args, p.fpaths...) args = append(args, p.fpaths...)

View File

@@ -64,11 +64,11 @@ func (p officePrinter) Print(destination string) error {
for i, fpath := range p.fpaths { for i, fpath := range p.fpaths {
baseFilename := xrand.Get() baseFilename := xrand.Get()
tmpDest := fmt.Sprintf("%s/%d%s.pdf", dirPath, i, baseFilename) tmpDest := fmt.Sprintf("%s/%d%s.pdf", dirPath, i, baseFilename)
p.logger.DebugfOp(op, "converting '%s' to PDF...", fpath) p.logger.DebugOpf(op, "converting '%s' to PDF...", fpath)
if err := p.unoconv(ctx, fpath, tmpDest); err != nil { if err := p.unoconv(ctx, fpath, tmpDest); err != nil {
return err return err
} }
p.logger.DebugfOp(op, "'%s.pdf' created", baseFilename) p.logger.DebugOpf(op, "'%s.pdf' created", baseFilename)
fpaths[i] = tmpDest fpaths[i] = tmpDest
} }
if len(fpaths) == 1 { if len(fpaths) == 1 {
@@ -113,7 +113,15 @@ func (p officePrinter) unoconv(ctx context.Context, fpath, destination string) e
args = append(args, "--export", fmt.Sprintf("PageRange=%s", p.opts.PageRanges)) args = append(args, "--export", fmt.Sprintf("PageRange=%s", p.opts.PageRanges))
} }
args = append(args, "--output", destination, fpath) args = append(args, "--output", destination, fpath)
if err := xexec.Run(ctx, p.logger, "unoconv", args...); err != nil { err = xexec.Run(ctx, p.logger, "unoconv", args...)
// always remove user profile folders created by LibreOffice.
// see https://github.com/thecodingmachine/gotenberg/issues/192.
userProfileDirPath := fmt.Sprintf("/tmp/%d", port)
if err := os.RemoveAll(userProfileDirPath); err != nil {
// find a way to bubble up this error?
p.logger.ErrorOpf(op, "failed to remove user profile directory '%s': %s", userProfileDirPath, err.Error())
}
if err != nil {
// find a way to check it in the handlers? // find a way to check it in the handlers?
if p.opts.PageRanges != "" && strings.Contains(err.Error(), "exit status 5") { if p.opts.PageRanges != "" && strings.Contains(err.Error(), "exit status 5") {
return xerror.Invalid( return xerror.Invalid(

View File

@@ -12,5 +12,5 @@ type Printer interface {
func logOptions(logger xlog.Logger, opts interface{}) { func logOptions(logger xlog.Logger, opts interface{}) {
const op string = "printer.logOptions" const op string = "printer.logOptions"
logger.DebugfOp(op, "options: %+v", opts) logger.DebugOpf(op, "options: %+v", opts)
} }

View File

@@ -14,7 +14,7 @@ import (
// times out after given seconds. // times out after given seconds.
func WithTimeout(logger xlog.Logger, seconds float64) (context.Context, context.CancelFunc) { func WithTimeout(logger xlog.Logger, seconds float64) (context.Context, context.CancelFunc) {
const op string = "xcontext.WithTimeout" const op string = "xcontext.WithTimeout"
logger.DebugfOp(op, "creating context with '%.2fs' of timeout...", seconds) logger.DebugOpf(op, "creating context with '%.2fs' of timeout...", seconds)
return context.WithTimeout(context.Background(), xtime.Duration(seconds)) return context.WithTimeout(context.Background(), xtime.Duration(seconds))
} }

View File

@@ -84,11 +84,11 @@ func Run(ctx context.Context, logger xlog.Logger, binary string, args ...string)
}() }()
select { select {
case err := <-result: case err := <-result:
logger.DebugfOp(op, "command '%s' finished", strings.Join(cmd.Args, " ")) logger.DebugOpf(op, "command '%s' finished", strings.Join(cmd.Args, " "))
kill() kill()
return err return err
case <-ctx.Done(): case <-ctx.Done():
logger.DebugfOp(op, "command '%s' failed to finish before context.Context deadline", strings.Join(cmd.Args, " ")) logger.DebugOpf(op, "command '%s' failed to finish before context.Context deadline", strings.Join(cmd.Args, " "))
kill() kill()
return ctx.Err() return ctx.Err()
} }
@@ -102,7 +102,7 @@ func Run(ctx context.Context, logger xlog.Logger, binary string, args ...string)
// LogBeforeExecute logs a command before its execution. // LogBeforeExecute logs a command before its execution.
func LogBeforeExecute(logger xlog.Logger, cmd *exec.Cmd) { func LogBeforeExecute(logger xlog.Logger, cmd *exec.Cmd) {
const op string = "xexec.LogBeforeExecute" const op string = "xexec.LogBeforeExecute"
logger.DebugfOp(op, "executing command: %s", strings.Join(cmd.Args, " ")) logger.DebugOpf(op, "executing command: %s", strings.Join(cmd.Args, " "))
} }
func pipe(logger xlog.Logger, cmd *exec.Cmd) error { func pipe(logger xlog.Logger, cmd *exec.Cmd) error {

View File

@@ -104,9 +104,9 @@ func (l Logger) DebugOp(op, message string) {
l.entry.WithField("op", op).Debug(message) l.entry.WithField("op", op).Debug(message)
} }
// DebugfOp logs a debug message for given // DebugOpf logs a debug message for given
// logical operation and format. // logical operation and format.
func (l Logger) DebugfOp(op, format string, args ...interface{}) { func (l Logger) DebugOpf(op, format string, args ...interface{}) {
l.entry.WithField("op", op).Debugf(format, args...) l.entry.WithField("op", op).Debugf(format, args...)
} }
@@ -116,9 +116,9 @@ func (l Logger) InfoOp(op, message string) {
l.entry.WithField("op", op).Info(message) l.entry.WithField("op", op).Info(message)
} }
// InfofOp logs an info message for given // InfoOpf logs an info message for given
// logical operation and format. // logical operation and format.
func (l Logger) InfofOp(op, format string, args ...interface{}) { func (l Logger) InfoOpf(op, format string, args ...interface{}) {
l.entry.WithField("op", op).Infof(format, args...) l.entry.WithField("op", op).Infof(format, args...)
} }
@@ -128,9 +128,9 @@ func (l Logger) ErrorOp(op string, err error) {
l.entry.WithField("op", op).Error(err.Error()) l.entry.WithField("op", op).Error(err.Error())
} }
// ErrorfOp logs an error message for given // ErrorOpf logs an error message for given
// logical operation and format. // logical operation and format.
func (l Logger) ErrorfOp(op, format string, args ...interface{}) { func (l Logger) ErrorOpf(op, format string, args ...interface{}) {
l.entry.WithField("op", op).Errorf(format, args...) l.entry.WithField("op", op).Errorf(format, args...)
} }