from PIL import Image, ImageEnhance, ImageFilter, ImageOps, ImageDraw from pathlib import Path import base64, json, uuid, re, html # --- 1) Create clean regenerated logo from the newest generated image --- src = Path("/mnt/data/a_digital_vector_vector_illustration_features_a_go.png") img = Image.open(src).convert("RGBA") # Crop the central rounded gold tile only (no text, no poster UI). # Coordinates tuned to the generated 1024x1536 image. crop = img.crop((166, 365, 858, 1057)) # 692x692 # Slightly enhance sharpness/contrast and resize to master 1024. logo = crop.resize((1024, 1024), Image.Resampling.LANCZOS) logo = ImageEnhance.Contrast(logo).enhance(1.06) logo = ImageEnhance.Sharpness(logo).enhance(1.12) # Apply rounded alpha mask so black corners outside the app tile are clean/transparent. mask = Image.new("L", (1024, 1024), 0) draw = ImageDraw.Draw(mask) draw.rounded_rectangle((0, 0, 1023, 1023), radius=210, fill=255) logo.putalpha(mask) out_logo = Path("/mnt/data/logo-informe-predicacion-final.png") logo.save(out_logo) # Also create standard sizes icons_dir = Path("/mnt/data/iconos_informe_predicacion_final") icons_dir.mkdir(exist_ok=True) for size in [16, 32, 48, 64, 128, 180, 192, 256, 512, 1024]: logo.resize((size, size), Image.Resampling.LANCZOS).save(icons_dir / f"icon-{size}.png") # --- 2) Data --- CONG_ID = "11111111-1111-4111-8111-111111111111" raw_groups = [ ("Grupo 1", [ "DAQUA DOMINGO","TORRES MATIAS","DAQUA CLAUDIA","DAQUA GIULIANA","CORDOBA CARLOTA", "TORRES ESTELA","TORRES MAXIMO","TORRES LUANA","TORRES ROLANDO","TORRES ANTONIA", "MARTINEZ ELSA","RODRIGUEZ SAMUEL","QUISPE JUAN","QUISPE ADRIANA","SPOSETTI JEREMIAS", "SPOSETTI SHEILA","SPOSETTI LUANA","FERREIRA DANIELA","RIVERO FERNANDO","RIVERO LORENA", "HIDALGO GLADYS","RAMIREZ FERNANDO","RAMIREZ SILVIA","MARY DIAZ","ANDREA SERRANO","YEDRO SUSANA" ], "DAQUA DOMINGO", "TORRES MATIAS"), ("Grupo 2", [ "ELIAS CARABALLO","SOLIS HUGO","MELISA CARABALLO","MARIO MORENO","MORENO PAULA", "SOLIS MARIA","LIENDO EDITH","GONZALEZ OLGA","CASTRO RODOLFO","MENESES YONATHAN", "MENESES MARINA","BUENO JOSE","BUENO MERCEDES","MARTINEZ ANDREA","GOMEZ DANIEL", "GOMEZ SUSANA","PILAR TORRES","LEVINSON JOSUE","LEVINSON MAGALI","HIDALGO ADAN", "HIDALGO ROSA","OVIEDO VANESA","HERRERA YANINA","HERRERA FLORENCIA","BULLON LAURA","MARINA TORRES" ], "ELIAS CARABALLO", "SOLIS HUGO"), ("Grupo 3", [ "DIEGO SOLIS","CUTA JUAN","SOLIS LIANA","SOLIS BLANCA","SOLIS VALENTINO", "LUJAN RAFAEL","LUJAN VANINA","LUJAN SILVESTRE","LUJAN INDIA","LUJAN ASAI", "CUTA TERESA","SANCHEZ MALVINA","MOYANO YAMILA","MOYANO SOFIA","MOYANO ESTEFAN", "TEODORO CAÑETE","VELEZ ALEJANDRA","HEREDIA BEATRIZ","HEREDIA GABRIEL","AMAYA AIDA", "SOLORZANO LUCIANA","SOLORZANO MICHELLE","LANATI LORENA" ], "DIEGO SOLIS", "CUTA JUAN"), ("Grupo 4", [ "MARIO TRIFILETTI","DAQUA FEDERICO","DAQUA SOFIA","MARIA MAROLLA","MAIQUES MIRIAM", "CASCO MARTHA","BOCCARDO MARTA","CANDEBAT JULIO","DE CARA NOE","MIRO MARIO", "MIRO MARIA ESTER","MIRO CECILIA","PENALVER RUBEN","PENALVER SONIA","GUERRERO NORA", "TOLOSA MARTIN","TOLOSA ALEJANDRA","KEVIN ALVAREZ" ], "MARIO TRIFILETTI", "DAQUA FEDERICO"), ("Grupo 5", [ "QUARANTA LEONARDO","GABUTO DARIO","GABUTO MARILINA","YEDRO JUDITH","YEDRO FACUNDO", "QUARANTA MAILEN","QUARANTA GIOVANI","CABRERA ANDRES","LAIME JACINTA","LAIME ANAHI", "JUAN CARLOS REINOSO","GALAN SOLEDAD","GALAN PERPETUA","MAX KAREN","CABRERA DALMIRO", "CABRERA MABEL","CABRERA BELEN","LAIME LUIS","LAIME JEAN CARLOS","LAIME SARA", "LAIME WILBER","LAIME BEATRIZ" ], "QUARANTA LEONARDO", "GABUTO DARIO"), ("Grupo 6", [ "FABIANI GASTON","LUIS HANZIAK","FABIANI SILVANA","FABIANI GIULIANO","DELFINA HANZIAK", "RENDE MARTA","RAZETTO ROMAN","RAZETTO GIMENA","ROITH LUZ","RADOSAVAC CRISTIAN", "CABEZAS GABRIEL","CABEZAS VERONICA","CABEZAS MAXIMILIANO","CABEZAS LUCIANO", "DI ROCCO ANDRES","DI ROCCO BEATRIZ","MONICA TARABINI" ], "FABIANI GASTON", "LUIS HANZIAK"), ("Grupo Quechua", [ "QUISPE JUAN","QUISPE ADRIANA","LAIME WILBER","LAIME JACINTA","LAIME SARA", "LAIME ANAHI","LAIME BEATRIZ","LAIME LUIS MIGUEL","LAIME JEAN CARLO" ], None, "QUISPE JUAN"), ("Grupo 7", [ "NATALI RICARDO","LUCAS FARIAS","NATALI MIRIAM","FARIAS XOANA","MARTINEZ NAZARENO", "ALTAMIRANO EMILIA","AMAYA ESTELA","PESTRINI SALOME","TORRES VICTOR","TORRES LILIANA", "SOLIAN LIDIA","MIRANDA YULIANA","NODAR MARTA","FARIAS RAUL","FARIAS MIRTA" ], "NATALI RICARDO", "LUCAS FARIAS") ] def title_person(s): # Preserve accents if present; title is okay for display. return " ".join(w.capitalize() for w in s.split()) def split_person(full): parts = full.strip().split() # Sense/common cases from the list where the first words are given names rather than surname if full == "JUAN CARLOS REINOSO": return "Juan Carlos", "Reinoso" if full == "MARY DIAZ": return "Mary", "Diaz" if full == "ANDREA SERRANO": return "Andrea", "Serrano" if full == "MARIO MORENO": return "Mario", "Moreno" if full == "MELISA CARABALLO": return "Melisa", "Caraballo" if full == "PILAR TORRES": return "Pilar", "Torres" if full == "MARINA TORRES": return "Marina", "Torres" if full == "MARIA MAROLLA": return "Maria", "Marolla" if full == "KEVIN ALVAREZ": return "Kevin", "Alvarez" if full == "LUIS HANZIAK": return "Luis", "Hanziak" if full == "DELFINA HANZIAK": return "Delfina", "Hanziak" if full == "MONICA TARABINI": return "Monica", "Tarabini" if full == "MAX KAREN": # Image appears "MAX KAREN"; keep common spreadsheet order: apellido Max, nombre Karen return "Karen", "Max" # Default in the provided sheet: SURNAME NAME(S) apellido = parts[0].capitalize() nombre = " ".join(p.capitalize() for p in parts[1:]) if len(parts) > 1 else parts[0].capitalize() return nombre, apellido grupos = [] hermanos = [] for orden, (grupo_nombre, miembros, sup, aux) in enumerate(raw_groups, 1): gid = str(uuid.uuid5(uuid.NAMESPACE_DNS, "informe-predicacion-" + grupo_nombre)) grupos.append({ "id": gid, "congregacion_id": CONG_ID, "nombre": grupo_nombre, "orden": orden, "superintendente_nombre_original": sup, "auxiliar_nombre_original": aux, "superintendente_id": None, "auxiliar_id": None }) for original in miembros: nombre, apellido = split_person(original) hid = str(uuid.uuid5(uuid.NAMESPACE_DNS, "informe-predicacion-" + grupo_nombre + "-" + original)) hermanos.append({ "id": hid, "congregacion_id": CONG_ID, "grupo_id": gid, "nombre": nombre, "apellido": apellido, "rol": "publicador", "activo": True, "_original": original }) for g in grupos: for h in hermanos: if h["grupo_id"] == g["id"]: if g["superintendente_nombre_original"] and h["_original"] == g["superintendente_nombre_original"]: g["superintendente_id"] = h["id"] if g["auxiliar_nombre_original"] and h["_original"] == g["auxiliar_nombre_original"]: g["auxiliar_id"] = h["id"] data_initial = { "congregacion": {"id": CONG_ID, "nombre": "Congregación"}, "grupos": grupos, "hermanos": [{k:v for k,v in h.items() if not k.startswith("_")} for h in hermanos] } data_json = json.dumps(data_initial, ensure_ascii=False, indent=2) logo_b64 = base64.b64encode(out_logo.read_bytes()).decode() # Use existing constants from uploaded index supabase_url = "https://cxogburxgfivdkjdsaod.supabase.co" supabase_anon_key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImN4b2didXJ4Z2ZpdmRramRzYW9kIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzcyMTQzMDIsImV4cCI6MjA5Mjc5MDMwMn0.s59E9w7ty1kczzyHTsTgUzvrFB9gaaQMcBD9R5Inzc8" final_html = f""" Informe de Predicación

Informe de Predicación

Carga mensual simple y organizada