diff --git a/app.py b/app.py index 925e50f..4799a29 100644 --- a/app.py +++ b/app.py @@ -157,10 +157,17 @@ def _process_feed(feed_row): finally: socket.setdefaulttimeout(old_timeout) - if parsed.bozo and parsed.bozo_exception: - app.logger.warning(f"[ingesta] Feed {feed_id} bozo={parsed.bozo}: {parsed.bozo_exception}") - entries = parsed.entries or [] + status = getattr(parsed, "status", None) + + if parsed.bozo and getattr(parsed, "bozo_exception", None): + app.logger.warning(f"[ingesta] Feed {feed_id} bozo={parsed.bozo}: {parsed.bozo_exception}") + if (parsed.bozo and getattr(parsed, "bozo_exception", None)) or (status is not None and status >= 400): + if not entries: + raise RuntimeError( + f"Feed {feed_id} inválido o no es XML RSS/Atom (status={status}, bozo={parsed.bozo})" + ) + nuevos = 0 with get_conn() as conn: @@ -607,13 +614,42 @@ def manage_feeds(): per_page = 50 offset = (page - 1) * per_page + pais_id = request.args.get("pais_id") or None + categoria_id = request.args.get("categoria_id") or None + estado = request.args.get("estado") or "" + + where = [] + params: list[object] = [] + + if pais_id: + where.append("f.pais_id = %s") + params.append(int(pais_id)) + + if categoria_id: + where.append("f.categoria_id = %s") + params.append(int(categoria_id)) + + if estado == "activos": + where.append("f.activo = TRUE") + elif estado == "inactivos": + where.append("f.activo = FALSE") + elif estado == "errores": + where.append("COALESCE(f.fallos, 0) > 0") + + where_sql = "" + if where: + where_sql = "WHERE " + " AND ".join(where) + with get_conn() as conn, conn.cursor(cursor_factory=extras.DictCursor) as cur: - cur.execute("SELECT COUNT(*) FROM feeds;") + cur.execute( + f"SELECT COUNT(*) FROM feeds f {where_sql};", + params, + ) total_feeds = cur.fetchone()[0] if cur.rowcount else 0 total_pages = (total_feeds // per_page) + (1 if total_feeds % per_page else 0) cur.execute( - """ + f""" SELECT f.id, f.nombre, @@ -626,10 +662,11 @@ def manage_feeds(): FROM feeds f LEFT JOIN categorias c ON c.id = f.categoria_id LEFT JOIN paises p ON p.id = f.pais_id - ORDER BY f.nombre + {where_sql} + ORDER BY p.nombre NULLS LAST, c.nombre NULLS LAST, f.nombre LIMIT %s OFFSET %s; """, - (per_page, offset), + params + [per_page, offset], ) feeds = cur.fetchall() @@ -646,6 +683,9 @@ def manage_feeds(): page=page, categorias=categorias, paises=paises, + filtro_pais_id=pais_id, + filtro_categoria_id=categoria_id, + filtro_estado=estado, ) diff --git a/templates/dashboard.html b/templates/dashboard.html index 689463d..ce05af7 100644 --- a/templates/dashboard.html +++ b/templates/dashboard.html @@ -25,9 +25,38 @@
Exporta tu lista de feeds RSS o restaura/importa desde un archivo CSV.
- Exportar Feeds - Importar Feeds ++ Exporta tu lista de feeds RSS o restaura/importa desde un archivo CSV. + Además, puedes ir al organizador avanzado de feeds para filtrarlos + por país, categoría y estado (activos, caídos, con errores). +
+ + + + + +Exporta tu lista de fuentes URL o restaura/importa desde un archivo CSV.
- Exportar URLs - Importar Fuentes URL + + Exportar URLs + + + Importar Fuentes URL +| Categoría | País | Estado | +Fallos | Acciones | {% for feed in feeds %} -||||||
|---|---|---|---|---|---|---|---|---|---|---|
| {{ feed.nombre }} | -{{ feed.categoria or 'N/A' }} | -{{ feed.pais or 'Global' }} | ++ {{ feed.categoria or 'N/A' }} + | ++ {{ feed.pais or 'Global' }} + | {% if not feed.activo %} - KO + KO {% else %} OK {% endif %} | ++ {{ feed.fallos or 0 }} + | - - + + + + + + {% if not feed.activo %} - + + + {% endif %} | |||
| No hay feeds para mostrar. Añade el primero. | ++ No hay feeds para mostrar. + Añade el primero. + | |||||||||