forked from acsone/kwkhtmltopdf
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathkwkhtmltopdf_client.py
executable file
·92 lines (70 loc) · 2.41 KB
/
kwkhtmltopdf_client.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#!/usr/bin/env python
# Copyright (c) 2019 ACSONE SA/NV
# Distributed under the MIT License (http://opensource.org/licenses/MIT)
from __future__ import print_function
import os
import sys
import requests
CHUNK_SIZE = 2**16
class Error(Exception):
pass
class UsageError(Error):
pass
class ServerError(Error):
pass
def wkhtmltopdf(args):
url = os.getenv("KWKHTMLTOPDF_SERVER_URL")
hostname = os.getenv("HOSTNAME")
parts = []
def add_option(option):
# TODO option encoding?
parts.append(("option", (None, option)))
def add_file(filename):
with open(filename, "rb") as f:
parts.append(("file", (filename, f.read())))
if "-" in args:
raise UsageError("stdin/stdout input is not implemented")
output = "-"
if len(args) >= 2 and not args[-1].startswith("-") and not args[-2].startswith("-"):
output = args[-1]
args = args[:-1]
for arg in args:
if arg.startswith("-"):
add_option(arg)
elif arg.startswith("http://") or arg.startswith("https://"):
add_option(arg)
elif arg.startswith("file://"):
add_file(arg[7:])
elif os.path.isfile(arg):
# TODO better way to detect args that are actually options
# TODO in case an option has the same name as an existing file
# TODO only way I see so far is enumerating them in a static
# TODO datastructure (that can be initialized with a quick parse
# TODO of wkhtmltopdf --extended-help)
add_file(arg)
else:
add_option(arg)
if not parts:
add_option("-h")
try:
r = requests.post(url, files=parts, headers={"Host": hostname})
r.raise_for_status()
if output == "-":
if sys.version_info[0] < 3:
out = sys.stdout
else:
out = sys.stdout.buffer
else:
out = open(output, "wb")
for chunk in r.iter_content(chunk_size=CHUNK_SIZE):
out.write(chunk)
except requests.exceptions.ChunkedEncodingError:
# TODO look if client and server could use trailer headers
# TODO to report errors
raise ServerError("kwkhtmltopdf server error, consult server log")
if __name__ == "__main__":
try:
wkhtmltopdf(sys.argv[1:])
except Error as e:
print(e, file=sys.stderr)
sys.exit(-1)