actualización cero

This commit is contained in:
Juan Burgos
2026-08-03 14:57:44 +00:00
parent d073a071ad
commit 3ae490f25f
9 changed files with 1786 additions and 2 deletions

166
pdf/views.py Normal file
View File

@@ -0,0 +1,166 @@
# mi_proyecto/pdf/views.py
# dpsk - 2026
import io
from pathlib import Path
from django.http import HttpResponse
from django.template.loader import render_to_string
from weasyprint import HTML
from arches.app.models.resource import Resource
from django.contrib.auth.models import Group
from datetime import datetime
from zoneinfo import ZoneInfo
from functools import reduce
from operator import getitem
from pypdf import PdfReader, PdfWriter
import json
import ast
def ajustar_medios(resource_media_rel, medios_list):
medios = []
img=["image/bmp", "image/gif", "image/jpg", "image/jpeg", "image/png", "image/tif", "image/tiff"]
no_imagen_principal = True
try:
if isinstance(medios_list, list) :
for rel in resource_media_rel['related_resources']:
if isinstance(medios_list[0], dict) :
medio=next((item for item in medios_list if item['@value'] == rel['displayname']), None)
else:
medio = None
for til in rel['tiles']:
for dato in til['data']:
if isinstance(til['data'][dato], list):
for dat in til['data'][dato]:
idx = " - " + str(dat['index'] +1) if len(til['data'][dato])>1 else ""
if medio is not None and isinstance(medio, dict):
medio_nuevo = {'tipo': val for key, val in medio.items() if "Tipo" in key}
else:
if dat['type'] in img and no_imagen_principal:
medio_nuevo = {'tipo':'Imagen principal'}
no_imagen_principal = False
else:
medio_nuevo = {'tipo':'Medio'}
medio_nuevo.update({'@value':rel['displayname']+idx, 'file':dat['name'], 'url': dat['url'], 'formato':dat['type']})
medios.append(medio_nuevo)
# Reordenamos para que el primer medio de la lista sea de tipo Imagen principal o al menos del tipo imagen
medios.sort(key=lambda item: item.get('formato') not in img)
medios.sort(key=lambda item: item.get('tipo') != 'Imagen principal')
except:
pass
return medios
def find_key_path(data, target_key, current_path=None):
if current_path is None:
current_path = []
# Verifica si es diccionario válido
if isinstance(data, dict):
for key, value in data.items():
# si la clave buscada está en el nivel actual del diccionario.
if key == target_key:
return current_path + [key]
# Profundiza en el rastreo mientras agrega la clave actual a la ruta.
path = find_key_path(value, target_key, current_path + [key])
if path:
return path
# En caso de que la clave esté dentro de una lista
elif isinstance(data, list):
for index, item in enumerate(data):
path = find_key_path(item, target_key, current_path + [index])
if path:
return path
return None
def strdict_to_dict(strdict):
""" Representación de texto de un diccionario a formato json """
value = {}
try:
if isinstance(strdict, str):
value = json.dumps(ast.literal_eval(strdict))
except:
pass
return value
def export_resource_pdf(request, resourceid, printubic, printimgs, printpdfs):
resource = Resource.objects.get(pk=resourceid)
resource_data = resource.to_json()
# Corrección de medios relacionados, se normalizan claves y se adicionan propiedades
ruta_medios = find_key_path( resource_data, "Medio de información")
if ruta_medios is not None:
valor_medios=reduce(lambda dict_layer, key: dict_layer[key], ruta_medios, resource_data)
resource_rel=resource.get_related_resources(user=request.user,resourceinstance_graphid='6afc4e9e-727e-4152-8084-309267752650')
#resource_data["Información gráfica"]["Medio de información"] = ajustar_medios(resource_rel)
reduce(getitem, ruta_medios[:-1], resource_data)[ruta_medios[-1]] = ajustar_medios(resource_rel,valor_medios)
# Cambio de datos gis en texto a formato json
ruta_gis = find_key_path( resource_data, "Coordenadas / Geometría")
if ruta_gis is not None:
valor_gis=reduce(lambda dict_layer, key: dict_layer[key], ruta_gis, resource_data)["@value"]
reduce(getitem, ruta_gis[:-1], resource_data)[ruta_gis[-1]]["@value"] = strdict_to_dict(valor_gis)
# Extracción del identificador de grupo ETA
eta_group=""
ruta_meta_iden = find_key_path( resource_data, "Meta identificación")
if ruta_meta_iden is not None:
meta_iden=json.loads(strdict_to_dict(reduce(lambda dict_layer, key: dict_layer[key], ruta_meta_iden, resource_data)))
eta_group=str(Group.objects.get(pk=meta_iden["grp_eta"])).upper()
# Fecha del informe
sprpcb_url=request.build_absolute_uri('/')[:-1]
fecha=datetime.now(ZoneInfo("America/La_Paz"))
resources = [{
'resourceinstanceid': str(resource.resourceinstanceid),
'graph_id': str(resource.graph_id),
'displayname': resource.displayname,
'resource': resource_data,
'sprpcb_url': sprpcb_url,
'fecha': fecha,
'eta_group': eta_group,
'print_imgs': bool(int(printimgs)),
'print_pdfs': bool(int(printpdfs))
}]
context = {'resources': resources}
match str(resource.graph_id):
case "72420da0-db59-4048-aea2-03b0bc5cdcdf": # Actores
context["resources"][0]["grafo"]="Organizaciones y personas"
nombre_pdf = f'Actor_{resourceid}'
html_string = render_to_string('reports/actor_pdf_report.html', context)
case '8ea3bf67-89ce-474c-b3cb-6dd5ee3d6198': # Bienes inmuebles
context["resources"][0]["grafo"]="Patrimonio material - Bienes inmuebles"
html_string = render_to_string('reports/bim_pdf_report.html', context)
nombre_pdf = f'bienes_inmuebles_{resourceid}'
case '10b03fec-4d85-11ee-a708-ffcd06c08a5d': # Bienes muebles
context["resources"][0]["grafo"]="Patrimonio material - Bienes muebles"
html_string = render_to_string('reports/bm_pdf_report.html', context)
nombre_pdf = f'bienes_muebles_{resourceid}'
case "9b0e22c7-5c56-4be6-aa89-ae2632ba28e8": # Inmaterial
context["resources"][0]["grafo"]="Patrimonio Inmaterial"
html_string = render_to_string('reports/pi_pdf_report.html', context)
nombre_pdf = f'Inmaterial_{resourceid}'
gen_pdf_file = HTML(string=html_string, base_url=request.build_absolute_uri("/")).write_pdf()
merger = PdfWriter()
merger.append(PdfReader(io.BytesIO(gen_pdf_file)))
root_path = Path(__file__).resolve().parent.parent
for medio in reduce(getitem, ruta_medios[:-1], resource_data)[ruta_medios[-1]] :
if medio['formato'] == 'application/pdf' and bool(int(printpdfs)) :
merger.append(PdfReader(f'{root_path}/uploadedfiles/{medio["file"]}'))
output_buffer = io.BytesIO()
merger.write(output_buffer)
merger.close()
else:
output_buffer = io.BytesIO()
merger.write(output_buffer)
merger.close()
response = HttpResponse(output_buffer.getvalue(), content_type='application/pdf')
response['Content-Disposition'] = f'attachment; filename="{nombre_pdf}.pdf"'
return response