mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-08 08:32:16 +01:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df357c1008 | ||
|
|
871b52a288 | ||
|
|
8a4a043e9f | ||
|
|
c0297aa061 | ||
|
|
2aaa2eeaff | ||
|
|
5f62e5bacf |
2
.github/CONTRIBUTING.md
vendored
2
.github/CONTRIBUTING.md
vendored
@@ -8,7 +8,7 @@ find below useful information about how to contribute to the Gotenberg project.
|
||||
### Install from sources
|
||||
|
||||
1. Install and run the latest version of Docker
|
||||
2. Verify your Go version (>= 1.11)
|
||||
2. Verify your Go version (>= 1.12)
|
||||
3. Fork this repository
|
||||
4. Clone it outside of your `GOPATH` (we're using Go modules)
|
||||
|
||||
|
||||
3
Makefile
3
Makefile
@@ -1,4 +1,4 @@
|
||||
GOLANG_VERSION=1.11.2
|
||||
GOLANG_VERSION=1.12
|
||||
VERSION=snapshot
|
||||
DOCKER_USER=
|
||||
DOCKER_PASSWORD=
|
||||
@@ -11,6 +11,7 @@ doc:
|
||||
# gofmt and goimports all go files.
|
||||
fmt:
|
||||
go fmt ./...
|
||||
go mod tidy
|
||||
|
||||
# run all linters.
|
||||
lint:
|
||||
|
||||
@@ -16,7 +16,7 @@ At TheCodingMachine, we build a lot of web applications (intranets, extranets an
|
||||
* Performance :zap:: Google Chrome and Libreoffice (unoconv) started once in the background thanks to PM2
|
||||
* Failure prevention :broken_heart:: PM2 automatically restarts previous processes if they fail
|
||||
* Assets :package:: send your header, footer, images, fonts, stylesheets and so on for converting your HTML and Markdown to beaufitul PDFs!
|
||||
* Easily interact with the API using our [Go](/pkg) 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
|
||||
|
||||
|
||||
@@ -9,4 +9,4 @@ title: Introduction
|
||||
* Performance: Google Chrome and Libreoffice (unoconv) started once in the background thanks to PM2
|
||||
* Failure prevention: PM2 automatically restarts previous processes if they fail
|
||||
* Assets: send your header, footer, images, fonts, stylesheets and so on for converting your HTML and Markdown to beaufitul PDFs!
|
||||
* Easily interact with the API using our [Go](https://github.com/thecodingmachine/gotenberg/pkg) 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
|
||||
@@ -35,7 +35,7 @@ Gotenberg API is available at [http://localhost:3000](http://localhost:3000).
|
||||
## Go client
|
||||
|
||||
```bash
|
||||
$ go get -u github.com/thecodingmachine/gotenberg
|
||||
$ go get -u github.com/thecodingmachine/gotenberg-go-client/v4
|
||||
```
|
||||
|
||||
## PHP client
|
||||
|
||||
@@ -39,7 +39,7 @@ $ curl --request POST \
|
||||
### Go
|
||||
|
||||
```golang
|
||||
import "github.com/thecodingmachine/gotenberg/pkg"
|
||||
import "github.com/thecodingmachine/gotenberg-go-client/v4"
|
||||
|
||||
func main() {
|
||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||
@@ -113,7 +113,7 @@ $ curl --request POST \
|
||||
### Go
|
||||
|
||||
```golang
|
||||
import "github.com/thecodingmachine/gotenberg/pkg"
|
||||
import "github.com/thecodingmachine/gotenberg-go-client/v4"
|
||||
|
||||
func main() {
|
||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||
@@ -206,7 +206,7 @@ $ curl --request POST \
|
||||
### Go
|
||||
|
||||
```golang
|
||||
import "github.com/thecodingmachine/gotenberg/pkg"
|
||||
import "github.com/thecodingmachine/gotenberg-go-client/v4"
|
||||
|
||||
func main() {
|
||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||
@@ -266,7 +266,7 @@ $ curl --request POST \
|
||||
### Go
|
||||
|
||||
```golang
|
||||
import "github.com/thecodingmachine/gotenberg/pkg"
|
||||
import "github.com/thecodingmachine/gotenberg-go-client/v4"
|
||||
|
||||
func main() {
|
||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||
|
||||
@@ -31,7 +31,7 @@ $ curl --request POST \
|
||||
### Go
|
||||
|
||||
```golang
|
||||
import "github.com/thecodingmachine/gotenberg/pkg"
|
||||
import "github.com/thecodingmachine/gotenberg-go-client/v4"
|
||||
|
||||
func main() {
|
||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||
|
||||
@@ -42,7 +42,7 @@ $ curl --request POST \
|
||||
### Go
|
||||
|
||||
```golang
|
||||
import "github.com/thecodingmachine/gotenberg/pkg"
|
||||
import "github.com/thecodingmachine/gotenberg-go-client/v4"
|
||||
|
||||
func main() {
|
||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||
|
||||
@@ -43,7 +43,7 @@ $ curl --request POST \
|
||||
### Go
|
||||
|
||||
```golang
|
||||
import "github.com/thecodingmachine/gotenberg/pkg"
|
||||
import "github.com/thecodingmachine/gotenberg-go-client/v4"
|
||||
|
||||
func main() {
|
||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||
@@ -90,7 +90,7 @@ $ curl --request POST \
|
||||
### Go
|
||||
|
||||
```golang
|
||||
import "github.com/thecodingmachine/gotenberg/pkg"
|
||||
import "github.com/thecodingmachine/gotenberg-go-client/v4"
|
||||
|
||||
func main() {
|
||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||
|
||||
@@ -27,7 +27,7 @@ $ curl --request POST \
|
||||
### Go
|
||||
|
||||
```golang
|
||||
import "github.com/thecodingmachine/gotenberg/pkg"
|
||||
import "github.com/thecodingmachine/gotenberg-go-client/v4"
|
||||
|
||||
func main() {
|
||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||
|
||||
@@ -24,7 +24,7 @@ $ curl --request POST \
|
||||
### Go
|
||||
|
||||
```golang
|
||||
import "github.com/thecodingmachine/gotenberg/pkg"
|
||||
import "github.com/thecodingmachine/gotenberg-go-client/v4"
|
||||
|
||||
func main() {
|
||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||
|
||||
27
build/docs/content/08-filename.md
Normal file
27
build/docs/content/08-filename.md
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
title: Filename
|
||||
---
|
||||
|
||||
All endpoints accept a form field named `filename`.
|
||||
|
||||
If provided, the API will return the resulting PDF file with the given filename.
|
||||
Otherwise a random filename is used.
|
||||
|
||||
> The Go and PHP libraries do not provide a way to set this form field.
|
||||
> However, you may hijack the response from the API or store the resulting PDF
|
||||
> using a custom filename.
|
||||
>
|
||||
> **Attention:** this feature does not work if the form field `webhookURL` is given.
|
||||
|
||||
## Examples
|
||||
|
||||
### cURL
|
||||
|
||||
```bash
|
||||
$ curl --request POST \
|
||||
--url http://localhost:3000/convert/html \
|
||||
--header 'Content-Type: multipart/form-data' \
|
||||
--form files=@index.html \
|
||||
--form filename='result.pdf' \
|
||||
-o result.pdf
|
||||
```
|
||||
@@ -10,7 +10,7 @@ FROM golang:${GOLANG_VERSION}-stretch
|
||||
# | than gometalinter.
|
||||
# |
|
||||
|
||||
ENV GOLANGCI_LINT_VERSION 1.12.3
|
||||
ENV GOLANGCI_LINT_VERSION 1.15.0
|
||||
|
||||
RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b /usr/local/bin v${GOLANGCI_LINT_VERSION} &&\
|
||||
golangci-lint --version
|
||||
|
||||
@@ -45,4 +45,4 @@ COPY go.sum .
|
||||
# Install module dependencies.
|
||||
RUN go mod download
|
||||
|
||||
ENTRYPOINT ["build/tests/docker-entrypoint.sh"]
|
||||
ENTRYPOINT [ "build/tests/docker-entrypoint.sh" ]
|
||||
@@ -15,11 +15,4 @@ go test -race -cover -covermode=atomic github.com/thecodingmachine/gotenberg/int
|
||||
|
||||
# Finally testing processes shutdown.
|
||||
go test github.com/thecodingmachine/gotenberg/internal/pkg/pm2 -run TestChromeShutdown
|
||||
go test github.com/thecodingmachine/gotenberg/internal/pkg/pm2 -run TestUnoconvShutdown
|
||||
|
||||
# Testing Go client.
|
||||
go build -o /usr/local/bin/gotenberg cmd/gotenberg/main.go
|
||||
gotenberg &
|
||||
sleep 10
|
||||
go test -race -cover -covermode=atomic github.com/thecodingmachine/gotenberg/pkg
|
||||
sleep 5 # allows Gotenberg to remove generated files (concurrent requests).
|
||||
go test github.com/thecodingmachine/gotenberg/internal/pkg/pm2 -run TestUnoconvShutdown
|
||||
@@ -74,6 +74,10 @@
|
||||
<a href="#webhook">Webhook</a>
|
||||
</div>
|
||||
|
||||
<div class="item">
|
||||
<a href="#filename">Filename</a>
|
||||
</div>
|
||||
|
||||
<div class="item">
|
||||
<a href="#scalability">Scalability</a>
|
||||
</div>
|
||||
@@ -107,7 +111,7 @@
|
||||
<li>Performance: Google Chrome and Libreoffice (unoconv) started once in the background thanks to PM2</li>
|
||||
<li>Failure prevention: PM2 automatically restarts previous processes if they fail</li>
|
||||
<li>Assets: send your header, footer, images, fonts, stylesheets and so on for converting your HTML and Markdown to beaufitul PDFs!</li>
|
||||
<li>Easily interact with the API using our <a href="https://github.com/thecodingmachine/gotenberg/pkg">Go</a> and <a href="https://github.com/thecodingmachine/gotenberg-php-client">PHP</a> libraries</li>
|
||||
<li>Easily interact with the API using our <a href="https://github.com/thecodingmachine/gotenberg-go-client">Go</a> and <a href="https://github.com/thecodingmachine/gotenberg-php-client">PHP</a> libraries</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
@@ -152,7 +156,7 @@ Gotenberg API is available at <a href="http://localhost:3000">http://localhost:3
|
||||
<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 client</h2>
|
||||
|
||||
<pre class="chroma">$ go get -u github.com/thecodingmachine/gotenberg
|
||||
<pre class="chroma">$ go get -u github.com/thecodingmachine/gotenberg-go-client/v4
|
||||
</pre>
|
||||
|
||||
<h2 class="Heading"><a class="Anchor" aria-hidden="true" id="install.php_client" href="#install.php_client">
|
||||
@@ -215,7 +219,7 @@ which will be converted to PDF.</p>
|
||||
<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>
|
||||
|
||||
<pre class="chroma"><span class="kn">import</span> <span class="s">"github.com/thecodingmachine/gotenberg/pkg"</span>
|
||||
<pre class="chroma"><span class="kn">import</span> <span class="s">"github.com/thecodingmachine/gotenberg-go-client/v4"</span>
|
||||
|
||||
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
|
||||
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
||||
@@ -297,7 +301,7 @@ Also, <code>footer.html</code> CSS properties override the ones from <code>heade
|
||||
<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>
|
||||
|
||||
<pre class="chroma"><span class="kn">import</span> <span class="s">"github.com/thecodingmachine/gotenberg/pkg"</span>
|
||||
<pre class="chroma"><span class="kn">import</span> <span class="s">"github.com/thecodingmachine/gotenberg-go-client/v4"</span>
|
||||
|
||||
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
|
||||
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
||||
@@ -395,7 +399,7 @@ this value thanks to the form field <code>webFontsTimeout</code>.</p>
|
||||
<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>
|
||||
|
||||
<pre class="chroma"><span class="kn">import</span> <span class="s">"github.com/thecodingmachine/gotenberg/pkg"</span>
|
||||
<pre class="chroma"><span class="kn">import</span> <span class="s">"github.com/thecodingmachine/gotenberg-go-client/v4"</span>
|
||||
|
||||
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
|
||||
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
||||
@@ -462,7 +466,7 @@ Also, you have to set both <code>paperWidth</code> and <code>paperHeight</code>.
|
||||
<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>
|
||||
|
||||
<pre class="chroma"><span class="kn">import</span> <span class="s">"github.com/thecodingmachine/gotenberg/pkg"</span>
|
||||
<pre class="chroma"><span class="kn">import</span> <span class="s">"github.com/thecodingmachine/gotenberg-go-client/v4"</span>
|
||||
|
||||
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
|
||||
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
||||
@@ -535,7 +539,7 @@ If not, some of the content of the page might be hidden.</p>
|
||||
<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>
|
||||
|
||||
<pre class="chroma"><span class="kn">import</span> <span class="s">"github.com/thecodingmachine/gotenberg/pkg"</span>
|
||||
<pre class="chroma"><span class="kn">import</span> <span class="s">"github.com/thecodingmachine/gotenberg-go-client/v4"</span>
|
||||
|
||||
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
|
||||
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
||||
@@ -609,7 +613,7 @@ in the file <code>index.html</code>. This function will convert a given markdown
|
||||
<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>
|
||||
|
||||
<pre class="chroma"><span class="kn">import</span> <span class="s">"github.com/thecodingmachine/gotenberg/pkg"</span>
|
||||
<pre class="chroma"><span class="kn">import</span> <span class="s">"github.com/thecodingmachine/gotenberg-go-client/v4"</span>
|
||||
|
||||
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
|
||||
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
||||
@@ -692,7 +696,7 @@ See the <a href="#scalability">scalability section</a> to find how to mitigate t
|
||||
<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>
|
||||
|
||||
<pre class="chroma"><span class="kn">import</span> <span class="s">"github.com/thecodingmachine/gotenberg/pkg"</span>
|
||||
<pre class="chroma"><span class="kn">import</span> <span class="s">"github.com/thecodingmachine/gotenberg-go-client/v4"</span>
|
||||
|
||||
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
|
||||
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
||||
@@ -744,7 +748,7 @@ $client->store($request, $dest);
|
||||
<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>
|
||||
|
||||
<pre class="chroma"><span class="kn">import</span> <span class="s">"github.com/thecodingmachine/gotenberg/pkg"</span>
|
||||
<pre class="chroma"><span class="kn">import</span> <span class="s">"github.com/thecodingmachine/gotenberg-go-client/v4"</span>
|
||||
|
||||
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
|
||||
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
||||
@@ -810,7 +814,7 @@ will merge them and return the resulting PDF file.</p>
|
||||
<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>
|
||||
|
||||
<pre class="chroma"><span class="kn">import</span> <span class="s">"github.com/thecodingmachine/gotenberg/pkg"</span>
|
||||
<pre class="chroma"><span class="kn">import</span> <span class="s">"github.com/thecodingmachine/gotenberg-go-client/v4"</span>
|
||||
|
||||
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
|
||||
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
||||
@@ -870,7 +874,7 @@ to given URL.</p>
|
||||
<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>
|
||||
|
||||
<pre class="chroma"><span class="kn">import</span> <span class="s">"github.com/thecodingmachine/gotenberg/pkg"</span>
|
||||
<pre class="chroma"><span class="kn">import</span> <span class="s">"github.com/thecodingmachine/gotenberg-go-client/v4"</span>
|
||||
|
||||
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
|
||||
<span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">gotenberg</span><span class="p">.</span><span class="nx">Client</span><span class="p">{</span><span class="nx">Hostname</span><span class="p">:</span> <span class="s">"http://localhost:3000"</span><span class="p">}</span>
|
||||
@@ -898,6 +902,41 @@ $resp = $client->post($request);
|
||||
|
||||
</div>
|
||||
|
||||
<div class="Page" id="filename">
|
||||
<h1 class="Heading"><a class="Anchor" aria-hidden="true" id="filename" href="#filename">
|
||||
<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>Filename</h1>
|
||||
<p>All endpoints accept a form field named <code>filename</code>.</p>
|
||||
|
||||
<p>If provided, the API will return the resulting PDF file with the given filename.
|
||||
Otherwise a random filename is used.</p>
|
||||
|
||||
<blockquote>
|
||||
<p>The Go and PHP libraries do not provide a way to set this form field.
|
||||
However, you may hijack the response from the API or store the resulting PDF
|
||||
using a custom filename.</p>
|
||||
|
||||
<p><strong>Attention:</strong> this feature does not work if the form field <code>webhookURL</code> is given.</p>
|
||||
</blockquote>
|
||||
|
||||
<h2 class="Heading"><a class="Anchor" aria-hidden="true" id="filename.examples" href="#filename.examples">
|
||||
<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>Examples</h2>
|
||||
|
||||
<h3 class="Heading"><a class="Anchor" aria-hidden="true" id="filename.examples.c_url" href="#filename.examples.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>
|
||||
</a>cURL</h3>
|
||||
|
||||
<pre class="chroma">$ curl --request POST <span class="se">\
|
||||
</span><span class="se"></span> --url http://localhost:3000/convert/html <span class="se">\
|
||||
</span><span class="se"></span> --header <span class="s1">'Content-Type: multipart/form-data'</span> <span class="se">\
|
||||
</span><span class="se"></span> --form <span class="nv">files</span><span class="o">=</span>@index.html <span class="se">\
|
||||
</span><span class="se"></span> --form <span class="nv">filename</span><span class="o">=</span><span class="s1">'result.pdf'</span> <span class="se">\
|
||||
</span><span class="se"></span> -o result.pdf
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="Page" id="scalability">
|
||||
<h1 class="Heading"><a class="Anchor" aria-hidden="true" id="scalability" href="#scalability">
|
||||
<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>
|
||||
|
||||
14
go.mod
14
go.mod
@@ -1,19 +1,25 @@
|
||||
module github.com/thecodingmachine/gotenberg
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/google/go-cmp v0.2.0 // indirect
|
||||
github.com/gorilla/websocket v1.4.0 // indirect
|
||||
github.com/hhrutter/pdfcpu v0.1.19
|
||||
github.com/labstack/echo v0.0.0-20190126223945-739700bf4ef7
|
||||
github.com/labstack/echo/v4 v4.0.0
|
||||
github.com/labstack/gommon v0.2.8
|
||||
github.com/mafredri/cdp v0.20.0
|
||||
github.com/mattn/go-colorable v0.1.1 // indirect
|
||||
github.com/mattn/go-isatty v0.0.7 // indirect
|
||||
github.com/microcosm-cc/bluemonday v1.0.1
|
||||
github.com/pkg/errors v0.8.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.0.1
|
||||
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95 // indirect
|
||||
github.com/stretchr/testify v1.2.2
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 // indirect
|
||||
github.com/stretchr/testify v1.3.0
|
||||
github.com/valyala/fasttemplate v1.0.1 // indirect
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c // indirect
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc // indirect
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f // indirect
|
||||
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35 // indirect
|
||||
golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc // indirect
|
||||
)
|
||||
|
||||
32
go.sum
32
go.sum
@@ -1,3 +1,4 @@
|
||||
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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
@@ -8,17 +9,21 @@ github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/hhrutter/pdfcpu v0.1.19 h1:J6GjNFDPjurQWallPW9gmz3CcNqBfvgB7Dad9T3e8Hc=
|
||||
github.com/hhrutter/pdfcpu v0.1.19/go.mod h1:iaCmXGnOXPIvoGLELZZc4m/GpIopVsvLQ00thrbu8LU=
|
||||
github.com/labstack/echo v0.0.0-20190126223945-739700bf4ef7 h1:kFheQLunLP9dCBrmg3D7y9FD44tlk/nvZQ7JCNvvWEA=
|
||||
github.com/labstack/echo v0.0.0-20190126223945-739700bf4ef7/go.mod h1:rS0D1UPvC8/3sXjhSwEq+K1olh7ipbDhjDWATN2KSgA=
|
||||
github.com/labstack/gommon v0.2.7/go.mod h1:/tj9csK2iPSBvn+3NLM9e52usepMtrd5ilFYA+wQNJ4=
|
||||
github.com/labstack/echo/v4 v4.0.0 h1:q1GH+caIXPP7H2StPIdzy/ez9CO0EepqYeUg6vi9SWM=
|
||||
github.com/labstack/echo/v4 v4.0.0/go.mod h1:tZv7nai5buKSg5h/8E6zz4LsD/Dqh9/91Mvs7Z5Zyno=
|
||||
github.com/labstack/gommon v0.2.8 h1:JvRqmeZcfrHC5u6uVleB4NxxNbzx6gpbJiQknDbKQu0=
|
||||
github.com/labstack/gommon v0.2.8/go.mod h1:/tj9csK2iPSBvn+3NLM9e52usepMtrd5ilFYA+wQNJ4=
|
||||
github.com/mafredri/cdp v0.20.0 h1:dRq16FwXCAAbolR4W2iyRNsL14Bp6jFHLbRp2EkICVs=
|
||||
github.com/mafredri/cdp v0.20.0/go.mod h1:hgdiA0yp1uqhSaDOHJWPgXpMbh+LAfUdD9vbN2AM8gE=
|
||||
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/microcosm-cc/bluemonday v1.0.1 h1:SIYunPjnlXcW+gVfvm0IlSeR5U3WZUOLfVmqg85Go44=
|
||||
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
|
||||
@@ -29,19 +34,24 @@ 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/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95 h1:/vdW8Cb7EXrkqWGufVMES1OH2sU9gKVb2n9/1y5NMBY=
|
||||
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
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/fasttemplate v0.0.0-20170224212429-dcecefd839c4 h1:gKMu1Bf6QINDnvyZuTaACm9ofY+PRh+5vFz4oxBZeF8=
|
||||
github.com/valyala/fasttemplate v0.0.0-20170224212429-dcecefd839c4/go.mod h1:50wTf68f99/Zt14pr046Tgt3Lp2vLyFZKzbFXTOabXw=
|
||||
golang.org/x/crypto v0.0.0-20181106171534-e4dc69e5b2fd/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 h1:mKdxBk7AujPs8kU4m80U72y/zjbZ3UcXC7dClwKbUI0=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
|
||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
golang.org/x/crypto v0.0.0-20190130090550-b01c7a725664/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc h1:a3CU5tJYVj92DY2LaA1kUkrsqD5/3mLDhx2NcNqyW+0=
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35 h1:YAFjXN64LMvktoUZH9zgY4lGc/msGN7HQfoSuKCgaDU=
|
||||
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/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-20190322080309-f49334f85ddc h1:4gbWbmmPFp4ySWICouJl6emP0MyS31yy9SrTlAGFT+g=
|
||||
golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
||||
@@ -8,8 +8,8 @@ import (
|
||||
"os/signal"
|
||||
"time"
|
||||
|
||||
"github.com/labstack/echo"
|
||||
"github.com/labstack/echo/middleware"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
"github.com/thecodingmachine/gotenberg/internal/pkg/notify"
|
||||
"github.com/thecodingmachine/gotenberg/internal/pkg/pm2"
|
||||
"github.com/thecodingmachine/gotenberg/internal/pkg/printer"
|
||||
@@ -93,14 +93,17 @@ func print(c echo.Context, p printer.Printer, r *resource) error {
|
||||
}
|
||||
filename := fmt.Sprintf("%s.pdf", baseFilename)
|
||||
fpath := fmt.Sprintf("%s/%s", r.dirPath, filename)
|
||||
// if no webhook URL given, run conversion
|
||||
// and directly return the resulting PDF file
|
||||
// or an error.
|
||||
if r.webhookURL() == "" {
|
||||
defer r.removeAll()
|
||||
// if no webhook URL given, run conversion
|
||||
// and directly return the resulting PDF file
|
||||
// or an error.
|
||||
if err := p.Print(fpath); err != nil {
|
||||
return err
|
||||
}
|
||||
if r.filename() != "" {
|
||||
filename = r.filename()
|
||||
}
|
||||
return c.Attachment(fpath, filename)
|
||||
}
|
||||
// as a webhook URL has been given, we
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/labstack/echo"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/thecodingmachine/gotenberg/internal/pkg/printer"
|
||||
)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/labstack/echo"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/thecodingmachine/gotenberg/test"
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/thecodingmachine/gotenberg/internal/pkg/printer"
|
||||
)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/labstack/echo"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/thecodingmachine/gotenberg/test"
|
||||
)
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/labstack/echo"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/thecodingmachine/gotenberg/internal/pkg/printer"
|
||||
"github.com/thecodingmachine/gotenberg/internal/pkg/rand"
|
||||
)
|
||||
@@ -29,14 +29,17 @@ func merge(c echo.Context) error {
|
||||
}
|
||||
filename := fmt.Sprintf("%s.pdf", baseFilename)
|
||||
fpath := fmt.Sprintf("%s/%s", r.dirPath, filename)
|
||||
// if no webhook URL given, run merge
|
||||
// and directly return the resulting PDF file
|
||||
// or an error.
|
||||
if r.webhookURL() == "" {
|
||||
defer r.removeAll()
|
||||
// if no webhook URL given, run merge
|
||||
// and directly return the resulting PDF file
|
||||
// or an error.
|
||||
if err := printer.Merge(fpaths, fpath); err != nil {
|
||||
return err
|
||||
}
|
||||
if r.filename() != "" {
|
||||
filename = r.filename()
|
||||
}
|
||||
return c.Attachment(fpath, filename)
|
||||
}
|
||||
// as a webhook URL has been given, we
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/labstack/echo"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/thecodingmachine/gotenberg/test"
|
||||
)
|
||||
|
||||
@@ -3,7 +3,7 @@ package api
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/labstack/echo"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/thecodingmachine/gotenberg/internal/pkg/printer"
|
||||
)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/labstack/echo"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/thecodingmachine/gotenberg/test"
|
||||
)
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
"github.com/labstack/echo"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/thecodingmachine/gotenberg/internal/pkg/rand"
|
||||
)
|
||||
|
||||
@@ -23,6 +23,7 @@ const (
|
||||
marginRight string = "marginRight"
|
||||
landscape string = "landscape"
|
||||
webFontsTimeout string = "webFontsTimeout"
|
||||
filename string = "filename"
|
||||
)
|
||||
|
||||
// resource facilitates storing and accessing
|
||||
@@ -33,17 +34,6 @@ type resource struct {
|
||||
}
|
||||
|
||||
func newResource(c echo.Context) (*resource, error) {
|
||||
v := make(map[string]string)
|
||||
v[remoteURL] = c.FormValue(remoteURL)
|
||||
v[webhookURL] = c.FormValue(webhookURL)
|
||||
v[paperWidth] = c.FormValue(paperWidth)
|
||||
v[paperHeight] = c.FormValue(paperHeight)
|
||||
v[marginTop] = c.FormValue(marginTop)
|
||||
v[marginBottom] = c.FormValue(marginBottom)
|
||||
v[marginLeft] = c.FormValue(marginLeft)
|
||||
v[marginRight] = c.FormValue(marginRight)
|
||||
v[landscape] = c.FormValue(landscape)
|
||||
v[webFontsTimeout] = c.FormValue(webFontsTimeout)
|
||||
dirPath, err := rand.Get()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -51,7 +41,7 @@ func newResource(c echo.Context) (*resource, error) {
|
||||
if err := os.MkdirAll(dirPath, 0755); err != nil {
|
||||
return nil, fmt.Errorf("%s: making directory: %v", dirPath, err)
|
||||
}
|
||||
r := &resource{values: v, dirPath: dirPath}
|
||||
r := &resource{values: values(c), dirPath: dirPath}
|
||||
form, err := c.MultipartForm()
|
||||
if err != nil {
|
||||
return r, fmt.Errorf("getting multipart form: %v", err)
|
||||
@@ -71,6 +61,22 @@ func newResource(c echo.Context) (*resource, error) {
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func values(c echo.Context) map[string]string {
|
||||
v := make(map[string]string)
|
||||
v[remoteURL] = c.FormValue(remoteURL)
|
||||
v[webhookURL] = c.FormValue(webhookURL)
|
||||
v[paperWidth] = c.FormValue(paperWidth)
|
||||
v[paperHeight] = c.FormValue(paperHeight)
|
||||
v[marginTop] = c.FormValue(marginTop)
|
||||
v[marginBottom] = c.FormValue(marginBottom)
|
||||
v[marginLeft] = c.FormValue(marginLeft)
|
||||
v[marginRight] = c.FormValue(marginRight)
|
||||
v[landscape] = c.FormValue(landscape)
|
||||
v[webFontsTimeout] = c.FormValue(webFontsTimeout)
|
||||
v[filename] = c.FormValue(filename)
|
||||
return v
|
||||
}
|
||||
|
||||
func (r *resource) writeFile(filename string, in io.Reader) error {
|
||||
fpath := fmt.Sprintf("%s/%s", r.dirPath, filename)
|
||||
out, err := os.Create(fpath)
|
||||
@@ -205,4 +211,5 @@ func (r *resource) webFontsTimeout() (int64, error) {
|
||||
}
|
||||
|
||||
func (r *resource) webhookURL() string { return r.values[webhookURL] }
|
||||
func (r *resource) filename() string { return r.values[filename] }
|
||||
func (r *resource) removeAll() error { return os.RemoveAll(r.dirPath) }
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/thecodingmachine/gotenberg/internal/pkg/printer"
|
||||
)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/labstack/echo"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/thecodingmachine/gotenberg/test"
|
||||
)
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
# Gotenberg Go client
|
||||
|
||||
A simple Go client for interacting with a Gotenberg API.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
$ go get -u github.com/thecodingmachine/gotenberg
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```golang
|
||||
import "github.com/thecodingmachine/gotenberg/pkg"
|
||||
|
||||
func main() {
|
||||
// HTML conversion example.
|
||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||
req, _ := gotenberg.NewHTMLRequest("index.html")
|
||||
req.SetHeader("header.html")
|
||||
req.SetFooter("footer.html")
|
||||
req.SetAssets(
|
||||
"font.woff",
|
||||
"img.gif",
|
||||
"style.css",
|
||||
)
|
||||
req.SetPaperSize(gotenberg.A4)
|
||||
req.SetMargins(gotenberg.NormalMargins)
|
||||
req.SetLandscape(false)
|
||||
dest := "foo.pdf"
|
||||
c.Store(req, dest)
|
||||
}
|
||||
```
|
||||
|
||||
For more complete usages, head to the [documentation](https://thecodingmachine.github.io/gotenberg).
|
||||
173
pkg/client.go
173
pkg/client.go
@@ -1,173 +0,0 @@
|
||||
package gotenberg
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
const (
|
||||
remoteURL string = "remoteURL"
|
||||
webhookURL string = "webhookURL"
|
||||
paperWidth string = "paperWidth"
|
||||
paperHeight string = "paperHeight"
|
||||
marginTop string = "marginTop"
|
||||
marginBottom string = "marginBottom"
|
||||
marginLeft string = "marginLeft"
|
||||
marginRight string = "marginRight"
|
||||
landscape string = "landscape"
|
||||
webFontsTimeout string = "webFontsTimeout"
|
||||
)
|
||||
|
||||
var (
|
||||
// A3 paper size.
|
||||
A3 = [2]float64{11.7, 16.5}
|
||||
// A4 paper size.
|
||||
A4 = [2]float64{8.27, 11.7}
|
||||
// A5 paper size.
|
||||
A5 = [2]float64{5.8, 8.3}
|
||||
// A6 paper size.
|
||||
A6 = [2]float64{4.1, 5.8}
|
||||
// Letter paper size.
|
||||
Letter = [2]float64{8.5, 11}
|
||||
// Legal paper size.
|
||||
Legal = [2]float64{8.5, 14}
|
||||
// Tabloid paper size.
|
||||
Tabloid = [2]float64{11, 17}
|
||||
)
|
||||
|
||||
var (
|
||||
// NoMargins removes margins.
|
||||
NoMargins = [4]float64{0, 0, 0, 0}
|
||||
// NormalMargins uses 1 inche margins.
|
||||
NormalMargins = [4]float64{1, 1, 1, 1}
|
||||
// LargeMargins uses 2 inche margins.
|
||||
LargeMargins = [4]float64{2, 2, 2, 2}
|
||||
)
|
||||
|
||||
// Client facilitates interacting with
|
||||
// the Gotenberg API.
|
||||
type Client struct {
|
||||
Hostname string
|
||||
}
|
||||
|
||||
// Request is a type for sending
|
||||
// form values and form files to
|
||||
// the Gotenberg API.
|
||||
type Request interface {
|
||||
SetWebhookURL(webhookURL string)
|
||||
getPostURL() string
|
||||
getFormValues() map[string]string
|
||||
getFormFiles() map[string]string
|
||||
}
|
||||
|
||||
// ChromeRequest is a type for sending
|
||||
// conversion requests which will be
|
||||
// handle by Google Chrome.
|
||||
type ChromeRequest interface {
|
||||
SetHeader(fpath string) error
|
||||
SetFooter(fpath string) error
|
||||
SetPaperSize(size [2]float64)
|
||||
SetMargins(margins [4]float64)
|
||||
SetLandscape(isLandscape bool)
|
||||
SetWebFontsTimeout(timeout int64)
|
||||
}
|
||||
|
||||
// UnoconvRequest is a type for sending
|
||||
// conversion requests which will be
|
||||
// handle by unoconv.
|
||||
type UnoconvRequest interface {
|
||||
SetLandscape(landscape bool)
|
||||
}
|
||||
|
||||
// Post sends a request to the Gotenberg API
|
||||
// and returns the response.
|
||||
func (c *Client) Post(req Request) (*http.Response, error) {
|
||||
body, contentType, err := multipartForm(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
URL := fmt.Sprintf("%s%s", c.Hostname, req.getPostURL())
|
||||
resp, err := http.Post(URL, contentType, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Store creates the resulting PDF to given destination.
|
||||
func (c *Client) Store(req Request, dest string) error {
|
||||
if hasWebhook(req) {
|
||||
return errors.New("cannot use Store method with a webhook")
|
||||
}
|
||||
resp, err := c.Post(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return writeNewFile(dest, resp.Body)
|
||||
}
|
||||
|
||||
func hasWebhook(req Request) bool {
|
||||
webhookURL, ok := req.getFormValues()[webhookURL]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return webhookURL != ""
|
||||
}
|
||||
|
||||
func writeNewFile(fpath string, in io.Reader) error {
|
||||
if err := os.MkdirAll(filepath.Dir(fpath), 0755); err != nil {
|
||||
return fmt.Errorf("%s: making directory for file: %v", fpath, err)
|
||||
}
|
||||
out, err := os.Create(fpath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: creating new file: %v", fpath, err)
|
||||
}
|
||||
defer out.Close()
|
||||
err = out.Chmod(0644)
|
||||
if err != nil && runtime.GOOS != "windows" {
|
||||
return fmt.Errorf("%s: changing file mode: %v", fpath, err)
|
||||
}
|
||||
_, err = io.Copy(out, in)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: writing file: %v", fpath, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func fileExists(name string) bool {
|
||||
_, err := os.Stat(name)
|
||||
return !os.IsNotExist(err)
|
||||
}
|
||||
|
||||
func multipartForm(req Request) (*bytes.Buffer, string, error) {
|
||||
body := &bytes.Buffer{}
|
||||
writer := multipart.NewWriter(body)
|
||||
defer writer.Close()
|
||||
for filename, fpath := range req.getFormFiles() {
|
||||
in, err := os.Open(fpath)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("%s: opening file: %v", filename, err)
|
||||
}
|
||||
part, err := writer.CreateFormFile("files", filename)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("%s: creating form file: %v", filename, err)
|
||||
}
|
||||
_, err = io.Copy(part, in)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("%s: copying file: %v", filename, err)
|
||||
}
|
||||
}
|
||||
for name, value := range req.getFormValues() {
|
||||
if err := writer.WriteField(name, value); err != nil {
|
||||
return nil, "", fmt.Errorf("%s: writing form field: %v", name, err)
|
||||
}
|
||||
}
|
||||
return body, writer.FormDataContentType(), nil
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
/*
|
||||
Package gotenberg is a Go client for
|
||||
interacting with a Gotenberg API.
|
||||
|
||||
For more complete usages, head to the documentation:
|
||||
https://thecodingmachine.github.io/gotenberg/
|
||||
*/
|
||||
package gotenberg
|
||||
109
pkg/html.go
109
pkg/html.go
@@ -1,109 +0,0 @@
|
||||
package gotenberg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// HTMLRequest facilitates HTML conversion
|
||||
// with the Gotenberg API.
|
||||
type HTMLRequest struct {
|
||||
indexFilePath string
|
||||
headerFilePath string
|
||||
footerFilePath string
|
||||
assetFilePaths []string
|
||||
values map[string]string
|
||||
}
|
||||
|
||||
// NewHTMLRequest create HTMLRequest.
|
||||
func NewHTMLRequest(indexFilePath string) (*HTMLRequest, error) {
|
||||
if !fileExists(indexFilePath) {
|
||||
return nil, fmt.Errorf("%s: index file does not exist", indexFilePath)
|
||||
}
|
||||
return &HTMLRequest{indexFilePath: indexFilePath, values: make(map[string]string)}, nil
|
||||
}
|
||||
|
||||
// SetWebhookURL sets webhookURL form field.
|
||||
func (html *HTMLRequest) SetWebhookURL(webhookURL string) {
|
||||
html.values[webhookURL] = webhookURL
|
||||
}
|
||||
|
||||
// SetHeader sets header form file.
|
||||
func (html *HTMLRequest) SetHeader(fpath string) error {
|
||||
if !fileExists(fpath) {
|
||||
return fmt.Errorf("%s: header file does not exist", fpath)
|
||||
}
|
||||
html.headerFilePath = fpath
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetFooter sets footer form file.
|
||||
func (html *HTMLRequest) SetFooter(fpath string) error {
|
||||
if !fileExists(fpath) {
|
||||
return fmt.Errorf("%s: footer file does not exist", fpath)
|
||||
}
|
||||
html.footerFilePath = fpath
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetAssets sets assets form files.
|
||||
func (html *HTMLRequest) SetAssets(fpaths ...string) error {
|
||||
for _, fpath := range fpaths {
|
||||
if !fileExists(fpath) {
|
||||
return fmt.Errorf("%s: file does not exist", fpath)
|
||||
}
|
||||
}
|
||||
html.assetFilePaths = fpaths
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetPaperSize sets paperWidth and paperHeight form fields.
|
||||
func (html *HTMLRequest) SetPaperSize(size [2]float64) {
|
||||
html.values[paperWidth] = fmt.Sprintf("%f", size[0])
|
||||
html.values[paperHeight] = fmt.Sprintf("%f", size[1])
|
||||
}
|
||||
|
||||
// SetMargins sets marginTop, marginBottom,
|
||||
// marginLeft and marginRight form fields.
|
||||
func (html *HTMLRequest) SetMargins(margins [4]float64) {
|
||||
html.values[marginTop] = fmt.Sprintf("%f", margins[0])
|
||||
html.values[marginBottom] = fmt.Sprintf("%f", margins[1])
|
||||
html.values[marginLeft] = fmt.Sprintf("%f", margins[2])
|
||||
html.values[marginRight] = fmt.Sprintf("%f", margins[3])
|
||||
}
|
||||
|
||||
// SetLandscape sets landscape form field.
|
||||
func (html *HTMLRequest) SetLandscape(isLandscape bool) {
|
||||
html.values[landscape] = strconv.FormatBool(isLandscape)
|
||||
}
|
||||
|
||||
// SetWebFontsTimeout sets webFontsTimeout form field.
|
||||
func (html *HTMLRequest) SetWebFontsTimeout(timeout int64) {
|
||||
html.values[webFontsTimeout] = strconv.FormatInt(timeout, 10)
|
||||
}
|
||||
|
||||
func (html *HTMLRequest) getPostURL() string {
|
||||
return "/convert/html"
|
||||
}
|
||||
|
||||
func (html *HTMLRequest) getFormValues() map[string]string {
|
||||
return html.values
|
||||
}
|
||||
|
||||
func (html *HTMLRequest) getFormFiles() map[string]string {
|
||||
files := make(map[string]string)
|
||||
files["index.html"] = html.indexFilePath
|
||||
files["header.html"] = html.headerFilePath
|
||||
files["footer.html"] = html.footerFilePath
|
||||
for _, fpath := range html.assetFilePaths {
|
||||
files[filepath.Base(fpath)] = fpath
|
||||
}
|
||||
return files
|
||||
}
|
||||
|
||||
// Compile-time checks to ensure type implements desired interfaces.
|
||||
var (
|
||||
_ = Request(new(HTMLRequest))
|
||||
_ = ChromeRequest(new(HTMLRequest))
|
||||
)
|
||||
@@ -1,47 +0,0 @@
|
||||
package gotenberg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/thecodingmachine/gotenberg/internal/pkg/rand"
|
||||
"github.com/thecodingmachine/gotenberg/test"
|
||||
)
|
||||
|
||||
func TestHTML(t *testing.T) {
|
||||
c := &Client{Hostname: "http://localhost:3000"}
|
||||
req, err := NewHTMLRequest(test.HTMLTestFilePath(t, "index.html"))
|
||||
require.Nil(t, err)
|
||||
err = req.SetHeader(test.HTMLTestFilePath(t, "header.html"))
|
||||
require.Nil(t, err)
|
||||
err = req.SetFooter(test.HTMLTestFilePath(t, "footer.html"))
|
||||
require.Nil(t, err)
|
||||
err = req.SetAssets(
|
||||
test.HTMLTestFilePath(t, "font.woff"),
|
||||
test.HTMLTestFilePath(t, "img.gif"),
|
||||
test.HTMLTestFilePath(t, "style.css"),
|
||||
)
|
||||
require.Nil(t, err)
|
||||
req.SetPaperSize(A4)
|
||||
req.SetMargins(NormalMargins)
|
||||
req.SetLandscape(false)
|
||||
dirPath, err := rand.Get()
|
||||
require.Nil(t, err)
|
||||
dest := fmt.Sprintf("%s/foo.pdf", dirPath)
|
||||
err = c.Store(req, dest)
|
||||
assert.Nil(t, err)
|
||||
assert.FileExists(t, dest)
|
||||
err = os.RemoveAll(dirPath)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestConcurrentHTML(t *testing.T) {
|
||||
for i := 0; i < 10; i++ {
|
||||
go func() {
|
||||
TestHTML(t)
|
||||
}()
|
||||
}
|
||||
}
|
||||
122
pkg/markdown.go
122
pkg/markdown.go
@@ -1,122 +0,0 @@
|
||||
package gotenberg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// MarkdownRequest facilitates Markdown conversion
|
||||
// with the Gotenberg API.
|
||||
type MarkdownRequest struct {
|
||||
indexFilePath string
|
||||
markdownFilePaths []string
|
||||
headerFilePath string
|
||||
footerFilePath string
|
||||
assetFilePaths []string
|
||||
values map[string]string
|
||||
}
|
||||
|
||||
// NewMarkdownRequest create MarkdownRequest.
|
||||
func NewMarkdownRequest(indexFilePath string, markdownFilePaths ...string) (*MarkdownRequest, error) {
|
||||
if !fileExists(indexFilePath) {
|
||||
return nil, fmt.Errorf("%s: index file does not exist", indexFilePath)
|
||||
}
|
||||
for _, fpath := range markdownFilePaths {
|
||||
if !fileExists(fpath) {
|
||||
return nil, fmt.Errorf("%s: markdown file does not exist", fpath)
|
||||
}
|
||||
}
|
||||
return &MarkdownRequest{
|
||||
indexFilePath: indexFilePath,
|
||||
markdownFilePaths: markdownFilePaths,
|
||||
values: make(map[string]string),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SetWebhookURL sets webhookURL form field.
|
||||
func (markdown *MarkdownRequest) SetWebhookURL(webhookURL string) {
|
||||
markdown.values[webhookURL] = webhookURL
|
||||
}
|
||||
|
||||
// SetHeader sets header form file.
|
||||
func (markdown *MarkdownRequest) SetHeader(fpath string) error {
|
||||
if !fileExists(fpath) {
|
||||
return fmt.Errorf("%s: header file does not exist", fpath)
|
||||
}
|
||||
markdown.headerFilePath = fpath
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetFooter sets footer form file.
|
||||
func (markdown *MarkdownRequest) SetFooter(fpath string) error {
|
||||
if !fileExists(fpath) {
|
||||
return fmt.Errorf("%s: footer file does not exist", fpath)
|
||||
}
|
||||
markdown.footerFilePath = fpath
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetAssets sets assets form files.
|
||||
func (markdown *MarkdownRequest) SetAssets(fpaths ...string) error {
|
||||
for _, fpath := range fpaths {
|
||||
if !fileExists(fpath) {
|
||||
return fmt.Errorf("%s: file does not exist", fpath)
|
||||
}
|
||||
}
|
||||
markdown.assetFilePaths = fpaths
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetPaperSize sets paperWidth and paperHeight form fields.
|
||||
func (markdown *MarkdownRequest) SetPaperSize(size [2]float64) {
|
||||
markdown.values[paperWidth] = fmt.Sprintf("%f", size[0])
|
||||
markdown.values[paperHeight] = fmt.Sprintf("%f", size[1])
|
||||
}
|
||||
|
||||
// SetMargins sets marginTop, marginBottom,
|
||||
// marginLeft and marginRight form fields.
|
||||
func (markdown *MarkdownRequest) SetMargins(margins [4]float64) {
|
||||
markdown.values[marginTop] = fmt.Sprintf("%f", margins[0])
|
||||
markdown.values[marginBottom] = fmt.Sprintf("%f", margins[1])
|
||||
markdown.values[marginLeft] = fmt.Sprintf("%f", margins[2])
|
||||
markdown.values[marginRight] = fmt.Sprintf("%f", margins[3])
|
||||
}
|
||||
|
||||
// SetLandscape sets landscape form field.
|
||||
func (markdown *MarkdownRequest) SetLandscape(isLandscape bool) {
|
||||
markdown.values[landscape] = strconv.FormatBool(isLandscape)
|
||||
}
|
||||
|
||||
// SetWebFontsTimeout sets webFontsTimeout form field.
|
||||
func (markdown *MarkdownRequest) SetWebFontsTimeout(timeout int64) {
|
||||
markdown.values[webFontsTimeout] = strconv.FormatInt(timeout, 10)
|
||||
}
|
||||
|
||||
func (markdown *MarkdownRequest) getPostURL() string {
|
||||
return "/convert/markdown"
|
||||
}
|
||||
|
||||
func (markdown *MarkdownRequest) getFormValues() map[string]string {
|
||||
return markdown.values
|
||||
}
|
||||
|
||||
func (markdown *MarkdownRequest) getFormFiles() map[string]string {
|
||||
files := make(map[string]string)
|
||||
files["index.html"] = markdown.indexFilePath
|
||||
files["header.html"] = markdown.headerFilePath
|
||||
files["footer.html"] = markdown.footerFilePath
|
||||
for _, fpath := range markdown.markdownFilePaths {
|
||||
files[filepath.Base(fpath)] = fpath
|
||||
}
|
||||
for _, fpath := range markdown.assetFilePaths {
|
||||
files[filepath.Base(fpath)] = fpath
|
||||
}
|
||||
return files
|
||||
}
|
||||
|
||||
// Compile-time checks to ensure type implements desired interfaces.
|
||||
var (
|
||||
_ = Request(new(MarkdownRequest))
|
||||
_ = ChromeRequest(new(MarkdownRequest))
|
||||
)
|
||||
@@ -1,52 +0,0 @@
|
||||
package gotenberg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/thecodingmachine/gotenberg/internal/pkg/rand"
|
||||
"github.com/thecodingmachine/gotenberg/test"
|
||||
)
|
||||
|
||||
func TestMarkdown(t *testing.T) {
|
||||
c := &Client{Hostname: "http://localhost:3000"}
|
||||
req, err := NewMarkdownRequest(
|
||||
test.MarkdownTestFilePath(t, "index.html"),
|
||||
test.MarkdownTestFilePath(t, "paragraph1.md"),
|
||||
test.MarkdownTestFilePath(t, "paragraph2.md"),
|
||||
test.MarkdownTestFilePath(t, "paragraph3.md"),
|
||||
)
|
||||
require.Nil(t, err)
|
||||
err = req.SetHeader(test.MarkdownTestFilePath(t, "header.html"))
|
||||
require.Nil(t, err)
|
||||
err = req.SetFooter(test.MarkdownTestFilePath(t, "footer.html"))
|
||||
require.Nil(t, err)
|
||||
err = req.SetAssets(
|
||||
test.MarkdownTestFilePath(t, "font.woff"),
|
||||
test.MarkdownTestFilePath(t, "img.gif"),
|
||||
test.MarkdownTestFilePath(t, "style.css"),
|
||||
)
|
||||
require.Nil(t, err)
|
||||
req.SetPaperSize(A4)
|
||||
req.SetMargins(NormalMargins)
|
||||
req.SetLandscape(false)
|
||||
dirPath, err := rand.Get()
|
||||
require.Nil(t, err)
|
||||
dest := fmt.Sprintf("%s/foo.pdf", dirPath)
|
||||
err = c.Store(req, dest)
|
||||
assert.Nil(t, err)
|
||||
assert.FileExists(t, dest)
|
||||
err = os.RemoveAll(dirPath)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestConcurrentMarkdown(t *testing.T) {
|
||||
for i := 0; i < 10; i++ {
|
||||
go func() {
|
||||
TestMarkdown(t)
|
||||
}()
|
||||
}
|
||||
}
|
||||
49
pkg/merge.go
49
pkg/merge.go
@@ -1,49 +0,0 @@
|
||||
package gotenberg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// MergeRequest facilitates merging PDF
|
||||
// with the Gotenberg API.
|
||||
type MergeRequest struct {
|
||||
filePaths []string
|
||||
values map[string]string
|
||||
}
|
||||
|
||||
// NewMergeRequest create MergeRequest.
|
||||
func NewMergeRequest(fpaths ...string) (*MergeRequest, error) {
|
||||
for _, fpath := range fpaths {
|
||||
if !fileExists(fpath) {
|
||||
return nil, fmt.Errorf("%s: file does not exist", fpath)
|
||||
}
|
||||
}
|
||||
return &MergeRequest{filePaths: fpaths, values: make(map[string]string)}, nil
|
||||
}
|
||||
|
||||
// SetWebhookURL sets webhookURL form field.
|
||||
func (merge *MergeRequest) SetWebhookURL(webhookURL string) {
|
||||
merge.values[webhookURL] = webhookURL
|
||||
}
|
||||
|
||||
func (merge *MergeRequest) getPostURL() string {
|
||||
return "/merge"
|
||||
}
|
||||
|
||||
func (merge *MergeRequest) getFormValues() map[string]string {
|
||||
return merge.values
|
||||
}
|
||||
|
||||
func (merge *MergeRequest) getFormFiles() map[string]string {
|
||||
files := make(map[string]string)
|
||||
for _, fpath := range merge.filePaths {
|
||||
files[filepath.Base(fpath)] = fpath
|
||||
}
|
||||
return files
|
||||
}
|
||||
|
||||
// Compile-time checks to ensure type implements desired interfaces.
|
||||
var (
|
||||
_ = Request(new(MergeRequest))
|
||||
)
|
||||
@@ -1,37 +0,0 @@
|
||||
package gotenberg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/thecodingmachine/gotenberg/internal/pkg/rand"
|
||||
"github.com/thecodingmachine/gotenberg/test"
|
||||
)
|
||||
|
||||
func TestMerge(t *testing.T) {
|
||||
c := &Client{Hostname: "http://localhost:3000"}
|
||||
req, err := NewMergeRequest(
|
||||
test.PDFTestFilePath(t, "gotenberg.pdf"),
|
||||
test.PDFTestFilePath(t, "gotenberg.pdf"),
|
||||
)
|
||||
require.Nil(t, err)
|
||||
dirPath, err := rand.Get()
|
||||
require.Nil(t, err)
|
||||
dest := fmt.Sprintf("%s/foo.pdf", dirPath)
|
||||
err = c.Store(req, dest)
|
||||
assert.Nil(t, err)
|
||||
assert.FileExists(t, dest)
|
||||
err = os.RemoveAll(dirPath)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestConcurrentMerge(t *testing.T) {
|
||||
for i := 0; i < 10; i++ {
|
||||
go func() {
|
||||
TestMerge(t)
|
||||
}()
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
package gotenberg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// OfficeRequest facilitates Office documents
|
||||
// conversion with the Gotenberg API.
|
||||
type OfficeRequest struct {
|
||||
filePaths []string
|
||||
values map[string]string
|
||||
}
|
||||
|
||||
// NewOfficeRequest create OfficeRequest.
|
||||
func NewOfficeRequest(fpaths ...string) (*OfficeRequest, error) {
|
||||
for _, fpath := range fpaths {
|
||||
if !fileExists(fpath) {
|
||||
return nil, fmt.Errorf("%s: file does not exist", fpath)
|
||||
}
|
||||
}
|
||||
return &OfficeRequest{filePaths: fpaths, values: make(map[string]string)}, nil
|
||||
}
|
||||
|
||||
// SetWebhookURL sets webhookURL form field.
|
||||
func (office *OfficeRequest) SetWebhookURL(webhookURL string) {
|
||||
office.values[webhookURL] = webhookURL
|
||||
}
|
||||
|
||||
// SetLandscape sets landscape form field.
|
||||
func (office *OfficeRequest) SetLandscape(isLandscape bool) {
|
||||
office.values[landscape] = strconv.FormatBool(isLandscape)
|
||||
}
|
||||
|
||||
func (office *OfficeRequest) getPostURL() string {
|
||||
return "/convert/office"
|
||||
}
|
||||
|
||||
func (office *OfficeRequest) getFormValues() map[string]string {
|
||||
return office.values
|
||||
}
|
||||
|
||||
func (office *OfficeRequest) getFormFiles() map[string]string {
|
||||
files := make(map[string]string)
|
||||
for _, fpath := range office.filePaths {
|
||||
files[filepath.Base(fpath)] = fpath
|
||||
}
|
||||
return files
|
||||
}
|
||||
|
||||
// Compile-time checks to ensure type implements desired interfaces.
|
||||
var (
|
||||
_ = Request(new(OfficeRequest))
|
||||
_ = UnoconvRequest(new(OfficeRequest))
|
||||
)
|
||||
@@ -1,35 +0,0 @@
|
||||
package gotenberg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/thecodingmachine/gotenberg/internal/pkg/rand"
|
||||
"github.com/thecodingmachine/gotenberg/test"
|
||||
)
|
||||
|
||||
func TestOffice(t *testing.T) {
|
||||
c := &Client{Hostname: "http://localhost:3000"}
|
||||
req, err := NewOfficeRequest(test.OfficeTestFilePath(t, "document.docx"))
|
||||
require.Nil(t, err)
|
||||
req.SetLandscape(false)
|
||||
dirPath, err := rand.Get()
|
||||
require.Nil(t, err)
|
||||
dest := fmt.Sprintf("%s/foo.pdf", dirPath)
|
||||
err = c.Store(req, dest)
|
||||
assert.Nil(t, err)
|
||||
assert.FileExists(t, dest)
|
||||
err = os.RemoveAll(dirPath)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestConcurrentOffice(t *testing.T) {
|
||||
for i := 0; i < 10; i++ {
|
||||
go func() {
|
||||
TestOffice(t)
|
||||
}()
|
||||
}
|
||||
}
|
||||
90
pkg/url.go
90
pkg/url.go
@@ -1,90 +0,0 @@
|
||||
package gotenberg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// URLRequest facilitates remote URL conversion
|
||||
// with the Gotenberg API.
|
||||
type URLRequest struct {
|
||||
headerFilePath string
|
||||
footerFilePath string
|
||||
values map[string]string
|
||||
}
|
||||
|
||||
// NewURLRequest create URLRequest.
|
||||
func NewURLRequest(URL string) *URLRequest {
|
||||
req := &URLRequest{values: make(map[string]string)}
|
||||
req.values[remoteURL] = URL
|
||||
return req
|
||||
}
|
||||
|
||||
// SetWebhookURL sets webhookURL form field.
|
||||
func (url *URLRequest) SetWebhookURL(webhookURL string) {
|
||||
url.values[webhookURL] = webhookURL
|
||||
}
|
||||
|
||||
// SetHeader sets header form file.
|
||||
func (url *URLRequest) SetHeader(fpath string) error {
|
||||
if !fileExists(fpath) {
|
||||
return fmt.Errorf("%s: header file does not exist", fpath)
|
||||
}
|
||||
url.headerFilePath = fpath
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetFooter sets footer form file.
|
||||
func (url *URLRequest) SetFooter(fpath string) error {
|
||||
if !fileExists(fpath) {
|
||||
return fmt.Errorf("%s: footer file does not exist", fpath)
|
||||
}
|
||||
url.footerFilePath = fpath
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetPaperSize sets paperWidth and paperHeight form fields.
|
||||
func (url *URLRequest) SetPaperSize(size [2]float64) {
|
||||
url.values[paperWidth] = fmt.Sprintf("%f", size[0])
|
||||
url.values[paperHeight] = fmt.Sprintf("%f", size[1])
|
||||
}
|
||||
|
||||
// SetMargins sets marginTop, marginBottom,
|
||||
// marginLeft and marginRight form fields.
|
||||
func (url *URLRequest) SetMargins(margins [4]float64) {
|
||||
url.values[marginTop] = fmt.Sprintf("%f", margins[0])
|
||||
url.values[marginBottom] = fmt.Sprintf("%f", margins[1])
|
||||
url.values[marginLeft] = fmt.Sprintf("%f", margins[2])
|
||||
url.values[marginRight] = fmt.Sprintf("%f", margins[3])
|
||||
}
|
||||
|
||||
// SetLandscape sets landscape form field.
|
||||
func (url *URLRequest) SetLandscape(isLandscape bool) {
|
||||
url.values[landscape] = strconv.FormatBool(isLandscape)
|
||||
}
|
||||
|
||||
// SetWebFontsTimeout sets webFontsTimeout form field.
|
||||
func (url *URLRequest) SetWebFontsTimeout(timeout int64) {
|
||||
url.values[webFontsTimeout] = strconv.FormatInt(timeout, 10)
|
||||
}
|
||||
|
||||
func (url *URLRequest) getPostURL() string {
|
||||
return "/convert/url"
|
||||
}
|
||||
|
||||
func (url *URLRequest) getFormValues() map[string]string {
|
||||
return url.values
|
||||
}
|
||||
|
||||
func (url *URLRequest) getFormFiles() map[string]string {
|
||||
files := make(map[string]string)
|
||||
files["header.html"] = url.headerFilePath
|
||||
files["footer.html"] = url.footerFilePath
|
||||
return files
|
||||
}
|
||||
|
||||
// Compile-time checks to ensure type implements desired interfaces.
|
||||
var (
|
||||
_ = Request(new(URLRequest))
|
||||
_ = ChromeRequest(new(URLRequest))
|
||||
)
|
||||
@@ -1,41 +0,0 @@
|
||||
package gotenberg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/thecodingmachine/gotenberg/internal/pkg/rand"
|
||||
"github.com/thecodingmachine/gotenberg/test"
|
||||
)
|
||||
|
||||
func TestURL(t *testing.T) {
|
||||
c := &Client{Hostname: "http://localhost:3000"}
|
||||
req := NewURLRequest("http://google.com")
|
||||
err := req.SetHeader(test.URLTestFilePath(t, "header.html"))
|
||||
require.Nil(t, err)
|
||||
err = req.SetFooter(test.URLTestFilePath(t, "footer.html"))
|
||||
require.Nil(t, err)
|
||||
require.Nil(t, err)
|
||||
req.SetPaperSize(A4)
|
||||
req.SetMargins(NormalMargins)
|
||||
req.SetLandscape(false)
|
||||
dirPath, err := rand.Get()
|
||||
require.Nil(t, err)
|
||||
dest := fmt.Sprintf("%s/foo.pdf", dirPath)
|
||||
err = c.Store(req, dest)
|
||||
assert.Nil(t, err)
|
||||
assert.FileExists(t, dest)
|
||||
err = os.RemoveAll(dirPath)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestConcurrentURL(t *testing.T) {
|
||||
for i := 0; i < 10; i++ {
|
||||
go func() {
|
||||
TestURL(t)
|
||||
}()
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ DOCKER_PASSWORD="$4"
|
||||
|
||||
docker login -u "$DOCKER_USER" -p "$DOCKER_PASSWORD"
|
||||
|
||||
VERSION="${VERSION//v}"
|
||||
SEMVER=( ${VERSION//./ } )
|
||||
VERSION_LENGTH=${#SEMVER[@]}
|
||||
|
||||
|
||||
@@ -138,36 +138,6 @@ func copyDir(t *testing.T, kind string) string {
|
||||
return tmpDirPath
|
||||
}
|
||||
|
||||
// HTMLTestFilePath returns the absolute file path
|
||||
// of a file in "html" folder in test/testdata.
|
||||
func HTMLTestFilePath(t *testing.T, filename string) string {
|
||||
return abs(t, "html", filename)
|
||||
}
|
||||
|
||||
// URLTestFilePath returns the absolute file path
|
||||
// of a file in "url" folder in test/testdata.
|
||||
func URLTestFilePath(t *testing.T, filename string) string {
|
||||
return abs(t, "url", filename)
|
||||
}
|
||||
|
||||
// MarkdownTestFilePath returns the absolute file path
|
||||
// of a file in "markdown" folder in test/testdata.
|
||||
func MarkdownTestFilePath(t *testing.T, filename string) string {
|
||||
return abs(t, "markdown", filename)
|
||||
}
|
||||
|
||||
// OfficeTestFilePath returns the absolute file path
|
||||
// of a file in "office" folder in test/testdata.
|
||||
func OfficeTestFilePath(t *testing.T, filename string) string {
|
||||
return abs(t, "office", filename)
|
||||
}
|
||||
|
||||
// PDFTestFilePath returns the absolute file path
|
||||
// of a file in "pdf" folder in test/testdata.
|
||||
func PDFTestFilePath(t *testing.T, filename string) string {
|
||||
return abs(t, "pdf", filename)
|
||||
}
|
||||
|
||||
func abs(t *testing.T, kind, filename string) string {
|
||||
_, gofilename, _, ok := runtime.Caller(0)
|
||||
require.Equal(t, ok, true, "got no caller information")
|
||||
|
||||
Reference in New Issue
Block a user