Inicio Apuntes FPApuntes DAMAcceso a DatosGifteando: un buscador de GIFs de escritorio creado Python y Flet

Gifteando: un buscador de GIFs de escritorio creado Python y Flet

Publicado por
about gifteando

Una vez más aquí. Hoy vengo a dejar un pequeño programa sobre el que mi madre me dio la idea. Ella siempre se está enviando memes y gifs animados por whatsapp, y siempre me está preguntado dónde puede conseguir más gifs para enviarlos a sus amigas. El caso es que pensándolo un poco, me dije, y por qué no crear un pequeño buscador sencillo para que pueda buscar y descargar este tipo de imágenes (y así deje de darme la lata cada pocos días). Pues así es cómo nació Gifteando.

Esta es una aplicación de escritorio open source para buscar GIFs animados gratuitos, previsualizarlos y usarlos al momento en chats, documentos o foros. La aplicación está escrita en Python con Flet. La aplicación combina portales sin clave API (Openverse, GifCities, Wikimedia Commons) y catálogos populares con clave gratuita (Giphy y KLIPY). Poniendo el foco en la licencia, la atribución y un flujo rápido para copiar y pegar.

Si buscas un buscador de GIFs para Linux/Windows/macOS que no dependa solo de la web del navegador, que respete el contenido libre y que puedas auditar o extender, este artículo explica qué es Gifteando, para quién sirve y qué partes del código son las más importantes.

¿Qué problema resuelve un buscador de GIFs de escritorio?

Como decía líneas más arriba, este programa viene a buscar resolver un pequeño problema. En el día a día, un GIF sirve como reacción rápida: “gracias”, “ok”, “cara palmada”, un saludo. El problema clásico de las herramientas online es la fricción:

  • Abrir el navegador, buscar, descargar y luego arrastrar el archivo.
  • Depender de un único portal comercial.
  • No saber si ese GIF se puede reutilizar en un documento o en un foro (descargar gratis ≠ licencia libre).
  • Tener que crear cuenta y pegar una API key solo para probar la app.

Gifteando ataca eso con un enfoque práctico: ventana de escritorio, búsqueda al escribir, cuadrícula animada, detalle con copiar enlace, copiar GIF al portapapeles, copiar atribución, favoritos, recientes y filtro solo licencia libre.

Funciones que importan al usuario

gifteando funcionando

Búsqueda y portales

Al abrir la app, el portal por defecto es Sin clave: consulta Openverse, GifCities y Wikimedia Commons. Openverse prioriza resultados con información de licencia y atribución; GifCities aporta animaciones retro del archivo GeoCities (Internet Archive); Wikimedia Commons añade contenido libre vía API pública.

Si configuras las claves gratuitas, también puedes usar Giphy y KLIPY (memes y reacciones populares). El modo Todos mezcla fuentes abiertas y comerciales cuando hay clave.

Copiar, favoritos y licencia libre

Al abrir un GIF puedes:

  • Copiar enlace para pegarlo en un chat.
  • Copiar GIF como archivo en el portapapeles del escritorio.
  • Copiar atribución (título, autor, licencia y URL).
  • Marcarlo como favorito (estrella).
  • Guardarlo con el diálogo del sistema.

El interruptor Solo licencia libre deja visibles, de forma general, licencias tipo CC0, dominio público, CC BY y CC BY-SA, y oculta restricciones NC/ND o resultados sin datos de licencia. Encaja especialmente con Openverse y Wikimedia cuando el objetivo es contenido reutilizable.

Arquitectura de Gifteando: por qué el código está modular

La estructura del repositorio es deliberadamente simple:

ArchivoRol
main.pyArranque (`ft.run`)
gifteando/app.pyInterfaz Flet y orquestación
gifteando/providers.pyClientes HTTP de cada portal
gifteando/models.pyModelo común de GIF
gifteando/thumbs.pyMiniaturas y caché en disco
gifteando/library.pyFavoritos, recientes y filtro libre
gifteando/config.pyClaves API locales
gifteando/tray.pyIcono de bandeja con pystray

La idea clave de diseño: todos los portales se normalizan al mismo modelo. La UI no conoce JSON de Giphy ni de Wikimedia; solo trabaja con `GifItem`. Añadir un portal nuevo implica extender `providers.py`, no reescribir la ventana.

Las partes más importantes del código de Gifteando

1. El modelo común: `GifItem` en `models.py`

Este es el corazón de la extensibilidad. Un resultado no es “un dict de la API X”, sino un objeto congelado con lo necesario para mostrar, descargar y acreditar:

@dataclass(frozen=True)

class GifItem:

id: str

title: str

preview_url: str

download_url: str

source: str

attribution: str = ""

original_url: str = ""

page_url: str = ""

author: str = ""

license_name: str = ""

license_url: str = ""

Campos como `page_url`, `author` y `license_*` permiten algo que muchos buscadores de GIFs omiten: decir de dónde viene el archivo y bajo qué condiciones. Eso es crítico si usas Gifteando para material reutilizable, no solo para memes.

`SearchPage` agrupa la lista de ítems, el mapa de cursores de paginación por portal (`more`) y un `notice` para avisos parciales (por ejemplo, un portal caído mientras otros sí respondieron).

2. Proveedores e independencia ante fallos: `providers.py`

`providers.py` es el módulo más denso y el más estratégico. Aquí viven las URLs de Giphy, KLIPY, GifCities, Openverse y Wikimedia, el parseo de cada respuesta y la función `search()` que:

1. Filtra portales conocidos.

2. Omite Giphy/KLIPY si falta la clave (sin llamar a la red en vano).

3. Lanza una corrutina por portal con `asyncio.gather`.

4. Si un portal falla (red, 429, JSON raro), no tumba toda la búsqueda: el error se convierte en aviso y el resto de resultados se muestra.

5. Entrelaza resultados (`_interleave`) para que la cuadrícula no salga “todo Openverse y luego todo GifCities”.

Detalles técnicos relevantes:

  • GifCities / Wayback: la URL se construye con el sufijo `id_` para pedir el GIF original y no el HTML del visor de Archive.org.
  • Wikimedia: se pide `iiurlwidth` para usar `thumburl` en la preview y reducir peso y rate limits.
  • Giphy: la preview prioriza formatos pequeños (`fixed_height_small`, etc.).
  • `fetch_bytes`: valida cabecera `GIF87a`/`GIF89a`, reintenta ante 429/503 (con más paciencia en dominios `wikimedia.org`) y respeta `Retry-After` cuando existe.

3. Miniaturas que no congelan la UI de Gifteando: `thumbs.py`

Mostrar GIFs grandes animados en una cuadrícula Flet/Flutter es un clásico cuello de botella: RAM, CPU y errores de decodificación de fotogramas. Gifteando no mete el original crudo en cada tarjeta.

`shrink_gif()` reduce lado máximo y número de fotogramas, y re-codifica a un GIF compatible con el motor de Flutter (RGB opaco + paleta). Las miniaturas se guardan en `~/.cache/gifteando/` con clave hash versionada (`v2`), de modo que la segunda visita al mismo recurso no vuelve a descargar ni a procesar.

Eso explica por qué la app puede sentirse rápida y por qué el código de preview es tan importante como el de búsqueda: sin thumbs, no hay producto usable.

4. Claves fuera del repositorio: `config.py`

Las API keys de Giphy y KLIPY se leen y escriben en:

~/.config/gifteando/config.json

con permisos `0600`. También se guarda un `customer_id` estable para KLIPY. Este detalle es esencial en cualquier guía de “aplicación Python con APIs de terceros”.

5. Favoritos, recientes y filtro libre: `library.py`

La persistencia de biblioteca vive en `~/.config/gifteando/library.json`. Ahí están favoritos, recientes y la preferencia del filtro de licencia libre.

La función `is_freely_reusable()` aplica heurísticas sobre `license_name` y `license_url`: admite CC0 / dominio público / CC BY / CC BY-SA y rechaza señales NC/ND. No sustituye el criterio legal humano, pero da una primera línea de filtro muy útil en búsquedas de material reutilizable.

`attribution_text()` prepara un texto listo para pegar: título, autor, licencia y enlace. Eso conecta el modelo de datos con el uso real en documentos y foros.

6. Interfaz y orquestación de Gifteando: `app.py`

