Initial clean commit
This commit is contained in:
commit
6784d81c2c
141 changed files with 25219 additions and 0 deletions
391
docs/FEED_DISCOVERY.md
Normal file
391
docs/FEED_DISCOVERY.md
Normal file
|
|
@ -0,0 +1,391 @@
|
|||
# Sistema de Descubrimiento y Gestión de Feeds RSS
|
||||
|
||||
Este documento describe el sistema mejorado de descubrimiento automático y gestión de feeds RSS implementado en RSS2.
|
||||
|
||||
## 📋 Visión General
|
||||
|
||||
El sistema ahora incluye dos mecanismos para gestionar feeds RSS:
|
||||
|
||||
1. **Gestión Manual Mejorada**: Interfaz web para descubrir y añadir feeds desde cualquier URL
|
||||
2. **Worker Automático**: Proceso en segundo plano que descubre feeds desde URLs almacenadas
|
||||
|
||||
## 🎯 Componentes del Sistema
|
||||
|
||||
### 1. Utilidad de Descubrimiento (`utils/feed_discovery.py`)
|
||||
|
||||
Módulo Python que proporciona funciones para:
|
||||
|
||||
- **`discover_feeds(url)`**: Descubre automáticamente todos los feeds RSS/Atom desde una URL
|
||||
- **`validate_feed(feed_url)`**: Valida un feed y extrae su información básica
|
||||
- **`get_feed_metadata(feed_url)`**: Obtiene metadatos detallados de un feed
|
||||
|
||||
```python
|
||||
from utils.feed_discovery import discover_feeds
|
||||
|
||||
# Descubrir feeds desde una URL
|
||||
feeds = discover_feeds('https://elpais.com')
|
||||
# Retorna: [{'url': '...', 'title': '...', 'valid': True, ...}, ...]
|
||||
```
|
||||
|
||||
### 2. Router de Feeds Mejorado (`routers/feeds.py`)
|
||||
|
||||
Nuevos endpoints añadidos:
|
||||
|
||||
#### Interfaz Web
|
||||
- **`GET/POST /feeds/discover`**: Interfaz para descubrir feeds desde una URL
|
||||
- Muestra todos los feeds encontrados
|
||||
- Permite seleccionar cuáles añadir
|
||||
- Aplica configuración global (categoría, país, idioma)
|
||||
|
||||
- **`POST /feeds/discover_and_add`**: Añade múltiples feeds seleccionados
|
||||
- Extrae automáticamente título y descripción
|
||||
- Evita duplicados
|
||||
- Muestra estadísticas de feeds añadidos
|
||||
|
||||
#### API JSON
|
||||
- **`POST /feeds/api/discover`**: API para descubrir feeds
|
||||
```json
|
||||
{
|
||||
"url": "https://example.com"
|
||||
}
|
||||
```
|
||||
Retorna:
|
||||
```json
|
||||
{
|
||||
"feeds": [...],
|
||||
"count": 5
|
||||
}
|
||||
```
|
||||
|
||||
- **`POST /feeds/api/validate`**: API para validar un feed específico
|
||||
```json
|
||||
{
|
||||
"url": "https://example.com/rss"
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Worker de Descubrimiento (`workers/url_discovery_worker.py`)
|
||||
|
||||
Worker automático que:
|
||||
|
||||
1. **Procesa URLs de la tabla `fuentes_url`**
|
||||
- Prioriza URLs nunca procesadas
|
||||
- Reintenta URLs con errores
|
||||
- Actualiza URLs antiguas
|
||||
|
||||
2. **Descubre y Crea Feeds Automáticamente**
|
||||
- Encuentra todos los feeds RSS en cada URL
|
||||
- Valida cada feed encontrado
|
||||
- Crea entradas en la tabla `feeds`
|
||||
- Evita duplicados
|
||||
|
||||
3. **Gestión de Estado**
|
||||
- Actualiza `last_check`, `last_status`, `status_message`
|
||||
- Maneja errores gracefully
|
||||
- Registra estadísticas detalladas
|
||||
|
||||
#### Configuración del Worker
|
||||
|
||||
Variables de entorno:
|
||||
|
||||
```bash
|
||||
# Intervalo de ejecución (minutos)
|
||||
URL_DISCOVERY_INTERVAL_MIN=15
|
||||
|
||||
# Número de URLs a procesar por ciclo
|
||||
URL_DISCOVERY_BATCH_SIZE=10
|
||||
|
||||
# Máximo de feeds a crear por URL
|
||||
MAX_FEEDS_PER_URL=5
|
||||
```
|
||||
|
||||
#### Estados de URLs en `fuentes_url`
|
||||
|
||||
| Estado | Descripción |
|
||||
|--------|-------------|
|
||||
| `success` | Feeds creados exitosamente |
|
||||
| `existing` | Feeds encontrados pero ya existían |
|
||||
| `no_feeds` | No se encontraron feeds RSS |
|
||||
| `no_valid_feeds` | Se encontraron feeds pero ninguno válido |
|
||||
| `error` | Error al procesar la URL |
|
||||
|
||||
## 🚀 Uso del Sistema
|
||||
|
||||
### Método 1: Interfaz Web Manual
|
||||
|
||||
1. **Navega a `/feeds/discover`**
|
||||
2. **Ingresa una URL** (ej: `https://elpais.com`)
|
||||
3. **Haz clic en "Buscar Feeds"**
|
||||
4. El sistema mostrará todos los feeds encontrados con:
|
||||
- Estado de validación
|
||||
- Título y descripción
|
||||
- Número de entradas
|
||||
- Tipo de feed (RSS/Atom)
|
||||
5. **Configura opciones globales**:
|
||||
- Categoría
|
||||
- País
|
||||
- Idioma
|
||||
6. **Selecciona los feeds deseados** y haz clic en "Añadir Feeds Seleccionados"
|
||||
|
||||
### Método 2: Worker Automático
|
||||
|
||||
1. **Añade URLs a la tabla `fuentes_url`**:
|
||||
```sql
|
||||
INSERT INTO fuentes_url (nombre, url, categoria_id, pais_id, idioma, active)
|
||||
VALUES ('El País', 'https://elpais.com', 1, 1, 'es', TRUE);
|
||||
```
|
||||
|
||||
2. **El worker procesará automáticamente**:
|
||||
- Cada 15 minutos (configurable)
|
||||
- Descubrirá todos los feeds
|
||||
- Creará entradas en `feeds`
|
||||
- Actualizará el estado
|
||||
|
||||
3. **Monitorea el progreso**:
|
||||
```sql
|
||||
SELECT nombre, url, last_check, last_status, status_message
|
||||
FROM fuentes_url
|
||||
ORDER BY last_check DESC;
|
||||
```
|
||||
|
||||
### Método 3: Interfaz de URLs (Existente)
|
||||
|
||||
Usa la interfaz web existente en `/urls/add_source` para añadir URLs que serán procesadas por el worker.
|
||||
|
||||
## 🔄 Flujo de Trabajo Completo
|
||||
|
||||
```
|
||||
┌─────────────────┐
|
||||
│ Usuario añade │
|
||||
│ URL del sitio │
|
||||
└────────┬────────┘
|
||||
│
|
||||
v
|
||||
┌─────────────────────────┐
|
||||
│ URL guardada en │
|
||||
│ tabla fuentes_url │
|
||||
└────────┬────────────────┘
|
||||
│
|
||||
v
|
||||
┌─────────────────────────┐
|
||||
│ Worker ejecuta cada │
|
||||
│ 15 minutos │
|
||||
└────────┬────────────────┘
|
||||
│
|
||||
v
|
||||
┌─────────────────────────┐
|
||||
│ Descubre feeds RSS │
|
||||
│ usando feedfinder2 │
|
||||
└────────┬────────────────┘
|
||||
│
|
||||
v
|
||||
┌─────────────────────────┐
|
||||
│ Valida cada feed │
|
||||
│ encontrado │
|
||||
└────────┬────────────────┘
|
||||
│
|
||||
v
|
||||
┌─────────────────────────┐
|
||||
│ Crea entradas en │
|
||||
│ tabla feeds │
|
||||
└────────┬────────────────┘
|
||||
│
|
||||
v
|
||||
┌─────────────────────────┐
|
||||
│ Ingestor Go procesa │
|
||||
│ feeds cada 15 minutos │
|
||||
└────────┬────────────────┘
|
||||
│
|
||||
v
|
||||
┌─────────────────────────┐
|
||||
│ Noticias descargadas │
|
||||
│ y procesadas │
|
||||
└─────────────────────────┘
|
||||
```
|
||||
|
||||
## 📊 Tablas de Base de Datos
|
||||
|
||||
### `fuentes_url`
|
||||
Almacena URLs de sitios web para descubrimiento automático:
|
||||
|
||||
```sql
|
||||
CREATE TABLE fuentes_url (
|
||||
id SERIAL PRIMARY KEY,
|
||||
nombre VARCHAR(255) NOT NULL,
|
||||
url TEXT NOT NULL UNIQUE,
|
||||
categoria_id INTEGER REFERENCES categorias(id),
|
||||
pais_id INTEGER REFERENCES paises(id),
|
||||
idioma CHAR(2) DEFAULT 'es',
|
||||
last_check TIMESTAMP,
|
||||
last_status VARCHAR(50),
|
||||
status_message TEXT,
|
||||
last_http_code INTEGER,
|
||||
active BOOLEAN DEFAULT TRUE
|
||||
);
|
||||
```
|
||||
|
||||
### `feeds`
|
||||
Almacena feeds RSS descubiertos y validados:
|
||||
|
||||
```sql
|
||||
CREATE TABLE feeds (
|
||||
id SERIAL PRIMARY KEY,
|
||||
nombre VARCHAR(255),
|
||||
descripcion TEXT,
|
||||
url TEXT NOT NULL UNIQUE,
|
||||
categoria_id INTEGER REFERENCES categorias(id),
|
||||
pais_id INTEGER REFERENCES paises(id),
|
||||
idioma CHAR(2),
|
||||
activo BOOLEAN DEFAULT TRUE,
|
||||
fallos INTEGER DEFAULT 0,
|
||||
last_etag TEXT,
|
||||
last_modified TEXT,
|
||||
last_error TEXT
|
||||
);
|
||||
```
|
||||
|
||||
## ⚙️ Configuración del Sistema
|
||||
|
||||
### Variables de Entorno
|
||||
|
||||
Añade al archivo `.env`:
|
||||
|
||||
```bash
|
||||
# RSS Ingestor
|
||||
RSS_POKE_INTERVAL_MIN=15 # Intervalo de ingesta (minutos)
|
||||
RSS_MAX_FAILURES=10 # Fallos máximos antes de desactivar feed
|
||||
RSS_FEED_TIMEOUT=60 # Timeout para descargar feeds (segundos)
|
||||
|
||||
# URL Discovery Worker
|
||||
URL_DISCOVERY_INTERVAL_MIN=15 # Intervalo de descubrimiento (minutos)
|
||||
URL_DISCOVERY_BATCH_SIZE=10 # URLs a procesar por ciclo
|
||||
MAX_FEEDS_PER_URL=5 # Máximo de feeds por URL
|
||||
```
|
||||
|
||||
### Docker Compose
|
||||
|
||||
El worker ya está configurado en `docker-compose.yml`:
|
||||
|
||||
```yaml
|
||||
url-discovery-worker:
|
||||
build: .
|
||||
container_name: rss2_url_discovery
|
||||
command: bash -lc "python -m workers.url_discovery_worker"
|
||||
environment:
|
||||
DB_HOST: db
|
||||
URL_DISCOVERY_INTERVAL_MIN: 15
|
||||
URL_DISCOVERY_BATCH_SIZE: 10
|
||||
MAX_FEEDS_PER_URL: 5
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
## 🔧 Comandos Útiles
|
||||
|
||||
### Ver logs del worker de descubrimiento
|
||||
```bash
|
||||
docker logs -f rss2_url_discovery
|
||||
```
|
||||
|
||||
### Reiniciar el worker
|
||||
```bash
|
||||
docker restart rss2_url_discovery
|
||||
```
|
||||
|
||||
### Ejecutar manualmente el worker (testing)
|
||||
```bash
|
||||
docker exec -it rss2_url_discovery python -m workers.url_discovery_worker
|
||||
```
|
||||
|
||||
### Ver estadísticas de descubrimiento
|
||||
```sql
|
||||
-- URLs procesadas recientemente
|
||||
SELECT nombre, url, last_check, last_status, status_message
|
||||
FROM fuentes_url
|
||||
WHERE last_check > NOW() - INTERVAL '1 day'
|
||||
ORDER BY last_check DESC;
|
||||
|
||||
-- Feeds creados recientemente
|
||||
SELECT nombre, url, fecha_creacion
|
||||
FROM feeds
|
||||
WHERE fecha_creacion > NOW() - INTERVAL '1 day'
|
||||
ORDER BY fecha_creacion DESC;
|
||||
```
|
||||
|
||||
## 🛠️ Troubleshooting
|
||||
|
||||
### El worker no encuentra feeds
|
||||
|
||||
1. Verifica que la URL sea accesible:
|
||||
```bash
|
||||
curl -I https://example.com
|
||||
```
|
||||
|
||||
2. Verifica los logs del worker:
|
||||
```bash
|
||||
docker logs rss2_url_discovery
|
||||
```
|
||||
|
||||
3. Prueba manualmente el descubrimiento:
|
||||
```python
|
||||
from utils.feed_discovery import discover_feeds
|
||||
feeds = discover_feeds('https://example.com')
|
||||
print(feeds)
|
||||
```
|
||||
|
||||
### Feeds duplicados
|
||||
|
||||
El sistema previene duplicados usando `ON CONFLICT (url) DO NOTHING`. Si un feed ya existe, simplemente se omite.
|
||||
|
||||
### Worker consume muchos recursos
|
||||
|
||||
Ajusta las configuraciones:
|
||||
|
||||
```bash
|
||||
# Reduce el batch size
|
||||
URL_DISCOVERY_BATCH_SIZE=5
|
||||
|
||||
# Aumenta el intervalo
|
||||
URL_DISCOVERY_INTERVAL_MIN=30
|
||||
|
||||
# Reduce feeds por URL
|
||||
MAX_FEEDS_PER_URL=3
|
||||
```
|
||||
|
||||
## 📝 Mejores Prácticas
|
||||
|
||||
1. **Añade URLs de sitios, no feeds directos**
|
||||
- ✅ `https://elpais.com`
|
||||
- ❌ `https://elpais.com/rss/feed.xml`
|
||||
|
||||
2. **Configura categoría y país correctamente**
|
||||
- Facilita la organización
|
||||
- Mejora la experiencia del usuario
|
||||
|
||||
3. **Monitorea el estado de las URLs**
|
||||
- Revisa periódicamente `fuentes_url`
|
||||
- Desactiva URLs que fallan consistentemente
|
||||
|
||||
4. **Limita el número de feeds por URL**
|
||||
- Evita sobrecarga de feeds similares
|
||||
- Mantén `MAX_FEEDS_PER_URL` entre 3-5
|
||||
|
||||
## 🎉 Ventajas del Sistema
|
||||
|
||||
✅ **Automatización completa**: Solo añade URLs, el sistema hace el resto
|
||||
✅ **Descubrimiento inteligente**: Encuentra todos los feeds disponibles
|
||||
✅ **Validación automática**: Solo crea feeds válidos y funcionales
|
||||
✅ **Sin duplicados**: Gestión inteligente de feeds existentes
|
||||
✅ **Escalable**: Procesa múltiples URLs en lotes
|
||||
✅ **Resiliente**: Manejo robusto de errores y reintentos
|
||||
✅ **Monitoreable**: Logs detallados y estados claros
|
||||
|
||||
## 📚 Referencias
|
||||
|
||||
- **feedfinder2**: https://github.com/dfm/feedfinder2
|
||||
- **feedparser**: https://feedparser.readthedocs.io/
|
||||
- **Tabla fuentes_url**: `/init-db/01.schema.sql`
|
||||
- **Worker**: `/workers/url_discovery_worker.py`
|
||||
- **Utilidades**: `/utils/feed_discovery.py`
|
||||
Loading…
Add table
Add a link
Reference in a new issue