--- 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.