From 866f5c432d92f19fc86f9c3e8c9b49c6ca493ca1 Mon Sep 17 00:00:00 2001 From: jlimolina Date: Tue, 13 Jan 2026 13:55:44 +0100 Subject: [PATCH] limpieza --- README.md | 194 ++++++++---------- rss-web-go/Dockerfile | 27 --- rss-web-go/go.mod | 9 - rss-web-go/main.go | 108 ---------- .../generar_videos_noticias.py | 0 start_docker.sh | 18 +- 6 files changed, 83 insertions(+), 273 deletions(-) delete mode 100644 rss-web-go/Dockerfile delete mode 100644 rss-web-go/go.mod delete mode 100644 rss-web-go/main.go rename generar_videos_noticias.py => scripts/generar_videos_noticias.py (100%) diff --git a/README.md b/README.md index 5df229a..14e2d8c 100644 --- a/README.md +++ b/README.md @@ -1,155 +1,125 @@ # RSS2 - Plataforma de Inteligencia de Noticias con IA -RSS2 es una plataforma avanzada de agregación, traducción y análisis de noticias diseñada para procesar grandes volúmenes de información en tiempo real. Utiliza una arquitectura de **microservicios híbrida (Go + Python/FastAPI)** y modelos de **Inteligencia Artificial** locales para transformar flujos RSS crudos en inteligencia accionable. +RSS2 es una plataforma avanzada de agregación, traducción, análisis y vectorización de noticias diseñada para procesar grandes volúmenes de información en tiempo real. Combina una arquitectura de **microservicios híbrida (Go + Python)** con modelos de **Inteligencia Artificial** locales para transformar flujos RSS crudos en inteligencia accionable, permitiendo búsqueda semántica y análisis de tendencias. --- -## 🏗️ Arquitectura y Servicios +## 🏗️ Arquitectura de Servicios (Docker) -El sistema se compone de múltiples contenedores Docker orquestados, divididos en 3 redes aisladas (`frontend`, `backend`, `monitoring`) para máxima seguridad. +El sistema está orquestado mediante Docker Compose y se divide en 3 redes aisladas (`frontend`, `backend`, `monitoring`) para garantizar la seguridad y el rendimiento. -### 🌐 Core & Frontend -| Servicio | Tecnología | Puerto | Descripción | -|----------|------------|--------|-------------| -| **`nginx`** | Nginx Alpine | **8001** | **Único punto de entrada público**. Reverse proxy, SSL, estáticos. | -| **`rss2_web`** | Python/FastAPI | - | Backend principal. API REST, Jinja2, lógica de negocio. | -| **`rss-web-go`** | Go/Gin | - | (Opcional) Microservicio web de alto rendimiento. | +### 🌐 Core & Acceso (Red Frontend) +| Servicio | Tecnología | Puerto Ext. | Descripción | +|----------|------------|-------------|-------------| +| **`nginx`** | Nginx Alpine | **8001** | **Gateway Público**. Proxy inverso que sirve la aplicación y archivos estáticos. | +| **`rss2_web`** | Python (Flask+Gunicorn) | - | Servidor de aplicación principal. Gestiona la API, interfaz web y lógica de negocio. | -### 🤖 Inteligencia Artificial & Workers -| Servicio | Descripción | Recursos | -|----------|-------------|----------| -| **`translator`** (x3) | Traducción Neural (NLLB-200) de cualquier idioma a Español. | GPU/CPU | -| **`embeddings`** | Generación de vectores semánticos para búsqueda inteligente. | GPU/CPU | -| **`ner`** | Reconocimiento de Entidades (Personas, Org, Lugares). | CPU | -| **`cluster`** | Agrupación de noticias por eventos similares. | CPU | -| **`topics`** | Clasificación temática de noticias. | CPU | -| **`qdrant-worker`** | Sincronización de vectores con Qdrant. | CPU | - -### 📥 Ingesta de Datos -| Servicio | Descripción | -|----------|-------------| -| **`rss-ingestor-go`** | Crawler de alto rendimiento en Go. Descarga cientos de RSS/min. | -| **`url-worker`** | Scraper que descarga y limpia el contenido completo (HTML) de las noticias. | -| **`url-discovery`** | Descubrimiento automático de nuevos feeds RSS. | - -### 💾 Almacenamiento de Datos +### 📥 Ingesta y Descubrimiento (Red Backend) | Servicio | Tecnología | Descripción | |----------|------------|-------------| -| **`db`** | PostgreSQL 18 | Base de datos principal (Escritura). Contraseñas fuertes. | -| **`db-replica`** | PostgreSQL 18 | Réplica de lectura (Actualmente en standby). | -| **`qdrant`** | Qdrant | **Base de datos vectorial**. Almacena embeddings para búsqueda semántica. | -| **`redis`** | Redis 7 | Broker de mensajes y caché. **Autenticado**. | +| **`rss-ingestor-go`** | **Go** | Crawler de ultra-alto rendimiento. Monitoriza y descarga cientos de feeds RSS por minuto. | +| **`url-worker`** | Python | Scraper profundo. Descarga el contenido completo (HTML limpio via `newspaper3k`) de cada noticia. | +| **`url-discovery-worker`**| Python | Agente autónomo que descubre y sugiere nuevos feeds RSS basándose en el tráfico actual. | -### 📊 Monitorización (Stack de Observabilidad) -| Servicio | Acceso | Descripción | -|----------|--------|-------------| -| **`grafana`** | `localhost:3001` | Dashboard visual de métricas del sistema y contenedores. | -| **`prometheus`** | *Interno* | Recolección de métricas de todos los servicios. | -| **`cadvisor`** | *Interno* | Métricas de uso de recursos de Docker (CPU, RAM). | +### � Procesamiento de IA (Red Backend) +Estos workers procesan asíncronamente la información utilizando modelos locales (GPU/CPU). + +| Servicio | Función | Modelo / Tecnología | +|----------|---------|---------------------| +| **`translator`** (x3) | **Traducción Neural** | `NLLB-200`. Traduce noticias de cualquier idioma al Español. Escalado horizontalmente (3 réplicas). | +| **`embeddings`** | **Vectorización** | `Sentence-Transformers`. Convierte texto en vectores matemáticos para búsqueda semántica. | +| **`ner`** | **Entidades** | Modelos SpaCy/Bert. Extrae Personas, Organizaciones y Lugares. | +| **`topics`** | **Clasificación** | Clasifica noticias en temas (Política, Economía, Tecnología, etc.). | +| **`cluster`** | **Agrupación** | Agrupa noticias sobre el mismo evento de diferentes fuentes. | +| **`related`** | **Relaciones** | Calcula y enlaza noticias relacionadas temporal y contextualmente. | + +### 💾 Almacenamiento y Búsqueda (Red Backend) +| Servicio | Rol | Descripción | +|----------|-----|-------------| +| **`db`** | Base de Datos Relacional | **PostgreSQL 18**. Almacenamiento principal de noticias, usuarios y configuración. | +| **`qdrant`** | Base de Datos Vectorial | **Qdrant**. Motor de búsqueda semántica de alta velocidad. | +| **`qdrant-worker`**| Sincronización | Worker dedicado a mantener sincronizados PostgreSQL y Qdrant. | +| **`redis`** | Caché y Colas | **Redis 7**. Gestiona las colas de tareas para los workers y caché de sesión. | + +### ⚙️ Orquestación y Mantenimiento +| Servicio | Descripción | +|----------|-------------| +| **`rss-tasks`** | Scheduler (Cron) que ejecuta tareas periódicas de limpieza, mantenimiento y optimización de índices. | + +### 📊 Observabilidad (Red Monitoring) +Acceso exclusivo vía localhost o túnel SSH. + +| Servicio | Puerto Local | Descripción | +|----------|--------------|-------------| +| **`grafana`** | **3001** | Dashboard visual para monitorizar CPU/RAM, colas de Redis y estado de ingesta. | +| **`prometheus`**| - | Recolección de métricas de todos los contenedores. | +| **`cadvisor`** | - | Monitor de recursos del kernel de Linux para Docker. | --- -## 🚀 Instalación y Despliegue +## 🚀 Guía de Inicio Rápido -### 1. Clonar y Configurar +### Requisitos Previos +* Docker y Docker Compose V2. +* Drivers de NVIDIA (Opcional, pero recomendado para inferencia rápida de IA). + +### 1. Instalación ```bash git clone cd rss2 ``` -### 2. Generación de Credenciales Seguras (IMPORTANTE) -El sistema incluye un script para generar contraseñas fuertes automáticamente: +### 2. Configuración de Seguridad +Genera contraseñas robustas automáticamente para todos los servicios: ```bash ./generate_secure_credentials.sh ``` -Esto creará un archivo `.env` con contraseñas aleatorias para DB, Redis y Grafana. +*Esto creará un archivo `.env` configurado y seguro.* -### 3. Iniciar Servicios -El despliegue se gestiona con el script maestro seguro: +### 3. Iniciar la Plataforma +Utiliza el script de arranque que verifica dependencias y levanta el stack: ```bash -./migrate_to_secure.sh -``` -O manualmente: -```bash -docker-compose up -d +./start_docker.sh ``` +*Alternativamente: `docker compose up -d`* -### 4. Acceso -* **Web Pública**: [http://localhost:8001](http://localhost:8001) -* **Grafana (Monitorización)**: [http://localhost:3001](http://localhost:3001) - * *Usuario*: `admin` - * *Password*: (Ver archivo `.env` variable `GRAFANA_PASSWORD` o el output del generador) +### 4. Acceder a la Aplicación +* **Web Principal**: [http://localhost:8001](http://localhost:8001) +* **Monitorización**: [http://localhost:3001](http://localhost:3001) (Usuario: `admin`, Password: ver archivo `.env`) --- -## 🔒 Seguridad +## �️ Operaciones Comunes -El sistema ha sido auditado y fortificado (Enero 2026): - -1. **Redes Segmentadas**: - * `rss2_frontend`: Solo Nginx y Web App. - * `rss2_backend`: Base de datos y Workers (sin acceso externo). - * `rss2_monitoring`: Stack de observabilidad. - -2. **Puertos Cerrados**: - * Qdrant (6333), Prometheus (9090), Redis (6379) NO están expuestos al host. - * Solo puerto **8001** (Web) y **3001** (Grafana/Local) están abiertos. - -3. **Autenticación**: - * Redis requiere contraseña (`requirepass`). - * PostgreSQL usa autenticación estricta. - -4. **Scripts de Seguridad**: - * `verify_security.sh`: Ejecuta un test completo de la configuración de seguridad. - * `SECURITY_GUIDE.md`: Guía detallada de administración segura. - ---- - -## 🛠️ Comandos de Mantenimiento - -### Verificar estado del sistema +### Ver logs en tiempo real ```bash -docker-compose ps +# Ver todo el sistema +docker compose logs -f + +# Ver un servicio específico (ej. traductor o web) +docker compose logs -f translator +docker compose logs -f rss2_web ``` -### Ver logs +### Generación de Videos (Nuevo) +El sistema incluye un script para convertir noticias en videos narrados automáticamente: ```bash -docker-compose logs -f rss2_web # Web App -docker-compose logs -f translator # Traductor +# Ejecutar generador manual +python3 scripts/generar_videos_noticias.py ``` -### Copia de Seguridad (Backup) +### Copias de Seguridad (Backup) ```bash -# Backup de Base de Datos -docker exec rss2_db pg_dump -U rss rss > backup_$(date +%Y%m%d).sql +# Backup de PostgreSQL +docker exec rss2_db pg_dump -U rss rss > backup_full_$(date +%Y%m%d).sql -# Backup de Vectores (Qdrant) -# (Detener servicio antes recomendado) -tar -czf qdrant_backup.tar.gz qdrant_storage/ +# Backup de Qdrant (Vectores) +tar -czf vector_backup.tar.gz qdrant_storage/ ``` -### Actualización +### Reinicio Completo (con reconstrucción) +Si modificas código o configuración: ```bash -git pull -docker-compose up -d --build +docker compose down +docker compose up -d --build ``` - ---- - -## 🧠 Características de IA - -* **Búsqueda Semántica**: Encuentra noticias por significado ("conflictos en oriente medio") incluso si no contienen las palabras exactas, gracias a los embeddings vectoriales en Qdrant. -* **Detección de Idioma**: Automática para dirigir al traductor correcto. -* **Entidades**: Explorador visual de *quién* y *dónde* en las noticias. - ---- - -## 📂 Estructura de Directorios - -* `/routers`: API Endpoints (Python). -* `/workers`: Lógica de fondo (Traducción, Ingesta, IA). -* `/rss-ingestor-go`: Código del crawler en Go. -* `/monitoring`: Configuración de Prometheus y Grafana. -* `/templates`: Vistas HTML (Jinja2). -* `/static`: Assets frontend. -* `docker-compose.yml`: Definición de infraestructura. diff --git a/rss-web-go/Dockerfile b/rss-web-go/Dockerfile deleted file mode 100644 index a38d563..0000000 --- a/rss-web-go/Dockerfile +++ /dev/null @@ -1,27 +0,0 @@ -FROM golang:1.21-alpine AS builder - -WORKDIR /app - -# Install git -RUN apk add --no-cache git - -# Copy files -COPY . . - -# Download dependencies -RUN go mod tidy && go mod download - -# Build -RUN CGO_ENABLED=0 GOOS=linux go build -o rss-web . - -# Final stage -FROM alpine:latest -WORKDIR /root/ -COPY --from=builder /app/rss-web . - -# Copy static assets and templates manually for now (assuming context is root) -# In docker-compose we will mount volumes or copy them -# COPY templates ./templates -# COPY static ./static - -CMD ["./rss-web"] diff --git a/rss-web-go/go.mod b/rss-web-go/go.mod deleted file mode 100644 index 89d6c16..0000000 --- a/rss-web-go/go.mod +++ /dev/null @@ -1,9 +0,0 @@ -module rss-web-go - -go 1.21 - -require ( - github.com/gin-gonic/gin v1.9.1 - github.com/lib/pq v1.10.9 - github.com/joho/godotenv v1.5.1 -) diff --git a/rss-web-go/main.go b/rss-web-go/main.go deleted file mode 100644 index a57dc1e..0000000 --- a/rss-web-go/main.go +++ /dev/null @@ -1,108 +0,0 @@ -package main - -import ( - "database/sql" - "fmt" - "log" - "os" - "html/template" - "time" - - "github.com/gin-gonic/gin" - _ "github.com/lib/pq" -) - -var db *sql.DB - -func initDB() { - connStr := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", - os.Getenv("DB_HOST"), os.Getenv("DB_PORT"), os.Getenv("DB_USER"), os.Getenv("DB_PASS"), os.Getenv("DB_NAME")) - - var err error - db, err = sql.Open("postgres", connStr) - if err != nil { - log.Fatal(err) - } - - db.SetMaxOpenConns(25) - db.SetMaxIdleConns(25) - db.SetConnMaxLifetime(5 * time.Minute) - - if err = db.Ping(); err != nil { - log.Fatalf("Cannot connect to DB: %v", err) - } - log.Println("Connected to Database") -} - -// Template Functions (to replace Jinja filters) -var funcMap = template.FuncMap{ - "safe_html": func(s string) template.HTML { - return template.HTML(s) - }, - "format_date": func(t time.Time) string { - return t.Format("02/01/2006") - }, - "country_flag": func(code string) string { - // Placeholder logic, real logic needs country mapping - return "🏳️" - }, -} - -func main() { - // Debug mode for now - gin.SetMode(gin.DebugMode) - - initDB() - - r := gin.Default() - - // Load Templates with FuncMap - // We need to support the template structure. - // For now, let's try to load them directly, but likely we need to adapt syntax. - // r.SetFuncMap(funcMap) - // r.LoadHTMLGlob("templates/*") - - // Static Files - r.Static("/static", "./static") - - // Routes - r.GET("/", homeHandler) - r.GET("/health", func(c *gin.Context) { - c.JSON(200, gin.H{"status": "ok", "engine": "golang"}) - }) - - port := os.Getenv("PORT") - if port == "" { - port = "8001" - } - - log.Printf("Starting Server on port %s", port) - if err := r.Run("0.0.0.0:" + port); err != nil { - log.Fatalf("Server failed to start: %v", err) - } -} - -func homeHandler(c *gin.Context) { - // Simple query for testing connectivity - rows, err := db.Query("SELECT titulo, url FROM noticias ORDER BY fecha DESC LIMIT 10") - if err != nil { - c.String(500, "DB Error: %v", err) - return - } - defer rows.Close() - - var news []map[string]string - for rows.Next() { - var titulo, url string - if err := rows.Scan(&titulo, &url); err != nil { - continue - } - news = append(news, map[string]string{"titulo": titulo, "url": url}) - } - - // For now, return JSON to prove it works before porting the complex HTML - c.JSON(200, gin.H{ - "message": "Welcome to RSS2 Go Web Server", - "news": news, - }) -} diff --git a/generar_videos_noticias.py b/scripts/generar_videos_noticias.py similarity index 100% rename from generar_videos_noticias.py rename to scripts/generar_videos_noticias.py diff --git a/start_docker.sh b/start_docker.sh index e459bd9..1aef36d 100755 --- a/start_docker.sh +++ b/start_docker.sh @@ -7,23 +7,7 @@ cd "$(dirname "$0")" echo "=== RSS2 Docker Services ===" -# Verificar si el modelo CTranslate2 existe -CT2_MODEL="./models/nllb-ct2" -if [ ! -d "$CT2_MODEL" ]; then - echo "" - echo "⚠️ Modelo CTranslate2 no encontrado en $CT2_MODEL" - echo " Convirtiendo modelo (esto puede tardar 5-10 minutos)..." - echo "" - - # Verificar si ctranslate2 está instalado - if ! python3 -c "import ctranslate2" 2>/dev/null; then - echo "Instalando ctranslate2..." - pip install ctranslate2 - fi - - # Convertir el modelo - ./convert_model.sh -fi +# Verificación de modelo eliminada (script de conversión no disponible) echo "" echo "Iniciando servicios Docker..."