sistema_web/private-dynamic/content/gestion/reporte.py

736 lines
23 KiB
Python
Raw Normal View History

2023-02-27 16:21:22 -03:00
# coding: utf-8
import os
import math
from PIL import Image
from fpdf import FPDF
from flask import current_app
from flask_login import current_user
from tempfile import NamedTemporaryFile
from functools import cache
from webinterface.models.documentos import Documento
from datetime import datetime, timedelta, date
from PyPDF2 import PdfFileReader, PdfFileMerger
from webinterface.models.gestion import Objetivo, Accion, Evidencia, Comision
@cache
def logoyencabezado(Nodo):
uuid_nill = "00000000000000000000000000000000"
responsable = Nodo.responsable
while responsable.creado > 1:
responsable = responsable.supervisor
titulo = None
logo = None
docLogo = Documento.query.filter(Documento.hash==responsable.logo).one_or_none()
if docLogo is not None:
logoFile = docLogo.get_file()
if logoFile is not None:
logo = os.path.abspath(logoFile)
docTitulo = Documento.query.filter(Documento.hash==responsable.titulo).one_or_none()
if docTitulo is not None:
tituloFile = docTitulo.get_file()
if tituloFile is not None:
titulo = os.path.abspath(tituloFile)
return (logo, titulo)
def ReportePDF(Archivo, Nodo, Fini=None, Ffin=None):
logo, titulo = logoyencabezado(Nodo)
maindoc = plantillaReporte(Titulo=Nodo.nombre, Logo=logo, Encabezado=titulo)
maindoc.set_title(u"Reporte de Gestión: {}".format(Nodo.nombre))
maindoc.set_subject(Nodo.nombre)
maindoc.set_author("iLab Gestion: {}".format(maindoc.serial))
maindoc.set_creator(current_user.ascii_nombrecompleto)
Horachilena=datetime.today() - timedelta(hours=4)
Horachilenastr = Horachilena.strftime('Generado el %d/%m/%Y a las %H horas')
if isinstance(Fini,date) and isinstance(Ffin, date) and Fini < Ffin:
maindoc.Tapa('Reporte de Gestión desde {:%d/%m/%Y} hasta {:%d/%m/%Y}.'.format(Fini, Ffin), Linea2=Nodo.nombre, Linea3=Horachilenastr, Logo=True)
else:
maindoc.Tapa('Reporte de Gestión', Linea2=Nodo.nombre, Linea3=Horachilenastr, Logo=True)
maindoc, _, _ = ReporteNodo(maindoc, Nodo, True, Fini, Ffin)
paginas_en_blanco = maindoc.paginas_en_blanco
anexos_pdf = maindoc.anexospdf
paginas_reporte = maindoc.page_no()
current_app.logger.debug(u'PDF original tiene {} páginas'.format(paginas_reporte))
with NamedTemporaryFile() as tmp:
maindoc.output(name=tmp.name, dest='F')
merger = PdfFileMerger(strict=False)
pagina = 0
while pagina < paginas_reporte:
if pagina not in paginas_en_blanco:
merger.append(tmp.name, pages=(pagina, pagina+1))
pagina = pagina + 1
else:
archivo_pdf, largo = anexos_pdf.pop(0)
merger.append(archivo_pdf)
pagina = pagina + largo
merger.write(Archivo)
merger.close()
return "reporte_gestion-{}-{}.pdf".format(Nodo.id, maindoc.serial)
def ListaActaPDF(Archivo, Acta):
logo, titulo = logoyencabezado(Acta.objetivo)
maindoc = plantillaReporte(Titulo='Acta {}: {}'.format(Acta.secuencia, Acta.objetivo.nombre), Logo=logo, Encabezado=titulo)
maindoc.add_page()
maindoc.PutLogoCenter()
maindoc.Titulo1(u'{} - Acta {}'.format(Acta.objetivo.nombre, Acta.secuencia), align='C', newpage=False)
maindoc.Titulo2(u"Listado de Asistentes", align='C', Tight=True)
maindoc.Titulo2(u"Fecha: {}".format(Acta.horaini.strftime('%d/%m/%Y')), align='C', Tight=True)
count = 0
w = maindoc.AnchoFirma(Acta.asistentes)
for asistente in Acta.asistentes:
if count>0 and count % 11 == 0:
maindoc.add_page()
maindoc.ln(25)
count = count + 1
# maindoc.ln(5)
maindoc.Firma("{}) {}".format(count, asistente),Ancho=w)
maindoc.output(name=Archivo, dest='F')
return "Lista acta {}-{} {}.pdf".format(Acta.secuencia, Acta.objetivo.nombre, maindoc.serial)
def ActaPDF(Archivo, Acta):
logo, titulo = logoyencabezado(Acta.objetivo)
maindoc = plantillaReporte(Titulo='Acta {}: {}'.format(Acta.secuencia, Acta.objetivo.nombre), Logo=logo, Encabezado=titulo)
maindoc = ReporteActa(maindoc, Acta)
paginas_en_blanco = maindoc.paginas_en_blanco
anexos_pdf = maindoc.anexospdf
paginas_reporte = maindoc.page_no()
current_app.logger.debug(u'PDF original tiene {} páginas'.format(paginas_reporte))
with NamedTemporaryFile() as tmp:
maindoc.output(name=tmp.name, dest='F')
merger = PdfFileMerger(strict=False)
pagina = 0
while pagina < paginas_reporte:
if pagina not in paginas_en_blanco:
merger.append(tmp.name, pages=(pagina, pagina+1))
pagina = pagina + 1
else:
archivo_pdf, largo = anexos_pdf.pop(0)
merger.append(archivo_pdf)
pagina = pagina + largo
merger.write(Archivo)
merger.close()
return "acta {}-{} {}.pdf".format(Acta.secuencia, Acta.objetivo.nombre, maindoc.serial)
def ReporteActa(documento, Acta):
documento.add_page()
documento.PutLogoCenter()
documento.Titulo1(u'Acta {}'.format(Acta.secuencia), align='C', newpage=False)
documento.Titulo1(Acta.objetivo.nombre, align='C', newpage=False)
documento.LugaryFecha(Acta.lugar, Acta.horaini, Acta.horafin)
documento.Asistentes(Acta.asistentes)
documento.TituloParrafo(u'Temas', Acta.temas)
if len(Acta.desarrollo):
documento.TituloParrafo(u'Desarrollo', Acta.desarrollo)
if len(Acta.acuerdos):
documento.TituloParrafo(u'Acuerdos', Acta.acuerdos)
links = []
fotos = []
pdfs = []
evidencias = 0
for evidencia in Acta.anexos:
if evidencia.documento.nombre[:7] == 'http://' or evidencia.documento.nombre[:8] == 'https://':
# current_app.logger.debug(u'Link detectado: {}'.format(evidencia.documento.nombre))
links.append((evidencia.documento.nombre, evidencia.documento.descripcion))
evidencias = evidencias + 1
elif evidencia.documento.tamano > 0:
nombre, extension = os.path.splitext(evidencia.documento.nombre.lower())
if extension in ['.jpg', '.jpeg', '.png']:
evidencias = evidencias + 1
fotos.append(evidencia)
if extension in ['.pdf']:
evidencias = evidencias + 1
pdfs.append(evidencia)
if evidencias > 0:
if len(links) > 0:
documento.Titulo2('Anexos')
for link in links:
documento.Link(link)
if len(fotos) > 0:
documento.FotoEvidencia(fotos)
if len(pdfs) > 0:
largo = 0
for evidencia in pdfs:
archivo = PdfFileReader(open(evidencia.documento.get_file(), "rb"))
largo = largo + archivo.getNumPages()
documento.anexospdf = (evidencia.documento.get_file(), archivo.getNumPages())
documento.pagina_en_blanco(largo)
return documento
def ReporteNodo(documento, Nodo, Recursive=True, Fini=None, Ffin=None, anexoi=0, anexos={}):
documento.Titulo1(Nodo.nombre)
if isinstance(Fini,date) and isinstance(Ffin, date) and Fini < Ffin:
rango = True
DTini = datetime(Fini.year, Fini.month, Fini.day, 0, 0, 0)
DTfin = datetime(Ffin.year, Ffin.month, Ffin.day, 23, 59, 59)
else:
rango = False
if Nodo.sub_HDS < 1:
documento.Item(Sujeto='Dedicación al objetivo:',Predicado= u'{} Horas cronológicas'.format(round(Nodo.sub_horas,1)), Ancho=55)
else:
documento.Item(Sujeto='Dedicación al objetivo:',Predicado= u'{} Horas cronológicas ({} Horas de dedicación semanal)'.format(round(Nodo.sub_horas,1), Nodo.sub_HDS), Ancho=55)
if len(Nodo.descripcion)>0:
documento.Titulo3("Descripción del Objetivo")
documento.Parrafo(Nodo.descripcion)
# indicadores
eactas = 0
for Acta in Nodo.actasr:
if rango and (Acta.horaini < DTini or Acta.horaini > DTfin):
continue
if eactas == 0:
documento.Titulo2("Actas")
documento.Indicador(Glosa="Acta/Lugar", vIni="Fecha", vAct="Hora", vFin="Fin", Titulo=True, ancho=25)
eactas = eactas + 1
documento.Indicador(Glosa="Acta {}: {}".format(Acta.secuencia, Acta.lugar), vIni=Acta.horaini.strftime('%d/%m/%Y'), vAct=Acta.horaini.strftime('%H:%M'), vFin=Acta.horafin.strftime('%H:%M'), ancho=25)
# indicadores
eind = 0
for Indicador in Nodo.indicadores:
if eind == 0:
documento.Titulo2("Indicadores")
documento.Indicador(Glosa="Indicador", vIni="Inicial", vAct="Actual", vFin="Meta", Titulo=True)
eind = eind + 1
documento.Indicador(Glosa=Indicador.nombre, vIni=Indicador.inicial, vAct=Indicador.valor, vFin=Indicador.meta)
# Actividades
if Recursive is True:
anexos = {}
eact = 0
for Accion in Nodo.iactividades:
if rango and (Accion.fecha < Fini or Accion.fecha > Ffin):
continue
if eact == 0:
documento.Titulo2("Actividades Realizadas", border='b', Tight=False)
eact = eact + 1
documento.Titulo2(u"Actividad {}: {}".format(eact, Accion.nombre))
documento.Item(Sujeto='Fecha:',Predicado= u'{}'.format(Accion.fecha.strftime('%d/%m/%Y')), Ancho=20)
if Accion.dedicacion < 26:
documento.Item(Sujeto='Dedicación:',Predicado= u'{} Horas cronológicas'.format(Accion.dedicacion), Ancho=30)
else:
documento.Item(Sujeto='Dedicación:',Predicado= u'{} Horas cronológicas ({} Horas de dedicación semanal)'.format(Accion.dedicacion, round(Accion.dedicacion/26,2)), Ancho=30)
if len(Accion.descripcion)>0:
documento.Titulo3(u"Descripción de la Actividad")
documento.Parrafo(Accion.descripcion)
evidencias = 0
links = []
for evidencia in Accion.evidencias:
if evidencia.documento.nombre[:7] == 'http://' or evidencia.documento.nombre[:8] == 'https://':
links.append((evidencia.documento.nombre, evidencia.documento.descripcion))
elif evidencia.documento.tamano > 0:
nombre, extension = os.path.splitext(evidencia.documento.nombre.lower())
if extension in ['.jpg', '.jpeg', '.png', '.pdf']:
evidencias = evidencias + 1
if evidencias > 0 or len(links) > 0:
documento.Titulo3('Evidencias')
if len(links)>0:
for link in links:
documento.Link(link)
if evidencias > 0:
if anexoi > 25:
v1 = chr(ord('A') + int(anexoi/26) - 1)
v2 = chr(ord('A') + anexoi%26)
v = '{}{}'.format(v1,v2)
else:
v = chr(ord('A') + anexoi)
anexoi = anexoi + 1
anexos[v] = Accion
documento.Parrafo(u'Ver Anexo {}.'.format(v))
if Recursive is True:
for hijo in Nodo.hijos:
documento, anexoi, anexos = ReporteNodo(documento, hijo, Recursive=False, Fini=Fini, Ffin=Ffin, anexoi=anexoi, anexos=anexos)
else:
return (documento, anexoi, anexos)
eacta = 0
for Acta in Nodo.actasr:
if rango and (Acta.horaini < DTini or Acta.horaini > DTfin):
continue
if eacta == 0:
eacta = 1
documento.Tapa('Anexo Actas')
documento = ReporteActa(documento, Acta)
if Recursive is True:
for hijo in Nodo.hijos:
for Acta in hijo.actas:
if rango and (Acta.horaini < DTini or Acta.horaini > DTfin):
continue
if eacta == 0:
eacta = 1
documento.Tapa('Anexo Actas')
documento = ReporteActa(documento, Acta)
for letra, anexo in anexos.items():
documento.Tapa('Anexo {}'.format(letra))
fotos = []
pdfs = []
for evidencia in anexo.evidencias:
nombre, extension = os.path.splitext(evidencia.documento.nombre.lower())
if extension in ['.jpg', '.jpeg', '.png']:
fotos.append(evidencia)
if extension in ['.pdf']:
pdfs.append(evidencia)
if len(fotos) > 0:
documento.FotoEvidencia(fotos)
if len(pdfs) > 0:
largo = 0
for evidencia in pdfs:
archivo = PdfFileReader(open(evidencia.documento.get_file(), "rb"))
largo = largo + archivo.getNumPages()
documento.anexospdf = (evidencia.documento.get_file(), archivo.getNumPages())
documento.pagina_en_blanco(largo)
return (documento, anexoi, anexos)
class plantillaReporte(FPDF):
def __init__(self, Titulo = None, Logo = None, Encabezado = None):
super(plantillaReporte, self).__init__('P', 'mm', 'Letter')
self.set_compression(True)
self.add_font('dejavu', '', fname='/srv/font/DejaVuSerif.ttf', uni=True)
self.add_font('dejavu', 'B', fname='/srv/font/DejaVuSerif-Bold.ttf', uni=True)
self.add_font('dejavu', 'I', fname='/srv/font/DejaVuSerif-Italic.ttf', uni=True)
self.add_font('dejavu', 'BI', fname='/srv/font/DejaVuSerif-BoldItalic.ttf', uni=True)
self.__titulo = Titulo
self.__ancho = 215.9 # 190 / 185
self.__alto = 279.4 # 125 / 120
self.__columna = 90
self.__limiteT2 = 0.8 * self.__alto
self.__limiteT3 = 0.85 * self.__alto
self.__codigo = datetime.today().strftime('%Y%m%d%H.%M%S')
self.__blanks = []
self.__pdf = []
self.__subtitulo = None
self.__h1 = 14
self.__h2 = 12
self.__h3 = 10
self.__logo = Logo
self.__encabezado = Encabezado
# self.__fecha = datetime.today().strftime('%d/%m/%Y a las %H horas')
# self.__titulos = []
# self.__ptitulos = []
# Encabezado
def header(self):
if self.__titulo is not None and self.page_no() > 1:
self.set_y(1)
self.cell(0, 5+self.__h1, u'', border='B', ln=1, align='C')
if self.__encabezado is not None:
imLogo = Image.open(os.path.abspath(self.__encabezado))
w, h = imLogo.size
ancho = self.__h2 * w / h
_, extension = os.path.splitext(self.__logo)
self.image(self.__encabezado, x=10, y=6, w=ancho, type=extension[1:])
else:
self.set_font('dejavu', 'B', self.__h2)
self.set_y(5)
self.cell(110, self.__h1, self.__titulo, border=0, ln=0, align='L')
# if self.__subtitulo is not None:
# self.cell(0, 10, self.__subtitulo, border=0, ln=0, align='R')
self.ln(self.__h2)
# Pie de Página
def footer(self):
# Position at 1.5 cm from bottom
if self.page_no() > 1:
self.set_y(-15)
self.cell(0, 8, u'', border='T', ln=1, align='C')
self.set_y(-15)
self.set_font('dejavu', '', 3)
self.cell(60, self.__h3, u'Versión: {}'.format(self.__codigo), border=0, ln=0, align='L')
self.set_font('dejavu', 'I', self.__h3)
self.cell(0, self.__h3, u'Página {}'.format(self.page_no()), border=0, ln=0, align='R')
def pagina_en_blanco(self, Num = 1):
for i in range(Num):
self.Tapa(u"Esta página fue dejada intencionalmente en blanco")
self.__blanks.append(self.page_no()-1)
@property
def anexospdf(self):
return self.__pdf
@anexospdf.setter
def anexospdf(self, valor):
self.__pdf.append(valor)
@property
def paginas_en_blanco(self):
return self.__blanks
@property
def serial(self):
return self.__codigo
def Tapa(self, Titulo, Linea2=None, Linea3=None, Logo=False):
if self.page_no() > 1:
self.__subtitulo = Titulo
self.add_page()
if self.__logo is not None and Logo is True:
self.ln(self.__h1)
self.ln(self.__h2)
self.PutLogoCenter()
if Linea2 or Linea3:
self.set_y((self.__alto-40)/2)
else:
self.set_y((self.__alto-20)/2)
self.set_font('dejavu', 'B', self.__h1+2)
self.multi_cell(0, self.__h1, Titulo, border=0, align='C')
if Linea2 is not None:
self.set_font('dejavu', 'B', self.__h1)
self.multi_cell(0, self.__h2, Linea2, border=0, align='C')
if Linea3 is not None:
self.set_font('dejavu', '', self.__h2)
self.multi_cell(0, self.__h3, Linea3, border=0, align='C')
def PutLogoCenter(self):
if self.__logo is not None:
yini = self.get_y()
imLogo = Image.open(os.path.abspath(self.__logo))
w, h = imLogo.size
y = self.__columna * h / w
xLogo = (self.__ancho - self.__columna) / 2
_, extension = os.path.splitext(self.__logo)
# current_app.logger.debug(u'Logo {} {} {} {} {}'.format(xLogo,w,h,y,extension))
self.image(self.__logo, x=xLogo, y=yini, w=self.__columna, type=extension[1:])
yfin = yini + y
self.set_y(yfin)
def Titulo1(self, Titulo, align='L', newpage=True):
if newpage:
self.add_page()
# self.__titulos.append(Titulo)
# self.__ptitulos.append(self.page_no())
self.set_font('dejavu', 'B', self.__h1)
self.multi_cell(0, self.__h1, Titulo, border=0, align=align)
# self.cell(0, self.__h1, Titulo, border=0, ln=0, align=align)
# self.ln(self.__h1)
def Titulo2(self, Titulo, border=0, align='L', Tight=True):
if not Tight:
self.ln(self.__h3)
if self.get_y() > self.__limiteT2:
self.add_page()
self.set_font('dejavu', 'B', self.__h2)
self.multi_cell(0, self.__h2, Titulo, border=0, align=align)
# self.cell(0, self.__h2, Titulo, border=border, ln=0, align=align)
# self.ln(self.__h2)
def Titulo3(self, Titulo):
if self.get_y() > self.__limiteT3:
self.add_page()
self.set_font('dejavu', 'B', self.__h3)
self.multi_cell(0, self.__h3, Titulo, border=0, align='L')
# self.cell(0, self.__h3, Titulo, border=0, ln=0, align='L')
# self.ln(self.__h3)
def Parrafo(self, Texto):
self.Normal()
self.multi_cell(0, self.__h3, Texto, align='J')
# self.ln(self.__h3)
def Normal(self):
self.set_font('dejavu', '', self.__h3)
def LimpiaColordeFondo(self):
self.set_fill_color(1, 1, 1)
def ColordeFondo(self):
self.set_fill_color(230, 230, 230)
def TituloParrafo(self, Titulo, Parrafo):
self.set_font('dejavu', 'B', self.__h2)
self.cell(0, self.__h2, Titulo, border=0, ln=1, align='L')
self.ColordeFondo()
self.Normal()
self.multi_cell(0, self.__h3, Parrafo, align='J', fill=True)
self.ln(self.__h3)
def LugaryFecha(self, lugar, horaini, horafin):
self.ColordeFondo()
self.set_font('dejavu', 'B', self.__h2)
self.cell(0, self.__h2, "Lugar", border=0, ln=1, align='L')
self.set_font('dejavu', '', self.__h2)
self.cell(0, self.__h2, lugar, border=0, ln=1, align='L', fill = True)
self.set_font('dejavu', 'B', self.__h2)
self.cell(67, self.__h2, 'Fecha', border=0, ln=0, align='L')
self.cell(67, self.__h2, 'Inicio', border=0, ln=0, align='L')
self.cell(61, self.__h2, u'Término', border=0, ln=1, align='L')
self.set_font('dejavu', '', self.__h2)
self.cell(61, self.__h2, horaini.strftime('%d/%m/%Y'), border=0, ln=0, align='C', fill = True)
self.cell(6, self.__h2, '', border=0, ln=0, align='L')
self.cell(61, self.__h2, horaini.strftime('%H:%M'), border=0, ln=0, align='C', fill = True)
self.cell(6, self.__h2, '', border=0, ln=0, align='L')
self.cell(61, self.__h2, horafin.strftime('%H:%M'), border=0, ln=1, align='C', fill = True)
def Asistentes(self, asistentes):
self.ColordeFondo()
self.set_font('dejavu', 'B', self.__h2)
self.cell(0, self.__h2, "Convocados", border=0, ln=1, align='L')
count = 0
for asistente in asistentes:
self.set_font('dejavu', '', self.__h3)
rcells = math.ceil(self.get_string_width(asistente)/61)
if rcells == 1:
w = 61
elif rcells == 2:
w = 128
else:
w = 195
if ((count + rcells) % 3 <= count % 3):
self.set_font('dejavu', '', self.__h3)
self.cell(w, self.__h3, asistente, border=0, ln=1, align='C', fill = True)
else:
self.set_font('dejavu', '', self.__h3)
self.cell(w, self.__h3, asistente, border=0, ln=0, align='C', fill = True)
self.cell(6, self.__h3, '', border=0, ln=0, align='L')
count = count + rcells
if count == 0:
self.set_font('dejavu', '', self.__h3)
self.cell(0, self.__h3, 'No existen convocados', border=0, ln=1, align='L')
elif count % 3 != 0:
self.ln(self.__h2)
def Indicador(self, Glosa, vIni, vAct, vFin, Titulo = False, ancho=16):
if Titulo:
self.set_font('dejavu', 'B', self.__h3)
else:
self.set_font('dejavu', '', self.__h3)
top = self.get_y()
anchoglosa = 195 - 3*ancho
self.multi_cell(anchoglosa, self.__h3, str(Glosa), border=1, align='J')
bottom = self.get_y()
if bottom < top: # si el final está en la siguiente página, partimos la celda desde arriba.
top = 20
altura = bottom - top # 125-45 = 80 | 125-36 = 89
self.set_y(top)
self.set_x(anchoglosa+10)
# current_app.logger.debug(u'Indicador: top:{} bottom:{} altura:{} anchoglosa:{}'.format(top,bottom,altura,anchoglosa))
self.cell(ancho, altura, str(vIni), border=1, ln=0, align='C')
self.cell(ancho, altura, str(vAct), border=1, ln=0, align='C')
self.cell(ancho, altura, str(vFin), border=1, ln=1, align='C')
self.set_y(bottom)
def AnchoFirma(self, asistentes):
w = 0
self.set_font('dejavu', '', self.__h1)
for asistente in asistentes:
w = max(w, self.get_string_width(asistente))
return w+10
def Firma(self, Sujeto, Ancho=80, Titulo=False):
if Titulo:
self.set_font('dejavu', 'B', self.__h1)
else:
self.set_font('dejavu', '', self.__h1)
self.cell(Ancho, self.__h1, Sujeto , ln=0, align='L')
self.cell(0 , self.__h1, '' , border='B', ln=1)
def Item(self, Sujeto, Predicado, Ancho=80, borde=0, ln=0, alineacion='L'):
self.set_font('dejavu', 'I', self.__h2)
self.cell(Ancho, self.__h3, Sujeto, border=borde, ln=0, align=alineacion)
self.set_font('dejavu', '', self.__h2)
self.cell(0, self.__h3, Predicado, border=borde, ln=1, align=alineacion)
def Link(self, linktupla):
link, descripcion = linktupla
self.set_font('dejavu', '', self.__h2)
self.cell(35, self.__h3, u'Link Externo:', border=0, ln=0, align='L')
self.set_text_color(r=0, g=0, b=255)
if len(descripcion) > 60:
self.cell(0, self.__h3, u"{}...".format(descripcion[:60]), border=0, ln=1, align='L', link=link)
elif len(descripcion) > 0:
self.cell(0, self.__h3, descripcion, border=0, ln=1, align='L', link=link)
elif len(link) > 60:
self.cell(0, self.__h3, u"{}...".format(link[:60]), border=0, ln=1, align='L', link=link)
else:
self.cell(0, self.__h3, link, border=0, ln=1, align='L', link=link)
self.set_text_color(r=0, g=0, b=0)
def FotoEvidencia(self, fotos):
self.add_page()
nfotos = len(fotos)
filas = int(nfotos/2)
sobran = nfotos % 2
seq = 0
self.set_font('dejavu', '', self.__h2)
for fila in range(filas):
primera = seq
segunda = primera + 1
seq = seq + 2
# Obtenemos el tamaño de la imagen
im1 = Image.open(os.path.abspath(fotos[primera].documento.get_file()))
w1, h1 = im1.size
im2 = Image.open(os.path.abspath(fotos[segunda].documento.get_file()))
w2, h2 = im2.size
#Calculamos la altura a medio espacio
y1 = self.__columna * h1 / w1
y2 = self.__columna * h2 / w2
# Vemos si tenemos suficiente espacio en la hoja para poner ambas imagenes
ymax = max(y1, y2)
if ymax + self.get_y() > self.__limiteT3:
self.add_page()
# Guardamos la posición inicial antes de pegar las imagenes y sus captions
posicionYinicial = self.get_y()
## Primera imagen
yImagenCentrada = posicionYinicial + ymax - y1
xColumna1 = 10
_, extension = os.path.splitext(fotos[primera].documento.nombre)
self.image(fotos[primera].documento.get_file(), x=xColumna1, y=yImagenCentrada, w=self.__columna, type=extension[1:])
yImagenCentrada = posicionYinicial + ymax - y2
xColumna2 = 25 + self.__columna
_, extension = os.path.splitext(fotos[segunda].documento.nombre)
self.image(fotos[segunda].documento.get_file(), x=xColumna2, y=yImagenCentrada, w=self.__columna, type=extension[1:])
# Captions de las imagenes
self.set_x(10)
self.set_y(posicionYinicial + ymax + self.__h3)
self.multi_cell(w=self.__columna, h=self.__h3, txt=fotos[primera].documento.descripcion or fotos[primera].documento.nombre, border=0, align='C')
y1 = self.get_y()
self.set_y(posicionYinicial + ymax + self.__h3)
self.set_x(xColumna2)
self.multi_cell(w=self.__columna, h=self.__h3, txt=fotos[segunda].documento.descripcion or fotos[segunda].documento.nombre, border=0, align='C')
y2 = self.get_y()
# Dejamos el cursor bajo ambos captions
self.set_y(max(y1,y2))
self.ln(self.__h3)
if sobran > 0:
seq = nfotos-1
im1 = Image.open(os.path.abspath(fotos[seq].documento.get_file()))
w1, h1 = im1.size
y1 = self.__columna * h1 / w1
if y1 + self.get_y() > self.__limiteT2:
self.add_page()
# Guardamos la posición inicial antes de pegar las imagenes y sus captions
posicionYinicial = self.get_y()
xColumna1 = 10 + self.__columna / 2
_, extension = os.path.splitext(fotos[seq].documento.nombre)
self.image(fotos[seq].documento.get_file(), x=xColumna1, y=posicionYinicial, w=self.__columna, type=extension[1:])
self.set_y(posicionYinicial + y1 + self.__h3)
self.set_x(xColumna1)
self.multi_cell(w=self.__columna, h=self.__h3, txt=fotos[seq].documento.descripcion or fotos[seq].documento.nombre, border=0, align='C')