Created
October 11, 2016 11:38
-
-
Save ryllada/d9cb322c15161c5ca24ca21a936fdb75 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- encoding: utf-8 -*- | |
from django.template.loader import get_template | |
from django.template import Context | |
from django.conf import settings | |
import cStringIO as StringIO | |
import ho.pisa as pisa | |
import datetime | |
import os | |
import subprocess | |
WK_OPCIONES_MULTIPLES_ENTRADAS_A3 = { | |
'--margin-bottom ': '0', | |
'--margin-left ': '0', | |
'--margin-right ': '0', | |
'--margin-top ': '0', | |
'--orientation ': 'Portrait', | |
'--dpi ': '300', | |
'--disable-smart-shrinking': '', | |
'--page-size ': 'A3', | |
'--footer-center ': u""""[page] / [topage]\"""", | |
'-q': '', | |
} | |
WK_OPCIONES_MULTIPLES_ENTRADAS_186x80 = { | |
'--page-width ': '186mm', | |
'--page-height ': '80mm', | |
'--dpi ': '300', | |
'--margin-bottom ': '0', | |
'--margin-left ': '0', | |
'--margin-right ': '0', | |
'--margin-top ': '0', | |
'--disable-smart-shrinking': '', | |
'-q': '', | |
} | |
WK_OPCIONES_ENTRADA_EVENTO_A4 = { | |
'--margin-bottom ': '0', | |
'--margin-left ': '0', | |
'--margin-right ': '0', | |
'--margin-top ': '0', | |
'--dpi ': '300', | |
'--disable-smart-shrinking': '', | |
'--page-size ': 'A4', | |
'-q': '', | |
} | |
class PDFHandler(object): | |
""" Se encarga de crear ficheros PDF temporales en el sistema de ficheros | |
local, para luego poder usar en cualquier lugar, por ejemplo como respuesta | |
de una vista, como creación de un adjunto de un correo. | |
Recordar que es mejor que se lancen excepciones desde aquÃ, y se manipulen | |
en la capa superior (vistas generalmente). | |
""" | |
contexto = {} | |
wk_options = {'--margin-bottom ': '0', | |
'--margin-left ': '0', | |
'--margin-right ': '0', | |
'--margin-top ': '0', | |
'--dpi ': '96', | |
'--disable-smart-shrinking': '', | |
'-q': '', | |
} | |
# Ins | |
template_path = None | |
template = None | |
nombre_base = u'' | |
# Outs | |
pdf_file_path = None | |
rendered_filenames = () # Lista de absolute paths de ficheros renderizados | |
def __init__(self, *args, **kwargs): | |
for key, value in kwargs.iteritems(): | |
setattr(self, key, value) | |
super(PDFHandler, self).__init__(*args, **kwargs) | |
return | |
# Renders privados | |
def _render_via_wkhtml(self, **kwargs): | |
self.nombre_base += u'%s' % ( | |
unicode(datetime.datetime.now()).replace(' ', '_'), ) | |
_filename_in = os.path.join( | |
settings.TEMP_ROOT, '%s.html' % self.nombre_base) | |
_filein = open(_filename_in, 'w') | |
_filein.write(self.template) | |
_filein.close() | |
self.rendered_filenames += (_filename_in, ) | |
_cmd_tuple = ('wkhtmltopdf',) | |
for item, value in self.wk_options.iteritems(): | |
_cmd_tuple += (item + value, ) | |
_filename_out = os.path.join( | |
settings.TEMP_ROOT, '%s.pdf' % self.nombre_base) | |
_cmd_tuple += (_filename_in, _filename_out, ) | |
if settings.DEBUG: | |
print 'DEBUG;', ' '.join(_cmd_tuple) | |
_out = subprocess.call(' '.join(_cmd_tuple), shell=True, close_fds=True) | |
if _out != 0: | |
raise RuntimeError( | |
u"""Salida del wkhtmltopdf: %d - filenamein: | |
%s - filenameout: %s - comando: %s""" % ( | |
_out, _filename_in, _filename_out, _cmd_tuple, ) | |
) | |
_fileout = open(_filename_out) # Test | |
_fileout.close() | |
self.pdf_file_path = _filename_out | |
self.rendered_filenames += (_filename_out, ) | |
return | |
def _render_template(self, template, contexto_dict=None, contexto=None): | |
_contexto = contexto or Context(contexto_dict) | |
self.template = get_template(template) | |
self.template = self.template.render(_contexto) | |
self.template = self.template.encode("UTF-8") | |
# Métodos públicos | |
def clear(self): | |
# Elimina los ficheros creados | |
for item in self.rendered_filenames: | |
try: | |
os.unlink(item) | |
except OSError: | |
pass | |
self.rendered_filenames = () | |
return | |
def render_wkhtmlpdf(self, template, contexto_dict=None, contexto=None): | |
self._render_template(template, contexto_dict, contexto) | |
self._render_via_wkhtml() | |
return | |
def render_pisa(self, template, contexto_dict=None, contexto=None): | |
from cgi import escape | |
result = StringIO.StringIO() | |
self._render_template(template, contexto_dict, contexto) | |
_pdf = pisa.pisaDocument( | |
StringIO.StringIO(self.template), result, | |
link_callback=self._fetch_resources_pisa, encoding='UTF-8') | |
self.result = result.getvalue() | |
return | |
def _fetch_resources_pisa(self, uri, rel): | |
return settings.MEDIA_ROOT + uri.replace(settings.MEDIA_URL, "/") | |
# Customs | |
def render_entrada_evento(self, entrada, contexto={}, debug_local=False): | |
self.contexto = Context(contexto) | |
self.contexto['entrada'] = entrada | |
self.contexto['sesion'] = entrada.recibo.inscripcion.tarifa.sesion | |
self.contexto['MEDIA_ROOT'] = settings.MEDIA_ROOT | |
self.contexto['MEDIA_URL'] = settings.MEDIA_URL | |
self.contexto['absolute_static_paths'] = not debug_local | |
self.template_path = 'eventos/pdf/entrada_a4.html' | |
self.template = get_template(self.template_path) | |
self.template = self.template.render(self.contexto) | |
self.template = self.template.encode("UTF-8") | |
if debug_local: | |
return | |
self.wk_options.update(WK_OPCIONES_ENTRADA_EVENTO_A4) | |
self._render_via_wkhtml() | |
return | |
# Múltiples: Como norma no se deberÃa usar en vistas | |
def render_multiples_entradas_186x80(self, query, contexto={}, | |
debug_local=False, **kwargs): | |
self.contexto = Context(contexto) | |
self.contexto['object_list'] = query | |
self.template_path = kwargs['template'] | |
if debug_local: | |
self.contexto['absolute_static_paths'] = False | |
self.contexto['MEDIA_URL'] = settings.MEDIA_URL | |
else: | |
self.contexto['absolute_static_paths'] = True | |
self.contexto['MEDIA_ROOT'] = settings.MEDIA_ROOT | |
self.template = get_template(self.template_path) | |
self.template = self.template.render(self.contexto) | |
self.template = self.template.encode("UTF-8") | |
self.wk_options.update(WK_OPCIONES_MULTIPLES_ENTRADAS_186x80) | |
self.nombre_base = kwargs['template'].replace('/', '_') | |
self._render_via_wkhtml() | |
return | |
def render_multiples_entradas_evento_a3(self, bloques, contexto={}, | |
debug_local=False, **kwargs): | |
""" Página con bloques de diez | |
""" | |
self.contexto = Context(contexto) | |
try: | |
self.template_path = kwargs['template'] | |
except KeyError: | |
self.template_path = 'eventos/pdf/entradas_multiples_a3.html' | |
self.contexto['bloques_entradas'] = bloques | |
if debug_local: | |
self.contexto['absolute_static_paths'] = False | |
self.contexto['MEDIA_URL'] = settings.MEDIA_URL | |
else: | |
self.contexto['absolute_static_paths'] = True | |
self.contexto['MEDIA_ROOT'] = settings.MEDIA_ROOT | |
self.template = get_template(self.template_path) | |
self.template = self.template.render(self.contexto) | |
self.template = self.template.encode("UTF-8") | |
self.wk_options = WK_OPCIONES_MULTIPLES_ENTRADAS_A3 | |
_kwargs = {} | |
try: | |
self.nombre_base = kwargs['raiz_nombre'] | |
except KeyError: | |
self.nombre_base = kwargs['template'].replace('/', '_') | |
self._render_via_wkhtml(**_kwargs) | |
return |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment