diff --git a/Dockerfile b/Dockerfile index 0a0b057d..7ec0f1c6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,23 @@ -FROM openlabs/docker-wkhtmltopdf:latest +FROM ubuntu:14.04.3 MAINTAINER Sharoon Thomas +RUN sed 's/main$/main universe/' -i /etc/apt/sources.list +RUN apt-get update +RUN apt-get upgrade -y + +# Download and install wkhtmltopdf +RUN apt-get install -y build-essential xorg libssl-dev libxrender-dev wget gdebi +RUN wget http://download.gna.org/wkhtmltopdf/0.12/0.12.2.1/wkhtmltox-0.12.2.1_linux-trusty-amd64.deb +RUN gdebi --n wkhtmltox-0.12.2.1_linux-trusty-amd64.deb + # Install dependencies for running web service RUN apt-get install -y python-pip RUN pip install werkzeug executor gunicorn +# Copy the python app that gunicorn will use ADD app.py /app.py EXPOSE 80 -ENTRYPOINT ["usr/local/bin/gunicorn"] - -# Show the extended help +# Execute gunicorn on the docker +ENTRYPOINT ["/usr/local/bin/gunicorn"] CMD ["-b", "0.0.0.0:80", "--log-file", "-", "app:application"] diff --git a/README.md b/README.md index 7bbd483e..324e5885 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,13 @@ docker port 071599a1373e 80 where 071599a1373e is the container SHA that docker assigned when `docker run` was executed in the previous command. -Take a note of the public port number where docker binds to. +or + +```sh +docker ps +``` + +To obtain some information about de container, which include de ip and the port where the container runs. Take a note of the public port number where docker binds to. ## Using the webservice @@ -38,7 +44,7 @@ This is a convenient way to use the service from command line utilities like curl. ```sh -curl -X POST -vv -F 'file=@path/to/local/file.html' http://:/ -o path/to/output/file.pdf +curl -X POST -vv -F 'fichs=@path/to/local/file.html' http://:/ -o path/to/output/file.pdf ``` where: @@ -46,6 +52,12 @@ where: * docker-host is the hostname or address of the docker host running the container * port is the public port to which the container is bound to. +To add multiple html files simply add them to the curl command: + +```sh +curl -X POST -vv -F 'fichs=@file1.html' -F 'fichs=@file2.html' -F 'fichs=@file3.html' http://:/ -o path/to/output/file.pdf +``` + ### JSON API If you are planning on using this service in your application, @@ -60,7 +72,9 @@ import requests url = 'http://:/' data = { - 'contents': open('/file/to/convert.html').read().encode('base64'), + 'fichs': { + 'f1' : open('/file/to/file1.html').read().encode('base64') + } } headers = { 'Content-Type': 'application/json', # This is important @@ -69,10 +83,10 @@ response = requests.post(url, data=json.dumps(data), headers=headers) # Save the response contents to a file with open('/path/to/local/file.pdf', 'wb') as f: - f.write(response.content) + f.write(response.content.decode('base64')) ``` -Here is another example in python, but this time we pass options to wkhtmltopdf. +Here is another example in python, but this time we pass multiple files and options to wkhtmltopdf. When passing our settings we omit the double dash "--" at the start of the option. For documentation on what options are available, visit http://wkhtmltopdf.org/usage/wkhtmltopdf.txt @@ -82,7 +96,11 @@ import requests url = 'http://:/' data = { - 'contents': open('/file/to/convert.html').read().encode('base64'), + 'fichs': { + 'f1' : open('/file/to/file1.html').read().encode('base64'), + 'f2' : open('/file/to/file2.html').read().encode('base64'), + 'f3' : open('/file/to/file3.html').read().encode('base64') + }, 'options': { #Omitting the "--" at the start of the option 'margin-top': '6', @@ -90,7 +108,8 @@ data = { 'margin-right': '6', 'margin-bottom': '6', 'page-width': '105mm', - 'page-height': '40mm' + 'page-height': '40mm', + 'enable-javascript': '' } } headers = { @@ -100,7 +119,7 @@ response = requests.post(url, data=json.dumps(data), headers=headers) # Save the response contents to a file with open('/path/to/local/file.pdf', 'wb') as f: - f.write(response.content) + f.write(response.content.decode('base64')) ``` ## TODO diff --git a/app.py b/app.py index 273f15b6..2261b7bd 100644 --- a/app.py +++ b/app.py @@ -1,7 +1,6 @@ #! /usr/bin/env python """ WSGI APP to convert wkhtmltopdf As a webservice - :copyright: (c) 2013 by Openlabs Technologies & Consulting (P) Limited :license: BSD, see LICENSE for more details. """ @@ -12,7 +11,6 @@ from werkzeug.wrappers import Request, Response from executor import execute - @Request.application def application(request): """ @@ -26,46 +24,62 @@ def application(request): request_is_json = request.content_type.endswith('json') - with tempfile.NamedTemporaryFile(suffix='.html') as source_file: + if request_is_json: + # If a JSON payload is there, all data is in the payload + payload = json.loads(request.data) + ficheros = payload.get('fichs', {}) + options = payload.get('options', {}) + elif request.files: + # Check if any files were uploaded + ficheros = request.files.getlist('fichs') + # Load any options that may have been provided in options + options = json.loads(request.form.get('options', '{}')) + + # Adding the args for wkhtmltopdf + args = ['wkhtmltopdf'] + # Add Global Options + if options: + for option, value in options.items(): + args.append('--%s' % option) + if value: + args.append('"%s"' % value) + + if ficheros: if request_is_json: - # If a JSON payload is there, all data is in the payload - payload = json.loads(request.data) - source_file.write(payload['contents'].decode('base64')) - options = payload.get('options', {}) + for f, value in ficheros.items(): + sf = tempfile.NamedTemporaryFile(suffix='.html', delete=False) + sf.write(value.decode('base64')) + sf.close() + # Add source file name + args += [sf.name] elif request.files: - # First check if any files were uploaded - source_file.write(request.files['file'].read()) - # Load any options that may have been provided in options - options = json.loads(request.form.get('options', '{}')) - - source_file.flush() + for f in ficheros: + sf = tempfile.NamedTemporaryFile(suffix='.html', delete=False) + sf.write(f.read()) + sf.close() + # Add source file name + args += [sf.name] - # Evaluate argument to run with subprocess - args = ['wkhtmltopdf'] + # Add source file name and output file name + pdf_file_name = 'pdf_file.pdf' + args += [pdf_file_name] - # Add Global Options - if options: - for option, value in options.items(): - args.append('--%s' % option) - if value: - args.append('"%s"' % value) - - # Add source file name and output file name - file_name = source_file.name - args += [file_name, file_name + ".pdf"] - - # Execute the command using executor - execute(' '.join(args)) + # Execute the command using executor + execute(' '.join(args)) + if request_is_json: + return Response(open(pdf_file_name, 'r').read().encode('base64')) + else: return Response( - wrap_file(request.environ, open(file_name + '.pdf')), - mimetype='application/pdf', + wrap_file(request.environ, open(pdf_file_name, 'r')), + mimetype='application/pdf' ) - if __name__ == '__main__': from werkzeug.serving import run_simple run_simple( '127.0.0.1', 5000, application, use_debugger=True, use_reloader=True ) + + \ No newline at end of file