← Volver a proyectos

vCard QR Generator

Una pequeña aplicación web autoalojada que convierte datos de contacto en códigos QR vCard para tarjetas de presentación, con un logo opcional en el centro. La construí para correr como un solo proceso local, y como el contacto vive dentro del propio QR, cualquier cámara de teléfono puede escanearlo y ofrecer guardar el contacto sin necesidad de internet.

Arquitectura

Panel webFastAPI + SQLiteArchivos QR (PNG, SVG)
La vCard va incrustada en el QR, así que escanear una tarjeta no requiere servidor ni internet.

Un solo proceso FastAPI sirve páginas Jinja2 renderizadas en el servidor: un panel, un formulario de empleado y una página de configuración. Los empleados son filas en SQLite mediante SQLAlchemy, y el texto de la vCard no se guarda, sino que se reconstruye a partir de la fila cada vez que un QR o una descarga .vcf lo necesita. En cada guardado, segno codifica ese texto en un PNG y un SVG con el nombre del slug del empleado, y Pillow pega el logo sobre el PNG. Subir un nuevo logo de la empresa regenera todos los QR que usan el predeterminado.

Decisiones clave

Un generador de vCard escrito a mano

La mayoría de las bibliotecas de vCard producen una salida que difiere un poco de lo que esperan Apple Contacts y Google Contacts, así que escribí a mano un generador pequeño. Emite vCard 3.0 con finales de línea CRLF y pone N antes de FN, porque iOS es exigente con el orden de los campos. Los nombres, el cargo y la empresa se escapan para barras invertidas, comas, puntos y comas y saltos de línea, empezando por las barras invertidas para no duplicar los escapes nuevos.

Corrección de errores nivel H para darle espacio al logo

El PNG lleva un logo cuadrado pegado en el centro, del 22 % del ancho de la imagen, que tapa parte del código. Genero cada código con el nivel H, la corrección de errores más alta, que puede recuperar cerca del 30 % de los datos, así que se sigue leyendo en teléfonos modernos. El SVG no lleva logo y queda como un vector limpio para imprimir, donde un diseñador puede colocar el logo a mano.

Un slug por persona nombra cada archivo

Cada empleado recibe un slug a partir de su nombre: se quitan los acentos, el texto pasa a minúsculas y los espacios se vuelven guiones. Si el slug ya existe, la aplicación agrega -2, -3, y así sucesivamente. El slug nombra el PNG, el SVG y el logo personalizado de esa persona, así que cuando un cambio de nombre lo modifica, la aplicación borra los archivos QR viejos, mueve el logo y escribe unos nuevos.

La parte difícil

La foto que los teléfonos no guardaban

Las primeras versiones ponían una foto en base64 dentro de la vCard, pero por lo general los teléfonos no la guardaban. Las apps de cámara de iOS y Android solo leen los campos comunes de un QR, mientras que el analizador completo de la app Contactos sí lee la foto cuando se abre un archivo .vcf. La única corrección confiable es un QR que apunte a un servidor, lo que exige un host público e internet al momento de escanear. Mantuve el QR estático y sin conexión, quité la foto y llevé la marca a un logo en el centro del código.

Seguridad y rendimiento

  • Los scripts de arranque hacen que la app escuche solo en 127.0.0.1 y no hay inicio de sesión, así que sigue siendo una herramienta local para un solo usuario. El README indica no exponerla públicamente sin agregar autenticación y HTTPS.
  • Un logo subido se rechaza si está vacío, si pesa más de 5 MB, si se declara como algo distinto de PNG o JPG, o si Pillow no puede decodificarlo. Luego la app guarda un PNG recodificado de 400 por 400 píxeles, nunca el archivo original.

Stack

PythonFastAPISQLitesegnoPillow

Enlaces