feat(infra): auto-commit con 88 cambios

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-11 00:16:46 +02:00
parent 6bc97df5c0
commit eb8dbf66a1
126 changed files with 10933 additions and 287 deletions
@@ -0,0 +1,94 @@
---
name: generate_initials_avatar
kind: function
lang: py
domain: infra
version: "1.0.0"
purity: impure
signature: "def generate_initials_avatar(text: str, out_path: str, bg_hex: str = \"\", size: int = 256, fg_hex: str = \"#FFFFFF\") -> str"
description: "Genera un avatar circular de iniciales (foto de perfil) como PNG: circulo de color con 1-2 iniciales blancas centradas. Color de fondo derivado de forma determinista del texto si no se especifica."
tags: [avatar, icon, rofi, pillow, profile, initials]
params:
- name: text
desc: "Nombre del que derivar las iniciales (ej. 'John Doe', 'osint_01'). Se trocea por espacios, guiones y guiones bajos."
- name: out_path
desc: "Ruta de salida del PNG. Se crea el directorio padre si no existe. Rutas relativas se resuelven contra el cwd."
- name: bg_hex
desc: "Color de fondo del circulo en formato '#RRGGBB'. Si va vacio ('') se deriva de forma determinista de text via md5 sobre una paleta de 12 colores."
- name: size
desc: "Lado del PNG cuadrado en pixels. Default 256. El circulo deja ~4% de margen; fuera queda transparente."
- name: fg_hex
desc: "Color del texto de las iniciales en '#RRGGBB'. Default blanco '#FFFFFF'."
output: "La misma out_path recibida. Efecto: escribe un PNG RGBA cuadrado con el avatar circular en disco."
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [hashlib, os, pathlib, PIL]
tested: false
tests: []
test_file_path: ""
file_path: "python/functions/infra/generate_initials_avatar.py"
---
## Ejemplo
```python
import sys, os
sys.path.insert(0, os.path.join("python", "functions"))
from infra.generate_initials_avatar import generate_initials_avatar
# Color de fondo determinista derivado del nombre.
generate_initials_avatar("Aurgi", "/tmp/aurgi.png") # -> circulo con "A"
generate_initials_avatar("John Doe", "/tmp/john.png") # -> circulo con "JD"
# Color de fondo explicito + tamano custom.
generate_initials_avatar("Personal", "/tmp/personal.png", bg_hex="#7c3aed", size=128)
```
Desde el dispatcher (genera con defaults, fondo derivado del texto):
```bash
./fn run generate_initials_avatar_py_infra "Aurgi" /tmp/aurgi.png
```
## Cuando usarla
Cuando necesites un icono reconocible de un perfil (navegador, usuario, cuenta)
y no tengas una foto real: genera un avatar de iniciales determinista por nombre.
Util para entradas de rofi, launchers, listas de perfiles o cualquier UI que
muestre un identificador visual estable. Mismo `text` -> mismo color siempre.
## Gotchas
- **Impura**: escribe un PNG a disco. Crea el directorio padre si falta y lanza
`OSError` con mensaje claro si la escritura falla.
- **Fondo transparente**: solo el circulo (con ~4% de margen) lleva color; las
esquinas del PNG quedan con alpha 0. Si lo pegas sobre un fondo claro, el
circulo se ve recortado correctamente, pero un visor que ignore el alpha
mostrara las esquinas negras.
- **Dependencia Pillow**: requiere `PIL` (Pillow) instalado en el venv del
registry (`python/.venv`). No usa cairosvg.
- **Fuente DejaVu hardcodeada**: usa `/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf`.
Si no existe (otro SO/distro), cae a `ImageFont.load_default()`, que es mas
pequena y pixelada — las iniciales se veran peor pero no falla.
- **Antialiasing 4x**: renderiza a `size*4` y reduce con LANCZOS. Para `size`
muy grande (>1024) el coste de memoria/tiempo crece cuadraticamente.
## Notas
Reglas de iniciales: trocea por espacios, `-` y `_`; toma la primera letra
alfabetica de los dos primeros tokens que empiecen por letra (max 2, en
mayusculas). Si solo un token tiene letra inicial -> 1 inicial. Si ninguno
empieza por letra -> primer caracter alfanumerico del texto. Ejemplos:
"Aurgi" -> "A", "Work" -> "W", "osint_01" -> "O", "John Doe" -> "JD",
"Personal" -> "P".
Paleta determinista (12 colores tipo Tailwind 500): sky, emerald, violet,
amber, rose, indigo, teal, orange, fuchsia, lime, cyan, red. El indice se
elige con `int(md5(text), 16) % 12`, estable entre procesos.
Las funciones auxiliares `derive_initials(text)` y `derive_bg_color(text)` son
publicas y reutilizables por separado si solo necesitas la logica de iniciales
o de color sin generar el PNG.