Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8a4a043e9f | ||
|
|
c0297aa061 | ||
|
|
2aaa2eeaff | ||
|
|
5f62e5bacf | ||
|
|
ab78559710 | ||
|
|
0d75bb1d3e | ||
|
|
6441062e7f | ||
|
|
4827a45f22 | ||
|
|
40eef457ab | ||
|
|
c22a4d109b | ||
|
|
571c3e04c4 | ||
|
|
f9fb97a572 | ||
|
|
e6484bb2d5 | ||
|
|
19f51fdc1f | ||
|
|
25f7ba3ee6 | ||
|
|
a3cd1ff4e1 | ||
|
|
f62c717f79 | ||
|
|
3ed99133d4 | ||
|
|
ab25cc331d | ||
|
|
2648992a9b | ||
|
|
7bcc3d081e | ||
|
|
affd1c45ca | ||
|
|
8c7458812d |
2
.github/CONTRIBUTING.md
vendored
@@ -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.11)
|
2. Verify your Go version (>= 1.12)
|
||||||
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)
|
||||||
|
|
||||||
|
|||||||
3
Makefile
@@ -1,4 +1,4 @@
|
|||||||
GOLANG_VERSION=1.11.2
|
GOLANG_VERSION=1.12
|
||||||
VERSION=snapshot
|
VERSION=snapshot
|
||||||
DOCKER_USER=
|
DOCKER_USER=
|
||||||
DOCKER_PASSWORD=
|
DOCKER_PASSWORD=
|
||||||
@@ -11,6 +11,7 @@ doc:
|
|||||||
# gofmt and goimports all go files.
|
# gofmt and goimports all go files.
|
||||||
fmt:
|
fmt:
|
||||||
go fmt ./...
|
go fmt ./...
|
||||||
|
go mod tidy
|
||||||
|
|
||||||
# run all linters.
|
# run all linters.
|
||||||
lint:
|
lint:
|
||||||
|
|||||||
@@ -16,14 +16,14 @@ 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
|
* 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
|
* 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!
|
* 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
|
## Quick start
|
||||||
|
|
||||||
Open a terminal and run the following command:
|
Open a terminal and run the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ docker run --rm -p 3000:3000 thecodingmachine/gotenberg:3
|
$ docker run --rm -p 3000:3000 thecodingmachine/gotenberg:4
|
||||||
```
|
```
|
||||||
|
|
||||||
The API is now available on your host at `http://localhost:3000`.
|
The API is now available on your host at `http://localhost:3000`.
|
||||||
@@ -33,7 +33,7 @@ to learn how to interact with it!
|
|||||||
|
|
||||||
## Badges
|
## Badges
|
||||||
|
|
||||||
[](https://microbadger.com/images/thecodingmachine/gotenberg:3)
|
[](https://microbadger.com/images/thecodingmachine/gotenberg:4)
|
||||||
[](https://travis-ci.org/thecodingmachine/gotenberg)
|
[](https://travis-ci.org/thecodingmachine/gotenberg)
|
||||||
[](https://godoc.org/github.com/thecodingmachine/gotenberg)
|
[](https://godoc.org/github.com/thecodingmachine/gotenberg)
|
||||||
[](https://goreportcard.com/report/thecodingmachine/gotenberg)
|
[](https://goreportcard.com/report/thecodingmachine/gotenberg)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
FROM thecodingmachine/gotenberg:3.2.0 AS hack
|
||||||
FROM debian:9.5-slim
|
FROM debian:9.5-slim
|
||||||
|
|
||||||
# |--------------------------------------------------------------------------
|
# |--------------------------------------------------------------------------
|
||||||
@@ -9,7 +10,7 @@ FROM debian:9.5-slim
|
|||||||
|
|
||||||
RUN echo "deb http://httpredir.debian.org/debian/ stretch main contrib non-free" > /etc/apt/sources.list &&\
|
RUN echo "deb http://httpredir.debian.org/debian/ stretch main contrib non-free" > /etc/apt/sources.list &&\
|
||||||
apt-get update &&\
|
apt-get update &&\
|
||||||
apt-get install -y curl wget python3-pip
|
apt-get install -y curl wget python3-pip ttf-mscorefonts-installer
|
||||||
|
|
||||||
# |--------------------------------------------------------------------------
|
# |--------------------------------------------------------------------------
|
||||||
# | PM2
|
# | PM2
|
||||||
@@ -19,7 +20,19 @@ RUN echo "deb http://httpredir.debian.org/debian/ stretch main contrib non-free"
|
|||||||
# | recovering. In our case: Chrome (headless) and Office (headless).
|
# | recovering. In our case: Chrome (headless) and Office (headless).
|
||||||
# |
|
# |
|
||||||
|
|
||||||
RUN curl -sL https://raw.githubusercontent.com/Unitech/pm2/master/packager/setup.deb.sh | bash -
|
# Yep, this is dirty. The following script does not work anymore (see https://github.com/Unitech/pm2/issues/4127).
|
||||||
|
#RUN curl -sL https://raw.githubusercontent.com/Unitech/pm2/master/packager/setup.deb.sh | bash -
|
||||||
|
|
||||||
|
# Installing PM2 with Node.js and npm breaks something which prevents Google Chrome to work as expected.
|
||||||
|
# So we just copy all PM2 related files from a previous version of Gotenberg.
|
||||||
|
|
||||||
|
RUN curl -sL https://deb.nodesource.com/setup_9.x | bash - &&\
|
||||||
|
apt-get install -y nodejs
|
||||||
|
|
||||||
|
COPY --from=hack /usr/bin/pm2 /usr/bin/pm2
|
||||||
|
COPY --from=hack /usr/share/pm2 /usr/share/pm2
|
||||||
|
COPY --from=hack /etc/default/pm2 /etc/default/pm2
|
||||||
|
COPY --from=hack /etc/systemd/system/pm2.service /etc/systemd/system/pm2.service
|
||||||
|
|
||||||
# |--------------------------------------------------------------------------
|
# |--------------------------------------------------------------------------
|
||||||
# | Chrome
|
# | Chrome
|
||||||
@@ -53,4 +66,39 @@ RUN pip3 install unoconv &&\
|
|||||||
# | https://github.com/thecodingmachine/gotenberg/issues/29
|
# | https://github.com/thecodingmachine/gotenberg/issues/29
|
||||||
# |
|
# |
|
||||||
|
|
||||||
RUN apt-get -y install pdftk
|
RUN apt-get -y install pdftk
|
||||||
|
|
||||||
|
# |--------------------------------------------------------------------------
|
||||||
|
# | Fonts
|
||||||
|
# |--------------------------------------------------------------------------
|
||||||
|
# |
|
||||||
|
# | Installs a handful of fonts.
|
||||||
|
# | Note: ttf-mscorefonts-installer are installed on top of this Dockerfile.
|
||||||
|
# |
|
||||||
|
|
||||||
|
# Credits:
|
||||||
|
# https://github.com/arachnys/athenapdf/blob/master/cli/Dockerfile
|
||||||
|
# https://help.accusoft.com/PrizmDoc/v12.1/HTML/Installing_Asian_Fonts_on_Ubuntu_and_Debian.html
|
||||||
|
RUN apt-get install -y \
|
||||||
|
culmus \
|
||||||
|
fonts-beng \
|
||||||
|
fonts-hosny-amiri \
|
||||||
|
fonts-lklug-sinhala \
|
||||||
|
fonts-lohit-guru \
|
||||||
|
fonts-lohit-knda \
|
||||||
|
fonts-samyak-gujr \
|
||||||
|
fonts-samyak-mlym \
|
||||||
|
fonts-samyak-taml \
|
||||||
|
fonts-sarai \
|
||||||
|
fonts-sil-abyssinica \
|
||||||
|
fonts-sil-padauk \
|
||||||
|
fonts-telu \
|
||||||
|
fonts-thai-tlwg \
|
||||||
|
ttf-liberation \
|
||||||
|
ttf-wqy-zenhei \
|
||||||
|
fonts-arphic-uming \
|
||||||
|
fonts-ipafont-mincho \
|
||||||
|
fonts-ipafont-gothic \
|
||||||
|
fonts-unfonts-core
|
||||||
|
|
||||||
|
COPY build/base/fonts.conf /etc/fonts/conf.d/100-gotenberg.conf
|
||||||
|
|||||||
29
build/base/fonts.conf
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?xml version='1.0'?>
|
||||||
|
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
|
||||||
|
<fontconfig>
|
||||||
|
<match target="font">
|
||||||
|
<edit mode="assign" name="rgba">
|
||||||
|
<const>rgb</const>
|
||||||
|
</edit>
|
||||||
|
</match>
|
||||||
|
<match target="font">
|
||||||
|
<edit mode="assign" name="hinting">
|
||||||
|
<bool>true</bool>
|
||||||
|
</edit>
|
||||||
|
</match>
|
||||||
|
<match target="font">
|
||||||
|
<edit mode="assign" name="hintstyle">
|
||||||
|
<const>hintslight</const>
|
||||||
|
</edit>
|
||||||
|
</match>
|
||||||
|
<match target="font">
|
||||||
|
<edit mode="assign" name="antialias">
|
||||||
|
<bool>true</bool>
|
||||||
|
</edit>
|
||||||
|
</match>
|
||||||
|
<match target="font">
|
||||||
|
<edit mode="assign" name="lcdfilter">
|
||||||
|
<const>lcddefault</const>
|
||||||
|
</edit>
|
||||||
|
</match>
|
||||||
|
</fontconfig>
|
||||||
@@ -9,4 +9,4 @@ title: Introduction
|
|||||||
* Performance: Google Chrome and Libreoffice (unoconv) started once in the background thanks to PM2
|
* Performance: Google Chrome and Libreoffice (unoconv) started once in the background thanks to PM2
|
||||||
* Failure prevention: PM2 automatically restarts previous processes if they fail
|
* 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!
|
* 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
|
||||||
@@ -7,7 +7,7 @@ Gotenberg is shipped within a Docker image.
|
|||||||
You may start it with:
|
You may start it with:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ docker run --rm -p 3000:3000 thecodingmachine/gotenberg:3
|
$ docker run --rm -p 3000:3000 thecodingmachine/gotenberg:4
|
||||||
```
|
```
|
||||||
|
|
||||||
> The API will be available at [http://localhost:3000](http://localhost:3000).
|
> The API will be available at [http://localhost:3000](http://localhost:3000).
|
||||||
@@ -22,7 +22,7 @@ services:
|
|||||||
# your others services
|
# your others services
|
||||||
|
|
||||||
gotenberg:
|
gotenberg:
|
||||||
image: thecodingmachine/gotenberg:3
|
image: thecodingmachine/gotenberg:4
|
||||||
```
|
```
|
||||||
|
|
||||||
> The API will be available under `gotenberg:3000` in your Docker Compose network.
|
> The API will be available under `gotenberg:3000` in your Docker Compose network.
|
||||||
@@ -35,7 +35,7 @@ Gotenberg API is available at [http://localhost:3000](http://localhost:3000).
|
|||||||
## Go client
|
## Go client
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ go get -u github.com/thecodingmachine/gotenberg
|
$ go get -u github.com/thecodingmachine/gotenberg-go-client/v4
|
||||||
```
|
```
|
||||||
|
|
||||||
## PHP client
|
## PHP client
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ $ curl --request POST \
|
|||||||
### Go
|
### Go
|
||||||
|
|
||||||
```golang
|
```golang
|
||||||
import "github.com/thecodingmachine/gotenberg/pkg"
|
import "github.com/thecodingmachine/gotenberg-go-client/v4"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||||
@@ -113,7 +113,7 @@ $ curl --request POST \
|
|||||||
### Go
|
### Go
|
||||||
|
|
||||||
```golang
|
```golang
|
||||||
import "github.com/thecodingmachine/gotenberg/pkg"
|
import "github.com/thecodingmachine/gotenberg-go-client/v4"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||||
@@ -185,7 +185,10 @@ But this won't:
|
|||||||
You may also use *remote* paths for Google fonts, images and so on.
|
You may also use *remote* paths for Google fonts, images and so on.
|
||||||
|
|
||||||
> If you want to install fonts directly in the Gotenberg Docker image,
|
> If you want to install fonts directly in the Gotenberg Docker image,
|
||||||
> see to the [fonts section](#office.fonts).
|
> see to the [fonts section](#fonts).
|
||||||
|
>
|
||||||
|
> For web fonts (Google fonts), there is a timeout of 500ms by default. You may update
|
||||||
|
> this value thanks to the form field `webFontsTimeout`.
|
||||||
|
|
||||||
### cURL
|
### cURL
|
||||||
|
|
||||||
@@ -203,16 +206,12 @@ $ curl --request POST \
|
|||||||
### Go
|
### Go
|
||||||
|
|
||||||
```golang
|
```golang
|
||||||
import "github.com/thecodingmachine/gotenberg/pkg"
|
import "github.com/thecodingmachine/gotenberg-go-client/v4"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||||
req, _ := gotenberg.NewHTMLRequest("index.html")
|
req, _ := gotenberg.NewHTMLRequest("index.html")
|
||||||
req.SetAssets([]string{
|
req.SetAssets("font.woff", "img.gif", "style.css")
|
||||||
"font.woff",
|
|
||||||
"img.gif",
|
|
||||||
"style.css",
|
|
||||||
})
|
|
||||||
dest := "result.pdf"
|
dest := "result.pdf"
|
||||||
c.Store(req, dest)
|
c.Store(req, dest)
|
||||||
}
|
}
|
||||||
@@ -234,8 +233,8 @@ $assets = [
|
|||||||
];
|
];
|
||||||
$request = new HTMLRequest($index);
|
$request = new HTMLRequest($index);
|
||||||
$request->setAssets($assets);
|
$request->setAssets($assets);
|
||||||
$dirPath = "/foo";
|
$dest = "result.pdf";
|
||||||
$filename = $client->store($request, $dirPath);
|
$client->store($request, $dest);
|
||||||
```
|
```
|
||||||
|
|
||||||
## Paper size, margins, orientation
|
## Paper size, margins, orientation
|
||||||
@@ -267,7 +266,7 @@ $ curl --request POST \
|
|||||||
### Go
|
### Go
|
||||||
|
|
||||||
```golang
|
```golang
|
||||||
import "github.com/thecodingmachine/gotenberg/pkg"
|
import "github.com/thecodingmachine/gotenberg-go-client/v4"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||||
@@ -294,6 +293,6 @@ $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);
|
||||||
$dirPath = "/foo";
|
$dest = "result.pdf";
|
||||||
$filename = $client->store($request, $dirPath);
|
$client->store($request, $dest);
|
||||||
```
|
```
|
||||||
56
build/docs/content/03-url.md
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
---
|
||||||
|
title: URL
|
||||||
|
---
|
||||||
|
|
||||||
|
Gotenberg provides the endpoint `/convert/url` for remote URL conversions.
|
||||||
|
|
||||||
|
It accepts `POST` requests with a `multipart/form-data` Content-Type.
|
||||||
|
|
||||||
|
## Basic
|
||||||
|
|
||||||
|
This endpoint does not accept an `index.html` file nor assets files but a form field
|
||||||
|
named `remoteURL` instead. Otherwise, URL conversions work the same as HTML conversions.
|
||||||
|
|
||||||
|
> **Attention:** when converting a website to PDF, you should remove all margins.
|
||||||
|
> If not, some of the content of the page might be hidden.
|
||||||
|
|
||||||
|
### cURL
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ curl --request POST \
|
||||||
|
--url http://localhost:3000/convert/url \
|
||||||
|
--header 'Content-Type: multipart/form-data' \
|
||||||
|
--form remoteURL=https://google.com
|
||||||
|
--form marginTop=0 \
|
||||||
|
--form marginBottom=0 \
|
||||||
|
--form marginLeft=0 \
|
||||||
|
--form marginRight=0 \
|
||||||
|
-o result.pdf
|
||||||
|
```
|
||||||
|
|
||||||
|
### Go
|
||||||
|
|
||||||
|
```golang
|
||||||
|
import "github.com/thecodingmachine/gotenberg-go-client/v4"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||||
|
req := gotenberg.NewURLRequest("https://google.com")
|
||||||
|
req.SetMargins(gotenberg.NoMargins)
|
||||||
|
dest := "result.pdf"
|
||||||
|
c.Store(req, dest)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### PHP
|
||||||
|
|
||||||
|
```php
|
||||||
|
use TheCodingMachine\Gotenberg\Client;
|
||||||
|
use TheCodingMachine\Gotenberg\URLRequest;
|
||||||
|
|
||||||
|
$client = new Client('http://localhost:3000', new \Http\Adapter\Guzzle6\Client());
|
||||||
|
$request = new URLRequest('https://google.com');
|
||||||
|
$request->setMargins(Request::NO_MARGINS);
|
||||||
|
$dest = "result.pdf";
|
||||||
|
$client->store($request, $dest);
|
||||||
|
```
|
||||||
@@ -42,11 +42,11 @@ $ curl --request POST \
|
|||||||
### Go
|
### Go
|
||||||
|
|
||||||
```golang
|
```golang
|
||||||
import "github.com/thecodingmachine/gotenberg/pkg"
|
import "github.com/thecodingmachine/gotenberg-go-client/v4"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||||
req, _ := gotenberg.NewMarkdownRequest("index.html", []string{"file.md"})
|
req, _ := gotenberg.NewMarkdownRequest("index.html", "file.md")
|
||||||
dest := "result.pdf"
|
dest := "result.pdf"
|
||||||
c.Store(req, dest)
|
c.Store(req, dest)
|
||||||
}
|
}
|
||||||
@@ -65,6 +65,6 @@ $markdowns = [
|
|||||||
DocumentFactory::makeFromPath('file.md', 'file.md'),
|
DocumentFactory::makeFromPath('file.md', 'file.md'),
|
||||||
];
|
];
|
||||||
$request = new MarkdownRequest($index, $markdowns);
|
$request = new MarkdownRequest($index, $markdowns);
|
||||||
$dirPath = "/foo";
|
$dest = "result.pdf";
|
||||||
$filename = $client->store($request, $dirPath);
|
$client->store($request, $dest);
|
||||||
```
|
```
|
||||||
@@ -12,6 +12,7 @@ You may send one or more Office documents. Following file extensions are accepte
|
|||||||
|
|
||||||
* `.txt`
|
* `.txt`
|
||||||
* `.rtf`
|
* `.rtf`
|
||||||
|
* `.fodt`
|
||||||
* `.doc`
|
* `.doc`
|
||||||
* `.docx`
|
* `.docx`
|
||||||
* `.odt`
|
* `.odt`
|
||||||
@@ -42,11 +43,11 @@ $ curl --request POST \
|
|||||||
### Go
|
### Go
|
||||||
|
|
||||||
```golang
|
```golang
|
||||||
import "github.com/thecodingmachine/gotenberg/pkg"
|
import "github.com/thecodingmachine/gotenberg-go-client/v4"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||||
req, _ := gotenberg.NewOfficeRequest([]string{"document.docx", "document2.docx"})
|
req, _ := gotenberg.NewOfficeRequest("document.docx", "document2.docx")
|
||||||
dest := "result.pdf"
|
dest := "result.pdf"
|
||||||
c.Store(req, dest)
|
c.Store(req, dest)
|
||||||
}
|
}
|
||||||
@@ -65,18 +66,15 @@ $files = [
|
|||||||
DocumentFactory::makeFromPath('document2.docx', 'document2.docx'),
|
DocumentFactory::makeFromPath('document2.docx', 'document2.docx'),
|
||||||
];
|
];
|
||||||
$request = new OfficeRequest($files);
|
$request = new OfficeRequest($files);
|
||||||
$dirPath = "/foo";
|
$dest = "result.pdf";
|
||||||
$filename = $client->store($request, $dirPath);
|
$client->store($request, $dest);
|
||||||
```
|
```
|
||||||
|
|
||||||
## Paper size and orientation
|
## Orientation
|
||||||
|
|
||||||
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 and `portrait` orientation.
|
By default, it will be rendered with `portrait` orientation.
|
||||||
|
|
||||||
> Paper size has to be provided in `inches`.
|
|
||||||
> Also, you have to set both `paperWidth` and `paperHeight`.
|
|
||||||
|
|
||||||
### cURL
|
### cURL
|
||||||
|
|
||||||
@@ -85,8 +83,6 @@ $ curl --request POST \
|
|||||||
--url http://localhost:3000/convert/office \
|
--url http://localhost:3000/convert/office \
|
||||||
--header 'Content-Type: multipart/form-data' \
|
--header 'Content-Type: multipart/form-data' \
|
||||||
--form files=@document.docx \
|
--form files=@document.docx \
|
||||||
--form paperWidth=8.27 \
|
|
||||||
--form paperHeight=11.27 \
|
|
||||||
--form landscape=true \
|
--form landscape=true \
|
||||||
-o result.pdf
|
-o result.pdf
|
||||||
```
|
```
|
||||||
@@ -94,12 +90,11 @@ $ curl --request POST \
|
|||||||
### Go
|
### Go
|
||||||
|
|
||||||
```golang
|
```golang
|
||||||
import "github.com/thecodingmachine/gotenberg/pkg"
|
import "github.com/thecodingmachine/gotenberg-go-client/v4"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||||
req, _ := gotenberg.NewOfficeRequest([]string{"document.docx"})
|
req, _ := gotenberg.NewOfficeRequest("document.docx")
|
||||||
req.SetPaperSize(gotenberg.A4)
|
|
||||||
req.SetLandscape(true)
|
req.SetLandscape(true)
|
||||||
dest := "result.pdf"
|
dest := "result.pdf"
|
||||||
c.Store(req, dest)
|
c.Store(req, dest)
|
||||||
@@ -118,20 +113,7 @@ $files = [
|
|||||||
DocumentFactory::makeFromPath('document.docx', 'document.docx'),
|
DocumentFactory::makeFromPath('document.docx', 'document.docx'),
|
||||||
];
|
];
|
||||||
$request = new OfficeRequest($files);
|
$request = new OfficeRequest($files);
|
||||||
$request->setPaperSize(Request::A4);
|
|
||||||
$request->setLandscape(true);
|
$request->setLandscape(true);
|
||||||
$dirPath = "/foo";
|
$dest = "result.pdf";
|
||||||
$filename = $client->store($request, $dirPath);
|
$client->store($request, $dest);
|
||||||
```
|
|
||||||
|
|
||||||
## Fonts
|
|
||||||
|
|
||||||
By default, only `ttf-mscorefonts` fonts are installed.
|
|
||||||
|
|
||||||
If you wish to use more fonts, you will have to create your own image:
|
|
||||||
|
|
||||||
```Dockerfile
|
|
||||||
FROM thecodingmachine/gotenberg:3
|
|
||||||
|
|
||||||
RUN apt-get -y install yourfonts
|
|
||||||
```
|
```
|
||||||
@@ -8,9 +8,11 @@ It accepts `POST` requests with a `multipart/form-data` Content-Type.
|
|||||||
|
|
||||||
## Basic
|
## Basic
|
||||||
|
|
||||||
Nothing special here: you may send one or more PDF files and the API
|
Nothing fancy here: you may send one or more PDF files and the API
|
||||||
will merge them and return the resulting PDF file.
|
will merge them and return the resulting PDF file.
|
||||||
|
|
||||||
|
> **Attention:** Gotenberg merges the PDF files alphabetically.
|
||||||
|
|
||||||
### cURL
|
### cURL
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -25,11 +27,11 @@ $ curl --request POST \
|
|||||||
### Go
|
### Go
|
||||||
|
|
||||||
```golang
|
```golang
|
||||||
import "github.com/thecodingmachine/gotenberg/pkg"
|
import "github.com/thecodingmachine/gotenberg-go-client/v4"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||||
req, _ := gotenberg.NewMergeRequest([]string{"file.pdf", "file2.pdf"})
|
req, _ := gotenberg.NewMergeRequest("file.pdf", "file2.pdf")
|
||||||
dest := "result.pdf"
|
dest := "result.pdf"
|
||||||
c.Store(req, dest)
|
c.Store(req, dest)
|
||||||
}
|
}
|
||||||
@@ -48,6 +50,6 @@ $files = [
|
|||||||
DocumentFactory::makeFromPath('file2.pdf', 'file2.pdf'),
|
DocumentFactory::makeFromPath('file2.pdf', 'file2.pdf'),
|
||||||
];
|
];
|
||||||
$request = new MergeRequest($files);
|
$request = new MergeRequest($files);
|
||||||
$dirPath = "/foo";
|
$dest = "result.pdf";
|
||||||
$filename = $client->store($request, $dirPath);
|
$client->store($request, $dest);
|
||||||
```
|
```
|
||||||
@@ -24,7 +24,7 @@ $ curl --request POST \
|
|||||||
### Go
|
### Go
|
||||||
|
|
||||||
```golang
|
```golang
|
||||||
import "github.com/thecodingmachine/gotenberg/pkg"
|
import "github.com/thecodingmachine/gotenberg-go-client/v4"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
c := &gotenberg.Client{Hostname: "http://localhost:3000"}
|
||||||
@@ -14,7 +14,7 @@ services:
|
|||||||
# your others services
|
# your others services
|
||||||
|
|
||||||
gotenberg:
|
gotenberg:
|
||||||
image: thecodingmachine/gotenberg:3
|
image: thecodingmachine/gotenberg:4
|
||||||
```
|
```
|
||||||
|
|
||||||
You may now launch your services using:
|
You may now launch your services using:
|
||||||
11
build/docs/content/09-liveness.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
title: Liveness
|
||||||
|
---
|
||||||
|
|
||||||
|
Gotenberg provides the endpoint `/ping` for checking the API availability with
|
||||||
|
a simple `GET` request.
|
||||||
|
|
||||||
|
This feature is especially useful for liveness/readiness probes in Kubernetes:
|
||||||
|
|
||||||
|
* [Pod lifecycle](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes)
|
||||||
|
* [Configure Liveness and Readiness Probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/)
|
||||||
13
build/docs/content/10-fonts.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
title: Fonts
|
||||||
|
---
|
||||||
|
|
||||||
|
By default, a handful of fonts are installed. Asian characters are also supported out of the box.
|
||||||
|
|
||||||
|
If you wish to use more fonts, you will have to create your own image:
|
||||||
|
|
||||||
|
```Dockerfile
|
||||||
|
FROM thecodingmachine/gotenberg:4
|
||||||
|
|
||||||
|
RUN apt-get -y install yourfonts
|
||||||
|
```
|
||||||
@@ -10,7 +10,7 @@ FROM golang:${GOLANG_VERSION}-stretch
|
|||||||
# | than gometalinter.
|
# | 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} &&\
|
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
|
golangci-lint --version
|
||||||
|
|||||||
@@ -45,4 +45,4 @@ COPY go.sum .
|
|||||||
# Install module dependencies.
|
# Install module dependencies.
|
||||||
RUN go mod download
|
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.
|
# 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 TestChromeShutdown
|
||||||
go test github.com/thecodingmachine/gotenberg/internal/pkg/pm2 -run TestUnoconvShutdown
|
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).
|
|
||||||
247
docs/index.html
@@ -1,10 +1,30 @@
|
|||||||
<!DOCTYPE html><html><head>
|
<!DOCTYPE html><html><head>
|
||||||
|
|
||||||
|
<script async="" src="https://www.googletagmanager.com/gtag/js?id=UA-10196481-9"></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag(){dataLayer.push(arguments);}
|
||||||
|
gtag('js', new Date());
|
||||||
|
|
||||||
|
gtag('config', 'UA-10196481-9');
|
||||||
|
</script>
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
<meta http-equiv="x-ua-compatible" content="ie=edge"/>
|
<meta http-equiv="x-ua-compatible" content="ie=edge"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||||
<title>Gotenberg · A Docker-powered stateless API for converting HTML, Markdown and Office documents to PDF.</title>
|
<title>Gotenberg · A Docker-powered stateless API for converting HTML, Markdown and Office documents to PDF.</title>
|
||||||
|
<link rel="apple-touch-icon-precomposed" sizes="57x57" href="theme/gotenberg/img/apple-touch-icon-57x57.png"/>
|
||||||
|
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="theme/gotenberg/img/apple-touch-icon-114x114.png"/>
|
||||||
|
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="theme/gotenberg/img/apple-touch-icon-72x72.png"/>
|
||||||
|
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="theme/gotenberg/img/apple-touch-icon-144x144.png"/>
|
||||||
|
<link rel="apple-touch-icon-precomposed" sizes="60x60" href="theme/gotenberg/img/apple-touch-icon-60x60.png"/>
|
||||||
|
<link rel="apple-touch-icon-precomposed" sizes="120x120" href="theme/gotenberg/img/apple-touch-icon-120x120.png"/>
|
||||||
|
<link rel="apple-touch-icon-precomposed" sizes="76x76" href="theme/gotenberg/img/apple-touch-icon-76x76.png"/>
|
||||||
|
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="theme/gotenberg/img/apple-touch-icon-152x152.png"/>
|
||||||
|
<link rel="icon" type="image/png" href="theme/gotenberg/img/favicon-196x196.png" sizes="196x196"/>
|
||||||
|
<link rel="icon" type="image/png" href="theme/gotenberg/img/favicon-96x96.png" sizes="96x96"/>
|
||||||
<link rel="icon" type="image/png" href="theme/gotenberg/img/favicon-32x32.png" sizes="32x32"/>
|
<link rel="icon" type="image/png" href="theme/gotenberg/img/favicon-32x32.png" sizes="32x32"/>
|
||||||
<link rel="icon" type="image/png" href="theme/gotenberg/img/favicon-16x16.png" sizes="16x16"/>
|
<link rel="icon" type="image/png" href="theme/gotenberg/img/favicon-16x16.png" sizes="16x16"/>
|
||||||
|
<link rel="icon" type="image/png" href="theme/gotenberg/img/favicon-128.png" sizes="128x128"/>
|
||||||
<link rel="stylesheet" href="theme/gotenberg/css/index.css"/>
|
<link rel="stylesheet" href="theme/gotenberg/css/index.css"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -34,6 +54,10 @@
|
|||||||
<a href="#html">HTML</a>
|
<a href="#html">HTML</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="item">
|
||||||
|
<a href="#url">URL</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<a href="#markdown">Markdown</a>
|
<a href="#markdown">Markdown</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -54,6 +78,14 @@
|
|||||||
<a href="#scalability">Scalability</a>
|
<a href="#scalability">Scalability</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="item">
|
||||||
|
<a href="#liveness">Liveness</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="item">
|
||||||
|
<a href="#fonts">Fonts</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<a href="#links">Links</a>
|
<a href="#links">Links</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -75,7 +107,7 @@
|
|||||||
<li>Performance: Google Chrome and Libreoffice (unoconv) started once in the background thanks to PM2</li>
|
<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>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>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>
|
</ul>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -88,7 +120,7 @@
|
|||||||
|
|
||||||
<p>You may start it with:</p>
|
<p>You may start it with:</p>
|
||||||
|
|
||||||
<pre class="chroma">$ docker run --rm -p <span class="m">3000</span>:3000 thecodingmachine/gotenberg:3
|
<pre class="chroma">$ docker run --rm -p <span class="m">3000</span>:3000 thecodingmachine/gotenberg:4
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
@@ -104,8 +136,8 @@
|
|||||||
</span><span class="w"> </span><span class="c"># your others services</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="w">
|
||||||
</span><span class="w"> </span>gotenberg<span class="p">:</span><span class="w">
|
</span><span class="w"> </span>gotenberg<span class="p">:</span><span class="w">
|
||||||
</span><span class="w"> </span>image<span class="p">:</span><span class="w"> </span>thecodingmachine/gotenberg<span class="p">:</span><span class="m">3</span><span class="w">
|
</span><span class="w"> </span>image<span class="p">:</span><span class="w"> </span>thecodingmachine/gotenberg<span class="p">:</span><span class="m">4</span><span class="w">
|
||||||
</span><span class="w"></span></pre>
|
</span></pre>
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p>The API will be available under <code>gotenberg:3000</code> in your Docker Compose network.</p>
|
<p>The API will be available under <code>gotenberg:3000</code> in your Docker Compose network.</p>
|
||||||
@@ -120,7 +152,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>
|
<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>
|
</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>
|
</pre>
|
||||||
|
|
||||||
<h2 class="Heading"><a class="Anchor" aria-hidden="true" id="install.php_client" href="#install.php_client">
|
<h2 class="Heading"><a class="Anchor" aria-hidden="true" id="install.php_client" href="#install.php_client">
|
||||||
@@ -183,7 +215,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>
|
<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>
|
||||||
|
|
||||||
<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="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>
|
<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>
|
||||||
@@ -265,7 +297,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>
|
<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>
|
||||||
|
|
||||||
<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="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>
|
<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>
|
||||||
@@ -339,7 +371,10 @@ are on the same level as the <code>index.html</code> file.</p>
|
|||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p>If you want to install fonts directly in the Gotenberg Docker image,
|
<p>If you want to install fonts directly in the Gotenberg Docker image,
|
||||||
see to the <a href="#office.fonts">fonts section</a>.</p>
|
see to the <a href="#fonts">fonts section</a>.</p>
|
||||||
|
|
||||||
|
<p>For web fonts (Google fonts), there is a timeout of 500ms by default. You may update
|
||||||
|
this value thanks to the form field <code>webFontsTimeout</code>.</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
<h3 class="Heading"><a class="Anchor" aria-hidden="true" id="html.assets.c_url" href="#html.assets.c_url">
|
<h3 class="Heading"><a class="Anchor" aria-hidden="true" id="html.assets.c_url" href="#html.assets.c_url">
|
||||||
@@ -360,16 +395,12 @@ see to the <a href="#office.fonts">fonts section</a>.</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>
|
<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>
|
||||||
|
|
||||||
<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="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>
|
<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>
|
||||||
<span class="nx">req</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">gotenberg</span><span class="p">.</span><span class="nf">NewHTMLRequest</span><span class="p">(</span><span class="s">"index.html"</span><span class="p">)</span>
|
<span class="nx">req</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">gotenberg</span><span class="p">.</span><span class="nf">NewHTMLRequest</span><span class="p">(</span><span class="s">"index.html"</span><span class="p">)</span>
|
||||||
<span class="nx">req</span><span class="p">.</span><span class="nf">SetAssets</span><span class="p">([]</span><span class="kt">string</span><span class="p">{</span>
|
<span class="nx">req</span><span class="p">.</span><span class="nf">SetAssets</span><span class="p">(</span><span class="s">"font.woff"</span><span class="p">,</span> <span class="s">"img.gif"</span><span class="p">,</span> <span class="s">"style.css"</span><span class="p">)</span>
|
||||||
<span class="s">"font.woff"</span><span class="p">,</span>
|
|
||||||
<span class="s">"img.gif"</span><span class="p">,</span>
|
|
||||||
<span class="s">"style.css"</span><span class="p">,</span>
|
|
||||||
<span class="p">})</span>
|
|
||||||
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</span>
|
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</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>
|
||||||
<span class="p">}</span>
|
<span class="p">}</span>
|
||||||
@@ -392,8 +423,8 @@ $assets = [
|
|||||||
];
|
];
|
||||||
$request = new HTMLRequest($index);
|
$request = new HTMLRequest($index);
|
||||||
$request->setAssets($assets);
|
$request->setAssets($assets);
|
||||||
$dirPath = "/foo";
|
$dest = "result.pdf";
|
||||||
$filename = $client->store($request, $dirPath);
|
$client->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" href="#html.paper_size_margins_orientation">
|
||||||
@@ -431,7 +462,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>
|
<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>
|
||||||
|
|
||||||
<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="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>
|
<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>
|
||||||
@@ -459,8 +490,74 @@ $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);
|
||||||
$dirPath = "/foo";
|
$dest = "result.pdf";
|
||||||
$filename = $client->store($request, $dirPath);
|
$client->store($request, $dest);
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="Page" id="url">
|
||||||
|
<h1 class="Heading"><a class="Anchor" aria-hidden="true" id="url" href="#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>URL</h1>
|
||||||
|
<p>Gotenberg provides the endpoint <code>/convert/url</code> for remote URL conversions.</p>
|
||||||
|
|
||||||
|
<p>It accepts <code>POST</code> requests with a <code>multipart/form-data</code> Content-Type.</p>
|
||||||
|
|
||||||
|
<h2 class="Heading"><a class="Anchor" aria-hidden="true" id="url.basic" href="#url.basic">
|
||||||
|
<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>Basic</h2>
|
||||||
|
|
||||||
|
<p>This endpoint does not accept an <code>index.html</code> file nor assets files but a form field
|
||||||
|
named <code>remoteURL</code> instead. Otherwise, URL conversions work the same as HTML conversions.</p>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<p><strong>Attention:</strong> when converting a website to PDF, you should remove all margins.
|
||||||
|
If not, some of the content of the page might be hidden.</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
<h3 class="Heading"><a class="Anchor" aria-hidden="true" id="url.basic.c_url" href="#url.basic.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/url <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">remoteURL</span><span class="o">=</span>https://google.com
|
||||||
|
--form <span class="nv">marginTop</span><span class="o">=</span><span class="m">0</span> <span class="se">\
|
||||||
|
</span><span class="se"></span> --form <span class="nv">marginBottom</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> -o result.pdf
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h3 class="Heading"><a class="Anchor" aria-hidden="true" id="url.basic.go" href="#url.basic.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>
|
||||||
|
</a>Go</h3>
|
||||||
|
|
||||||
|
<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>
|
||||||
|
<span class="nx">req</span> <span class="o">:=</span> <span class="nx">gotenberg</span><span class="p">.</span><span class="nf">NewURLRequest</span><span class="p">(</span><span class="s">"https://google.com"</span><span class="p">)</span>
|
||||||
|
<span class="nx">req</span><span class="p">.</span><span class="nf">SetMargins</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">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</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="p">}</span>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h3 class="Heading"><a class="Anchor" aria-hidden="true" id="url.basic.php" href="#url.basic.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>
|
||||||
|
</a>PHP</h3>
|
||||||
|
|
||||||
|
<pre class="chroma">use TheCodingMachine\Gotenberg\Client;
|
||||||
|
use TheCodingMachine\Gotenberg\URLRequest;
|
||||||
|
|
||||||
|
$client = new Client('http://localhost:3000', new \Http\Adapter\Guzzle6\Client());
|
||||||
|
$request = new URLRequest('https://google.com');
|
||||||
|
$request->setMargins(Request::NO_MARGINS);
|
||||||
|
$dest = "result.pdf";
|
||||||
|
$client->store($request, $dest);
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -512,11 +609,11 @@ 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>
|
<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>
|
||||||
|
|
||||||
<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="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>
|
<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>
|
||||||
<span class="nx">req</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">gotenberg</span><span class="p">.</span><span class="nf">NewMarkdownRequest</span><span class="p">(</span><span class="s">"index.html"</span><span class="p">,</span> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">"file.md"</span><span class="p">})</span>
|
<span class="nx">req</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">gotenberg</span><span class="p">.</span><span class="nf">NewMarkdownRequest</span><span class="p">(</span><span class="s">"index.html"</span><span class="p">,</span> <span class="s">"file.md"</span><span class="p">)</span>
|
||||||
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</span>
|
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</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>
|
||||||
<span class="p">}</span>
|
<span class="p">}</span>
|
||||||
@@ -536,8 +633,8 @@ $markdowns = [
|
|||||||
DocumentFactory::makeFromPath('file.md', 'file.md'),
|
DocumentFactory::makeFromPath('file.md', 'file.md'),
|
||||||
];
|
];
|
||||||
$request = new MarkdownRequest($index, $markdowns);
|
$request = new MarkdownRequest($index, $markdowns);
|
||||||
$dirPath = "/foo";
|
$dest = "result.pdf";
|
||||||
$filename = $client->store($request, $dirPath);
|
$client->store($request, $dest);
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -559,6 +656,7 @@ $filename = $client->store($request, $dirPath);
|
|||||||
<ul>
|
<ul>
|
||||||
<li><code>.txt</code></li>
|
<li><code>.txt</code></li>
|
||||||
<li><code>.rtf</code></li>
|
<li><code>.rtf</code></li>
|
||||||
|
<li><code>.fodt</code></li>
|
||||||
<li><code>.doc</code></li>
|
<li><code>.doc</code></li>
|
||||||
<li><code>.docx</code></li>
|
<li><code>.docx</code></li>
|
||||||
<li><code>.odt</code></li>
|
<li><code>.odt</code></li>
|
||||||
@@ -594,11 +692,11 @@ 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>
|
<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>
|
||||||
|
|
||||||
<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="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>
|
<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>
|
||||||
<span class="nx">req</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">gotenberg</span><span class="p">.</span><span class="nf">NewOfficeRequest</span><span class="p">([]</span><span class="kt">string</span><span class="p">{</span><span class="s">"document.docx"</span><span class="p">,</span> <span class="s">"document2.docx"</span><span class="p">})</span>
|
<span class="nx">req</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">gotenberg</span><span class="p">.</span><span class="nf">NewOfficeRequest</span><span class="p">(</span><span class="s">"document.docx"</span><span class="p">,</span> <span class="s">"document2.docx"</span><span class="p">)</span>
|
||||||
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</span>
|
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</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>
|
||||||
<span class="p">}</span>
|
<span class="p">}</span>
|
||||||
@@ -618,24 +716,19 @@ $files = [
|
|||||||
DocumentFactory::makeFromPath('document2.docx', 'document2.docx'),
|
DocumentFactory::makeFromPath('document2.docx', 'document2.docx'),
|
||||||
];
|
];
|
||||||
$request = new OfficeRequest($files);
|
$request = new OfficeRequest($files);
|
||||||
$dirPath = "/foo";
|
$dest = "result.pdf";
|
||||||
$filename = $client->store($request, $dirPath);
|
$client->store($request, $dest);
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<h2 class="Heading"><a class="Anchor" aria-hidden="true" id="office.paper_size_and_orientation" href="#office.paper_size_and_orientation">
|
<h2 class="Heading"><a class="Anchor" aria-hidden="true" id="office.orientation" href="#office.orientation">
|
||||||
<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 and orientation</h2>
|
</a>Orientation</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 and <code>portrait</code> orientation.</p>
|
<p>By default, it will be rendered with <code>portrait</code> orientation.</p>
|
||||||
|
|
||||||
<blockquote>
|
<h3 class="Heading"><a class="Anchor" aria-hidden="true" id="office.orientation.c_url" href="#office.orientation.c_url">
|
||||||
<p>Paper size has to be provided in <code>inches</code>.
|
|
||||||
Also, you have to set both <code>paperWidth</code> and <code>paperHeight</code>.</p>
|
|
||||||
</blockquote>
|
|
||||||
|
|
||||||
<h3 class="Heading"><a class="Anchor" aria-hidden="true" id="office.paper_size_and_orientation.c_url" href="#office.paper_size_and_orientation.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>
|
||||||
|
|
||||||
@@ -643,29 +736,26 @@ Also, you have to set both <code>paperWidth</code> and <code>paperHeight</code>.
|
|||||||
</span><span class="se"></span> --url http://localhost:3000/convert/office <span class="se">\
|
</span><span class="se"></span> --url http://localhost:3000/convert/office <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> --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>@document.docx <span class="se">\
|
</span><span class="se"></span> --form <span class="nv">files</span><span class="o">=</span>@document.docx <span class="se">\
|
||||||
</span><span class="se"></span> --form <span class="nv">paperWidth</span><span class="o">=</span><span class="m">8</span>.27 <span class="se">\
|
|
||||||
</span><span class="se"></span> --form <span class="nv">paperHeight</span><span class="o">=</span><span class="m">11</span>.27 <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> -o result.pdf
|
</span><span class="se"></span> -o result.pdf
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<h3 class="Heading"><a class="Anchor" aria-hidden="true" id="office.paper_size_and_orientation.go" href="#office.paper_size_and_orientation.go">
|
<h3 class="Heading"><a class="Anchor" aria-hidden="true" id="office.orientation.go" href="#office.orientation.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>
|
||||||
|
|
||||||
<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="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>
|
<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>
|
||||||
<span class="nx">req</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">gotenberg</span><span class="p">.</span><span class="nf">NewOfficeRequest</span><span class="p">([]</span><span class="kt">string</span><span class="p">{</span><span class="s">"document.docx"</span><span class="p">})</span>
|
<span class="nx">req</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">gotenberg</span><span class="p">.</span><span class="nf">NewOfficeRequest</span><span class="p">(</span><span class="s">"document.docx"</span><span class="p">)</span>
|
||||||
<span class="nx">req</span><span class="p">.</span><span class="nf">SetPaperSize</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">SetLandscape</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">SetLandscape</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
|
||||||
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</span>
|
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</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>
|
||||||
<span class="p">}</span>
|
<span class="p">}</span>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<h3 class="Heading"><a class="Anchor" aria-hidden="true" id="office.paper_size_and_orientation.php" href="#office.paper_size_and_orientation.php">
|
<h3 class="Heading"><a class="Anchor" aria-hidden="true" id="office.orientation.php" href="#office.orientation.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>
|
||||||
|
|
||||||
@@ -678,25 +768,11 @@ $files = [
|
|||||||
DocumentFactory::makeFromPath('document.docx', 'document.docx'),
|
DocumentFactory::makeFromPath('document.docx', 'document.docx'),
|
||||||
];
|
];
|
||||||
$request = new OfficeRequest($files);
|
$request = new OfficeRequest($files);
|
||||||
$request->setPaperSize(Request::A4);
|
|
||||||
$request->setLandscape(true);
|
$request->setLandscape(true);
|
||||||
$dirPath = "/foo";
|
$dest = "result.pdf";
|
||||||
$filename = $client->store($request, $dirPath);
|
$client->store($request, $dest);
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<h2 class="Heading"><a class="Anchor" aria-hidden="true" id="office.fonts" href="#office.fonts">
|
|
||||||
<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>Fonts</h2>
|
|
||||||
|
|
||||||
<p>By default, only <code>ttf-mscorefonts</code> fonts are installed.</p>
|
|
||||||
|
|
||||||
<p>If you wish to use more fonts, you will have to create your own image:</p>
|
|
||||||
|
|
||||||
<pre class="chroma"><span class="k">FROM</span><span class="s"> thecodingmachine/gotenberg:3</span><span class="err">
|
|
||||||
</span><span class="err">
|
|
||||||
</span><span class="err"></span><span class="k">RUN</span> apt-get -y install yourfonts<span class="err">
|
|
||||||
</span><span class="err"></span></pre>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="Page" id="merge">
|
<div class="Page" id="merge">
|
||||||
@@ -711,9 +787,13 @@ $filename = $client->store($request, $dirPath);
|
|||||||
<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>Basic</h2>
|
</a>Basic</h2>
|
||||||
|
|
||||||
<p>Nothing special here: you may send one or more PDF files and the API
|
<p>Nothing fancy here: you may send one or more PDF files and the API
|
||||||
will merge them and return the resulting PDF file.</p>
|
will merge them and return the resulting PDF file.</p>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<p><strong>Attention:</strong> Gotenberg merges the PDF files alphabetically.</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
<h3 class="Heading"><a class="Anchor" aria-hidden="true" id="merge.basic.c_url" href="#merge.basic.c_url">
|
<h3 class="Heading"><a class="Anchor" aria-hidden="true" id="merge.basic.c_url" href="#merge.basic.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>
|
||||||
@@ -730,11 +810,11 @@ 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>
|
<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>
|
||||||
|
|
||||||
<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="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>
|
<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>
|
||||||
<span class="nx">req</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">gotenberg</span><span class="p">.</span><span class="nf">NewMergeRequest</span><span class="p">([]</span><span class="kt">string</span><span class="p">{</span><span class="s">"file.pdf"</span><span class="p">,</span> <span class="s">"file2.pdf"</span><span class="p">})</span>
|
<span class="nx">req</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">gotenberg</span><span class="p">.</span><span class="nf">NewMergeRequest</span><span class="p">(</span><span class="s">"file.pdf"</span><span class="p">,</span> <span class="s">"file2.pdf"</span><span class="p">)</span>
|
||||||
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</span>
|
<span class="nx">dest</span> <span class="o">:=</span> <span class="s">"result.pdf"</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>
|
||||||
<span class="p">}</span>
|
<span class="p">}</span>
|
||||||
@@ -754,8 +834,8 @@ $files = [
|
|||||||
DocumentFactory::makeFromPath('file2.pdf', 'file2.pdf'),
|
DocumentFactory::makeFromPath('file2.pdf', 'file2.pdf'),
|
||||||
];
|
];
|
||||||
$request = new MergeRequest($files);
|
$request = new MergeRequest($files);
|
||||||
$dirPath = "/foo";
|
$dest = "result.pdf";
|
||||||
$filename = $client->store($request, $dirPath);
|
$client->store($request, $dest);
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -790,7 +870,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>
|
<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>
|
||||||
|
|
||||||
<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="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>
|
<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>
|
||||||
@@ -833,8 +913,8 @@ $resp = $client->post($request);
|
|||||||
</span><span class="w"> </span><span class="c"># your others services</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="w">
|
||||||
</span><span class="w"> </span>gotenberg<span class="p">:</span><span class="w">
|
</span><span class="w"> </span>gotenberg<span class="p">:</span><span class="w">
|
||||||
</span><span class="w"> </span>image<span class="p">:</span><span class="w"> </span>thecodingmachine/gotenberg<span class="p">:</span><span class="m">3</span><span class="w">
|
</span><span class="w"> </span>image<span class="p">:</span><span class="w"> </span>thecodingmachine/gotenberg<span class="p">:</span><span class="m">4</span><span class="w">
|
||||||
</span><span class="w"></span></pre>
|
</span></pre>
|
||||||
|
|
||||||
<p>You may now launch your services using:</p>
|
<p>You may now launch your services using:</p>
|
||||||
|
|
||||||
@@ -846,6 +926,37 @@ redirect a request to a Gotenberg container according to the round-robin strateg
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="Page" id="liveness">
|
||||||
|
<h1 class="Heading"><a class="Anchor" aria-hidden="true" id="liveness" href="#liveness">
|
||||||
|
<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>Liveness</h1>
|
||||||
|
<p>Gotenberg provides the endpoint <code>/ping</code> for checking the API availability with
|
||||||
|
a simple <code>GET</code> request.</p>
|
||||||
|
|
||||||
|
<p>This feature is especially useful for liveness/readiness probes in Kubernetes:</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><a href="https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes">Pod lifecycle</a></li>
|
||||||
|
<li><a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/">Configure Liveness and Readiness Probes</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="Page" id="fonts">
|
||||||
|
<h1 class="Heading"><a class="Anchor" aria-hidden="true" id="fonts" href="#fonts">
|
||||||
|
<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>Fonts</h1>
|
||||||
|
<p>By default, a handful of fonts are installed. Asian characters are also supported out of the box.</p>
|
||||||
|
|
||||||
|
<p>If you wish to use more fonts, you will have to create your own image:</p>
|
||||||
|
|
||||||
|
<pre class="chroma"><span class="k">FROM</span><span class="s"> thecodingmachine/gotenberg:4</span><span class="err">
|
||||||
|
</span><span class="err">
|
||||||
|
</span><span class="err"></span><span class="k">RUN</span> apt-get -y install yourfonts<span class="err">
|
||||||
|
</span></pre>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="Page" id="links">
|
<div class="Page" id="links">
|
||||||
<h1 class="Heading"><a class="Anchor" aria-hidden="true" id="links" href="#links">
|
<h1 class="Heading"><a class="Anchor" aria-hidden="true" id="links" href="#links">
|
||||||
<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>
|
||||||
|
|||||||
BIN
docs/theme/gotenberg/img/apple-touch-icon-114x114.png
vendored
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
docs/theme/gotenberg/img/apple-touch-icon-120x120.png
vendored
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
docs/theme/gotenberg/img/apple-touch-icon-144x144.png
vendored
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
docs/theme/gotenberg/img/apple-touch-icon-152x152.png
vendored
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
docs/theme/gotenberg/img/apple-touch-icon-57x57.png
vendored
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
docs/theme/gotenberg/img/apple-touch-icon-60x60.png
vendored
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
docs/theme/gotenberg/img/apple-touch-icon-72x72.png
vendored
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
BIN
docs/theme/gotenberg/img/apple-touch-icon-76x76.png
vendored
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
docs/theme/gotenberg/img/favicon-128.png
vendored
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
docs/theme/gotenberg/img/favicon-16x16.png
vendored
|
Before Width: | Height: | Size: 923 B After Width: | Height: | Size: 917 B |
BIN
docs/theme/gotenberg/img/favicon-196x196.png
vendored
Normal file
|
After Width: | Height: | Size: 53 KiB |
BIN
docs/theme/gotenberg/img/favicon-32x32.png
vendored
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
BIN
docs/theme/gotenberg/img/favicon-96x96.png
vendored
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
docs/theme/gotenberg/img/favicon.ico
vendored
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 34 KiB |
BIN
docs/theme/gotenberg/img/mstile-144x144.png
vendored
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
docs/theme/gotenberg/img/mstile-150x150.png
vendored
Normal file
|
After Width: | Height: | Size: 95 KiB |
BIN
docs/theme/gotenberg/img/mstile-310x150.png
vendored
Normal file
|
After Width: | Height: | Size: 182 KiB |
BIN
docs/theme/gotenberg/img/mstile-310x310.png
vendored
Normal file
|
After Width: | Height: | Size: 372 KiB |
BIN
docs/theme/gotenberg/img/mstile-70x70.png
vendored
Normal file
|
After Width: | Height: | Size: 24 KiB |
22
docs/theme/gotenberg/views/index.html
vendored
@@ -1,12 +1,32 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||||
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-10196481-9"></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag(){dataLayer.push(arguments);}
|
||||||
|
gtag('js', new Date());
|
||||||
|
|
||||||
|
gtag('config', 'UA-10196481-9');
|
||||||
|
</script>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>{{.Title}} · {{.Subtitle}}</title>
|
<title>{{.Title}} · {{.Subtitle}}</title>
|
||||||
|
<link rel="apple-touch-icon-precomposed" sizes="57x57" href="theme/gotenberg/img/apple-touch-icon-57x57.png" />
|
||||||
|
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="theme/gotenberg/img/apple-touch-icon-114x114.png" />
|
||||||
|
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="theme/gotenberg/img/apple-touch-icon-72x72.png" />
|
||||||
|
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="theme/gotenberg/img/apple-touch-icon-144x144.png" />
|
||||||
|
<link rel="apple-touch-icon-precomposed" sizes="60x60" href="theme/gotenberg/img/apple-touch-icon-60x60.png" />
|
||||||
|
<link rel="apple-touch-icon-precomposed" sizes="120x120" href="theme/gotenberg/img/apple-touch-icon-120x120.png" />
|
||||||
|
<link rel="apple-touch-icon-precomposed" sizes="76x76" href="theme/gotenberg/img/apple-touch-icon-76x76.png" />
|
||||||
|
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="theme/gotenberg/img/apple-touch-icon-152x152.png" />
|
||||||
|
<link rel="icon" type="image/png" href="theme/gotenberg/img/favicon-196x196.png" sizes="196x196" />
|
||||||
|
<link rel="icon" type="image/png" href="theme/gotenberg/img/favicon-96x96.png" sizes="96x96" />
|
||||||
<link rel="icon" type="image/png" href="theme/gotenberg/img/favicon-32x32.png" sizes="32x32" />
|
<link rel="icon" type="image/png" href="theme/gotenberg/img/favicon-32x32.png" sizes="32x32" />
|
||||||
<link rel="icon" type="image/png" href="theme/gotenberg/img/favicon-16x16.png" sizes="16x16" />
|
<link rel="icon" type="image/png" href="theme/gotenberg/img/favicon-16x16.png" sizes="16x16" />
|
||||||
|
<link rel="icon" type="image/png" href="theme/gotenberg/img/favicon-128.png" sizes="128x128" />
|
||||||
<link rel="stylesheet" href="theme/gotenberg/css/index.css">
|
<link rel="stylesheet" href="theme/gotenberg/css/index.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
8
go.mod
@@ -1,21 +1,21 @@
|
|||||||
module github.com/thecodingmachine/gotenberg
|
module github.com/thecodingmachine/gotenberg
|
||||||
|
|
||||||
|
go 1.12
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/derekparker/delve v1.1.0
|
|
||||||
github.com/google/go-cmp v0.2.0 // indirect
|
github.com/google/go-cmp v0.2.0 // indirect
|
||||||
github.com/gorilla/websocket v1.4.0 // indirect
|
github.com/gorilla/websocket v1.4.0 // indirect
|
||||||
github.com/hhrutter/pdfcpu v0.1.19
|
github.com/hhrutter/pdfcpu v0.1.19
|
||||||
github.com/labstack/echo v0.0.0-20181123063703-c7eb8da9ec73
|
github.com/labstack/echo v0.0.0-20190126223945-739700bf4ef7
|
||||||
github.com/labstack/gommon v0.2.8
|
github.com/labstack/gommon v0.2.8
|
||||||
github.com/mafredri/cdp v0.20.0
|
github.com/mafredri/cdp v0.20.0
|
||||||
github.com/microcosm-cc/bluemonday v1.0.1
|
github.com/microcosm-cc/bluemonday v1.0.1
|
||||||
github.com/pkg/errors v0.8.0 // indirect
|
github.com/pkg/errors v0.8.0 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.0.1
|
github.com/russross/blackfriday/v2 v2.0.1
|
||||||
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95 // indirect
|
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95 // indirect
|
||||||
github.com/stretchr/objx v0.1.1 // indirect
|
|
||||||
github.com/stretchr/testify v1.2.2
|
github.com/stretchr/testify v1.2.2
|
||||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 // indirect
|
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 // indirect
|
||||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc
|
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc // indirect
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f // 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-20181128092732-4ed8d59d0b35 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
12
go.sum
@@ -1,21 +1,15 @@
|
|||||||
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/derekparker/delve v1.1.0 h1:icd65nMp7s2HiLz6y/6RCVXBdoED3xxYLwX09EMaRCc=
|
|
||||||
github.com/derekparker/delve v1.1.0/go.mod h1:pMSZMfp0Nhbm8qdZJkuE/yPGOkLpGXLS1I4poXQpuJU=
|
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
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/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
||||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
github.com/hhrutter/pdfcpu v0.1.18 h1:GX3d6tZxmQlmB5X9VUyOtx7+HZZpR+8ISLqBineP6dc=
|
|
||||||
github.com/hhrutter/pdfcpu v0.1.18/go.mod h1:iaCmXGnOXPIvoGLELZZc4m/GpIopVsvLQ00thrbu8LU=
|
|
||||||
github.com/hhrutter/pdfcpu v0.1.19 h1:J6GjNFDPjurQWallPW9gmz3CcNqBfvgB7Dad9T3e8Hc=
|
github.com/hhrutter/pdfcpu v0.1.19 h1:J6GjNFDPjurQWallPW9gmz3CcNqBfvgB7Dad9T3e8Hc=
|
||||||
github.com/hhrutter/pdfcpu v0.1.19/go.mod h1:iaCmXGnOXPIvoGLELZZc4m/GpIopVsvLQ00thrbu8LU=
|
github.com/hhrutter/pdfcpu v0.1.19/go.mod h1:iaCmXGnOXPIvoGLELZZc4m/GpIopVsvLQ00thrbu8LU=
|
||||||
github.com/labstack/echo v0.0.0-20181123063703-c7eb8da9ec73 h1:oQvA3Xy8274W5Ldgo6Nogy4lX8XO5AaIBsjF5Ggk0IU=
|
github.com/labstack/echo v0.0.0-20190126223945-739700bf4ef7 h1:kFheQLunLP9dCBrmg3D7y9FD44tlk/nvZQ7JCNvvWEA=
|
||||||
github.com/labstack/echo v0.0.0-20181123063703-c7eb8da9ec73/go.mod h1:rS0D1UPvC8/3sXjhSwEq+K1olh7ipbDhjDWATN2KSgA=
|
github.com/labstack/echo v0.0.0-20190126223945-739700bf4ef7/go.mod h1:rS0D1UPvC8/3sXjhSwEq+K1olh7ipbDhjDWATN2KSgA=
|
||||||
github.com/labstack/echo v3.3.5+incompatible h1:9PfxPUmasKzeJor9uQTaXLT6WUG/r+vSTmvXxvv3JO4=
|
|
||||||
github.com/labstack/echo v3.3.5+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s=
|
|
||||||
github.com/labstack/gommon v0.2.7/go.mod h1:/tj9csK2iPSBvn+3NLM9e52usepMtrd5ilFYA+wQNJ4=
|
github.com/labstack/gommon v0.2.7/go.mod h1:/tj9csK2iPSBvn+3NLM9e52usepMtrd5ilFYA+wQNJ4=
|
||||||
github.com/labstack/gommon v0.2.8 h1:JvRqmeZcfrHC5u6uVleB4NxxNbzx6gpbJiQknDbKQu0=
|
github.com/labstack/gommon v0.2.8 h1:JvRqmeZcfrHC5u6uVleB4NxxNbzx6gpbJiQknDbKQu0=
|
||||||
github.com/labstack/gommon v0.2.8/go.mod h1:/tj9csK2iPSBvn+3NLM9e52usepMtrd5ilFYA+wQNJ4=
|
github.com/labstack/gommon v0.2.8/go.mod h1:/tj9csK2iPSBvn+3NLM9e52usepMtrd5ilFYA+wQNJ4=
|
||||||
@@ -35,8 +29,6 @@ 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 v0.0.0-20170918181015-86672fcb3f95 h1:/vdW8Cb7EXrkqWGufVMES1OH2sU9gKVb2n9/1y5NMBY=
|
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/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
|
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
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/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||||
|
|||||||
@@ -67,9 +67,11 @@ func setup() *echo.Echo {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
e.GET("/ping", func(c echo.Context) error { return nil })
|
||||||
e.POST("/merge", merge)
|
e.POST("/merge", merge)
|
||||||
g := e.Group("/convert")
|
g := e.Group("/convert")
|
||||||
g.POST("/html", convertHTML)
|
g.POST("/html", convertHTML)
|
||||||
|
g.POST("/url", convertURL)
|
||||||
g.POST("/markdown", convertMarkdown)
|
g.POST("/markdown", convertMarkdown)
|
||||||
g.POST("/office", convertOffice)
|
g.POST("/office", convertOffice)
|
||||||
return e
|
return e
|
||||||
|
|||||||
18
internal/app/api/api_test.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/labstack/echo"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPing(t *testing.T) {
|
||||||
|
req := httptest.NewRequest(http.MethodGet, "/ping", nil)
|
||||||
|
rec := httptest.NewRecorder()
|
||||||
|
e := echo.New()
|
||||||
|
_ = e.NewContext(req, rec)
|
||||||
|
assert.Equal(t, http.StatusOK, rec.Code)
|
||||||
|
}
|
||||||
@@ -47,5 +47,10 @@ func convertHTML(c echo.Context) error {
|
|||||||
return hijackErr(err, r)
|
return hijackErr(err, r)
|
||||||
}
|
}
|
||||||
p.Landscape = landscape
|
p.Landscape = landscape
|
||||||
|
chromeWebFontsTimeout, err := r.webFontsTimeout()
|
||||||
|
if err != nil {
|
||||||
|
return hijackErr(err, r)
|
||||||
|
}
|
||||||
|
p.WebFontsTimeout = chromeWebFontsTimeout
|
||||||
return print(c, p, r)
|
return print(c, p, r)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,5 +46,10 @@ func convertMarkdown(c echo.Context) error {
|
|||||||
return hijackErr(err, r)
|
return hijackErr(err, r)
|
||||||
}
|
}
|
||||||
p.Landscape = landscape
|
p.Landscape = landscape
|
||||||
|
chromeWebFontsTimeout, err := r.webFontsTimeout()
|
||||||
|
if err != nil {
|
||||||
|
return hijackErr(err, r)
|
||||||
|
}
|
||||||
|
p.WebFontsTimeout = chromeWebFontsTimeout
|
||||||
return print(c, p, r)
|
return print(c, p, r)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
var officeExts = []string{
|
var officeExts = []string{
|
||||||
".txt",
|
".txt",
|
||||||
".rtf",
|
".rtf",
|
||||||
|
".fodt",
|
||||||
".doc",
|
".doc",
|
||||||
".docx",
|
".docx",
|
||||||
".odt",
|
".odt",
|
||||||
@@ -38,12 +39,6 @@ func convertOffice(c echo.Context) error {
|
|||||||
return hijackErr(errors.New("no suitable office documents to convert"), r)
|
return hijackErr(errors.New("no suitable office documents to convert"), r)
|
||||||
}
|
}
|
||||||
p := &printer.Office{Context: ctx, FilePaths: fpaths}
|
p := &printer.Office{Context: ctx, FilePaths: fpaths}
|
||||||
paperSize, err := r.paperSize()
|
|
||||||
if err != nil {
|
|
||||||
return hijackErr(err, r)
|
|
||||||
}
|
|
||||||
p.PaperWidth = paperSize[0]
|
|
||||||
p.PaperHeight = paperSize[1]
|
|
||||||
landscape, err := r.landscape()
|
landscape, err := r.landscape()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return hijackErr(err, r)
|
return hijackErr(err, r)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
@@ -12,14 +13,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
webhookURL string = "webhookURL"
|
remoteURL string = "remoteURL"
|
||||||
paperWidth string = "paperWidth"
|
webhookURL string = "webhookURL"
|
||||||
paperHeight string = "paperHeight"
|
paperWidth string = "paperWidth"
|
||||||
marginTop string = "marginTop"
|
paperHeight string = "paperHeight"
|
||||||
marginBottom string = "marginBottom"
|
marginTop string = "marginTop"
|
||||||
marginLeft string = "marginLeft"
|
marginBottom string = "marginBottom"
|
||||||
marginRight string = "marginRight"
|
marginLeft string = "marginLeft"
|
||||||
landscape string = "landscape"
|
marginRight string = "marginRight"
|
||||||
|
landscape string = "landscape"
|
||||||
|
webFontsTimeout string = "webFontsTimeout"
|
||||||
)
|
)
|
||||||
|
|
||||||
// resource facilitates storing and accessing
|
// resource facilitates storing and accessing
|
||||||
@@ -31,6 +34,7 @@ type resource struct {
|
|||||||
|
|
||||||
func newResource(c echo.Context) (*resource, error) {
|
func newResource(c echo.Context) (*resource, error) {
|
||||||
v := make(map[string]string)
|
v := make(map[string]string)
|
||||||
|
v[remoteURL] = c.FormValue(remoteURL)
|
||||||
v[webhookURL] = c.FormValue(webhookURL)
|
v[webhookURL] = c.FormValue(webhookURL)
|
||||||
v[paperWidth] = c.FormValue(paperWidth)
|
v[paperWidth] = c.FormValue(paperWidth)
|
||||||
v[paperHeight] = c.FormValue(paperHeight)
|
v[paperHeight] = c.FormValue(paperHeight)
|
||||||
@@ -39,6 +43,7 @@ func newResource(c echo.Context) (*resource, error) {
|
|||||||
v[marginLeft] = c.FormValue(marginLeft)
|
v[marginLeft] = c.FormValue(marginLeft)
|
||||||
v[marginRight] = c.FormValue(marginRight)
|
v[marginRight] = c.FormValue(marginRight)
|
||||||
v[landscape] = c.FormValue(landscape)
|
v[landscape] = c.FormValue(landscape)
|
||||||
|
v[webFontsTimeout] = c.FormValue(webFontsTimeout)
|
||||||
dirPath, err := rand.Get()
|
dirPath, err := rand.Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -180,5 +185,24 @@ func (r *resource) landscape() (bool, error) {
|
|||||||
return landscape, nil
|
return landscape, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *resource) remoteURL() (string, error) {
|
||||||
|
if r.values[remoteURL] == "" {
|
||||||
|
return "", errors.New("no remote URL")
|
||||||
|
}
|
||||||
|
return r.values[remoteURL], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *resource) webFontsTimeout() (int64, error) {
|
||||||
|
webFontsTimeoutStr := r.values[webFontsTimeout]
|
||||||
|
if webFontsTimeoutStr == "" {
|
||||||
|
return 500, nil
|
||||||
|
}
|
||||||
|
timeout, err := strconv.ParseInt(webFontsTimeoutStr, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 500, fmt.Errorf("web fonts timeout: %v", err)
|
||||||
|
}
|
||||||
|
return timeout, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *resource) webhookURL() string { return r.values[webhookURL] }
|
func (r *resource) webhookURL() string { return r.values[webhookURL] }
|
||||||
func (r *resource) removeAll() error { return os.RemoveAll(r.dirPath) }
|
func (r *resource) removeAll() error { return os.RemoveAll(r.dirPath) }
|
||||||
|
|||||||
56
internal/app/api/url.go
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/labstack/echo"
|
||||||
|
"github.com/thecodingmachine/gotenberg/internal/pkg/printer"
|
||||||
|
)
|
||||||
|
|
||||||
|
func convertURL(c echo.Context) error {
|
||||||
|
r, err := newResource(c)
|
||||||
|
if err != nil {
|
||||||
|
return hijackErr(err, r)
|
||||||
|
}
|
||||||
|
ctx, cancel := newContext(r)
|
||||||
|
if cancel != nil {
|
||||||
|
defer cancel()
|
||||||
|
}
|
||||||
|
p := &printer.HTML{Context: ctx}
|
||||||
|
URL, err := r.remoteURL()
|
||||||
|
if err != nil {
|
||||||
|
return hijackErr(err, r)
|
||||||
|
}
|
||||||
|
p.URL = URL
|
||||||
|
headerPath, _ := r.filePath("header.html")
|
||||||
|
if err := p.WithHeaderFile(headerPath); err != nil {
|
||||||
|
return hijackErr(err, r)
|
||||||
|
}
|
||||||
|
footerPath, _ := r.filePath("footer.html")
|
||||||
|
if err := p.WithFooterFile(footerPath); err != nil {
|
||||||
|
return hijackErr(err, r)
|
||||||
|
}
|
||||||
|
paperSize, err := r.paperSize()
|
||||||
|
if err != nil {
|
||||||
|
return hijackErr(err, r)
|
||||||
|
}
|
||||||
|
p.PaperWidth = paperSize[0]
|
||||||
|
p.PaperHeight = paperSize[1]
|
||||||
|
paperMargins, err := r.paperMargins()
|
||||||
|
if err != nil {
|
||||||
|
return hijackErr(err, r)
|
||||||
|
}
|
||||||
|
p.MarginTop = paperMargins[0]
|
||||||
|
p.MarginBottom = paperMargins[1]
|
||||||
|
p.MarginLeft = paperMargins[2]
|
||||||
|
p.MarginRight = paperMargins[3]
|
||||||
|
landscape, err := r.landscape()
|
||||||
|
if err != nil {
|
||||||
|
return hijackErr(err, r)
|
||||||
|
}
|
||||||
|
p.Landscape = landscape
|
||||||
|
chromeWebFontsTimeout, err := r.webFontsTimeout()
|
||||||
|
if err != nil {
|
||||||
|
return hijackErr(err, r)
|
||||||
|
}
|
||||||
|
p.WebFontsTimeout = chromeWebFontsTimeout
|
||||||
|
return print(c, p, r)
|
||||||
|
}
|
||||||
24
internal/app/api/url_test.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/labstack/echo"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/thecodingmachine/gotenberg/test"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestURL(t *testing.T) {
|
||||||
|
body, contentType := test.URLTestMultipartForm(t)
|
||||||
|
req := httptest.NewRequest(http.MethodPost, "/convert/url", body)
|
||||||
|
req.Header.Set(echo.HeaderContentType, contentType)
|
||||||
|
rec := httptest.NewRecorder()
|
||||||
|
e := echo.New()
|
||||||
|
c := e.NewContext(req, rec)
|
||||||
|
if assert.NoError(t, convertURL(c)) {
|
||||||
|
assert.Equal(t, http.StatusOK, rec.Code)
|
||||||
|
assert.Equal(t, "application/pdf", rec.Header().Get(echo.HeaderContentType))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,17 +18,18 @@ import (
|
|||||||
|
|
||||||
// HTML facilitates HTML to PDF conversion.
|
// HTML facilitates HTML to PDF conversion.
|
||||||
type HTML struct {
|
type HTML struct {
|
||||||
Context context.Context
|
Context context.Context
|
||||||
URL string
|
URL string
|
||||||
HeaderHTML string
|
HeaderHTML string
|
||||||
FooterHTML string
|
FooterHTML string
|
||||||
PaperWidth float64
|
PaperWidth float64
|
||||||
PaperHeight float64
|
PaperHeight float64
|
||||||
MarginTop float64
|
MarginTop float64
|
||||||
MarginBottom float64
|
MarginBottom float64
|
||||||
MarginLeft float64
|
MarginLeft float64
|
||||||
MarginRight float64
|
MarginRight float64
|
||||||
Landscape bool
|
Landscape bool
|
||||||
|
WebFontsTimeout int64
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultHeaderFooterHTML string = "<html><head></head><body></body></html>"
|
const defaultHeaderFooterHTML string = "<html><head></head><body></body></html>"
|
||||||
@@ -103,14 +104,17 @@ func (html *HTML) Print(destination string) error {
|
|||||||
return fmt.Errorf("waiting for page loading: %v", err)
|
return fmt.Errorf("waiting for page loading: %v", err)
|
||||||
}
|
}
|
||||||
// inject a script to make sure web fonts are loaded.
|
// inject a script to make sure web fonts are loaded.
|
||||||
script := `new Promise((resolve, reject) => {
|
script := fmt.Sprintf(`new Promise((resolve, reject) => {
|
||||||
document.fonts.ready.then(function () {
|
document.fonts.ready.then(function () {
|
||||||
resolve('fonts loaded');
|
resolve('fonts loaded');
|
||||||
});
|
});
|
||||||
setTimeout(resolve.bind(resolve, 'timeout'), %.0f);
|
setTimeout(resolve.bind(resolve, 'timeout'), %d);
|
||||||
});`
|
});`, html.WebFontsTimeout)
|
||||||
scriptArg := runtime.NewEvaluateArgs(script).SetAwaitPromise(true)
|
scriptArg := runtime.NewEvaluateArgs(script).SetAwaitPromise(true)
|
||||||
returnObj, _ := c.Runtime.Evaluate(html.Context, scriptArg)
|
returnObj, _ := c.Runtime.Evaluate(html.Context, scriptArg)
|
||||||
|
if returnObj.ExceptionDetails != nil {
|
||||||
|
return fmt.Errorf("script evaluated with exception: %+v", returnObj.ExceptionDetails)
|
||||||
|
}
|
||||||
loadFontsResult := string(returnObj.Result.Value)
|
loadFontsResult := string(returnObj.Result.Value)
|
||||||
if strings.Contains(loadFontsResult, "timeout") {
|
if strings.Contains(loadFontsResult, "timeout") {
|
||||||
return errors.New("timed out loading fonts")
|
return errors.New("timed out loading fonts")
|
||||||
|
|||||||
@@ -15,17 +15,18 @@ import (
|
|||||||
|
|
||||||
// Markdown facilitates Markdown to PDF conversion.
|
// Markdown facilitates Markdown to PDF conversion.
|
||||||
type Markdown struct {
|
type Markdown struct {
|
||||||
Context context.Context
|
Context context.Context
|
||||||
TemplatePath string
|
TemplatePath string
|
||||||
HeaderHTML string
|
HeaderHTML string
|
||||||
FooterHTML string
|
FooterHTML string
|
||||||
PaperWidth float64
|
PaperWidth float64
|
||||||
PaperHeight float64
|
PaperHeight float64
|
||||||
MarginTop float64
|
MarginTop float64
|
||||||
MarginBottom float64
|
MarginBottom float64
|
||||||
MarginLeft float64
|
MarginLeft float64
|
||||||
MarginRight float64
|
MarginRight float64
|
||||||
Landscape bool
|
Landscape bool
|
||||||
|
WebFontsTimeout int64
|
||||||
|
|
||||||
html *HTML
|
html *HTML
|
||||||
}
|
}
|
||||||
@@ -52,6 +53,7 @@ func (md *Markdown) Print(destination string) error {
|
|||||||
md.html.MarginLeft = md.MarginLeft
|
md.html.MarginLeft = md.MarginLeft
|
||||||
md.html.MarginRight = md.MarginRight
|
md.html.MarginRight = md.MarginRight
|
||||||
md.html.Landscape = md.Landscape
|
md.html.Landscape = md.Landscape
|
||||||
|
md.html.WebFontsTimeout = md.WebFontsTimeout
|
||||||
tmpl, err := template.
|
tmpl, err := template.
|
||||||
New(filepath.Base(md.TemplatePath)).
|
New(filepath.Base(md.TemplatePath)).
|
||||||
Funcs(template.FuncMap{"toHTML": toHTML}).
|
Funcs(template.FuncMap{"toHTML": toHTML}).
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/thecodingmachine/gotenberg/internal/pkg/rand"
|
"github.com/thecodingmachine/gotenberg/internal/pkg/rand"
|
||||||
@@ -17,11 +16,9 @@ var mu sync.Mutex
|
|||||||
|
|
||||||
// Office facilitates Office documents to PDF conversion.
|
// Office facilitates Office documents to PDF conversion.
|
||||||
type Office struct {
|
type Office struct {
|
||||||
Context context.Context
|
Context context.Context
|
||||||
FilePaths []string
|
FilePaths []string
|
||||||
PaperWidth float64
|
Landscape bool
|
||||||
PaperHeight float64
|
|
||||||
Landscape bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print converts Office documents to PDF.
|
// Print converts Office documents to PDF.
|
||||||
@@ -36,15 +33,9 @@ func (o *Office) Print(destination string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
tmpDest := fmt.Sprintf("%s/%s.pdf", dirPath, baseFilename)
|
tmpDest := fmt.Sprintf("%s/%s.pdf", dirPath, baseFilename)
|
||||||
paperSize, err := unoconvPaperSize(o.PaperWidth, o.PaperHeight)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
cmdArgs := []string{
|
cmdArgs := []string{
|
||||||
"--format",
|
"--format",
|
||||||
"pdf",
|
"pdf",
|
||||||
"--printer",
|
|
||||||
paperSize,
|
|
||||||
}
|
}
|
||||||
if o.Landscape {
|
if o.Landscape {
|
||||||
cmdArgs = append(cmdArgs, "--printer", "PaperOrientation=landscape")
|
cmdArgs = append(cmdArgs, "--printer", "PaperOrientation=landscape")
|
||||||
@@ -70,18 +61,6 @@ func (o *Office) Print(destination string) error {
|
|||||||
return Merge(fpaths, destination)
|
return Merge(fpaths, destination)
|
||||||
}
|
}
|
||||||
|
|
||||||
func unoconvPaperSize(paperWidth, paperHeight float64) (string, error) {
|
|
||||||
width, err := strconv.Atoi(fmt.Sprintf("%.0f", paperWidth*25.4))
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("%0.f: converting width to millimiter: %v", paperWidth, err)
|
|
||||||
}
|
|
||||||
height, err := strconv.Atoi(fmt.Sprintf("%.0f", paperHeight*25.4))
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("%0.f: converting height to millimiter: %v", paperHeight, err)
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("PaperSize=%dx%d", width, height), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compile-time checks to ensure type implements desired interfaces.
|
// Compile-time checks to ensure type implements desired interfaces.
|
||||||
var (
|
var (
|
||||||
_ = Printer(new(Office))
|
_ = Printer(new(Office))
|
||||||
|
|||||||
@@ -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([]string{
|
|
||||||
"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).
|
|
||||||
172
pkg/client.go
@@ -1,172 +0,0 @@
|
|||||||
package gotenberg
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"mime/multipart"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
webhookURL string = "webhookURL"
|
|
||||||
paperWidth string = "paperWidth"
|
|
||||||
paperHeight string = "paperHeight"
|
|
||||||
marginTop string = "marginTop"
|
|
||||||
marginBottom string = "marginBottom"
|
|
||||||
marginLeft string = "marginLeft"
|
|
||||||
marginRight string = "marginRight"
|
|
||||||
landscape string = "landscape"
|
|
||||||
)
|
|
||||||
|
|
||||||
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
|
|
||||||
SetAssets(fpaths []string) error
|
|
||||||
SetPaperSize(size [2]float64)
|
|
||||||
SetMargins(margins [4]float64)
|
|
||||||
SetLandscape(isLandscape bool)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnoconvRequest is a type for sending
|
|
||||||
// conversion requests which will be
|
|
||||||
// handle by unoconv.
|
|
||||||
type UnoconvRequest interface {
|
|
||||||
SetPaperSize(size [2]float64)
|
|
||||||
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.gotenberg.github.io.
|
|
||||||
*/
|
|
||||||
package gotenberg
|
|
||||||
104
pkg/html.go
@@ -1,104 +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)
|
|
||||||
}
|
|
||||||
|
|
||||||
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([]string{
|
|
||||||
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)
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
117
pkg/markdown.go
@@ -1,117 +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)
|
|
||||||
}
|
|
||||||
|
|
||||||
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,54 +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"),
|
|
||||||
[]string{
|
|
||||||
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([]string{
|
|
||||||
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
@@ -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([]string{
|
|
||||||
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,62 +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
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPaperSize sets paperWidth and paperHeight form fields.
|
|
||||||
func (office *OfficeRequest) SetPaperSize(size [2]float64) {
|
|
||||||
office.values[paperWidth] = fmt.Sprintf("%f", size[0])
|
|
||||||
office.values[paperHeight] = fmt.Sprintf("%f", size[1])
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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,38 +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([]string{
|
|
||||||
test.OfficeTestFilePath(t, "document.docx"),
|
|
||||||
})
|
|
||||||
require.Nil(t, err)
|
|
||||||
req.SetPaperSize(A4)
|
|
||||||
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)
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,6 +9,7 @@ DOCKER_PASSWORD="$4"
|
|||||||
|
|
||||||
docker login -u "$DOCKER_USER" -p "$DOCKER_PASSWORD"
|
docker login -u "$DOCKER_USER" -p "$DOCKER_PASSWORD"
|
||||||
|
|
||||||
|
VERSION="${VERSION//v}"
|
||||||
SEMVER=( ${VERSION//./ } )
|
SEMVER=( ${VERSION//./ } )
|
||||||
VERSION_LENGTH=${#SEMVER[@]}
|
VERSION_LENGTH=${#SEMVER[@]}
|
||||||
|
|
||||||
@@ -21,11 +22,13 @@ docker build -t thecodingmachine/gotenberg:base -f build/base/Dockerfile .
|
|||||||
docker build \
|
docker build \
|
||||||
--build-arg GOLANG_VERSION=${GOLANG_VERSION} \
|
--build-arg GOLANG_VERSION=${GOLANG_VERSION} \
|
||||||
--build-arg VERSION=${VERSION} \
|
--build-arg VERSION=${VERSION} \
|
||||||
|
-t thecodingmachine/gotenberg:latest \
|
||||||
-t thecodingmachine/gotenberg:${SEMVER[0]} \
|
-t thecodingmachine/gotenberg:${SEMVER[0]} \
|
||||||
-t thecodingmachine/gotenberg:${SEMVER[0]}.${SEMVER[1]} \
|
-t thecodingmachine/gotenberg:${SEMVER[0]}.${SEMVER[1]} \
|
||||||
-t thecodingmachine/gotenberg:${SEMVER[0]}.${SEMVER[1]}.${SEMVER[2]} \
|
-t thecodingmachine/gotenberg:${SEMVER[0]}.${SEMVER[1]}.${SEMVER[2]} \
|
||||||
-f build/package/Dockerfile .
|
-f build/package/Dockerfile .
|
||||||
|
|
||||||
|
docker push "thecodingmachine/gotenberg:latest"
|
||||||
docker push "thecodingmachine/gotenberg:${SEMVER[0]}"
|
docker push "thecodingmachine/gotenberg:${SEMVER[0]}"
|
||||||
docker push "thecodingmachine/gotenberg:${SEMVER[0]}.${SEMVER[1]}"
|
docker push "thecodingmachine/gotenberg:${SEMVER[0]}.${SEMVER[1]}"
|
||||||
docker push "thecodingmachine/gotenberg:${SEMVER[0]}.${SEMVER[1]}.${SEMVER[2]}"
|
docker push "thecodingmachine/gotenberg:${SEMVER[0]}.${SEMVER[1]}.${SEMVER[2]}"
|
||||||
15
test/testdata/url/footer.html
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-size: 8rem;
|
||||||
|
margin: 4rem auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
<span class="pageNumber"></span> of <span class="totalPages"></span>
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
13
test/testdata/url/header.html
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-size: 8rem;
|
||||||
|
margin: 4rem auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<span class="title"></span>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -23,6 +23,13 @@ func HTMLTestMultipartForm(t *testing.T) (*bytes.Buffer, string) {
|
|||||||
return multipartForm(t, "html")
|
return multipartForm(t, "html")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// URLTestMultipartForm returns the body
|
||||||
|
// for a multipate/form-data request with all
|
||||||
|
// files under "url" folder.
|
||||||
|
func URLTestMultipartForm(t *testing.T) (*bytes.Buffer, string) {
|
||||||
|
return multipartForm(t, "url")
|
||||||
|
}
|
||||||
|
|
||||||
// MarkdownTestMultipartForm returns the body
|
// MarkdownTestMultipartForm returns the body
|
||||||
// for a multipate/form-data request with all
|
// for a multipate/form-data request with all
|
||||||
// files under "markdown" folder.
|
// files under "markdown" folder.
|
||||||
@@ -65,6 +72,10 @@ func multipartForm(t *testing.T, kind string) (*bytes.Buffer, string) {
|
|||||||
_, err = io.Copy(part, file)
|
_, err = io.Copy(part, file)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
}
|
}
|
||||||
|
if kind == "url" {
|
||||||
|
err := writer.WriteField("remoteURL", "http://google.com")
|
||||||
|
require.Nil(t, err)
|
||||||
|
}
|
||||||
return body, writer.FormDataContentType()
|
return body, writer.FormDataContentType()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,6 +85,12 @@ func HTMLTestDirPath(t *testing.T) string {
|
|||||||
return copyDir(t, "html")
|
return copyDir(t, "html")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// URLTestDirPath creates a copy
|
||||||
|
// of "url" folder in test/testdata.
|
||||||
|
func URLTestDirPath(t *testing.T) string {
|
||||||
|
return copyDir(t, "url")
|
||||||
|
}
|
||||||
|
|
||||||
// MarkdownTestDirPath creates a copy
|
// MarkdownTestDirPath creates a copy
|
||||||
// of "markdown" folder in test/testdata.
|
// of "markdown" folder in test/testdata.
|
||||||
func MarkdownTestDirPath(t *testing.T) string {
|
func MarkdownTestDirPath(t *testing.T) string {
|
||||||
@@ -121,30 +138,6 @@ func copyDir(t *testing.T, kind string) string {
|
|||||||
return tmpDirPath
|
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 {
|
func abs(t *testing.T, kind, filename string) string {
|
||||||
_, gofilename, _, ok := runtime.Caller(0)
|
_, gofilename, _, ok := runtime.Caller(0)
|
||||||
require.Equal(t, ok, true, "got no caller information")
|
require.Equal(t, ok, true, "got no caller information")
|
||||||
|
|||||||