`app.py` es grande porque concentra la experiencia: menú, debounce de búsqueda, cuadrícula, diálogo de detalle, portapapeles Flet (`Clipboard.set` / `set_files`), interruptor de licencia libre, favoritos y la lógica de “cerrar ventana → ocultar en bandeja”.

Puntos de implementación que merecen atención:

  • Debounce al escribir (unos 450 ms) para no martillar las APIs.
  • Semáforo de descarga (una descarga a la vez) para mitigar rate limits de Wikimedia.
  • Generación de búsqueda: si el usuario lanza otra query mientras cargan previews, las actualizaciones viejas se descartan.
  • Avisos parciales cuando un portal falla pero hay resultados de otros.

La UI habla el lenguaje del usuario (español), con la excepción de cumplimiento de KLIPY: el placeholder debe ser “Search KLIPY” cuando ese es el único portal activo.

7. Bandeja del sistema: `tray.py`

Flet no incluye bandeja nativa. Gifteando usa pystray en un hilo daemon, con menú (mostrar, buscar, favoritos, recientes, claves, ocultar, salir) y callbacks que se reinyectan al event loop de la UI. El icono se genera a partir de `gifteando/img/logo.png`.

En Linux hace falta soporte AppIndicator (por ejemplo `gir1.2-ayatanaappindicator3-0.1` en Ubuntu/Debian) para que el menú de la bandeja sea usable.

Cómo instalar y usar Gifteando

gif abierto

Requisitos: Python 3.11+. En Linux, Zenity para el diálogo de guardar y AppIndicator para la bandeja.

git clone https://github.com/entreunosyceros/gifteando.git

cd gifteando

python3 -m venv .venv

source .venv/bin/activate

pip install -r requirements.txt

python3 main.py

Para realizar la búsqueda de un gif, es necesario escribir al menos dos letras: la búsqueda se lanza sola al dejar de teclear. También puedes usar el botón Buscar o Archivo → Buscar.

Para generar un ejecutable de escritorio con Flet Pack / PyInstaller, en la carpeta que incluya el código descargado, se encuentra un archivo .sh con el que crear el ejecutable. Basta con abrir una terminal (Ctrl+Alt+T) y ejecutarlo con el siguiente comando:

./empaquetar.sh

El script usa el `.venv` del proyecto e ignora un posible `flet` incorrecto en `~/.local/bin`. El binario queda en `dist/`. Por eso lo más lógico es primero crear el entorno virtual e instalar las dependencias.

¿Para qué me ha servido escribir este código?

Si te gusta desarrollar con Python, escribir el código de este programa, me ha servido para practicar con Python asíncrono, httpx, integración multi-API o UI de escritorio con Flet, Gifteando concentra patrones reales:

1. Contrato de dominio (`GifItem`) entre red y UI.

2. Resiliencia parcial con `asyncio.gather` y errores por fuente.

3. Caché y transformación de medios (Pillow) pensada para el runtime de Flutter.

4. Configuración XDG (`~/.config`, `~/.cache`) en apps de escritorio Linux.

5. Separación de secretos respecto al repositorio público.

6. Utilidad de bandeja con un puente hilo → asyncio.

En otras palabras: no es solo un “wrapper de Giphy”; es un buscador de GIFs multi-portal con criterios de licencia y UX de producto.

Conclusión sobre Gifteando

Gifteando es un buscador de GIFs animados de escritorio en Python y Flet, pensado para usar reacciones rápido y, cuando importa, respetar licencias abiertas y atribución. Su valor técnico está en el modelo común `GifItem`, en `providers.py` (búsqueda paralela y tolerante a fallos), en `thumbs.py` (previews sostenibles), en `config.py`/`library.py` (datos locales fuera de Git) y en la orquestación de `app.py`.

Si quieres probarlo, contribuir o empaquetarlo, el código está disponible en este repositorio de GitHub.

También te puede interesar ...

Deja un comentario

* Al utilizar este formulario, aceptas que este sitio web almacene y maneje tus datos.

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Adblock Detectado!!

Ayúdanos deshabilitando la extensión AdBlocker de tu navegador para visitar esta web.
Si no sabes hacerlo en Chrome, consulta el siguiente enlace. Si utilizas Firefox, puedes consultar este otro enlace.
Esto mejorará tu experiencia en este sitio web.