Refactor: streamline core service and clean workspace

This commit is contained in:
renato97
2025-12-16 23:09:48 +00:00
parent 9fb01d5c22
commit b26248076b
18 changed files with 157 additions and 1649 deletions

5
.gitignore vendored
View File

@@ -20,10 +20,6 @@ resumenes_docx/**/*.md
resumenes/**/*.md resumenes/**/*.md
resumenes/**/*.docx resumenes/**/*.docx
# Ollama data
ollama_data/
ollama_data/models/blobs/
# Node.js # Node.js
.npm/ .npm/
@@ -51,7 +47,6 @@ cbc-main.pid
.gemini/ .gemini/
.ssh/ .ssh/
.sudo_as_admin_successful .sudo_as_admin_successful
resumenes/
# IDE and editor files # IDE and editor files
.vscode/ .vscode/

View File

@@ -1,240 +0,0 @@
# 🏗️ Arquitectura del Sistema Integrado
## 📊 Diagrama General
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ SISTEMA COMPLETO │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ SERVICIO │ │ DASHBOARD │ │
│ │ PRINCIPAL │◄────── Comparte ───────►│ WEB │ │
│ │ (main.py) │ contexto │ (dashboard) │ │
│ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │
│ │ Polling cada 5s │ API REST │
│ ▼ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ PROCESAMIENTO AUTOMÁTICO │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ AUDIO │ │ PDF │ │ TXT │ │ WEBDAV │ │ │
│ │ │Whisper+IA│ │ OCR+IA │ │ IA │ │ Sync │ │ │
│ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │
│ └──────┼─────────────┼─────────────┼────────────┼─────────┘ │
│ │ │ │ │ │
│ └─────────────┴─────────────┴────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────┐ │
│ │ NEXTCLOUD │ │
│ │ (WebDAV) │ │
│ └────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
## 🔄 Flujo de Datos
### 1. Servicio Principal (main.py)
```
Inicio → start_dashboard() → main() [Bucle infinito]
↓ ↓ ↓
Dashboard Hilo separado Polling 5s
Web (5000) (daemon) ↓
Check Archivos
Procesar
Subir a Nextcloud
```
### 2. Dashboard Web (dashboard.py)
```
HTTP Request → Flask App → API Endpoints
↓ ↓ ↓
localhost:5000 Routing file_manager
↓ ↓ ↓
Browser Python Code Operar archivos
```
## 📡 Comunicación entre Componentes
### Imports Compartidos
```python
# main.py importa del dashboard
import dashboard
dashboard.app.run() # En hilo separado
# dashboard.py importa de main
from main import (
AUDIO_EXTENSIONS,
LOCAL_DOWNLOADS_PATH,
load_processed_files,
process_audio_file
)
```
### Estado Compartido
- ✅ Variables de configuración
- ✅ Funciones de procesamiento
- ✅ Registro de archivos procesados
- ✅ Conexión WebDAV a Nextcloud
## 🎯 Modos de Ejecución
### Modo 1: Servicio Completo
```bash
python3 main.py
```
```
┌─────────────────────────────────────┐
│ THREAD PRINCIPAL │
│ ┌──────────────────────────────┐ │
│ │ main() - Bucle principal │ │
│ │ - Polling Nextcloud │ │
│ │ - Procesar archivos │ │
│ └──────────────────────────────┘ │
└─────────────────────────────────────┘
│ threading.Thread
┌─────────────────────────────────────┐
│ DASHBOARD THREAD (daemon) │
│ ┌──────────────────────────────┐ │
│ │ Flask Web Server │ │
│ │ - Puerto 5000 │ │
│ │ - API REST │ │
│ │ - Interfaz web │ │
│ └──────────────────────────────┘ │
└─────────────────────────────────────┘
```
### Modo 2: Solo Dashboard
```bash
python3 main.py dashboard-only
```
```
┌─────────────────────────────────────┐
│ MAIN THREAD │
│ ┌──────────────────────────────┐ │
│ │ Flask Web Server ONLY │ │
│ │ - Puerto 5000 │ │
│ │ - Sin bucle principal │ │
│ └──────────────────────────────┘ │
└─────────────────────────────────────┘
```
## 🗂️ Estructura de Archivos
```
/home/ren/cbc/
├── main.py # Servicio principal + integra dashboard
├── dashboard.py # Aplicación Flask independiente
├── test_dashboard.py # Script de pruebas
├── templates/
│ └── index.html # Interfaz web del dashboard
├── downloads/ # Archivos temporales locales
├── processed_files.txt # Registro de procesados
├── QUICKSTART.md # Guía de inicio rápido
├── DASHBOARD_INSTRUCTIONS.md # Manual detallado
└── ARQUITECTURA.md # Este archivo
```
## 🔌 API Endpoints del Dashboard
| Método | Endpoint | Función |
|--------|----------|---------|
| GET | `/` | Página principal |
| GET | `/api/files` | Obtener lista de archivos |
| POST | `/api/reprocess` | Reprocesar archivo |
| POST | `/api/mark-unprocessed` | Marcar como no procesado |
| GET | `/api/refresh` | Refrescar lista |
| GET | `/health` | Health check |
| GET | `/downloads/<archivo>` | Descargar archivo |
## 🚀 Proceso de Inicio
```
1. Usuario ejecuta: python3 main.py
├─► main.py inicia
│ │
│ ├─► acquire_lock() [Evitar múltiples instancias]
│ │
│ ├─► start_dashboard() [INICIA DASHBOARD]
│ │ │
│ │ ├─► import dashboard
│ │ │
│ │ ├─► threading.Thread(target=run_dashboard)
│ │ │
│ │ ├─► dashboard_thread.start()
│ │ │
│ │ └─► ✅ Dashboard en http://localhost:5000
│ │
│ ├─► time.sleep(2) [Pausa para dashboard]
│ │
│ └─► main() [INICIA BUCLE PRINCIPAL]
│ │
│ └─► while True:
│ │
│ ├─► Polling Nextcloud
│ ├─► Verificar archivos nuevos
│ ├─► Procesar automáticamente
│ └─► sleep(5) [esperar 5s]
└─► Servicio corriendo indefinidamente
├─► Dashboard accesible
└─► Procesamiento activo
```
## 🔐 Características de Seguridad
1. **Threading Daemon**
- Dashboard se cierra automáticamente con main.py
- No impide el cierre del programa
2. **Lock File**
- Evita múltiples instancias de main.py
- Protección automática via `fcntl`
3. **Error Handling**
- Dashboard puede fallar sin afectar main
- Logging detallado de errores
4. **CORS Enabled**
- Flask-CORS configurado
- Acceso desde cualquier origen
## 💡 Ventajas de la Integración
### ✅ Beneficios
- **Un solo comando** para todo
- **Contexto compartido** (config, funciones)
- **Cierre automático** (hilo daemon)
- **Logs unificados** (consola única)
- **Sin dependencias externas** (todo en main.py)
### ⚡ Rendimiento
- **Dashboard**: ~5-10MB RAM
- **Main**: Variable según procesamiento
- **Comunicación**: Directa (mismo proceso)
- **Latencia**: Mínima (sin red)
### 🛠️ Mantenimiento
- **Código unificado** en main.py
- **Menos archivos** de configuración
- **Debugging simplificado** (una sola consola)
- **Actualización fácil** (un solo archivo)
## 🎉 Resumen
El sistema está **completamente integrado**:
- ✅ Un solo comando: `python3 main.py`
- ✅ Dashboard automático en puerto 5000
- ✅ Servicio principal procesando 24/7
- ✅ Interfaz web moderna y responsive
- ✅ API REST completa
- ✅ Gestión de archivos en tiempo real
**¡Simplemente ejecuta `python3 main.py` y visita http://localhost:5000!** 🚀

View File

@@ -1,206 +0,0 @@
# 🎛️ Dashboard Integrado - Instrucciones de Uso
## 🚀 Inicio Rápido
### Ejecutar servicio completo con dashboard
```bash
python3 main.py
```
**¡Listo!** Tendrás:
- ✅ Servicio principal procesando archivos automáticamente
- ✅ Dashboard web accesible en **http://localhost:5000**
---
## 📊 ¿Qué es el Dashboard?
El dashboard es una **interfaz web moderna** que te permite:
### 🔍 Monitoreo
- Ver todos los archivos de audio en tiempo real
- Filtrar por origen (Local/WebDAV)
- Buscar archivos por nombre
- Ver estadísticas: total, procesados, pendientes
### ⚡ Control
- **Reprocesar archivos** con un solo click
- **Resetear archivos** para forzar reprocesamiento
- **Descargar resultados** en múltiples formatos
### 📁 Gestión de Archivos
Ver formatos disponibles para cada archivo:
- 📝 TXT (transcripción)
- 📋 MD (Markdown)
- 📄 DOCX (documento editable)
- 📑 PDF (documento PDF)
---
## 🌐 Uso del Dashboard
### 1. Acceder
Abre tu navegador en: **http://localhost:5000**
### 2. Ver Archivos
La página principal muestra:
- **Header**: Título del dashboard
- **Estadísticas**: Cards con total, procesados, pendientes
- **Controles**: Botones para refrescar y reprocesar
- **Lista**: Grid de archivos con información
### 3. Filtrar
Usa los filtros en la parte superior:
- ☑️ **Local**: Mostrar archivos de la carpeta downloads
- ☑️ **WebDAV**: Mostrar archivos de Nextcloud
- 🔍 **Búsqueda**: Escribir para filtrar por nombre
### 4. Acciones por Archivo
#### Para archivos **Pendientes**:
1. Click en botón **🚀 Procesar**
2. Confirmar si hay archivos existentes
3. El archivo se encola para procesamiento
4. El estado se actualiza automáticamente
#### Para archivos **Procesados**:
1. Click en botón **🔄 Resetear**
2. Confirmar la acción
3. El archivo se marca como no procesado
4. Podrás reprocesarlo cuando quieras
### 5. Descargar Resultados
Si un archivo tiene formatos disponibles, verás enlaces:
- 📝 TXT, 📋 MD, 📄 DOCX, 📑 PDF
- Click directo para descargar
---
## 🔧 Comandos Alternativos
### Solo Dashboard (sin servicio principal)
```bash
python3 main.py dashboard-only
```
### Otros comandos disponibles
```bash
# Servicio completo
python3 main.py
# Procesar audio individual
python3 main.py whisper audio.mp3 salida.txt
# Procesar PDF individual
python3 main.py pdf documento.pdf editable.docx
# Convertir texto a resumen
python3 main.py txt2docx texto.txt resumen.docx
# Generar quiz
python3 main.py quiz "texto del quiz" quiz.docx
```
---
## 📱 Interfaz Responsive
El dashboard funciona en:
- 💻 **Desktop**: Interfaz completa con todas las funciones
- 📱 **Móvil**: Adaptado para pantallas pequeñas
- 📲 **Tablet**: Experiencia optimizada para tablets
---
## 🎨 Características de la UI
- **Diseño moderno**: Gradientes y efectos glassmorphism
- **Animaciones suaves**: Transiciones y hover effects
- **Feedback visual**: Estados de carga y confirmación
- **Tema oscuro**: Colores elegantes y profesionales
- **Iconos**: Emojis para mejor identificación visual
---
## ⚙️ API Endpoints
El dashboard expone una API REST:
- `GET /api/files` - Obtener lista de archivos
- `POST /api/reprocess` - Reprocesar archivo
- `POST /api/mark-unprocessed` - Marcar como no procesado
- `GET /api/refresh` - Refrescar lista
- `GET /health` - Health check
- `GET /downloads/<archivo>` - Descargar archivo
---
## 🚨 Notas Importantes
### Logs
Los logs del dashboard aparecen en la consola donde ejecutaste `main.py`
### Errores Comunes
1. **Puerto 5000 en uso**
- Solución: Cambiar puerto en `dashboard.py` o terminar proceso anterior
2. **No aparecen archivos**
- Verificar conexión a Nextcloud
- Revisar variables de entorno NEXTCLOUD_*
- Comprobar que hay archivos en la carpeta Audios
3. **Error al procesar**
- Revisar logs en la consola
- Verificar dependencias (Flask, etc.)
- Comprobar espacio en disco
### Rendimiento
- El dashboard se ejecuta en **hilo separado**
- **No bloquea** el procesamiento principal
- Se inicia **automáticamente** con main.py
- **Cierre seguro** al terminar main.py
---
## 🎯 Casos de Uso
### 📚 Estudio Personal
1. Sube audios de clases a Nextcloud
2. El sistema los procesa automáticamente
3. Usa el dashboard para descargar resúmenes
4. Estudia con los documentos DOCX generados
### 🏢 Oficina
1. Configura Nextcloud empresarial
2. Comparte carpeta Audios con el equipo
3. Todos pueden subir archivos para procesar
4. Gestiona todo desde el dashboard web
### 🔄 Reprocesamiento
1. Un archivo falló al procesarse
2. Usa el dashboard para resetearlo
3. Reprocesa con un click
4. Descarga el resultado actualizado
---
## 🎉 ¡Disfruta!
**Simplemente ejecuta:**
```bash
python3 main.py
```
**Y visita:** http://localhost:5000
---
### ¿Necesitas Ayuda?
1. Revisa los logs en la consola
2. Verifica que Flask esté instalado: `pip3 install flask flask-cors`
3. Comprueba que el puerto 5000 esté libre
4. Asegúrate de tener conexión a Internet para APIs de IA
**¡El dashboard está listo para usar!** 🚀

View File

@@ -4,8 +4,18 @@ FROM nvidia/cuda:12.1.1-runtime-ubuntu22.04
# Evitar que los cuadros de diálogo de apt se bloqueen # Evitar que los cuadros de diálogo de apt se bloqueen
ENV DEBIAN_FRONTEND=noninteractive ENV DEBIAN_FRONTEND=noninteractive
# Instalar Python, pip, ffmpeg, Node.js y otras dependencias del sistema # Instalar Python, pip y dependencias del sistema
RUN apt-get update && apt-get install -y python3.10 python3-pip ffmpeg poppler-utils tesseract-ocr tesseract-ocr-spa curl && rm -rf /var/lib/apt/lists/* RUN apt-get update && apt-get install -y \
python3.10 \
python3-pip \
ffmpeg \
poppler-utils \
tesseract-ocr \
tesseract-ocr-spa \
curl \
libgl1 \
libglib2.0-0 \
&& rm -rf /var/lib/apt/lists/*
# Instalar Node.js 20 usando NodeSource repository # Instalar Node.js 20 usando NodeSource repository
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \ RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
@@ -18,17 +28,12 @@ RUN ln -s /usr/bin/python3 /usr/bin/python
# Establecer el directorio de trabajo # Establecer el directorio de trabajo
WORKDIR /app WORKDIR /app
# Copiar el archivo de requerimientos e instalar PyTorch con soporte para CUDA # Copiar requerimientos e instalar dependencias de Python
COPY requirements.txt . COPY requirements.txt .
RUN python3 -m pip install --no-cache-dir --upgrade pip && \
# Instalar PyTorch y las dependencias de audio/visión compatibles con CUDA 12.1 python3 -m pip install --no-cache-dir \
RUN python3 -m pip install --no-cache-dir --upgrade pip torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121 && \
RUN python3 -m pip install --no-cache-dir torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121 python3 -m pip install --no-cache-dir -r requirements.txt
# Instalar el resto de las dependencias
RUN python3 -m pip install --no-cache-dir -r requirements.txt
RUN apt-get update && apt-get install -y tesseract-ocr tesseract-ocr-spa libgl1 libglib2.0-0
RUN python3 -m pip install --no-cache-dir easyocr pytesseract opencv-python-headless pdf2image transformers
# Instalar Claude CLI # Instalar Claude CLI
RUN npm install -g @anthropic-ai/claude-code RUN npm install -g @anthropic-ai/claude-code

View File

@@ -1,32 +0,0 @@
FROM python:3.11-slim
# Establecer directorio de trabajo
WORKDIR /app
# Instalar dependencias del sistema
RUN apt-get update && apt-get install -y \
gcc \
g++ \
&& rm -rf /var/lib/apt/lists/*
# Copiar requirements y dependencias de Python
COPY requirements.txt requirements-dashboard.txt ./
# Instalar dependencias de Python
RUN pip install --no-cache-dir -r requirements-dashboard.txt
# Copiar archivos de la aplicación
COPY main.py dashboard.py ./
COPY templates/ ./templates/
# Crear directorios necesarios
RUN mkdir -p downloads resumenes_docx
# Establecer permisos
RUN chmod +x dashboard.py
# Exponer puerto
EXPOSE 5000
# Comando para ejecutar el dashboard
CMD ["python", "dashboard.py"]

View File

@@ -1,88 +0,0 @@
# 🚀 Quick Start - Dashboard Integrado
## ✅ Estado Actual
- ✅ Flask instalado y configurado
- ✅ Dashboard funcionando correctamente
- ✅ 210 archivos procesados detectados
- ✅ Todas las pruebas pasaron
## 🎯 Uso Inmediato
### Opción 1: Servicio Completo (Recomendado)
```bash
python3 main.py
```
**Resultado:**
- ✅ Servicio principal procesando archivos automáticamente
- ✅ Dashboard web disponible en http://localhost:5000
### Opción 2: Solo Dashboard
```bash
python3 main.py dashboard-only
```
### Opción 3: Probar Dashboard
```bash
python3 test_dashboard.py
```
## 📊 Dashboard Web
**URL:** http://localhost:5000
**Funciones:**
- 🔍 Ver archivos de audio en tiempo real
- 🔎 Filtrar por origen (Local/WebDAV)
- 🚀 Reprocesar archivos con 1 click
- 🔄 Resetear archivos procesados
- 📥 Descargar resultados (TXT, MD, DOCX, PDF)
- 📱 Interfaz responsive (móvil/tablet/desktop)
## 📁 Ubicaciones Importantes
- **Servicio Principal:** `/home/ren/cbc/main.py`
- **Dashboard:** `/home/ren/cbc/dashboard.py`
- **Interfaz Web:** `/home/ren/cbc/templates/index.html`
- **Pruebas:** `/home/ren/cbc/test_dashboard.py`
- **Instrucciones:** `/home/ren/cbc/DASHBOARD_INSTRUCTIONS.md`
## 🔧 Comandos Disponibles
```bash
# Servicio completo (main + dashboard)
python3 main.py
# Solo dashboard
python3 main.py dashboard-only
# Transcribir audio
python3 main.py whisper audio.mp3 salida.txt
# Procesar PDF
python3 main.py pdf documento.pdf editable.docx
# Texto a resumen
python3 main.py txt2docx texto.txt resumen.docx
# Generar quiz
python3 main.py quiz "texto" quiz.docx
# Marcar archivos como procesados
python3 main.py seed-processed
```
## 📞 Soporte
Si algo no funciona:
1. Ejecutar: `python3 test_dashboard.py`
2. Verificar logs en consola
3. Revisar: `/home/ren/cbc/DASHBOARD_INSTRUCTIONS.md`
## 🎉 ¡Listo para Usar!
**Simplemente ejecuta:**
```bash
python3 main.py
```
**Y visita:** http://localhost:5000

275
README.md
View File

@@ -1,194 +1,129 @@
# Nextcloud AI Service v8 Final # Nextcloud AI Service v8
Sistema completo de procesamiento de audio, PDF y generación de resúmenes colaborativos mediante 3 modelos de IA. Servicio unificado que escucha automáticamente tu Nextcloud, descarga audios y PDFs, los procesa con Whisper + 3 modelos de IA y publica resúmenes enriquecidos junto con un dashboard en tiempo real.
## 🚀 Características Principales ```
┌─────────────┐ ┌─────────────┐ ┌──────────────┐ ┌──────────────┐
### 🤖 Sistema Unificado de 3 IAs │ Nextcloud │───▶│ Whisper │───▶│ Claude (Z.ai)│───▶│ Gemini (CLI │
- **GPT-OSS-120B**: Extracción de puntos clave mediante DeepInfra API │ Audios/PDFs │ │ Transcribe │ │ Bullet + │ │ + API) │
- **Claude CLI**: Desarrollo de resúmenes integrales mediante Z.ai API └─────────────┘ └─────────────┘ │ Resumenes │ │ Formato final │
- **Gemini CLI**: Formato y estilo final mediante CLI de Google └──────┬───────┘ └──────┬───────┘
│ │
### 📁 Procesamiento de Archivos ▼ ▼
- **Audio**: Transcripción con Whisper y generación de resúmenes Markdown / DOCX / PDF Dashboard
- **PDF**: OCR avanzado y conversión a documentos editables
- **Documentos**: Generación de resúmenes automáticos
- **Sincronización**: Integración completa con Nextcloud via WebDAV
### 🎯 Características Técnicas
- **Docker Multi-etapa**: Optimizado para producción
- **GPU CUDA 12.1**: Aceleración por hardware NVIDIA
- **CLI Tools**: Claude CLI y Gemini CLI para máxima compatibilidad
- **Unificación**: Sistema colaborativo que genera un único documento final
## 🛠️ Instalación
### Requisitos
- Docker y Docker Compose
- NVIDIA GPU con drivers CUDA 12.1+
- 16GB+ RAM recomendado
- 20GB+ espacio en disco
### Configuración
1. **Clonar el repositorio**
```bash
git clone https://gitea.cbcren.online/ren/nextcloud-ai-v8-final.git
cd nextcloud-ai-v8-final
``` ```
2. **Configurar variables de entorno** ## Principales capacidades
```bash - **Pipeline único**: descarga desde Nextcloud vía WebDAV, transcribe con Whisper, resume con Claude + Gemini y clasifica automáticamente.
cp .env.example .env - **Dashboard integrado**: panel Flask (http://localhost:5000) para ver archivos, reprocesar o limpiar estados con un click.
# Editar .env con tus credenciales - **Diseño GPU-first**: Docker + CUDA 12.1 con PyTorch optimizado; limpieza agresiva de VRAM cuando los modelos están ociosos.
- **Alertas opcionales**: soporte Telegram y WebDAV retries para operaciones largas.
- **Código limpio**: sin Ollama ni servicios secundarios; sólo lo esencial para escalar y mantener.
## Estructura mínima
```
cbc/
├─ Dockerfile
├─ docker-compose.yml
├─ main.py # Servicio principal + loop de monitoreo
├─ dashboard.py # Flask dashboard reutilizando la lógica de main.py
├─ templates/index.html # UI del dashboard
├─ requirements.txt
└─ README.md
``` ```
3. **Iniciar servicios** ## Requisitos
- NVIDIA GPU con drivers CUDA 12.1+ y `nvidia-container-toolkit` si usas Docker.
- Python 3.10+ (el Dockerfile usa 3.10) y Node.js ≥ 20 para las CLI externas.
- Claves activas para:
- **Z.ai (Claude CLI)** → `ANTHROPIC_AUTH_TOKEN` y `ANTHROPIC_BASE_URL`.
- **Google Gemini** (CLI o API) → `GEMINI_API_KEY`.
- **DeepInfra GPT-OSS-120B** → `DEEPINFRA_API_KEY`.
- Servidor Nextcloud accesible por WebDAV (usuario, contraseña y URL remota).
### Instalación de las CLIs externas
```bash ```bash
docker-compose up -d npm install -g @anthropic-ai/claude-code
npm install -g @google/gemini-cli
``` ```
Recuerda exportar las mismas variables de entorno (`ANTHROPIC_*`, `GEMINI_API_KEY`) para que las CLIs compartan credenciales con el servicio.
## ⚙️ Configuración de Variables de Entorno ## Configuración
1. Copia el ejemplo `.env` (no versionado) y completa:
### Nextcloud
```env ```env
NEXTCLOUD_URL=https://tu-nextcloud.com NEXTCLOUD_URL=http://tu-servidor:8080/remote.php/webdav
NEXTCLOUD_USER=tu_usuario NEXTCLOUD_USER=...
NEXTCLOUD_PASS=tu_contraseña NEXTCLOUD_PASS=...
```
### APIs de IA GEMINI_API_KEY=...
```env DEEPINFRA_API_KEY=...
GEMINI_API_KEY=tu_gemini_key
DEEPINFRA_API_KEY=tu_deepinfra_key
ANTHROPIC_BASE_URL=https://api.z.ai/api/anthropic ANTHROPIC_BASE_URL=https://api.z.ai/api/anthropic
ANTHROPIC_AUTH_TOKEN=tu_z_ai_token ANTHROPIC_AUTH_TOKEN=...
TELEGRAM_TOKEN=... (opcional)
TELEGRAM_CHAT_ID=... (opcional)
``` ```
2. Crea los directorios utilizados por los volúmenes (si no existen):
### Notificaciones (Opcional)
```env
TELEGRAM_TOKEN=tu_bot_token
TELEGRAM_CHAT_ID=tu_chat_id
```
## 📊 Arquitectura del Sistema
```
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ GPT-OSS-120B │───▶│ Claude CLI │───▶│ Gemini CLI │
│ (DeepInfra) │ │ (Z.ai) │ │ (Google) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────┐
│ Sistema Unificado │
│ (Documento Final Único) │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ Nextcloud Service │
│ (Sincronización WebDAV) │
└─────────────────────────────────────────────────────────────────┘
```
## 🔧 Uso
### Procesamiento Automático
1. Sube archivos de audio a la carpeta `Audios` en Nextcloud
2. El sistema detecta automáticamente y genera resúmenes
3. Los documentos finales se guardan en `Documentos`
4. Las versiones Markdown se sincronizan con `Notes`
### Monitoreo
- **Logs**: `docker-compose logs -f app`
- **Estado**: `docker-compose ps`
- **Telegram**: Notificaciones automáticas (si está configurado)
## 🎨 Salida del Sistema
El sistema genera documentos unificados con:
1. **Puntos Clave**: Extraídos por GPT-OSS-120B
2. **Resumen Integral**: Desarrollado por Claude CLI (500+ palabras)
3. **Quiz de Evaluación**: 10 preguntas de opción múltiple
4. **Metadatos**: Información del proceso colaborativo
## 🐳 Docker
### Estructura de Contenedores
- **app**: Servicio principal con soporte GPU
- **ollama**: Servidor Ollama para modelos locales
### Personalización
```bash ```bash
# Reconstruir contenedores mkdir -p downloads resumenes_docx
docker-compose build
# Reiniciar servicios
docker-compose restart
# Ver logs en tiempo real
docker-compose logs -f app
``` ```
## 🚨 Troubleshooting ## Ejecución local (sin Docker)
```bash
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
python3 main.py
```
- El dashboard se expone en `http://localhost:5000`.
- Los registros viven en `logs/service.log`.
### Problemas Comunes ## Ejecución con Docker
```bash
docker compose up -d --build
docker compose logs -f app
```
El único servicio (`nextcloud_ai_app`) ya expone el dashboard y comparte `downloads/` y `resumenes_docx/` como volúmenes.
1. **Error de permisos Claude CLI** ## Flujo del pipeline
- Solución: `CLAUDE_DANGEROUSLY_SKIP_PERMISSIONS=1` en docker-compose.yml 1. **Monitoreo**: cada `POLL_INTERVAL` segundos se listan nuevas entradas en Nextcloud (`Audios`, `Pdf`, `Textos`...).
2. **Descarga y preproceso**: los archivos se guardan en `downloads/` con normalización y sanitización de nombres.
3. **Transcripción (Whisper)**: modelo `medium` optimizado para español (soporte GPU).
4. **Resúmenes colaborativos**:
- Claude CLI genera bullet points por lotes y resumen integral.
- Gemini CLI/API aplica formato final y estilo consistente.
5. **Clasificación y renombrado**: se detectan temáticas (Historia, Contabilidad, Gobierno, Otras Clases) + topics para nombrar archivos inteligentemente.
6. **Entrega**: se generan `.md`, `.docx`, `.pdf` y se suben de nuevo a Nextcloud.
7. **Dashboard**: refleja estado (procesados/pendientes), permite reprocesar o resetear registros, y sirve descargas locales.
2. **Timeout en procesamiento** ## Dashboard en detalle
- Aumentar `MODEL_TIMEOUT_SECONDS` en .env - **Vista general**: tarjetas con totales, filtros por origen (local/WebDAV) y buscador instantáneo.
- **Acciones rápidas**:
- `Procesar`: envía el archivo nuevamente al pipeline.
- `Resetear`: elimina la marca de procesado para forzar un reprocesamiento automático.
- `Descargar`: enlaces directos a TXT/MD/DOCX/PDF disponibles.
- **API**:
- `GET /api/files` → listado.
- `POST /api/reprocess` → reprocesa.
- `POST /api/mark-unprocessed` → limpia estado.
- `GET /api/refresh` → sincroniza.
- `GET /health` → healthcheck.
3. **Problemas de GPU** ## Buenas prácticas operativas
- Verificar drivers NVIDIA y CUDA 12.1+ - **CUDA libre**: el servicio libera VRAM si los modelos quedan ociosos; revisa el log para ver las limpiezas agresivas.
- Comprobar `nvidia-smi` -.**Telegram**: usa `ERROR_THROTTLE_SECONDS` para evitar spam en errores repetidos.
- **Respaldo**: `processed_files.txt` guarda el historial de todo lo procesado; respáldalo si cambias de servidor.
- **Extensibilidad**: si necesitas nuevos formatos o pasos, agrega funciones en `main.py` reutilizando `ThreadPoolExecutor` y los helpers existentes.
4. **Error de APIs** ## Troubleshooting rápido
- Verificar keys y endpoints en .env | Problema | Fix |
- Comprobar límites de las APIs | --- | --- |
| Claude o Gemini devuelven error de permisos | Exporta `CLAUDE_DANGEROUSLY_SKIP_PERMISSIONS=1` (ya se envía al contenedor). |
## 📈 Métricas y Optimización | No aparecen archivos en el dashboard | Verifica credenciales Nextcloud y `logs/service.log`. |
| Tiempo de espera alto en WebDAV | Ajusta `HTTP_TIMEOUT` y `WEBDAV_MAX_RETRIES` en `.env`. |
### Rendimiento | GPU ocupada constantemente | Reduce `MODEL_TIMEOUT_SECONDS` o baja el tamaño del modelo Whisper. |
- **Tiempo de procesamiento**: ~2-5 minutos por audio de 5min
- **Uso de VRAM**: ~8-12GB con modelos GPU
- **Calidad de resúmenes**: Formato académico con análisis profundo
### Optimización
- **VRAM Management**: Limpieza automática cada 5 minutos
- **Error Handling**: Reintentos automáticos con backoff exponencial
- **Timeout Configurable**: Adaptarse a diferentes cargas de trabajo
## 🔐 Seguridad
- **API Keys**: Almacenadas como variables de entorno
- **WebDAV**: Autenticación básica con HTTPS
- **CLI Tools**: Configuración segura sin permisos de root
- **Redes**: Aislamiento de contenedores Docker
## 🤝 Contribuciones
1. Fork del repositorio
2. Crear rama feature
3. Commit con cambios descriptivos
4. Pull Request para revisión
## 📄 Licencia
MIT License - Ver archivo LICENSE para detalles
## 📞 Soporte
Para problemas o preguntas:
- Crear issue en el repositorio
- Revisar logs del sistema
- Verificar documentación de variables de entorno
--- ---
**Versión**: 8.0 Final La meta de esta versión es mantener el proyecto ágil y escalable: menos archivos, menos servicios y una sola fuente de verdad. Si necesitas habilitar nuevas integraciones (por ejemplo, más modelos o destinos), añade módulos dedicados dentro de `main.py` o expórtalos a un paquete propio manteniendo este núcleo ligero. ¡Felices resúmenes! 💡
**Última Actualización**: Septiembre 2024
**Estado**: Producción estable

View File

@@ -1,285 +0,0 @@
# 🤖 CBC Nextcloud AI Service - Documentación para Asistentes IA
## 📋 Resumen Ejecutivo
Este es un sistema automatizado de procesamiento de contenido académico que utiliza inteligencia artificial para transcribir audios, procesar PDFs y generar resúmenes colaborativos mediante la integración de 3 modelos de IA diferentes.
**Estado Actual**: ✅ ACTIVO y FUNCIONANDO
- **Servicio**: `cbc-main.service` (systemd)
- **Proceso Principal**: PID 49696 (única instancia)
- **GPU**: NVIDIA RTX 3050 (1.5GB/8GB en uso)
- **Última Actualización**: 2025-09-26
---
## 🖥️ Especificaciones del Sistema
### Hardware
- **CPU**: AMD Ryzen 5 5600X 6-Core Processor (12 hilos)
- **RAM**: 15GB DDR4 (9.7GB disponible)
- **GPU**: NVIDIA GeForce RTX 3050 (8GB VRAM)
- **Almacenamiento**: 439GB SSD (330GB libre)
- **Sistema Operativo**: Linux x86_64
### Software
- **Python**: 3.10.12
- **CUDA**: 12.2 (Driver 535.247.01)
- **Gestor de Servicios**: systemd
- **Directorio Principal**: `/home/ren/cbc/`
### Librerías Clave
- `torch` 2.8.0 (PyTorch con soporte CUDA)
- `transformers` 4.56.1 (Hugging Face)
- `whisper` 20240930 (OpenAI)
- `easyocr` 1.7.2 (OCR)
- `openai` 1.107.0 (API clientes)
- `python-docx` 1.2.0 (manipulación Word)
- `pdf2image` 1.17.0 (procesamiento PDF)
---
## 🚀 Funcionalidades Principales
### 1. Procesamiento de Audio
- **Formatos Soportados**: MP3, WAV, M4A, OGG
- **Transcripción**: Whisper (medium) con GPU aceleración
- **Salida**: Archivos de texto con timestamps
- **Ubicación**: Carpeta `Audios` en Nextcloud
### 2. Procesamiento de PDF
- **OCR Múltiple**: EasyOCR + Tesseract + TrOCR
- **Procesamiento por Lotes**: 3 páginas por chunk
- **Corrección IA**: Gemini para limpieza de texto
- **Salida**: Documentos DOCX editables
- **Ubicación**: Carpeta `Pdf` en Nextcloud
### 3. Sistema de Resúmenes Colaborativos
**3 Modelos de IA trabajando en secuencia**:
1. **GPT-OSS-120B** (DeepInfra API):
- Genera bullet points clave
- Análisis inicial del contenido
2. **Claude/Zhai** (CLI - API Z.ai):
- Desarrolla resumen integral
- 400-500 palabras estructuradas
3. **Gemini** (CLI - Google):
- Aplica formato final
- Optimiza presentación
### 4. Clasificación Inteligente de Contenido
El sistema clasifica automáticamente en 4 categorías temáticas:
- `historia` - Eventos históricos, cronologías
- `analisis_contable` - Contabilidad, finanzas, balances
- `instituciones_gobierno` - Política, gobierno, leyes
- `otras_clases` - Ciencias, tecnología, literatura, etc.
### 5. Generación de Quizzes
- **10 preguntas** de opción múltiple por documento
- **4 opciones** (A, B, C, D) por pregunta
- **Respuestas incluidas** en documentos separados
---
## ⚙️ Configuración Actual
### Variables de Entorno
```bash
CUDA_LAUNCH_BLOCKING=1 # Depuración CUDA síncrona
PYTHONPATH=/home/ren/cbc # Ruta del proyecto
HOME=/home/ren # Directorio home
```
### Rutas del Sistema
- **Descargas**: `/app/downloads/`
- **Resúmenes**: `./downloads/`
- **Documentos DOCX**: `./resumenes_docx/`
- **Archivos Procesados**: `/app/processed_files.txt`
### Límites de Recursos
- **Memoria RAM**: 8GB máximo
- **CPU**: 90% de cuota
- **Archivos Abiertos**: 65536
- **Reinicio Automático**: Siempre (10 segundos de espera)
---
## 📁 Estructura de Archivos Principal
```
/home/ren/cbc/
├── main.py # Servicio principal (72,405 líneas)
├── .env # Variables de entorno
├── requirements.txt # Dependencias Python
├── README_AI_ASSISTANT.md # Este documento
├── MEGA_HISTORIA_parte*.txt # Historiales académicos
├── resumen_*.py # Scripts de resumen
├── procesador_academico.py # Procesamiento especializado
├── analizador_*.py # Análisis de contenido
├── config_telegram.txt # Configuración Telegram
└── txt/ # Directorio de textos
```
---
## 🔧 Gestión del Servicio
### Comandos Essenciales
```bash
# Ver estado del servicio
sudo systemctl status cbc-main
# Ver logs en tiempo real
sudo journalctl -u cbc-main -f
# Detener servicio
sudo systemctl stop cbc-main
# Iniciar servicio
sudo systemctl start cbc-main
# Reiniciar servicio
sudo systemctl restart cbc-main
# Ver uso de GPU
nvidia-smi
# Ver uso de memoria del sistema
free -h
```
### Monitoreo de Salud
```bash
# Verificar proceso único
ps aux | grep "python3.*main.py" | grep -v grep
# Verificar memoria GPU
nvidia-smi --query-gpu=memory.used,memory.total --format=csv
# Verificar espacio en disco
df -h /
# Verificar actividad de red
sudo netstat -tlnp | grep :80
```
---
## 🚨 Problemas Comunes y Soluciones
### Error CUDA: "CUDA-capable device(s) is/are busy or unavailable"
**Causa**: Múltiples procesos compitiendo por recursos GPU
**Solución**:
```bash
# Verificar procesos múltiples
ps aux | grep "python3.*main.py"
# Si hay múltiples, reiniciar servicio
sudo systemctl restart cbc-main
```
### Error de Permiso: "Permission denied"
**Causa**: El servicio no tiene permisos para escribir en `/app/`
**Solución**:
```bash
# Crear directorios con permisos correctos
sudo mkdir -p /app/downloads /app/resumenes
sudo chown -R ren:ren /app/
```
### Alto Uso de Memoria GPU
**Configuración actual optimizada**:
- `MAX_PAGES_PER_CHUNK = 3` (reducido de 5)
- `PDF_DPI = 200` (reducido de 300)
- `batch_size = 1` (procesamiento individual)
- `_MODEL_TIMEOUT_SECONDS = 300` (liberación rápida)
---
## 🔄 Flujo de Trabajo Automático
### 1. Detección de Archivos
- Monitorea carpetas Nextcloud cada 5 segundos
- Verifica archivos no procesados en `processed_files.txt`
### 2. Procesamiento según Tipo
**Audio** → Transcripción → Resumen Colaborativo → Clasificación → Subida
**PDF** → OCR → Corrección IA → Documento Editable → Resumen → Subida
### 3. Clasificación y Organización
- Análisis de contenido con Gemini
- Clasificación en categorías temáticas
- Renombrado automático con temas extraídos
- Organización en carpetas específicas
### 4. Notificaciones
- Envío de alertas por Telegram
- Reportes de progreso y errores
- Confirmación de procesamiento completado
---
## 📊 Métricas de Rendimiento
### Rendimiento Actual
- **Procesamiento PDF**: ~3-5 minutos por documento (12 páginas)
- **Transcripción Audio**: ~2-3 minutos por 10 minutos de audio
- **Generación Resúmenes**: ~1-2 minutos por documento
- **Uso GPU**: 1.5GB (estable)
- **Uso CPU**: 44% promedio
- **Memoria RAM**: 1.1GB utilizada
### Optimizaciones Aplicadas
- ✅ Procesamiento único (sin duplicados)
- ✅ Gestión agresiva de VRAM
- ✅ Límites de recursos controlados
- ✅ Reintentos automáticos para errores CUDA
- ✅ Sistema de clasificación inteligente
---
## 🔮 Estado y Próximos Pasos
### Estado Actual: SISTEMA ESTABLE
- ✅ Servicio systemd funcionando correctamente
- ✅ GPU operativa sin errores
- ✅ Procesamiento de PDF activo
- ✅ Clasificación automática funcionando
- ✅ Notificaciones Telegram operativas
### Posibles Mejoras Futuras
- Implementar cola de procesamiento para manejar carga pesada
- Añadir interfaz web para monitoreo
- Optimizar tiempos de procesamiento con modelos más eficientes
- Implementar sistema de backup automático
- Añadir métricas detalladas de rendimiento
---
## 📞 Información de Contacto y Soporte
### Para Emergencias del Sistema
```bash
# Reinicio completo del sistema
sudo systemctl restart cbc-main
# Liberación forzada de VRAM
sudo pkill -f python3
sudo systemctl start cbc-main
```
### Archivos de Log Importantes
- **Journal Systemd**: `sudo journalctl -u cbc-main`
- **Log GPU**: `nvidia-smi --query-gpu=timestamp,memory.used --format=csv -l 1`
- **Log Memoria**: `free -h -s 5`
### Puntos Críticos del Sistema
1. **Disponibilidad GPU**: NVIDIA RTX 3050 (8GB)
2. **Espacio en Disco**: 330GB disponibles
3. **Conexión Nextcloud**: WebDAV funcional
4. **API Keys**: Configuradas y operativas
---
*Este documento fue generado automáticamente el 2025-09-26 para proporcionar a asistentes IA una comprensión completa del estado y funcionalidad del sistema CBC Nextcloud AI Service.*

View File

@@ -1,205 +0,0 @@
#!/bin/bash
set -euo pipefail
# ========================
# Define Constants
# ========================
SCRIPT_NAME=$(basename "$0")
NODE_MIN_VERSION=18
NODE_INSTALL_VERSION=22
NVM_VERSION="v0.40.3"
CLAUDE_PACKAGE="@anthropic-ai/claude-code"
CONFIG_DIR="$HOME/.claude"
CONFIG_FILE="$CONFIG_DIR/settings.json"
API_BASE_URL="https://api.z.ai/api/anthropic"
API_KEY_URL="https://z.ai/manage-apikey/apikey-list"
API_TIMEOUT_MS=3000000
# ========================
# Functions
# ========================
log_info() {
echo "🔹 $*"
}
log_success() {
echo "$*"
}
log_error() {
echo "$*" >&2
}
ensure_dir_exists() {
local dir="$1"
if [ ! -d "$dir" ]; then
mkdir -p "$dir" || {
log_error "Failed to create directory: $dir"
exit 1
}
fi
}
# ========================
# Node.js Installation
# ========================
install_nodejs() {
local platform=$(uname -s)
case "$platform" in
Linux|Darwin)
log_info "Installing Node.js on $platform..."
# Install nvm
log_info "Installing nvm ($NVM_VERSION)..."
curl -s https://raw.githubusercontent.com/nvm-sh/nvm/"$NVM_VERSION"/install.sh | bash
# Load nvm
log_info "Loading nvm environment..."
\. "$HOME/.nvm/nvm.sh"
# Install Node.js
log_info "Installing Node.js $NODE_INSTALL_VERSION..."
nvm install "$NODE_INSTALL_VERSION"
# Verify installation
node -v &>/dev/null || {
log_error "Node.js installation failed"
exit 1
}
log_success "Node.js installed: $(node -v)"
log_success "npm version: $(npm -v)"
;;
*)
log_error "Unsupported platform: $platform"
exit 1
;;
esac
}
# ========================
# Node.js Check
# ========================
check_nodejs() {
if command -v node &>/dev/null; then
current_version=$(node -v | sed 's/v//')
major_version=$(echo "$current_version" | cut -d. -f1)
if [ "$major_version" -ge "$NODE_MIN_VERSION" ]; then
log_success "Node.js is already installed: v$current_version"
return 0
else
log_info "Node.js v$current_version is installed but version < $NODE_MIN_VERSION. Upgrading..."
install_nodejs
fi
else
log_info "Node.js not found. Installing..."
install_nodejs
fi
}
# ========================
# Claude Code Installation
# ========================
install_claude_code() {
if command -v claude &>/dev/null; then
log_success "Claude Code is already installed: $(claude --version)"
else
log_info "Installing Claude Code..."
npm install -g "$CLAUDE_PACKAGE" || {
log_error "Failed to install claude-code"
exit 1
}
log_success "Claude Code installed successfully"
fi
}
configure_claude_json(){
node --eval '
const os = require("os");
const fs = require("fs");
const path = require("path");
const homeDir = os.homedir();
const filePath = path.join(homeDir, ".claude.json");
if (fs.existsSync(filePath)) {
const content = JSON.parse(fs.readFileSync(filePath, "utf-8"));
fs.writeFileSync(filePath, JSON.stringify({ ...content, hasCompletedOnboarding: true }, null, 2), "utf-8");
} else {
fs.writeFileSync(filePath, JSON.stringify({ hasCompletedOnboarding: true }, null, 2), "utf-8");
}'
}
# ========================
# API Key Configuration
# ========================
configure_claude() {
log_info "Configuring Claude Code..."
echo " You can get your API key from: $API_KEY_URL"
read -s -p "🔑 Please enter your Z.AI API key: " api_key
echo
if [ -z "$api_key" ]; then
log_error "API key cannot be empty. Please run the script again."
exit 1
fi
ensure_dir_exists "$CONFIG_DIR"
# Write settings.json
node --eval '
const os = require("os");
const fs = require("fs");
const path = require("path");
const homeDir = os.homedir();
const filePath = path.join(homeDir, ".claude", "settings.json");
const apiKey = "'"$api_key"'";
const content = fs.existsSync(filePath)
? JSON.parse(fs.readFileSync(filePath, "utf-8"))
: {};
fs.writeFileSync(filePath, JSON.stringify({
...content,
env: {
ANTHROPIC_AUTH_TOKEN: apiKey,
ANTHROPIC_BASE_URL: "'"$API_BASE_URL"'",
API_TIMEOUT_MS: "'"$API_TIMEOUT_MS"'",
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: 1
}
}, null, 2), "utf-8");
' || {
log_error "Failed to write settings.json"
exit 1
}
log_success "Claude Code configured successfully"
}
# ========================
# Main
# ========================
main() {
echo "🚀 Starting $SCRIPT_NAME"
check_nodejs
install_claude_code
configure_claude_json
configure_claude
echo ""
log_success "🎉 Installation completed successfully!"
echo ""
echo "🚀 You can now start using Claude Code with:"
echo " claude"
}
main "$@"

View File

@@ -1,21 +0,0 @@
cache_ttl: 30
dashboard:
enabled: true
host: 0.0.0.0
port: 5000
http_timeout: 30
max_workers: 2
models:
claude: claude-3-haiku
gemini: gemini-1.5-flash
whisper: base
notifications:
telegram_enabled: true
verbose_logging: true
poll_interval: 5
processing:
batch_size: 3
parallel_uploads: 3
retry_attempts: 3
vram_threshold: 0.8
webdav_retries: 3

View File

@@ -1,87 +0,0 @@
#!/usr/bin/env python3
import re
def corregir_texto_gallego(input_file, output_file):
"""Aplica correcciones de gallego a español al archivo de transcripción"""
# Correcciones más comunes de gallego a español
correcciones = {
"xeo": "yo",
"non": "no",
"hai": "hay",
"entóns": "entonces",
"máis": "más",
"tamén": "también",
"sempre": "siempre",
"verdade": "verdad",
"cousa": "cosa",
"xente": "gente",
"tempo": "tiempo",
"lingua": "lengua",
"pode": "puede",
"xamón": "shogun",
"xomón": "shogun",
"unha": "una",
"dunha": "de una",
"nunha": "en una",
"xeral": "general",
"xeraria": "jerarquía",
"ximéas": "temas",
"ximeas": "temas",
"ronquera": "reunión",
"xocalizar": "juntar",
"oanxacular": "juntar",
"xocal": "junto",
"lúmulo": "grupo",
"lúmido": "grupo",
"lúmada": "grupos",
"nulunxación": "reunificación",
"xotalipa": "capitalista",
"crente": "gente",
"enxucar": "juntar",
"agora": "ahora",
"cando": "cuando",
"temos": "tenemos",
"habíamos": "habíamos",
"era": "era",
"había": "había",
"existía": "existía",
"también": "también",
"vamos": "vamos",
"teníamos": "teníamos",
"vimos": "vimos",
"estaba": "estaba",
"estaban": "estaban",
"podía": "podía",
"podemos": "podemos",
"somos": "somos"
}
with open(input_file, 'r', encoding='utf-8') as f:
lines = f.readlines()
corrected_lines = []
for line in lines:
corrected_line = line
# Aplicar correcciones
for gallego, espanol in correcciones.items():
corrected_line = corrected_line.replace(gallego, espanol)
# Normalizar espacios múltiples
corrected_line = re.sub(r'\s+', ' ', corrected_line)
# Eliminar líneas que son solo repeticiones de "e" o "¿no?"
if corrected_line.strip() and not re.match(r'^\s*\[?\d+:\d+:\d+\]\s+(e\s+)+\s*$', corrected_line) and not re.match(r'^\s*\[?\d+:\d+:\d+\]\s+¿no\?\s*$', corrected_line):
corrected_lines.append(corrected_line)
with open(output_file, 'w', encoding='utf-8') as f:
f.writelines(corrected_lines)
print(f"Archivo corregido guardado en: {output_file}")
print(f"Líneas procesadas: {len(lines)}")
print(f"Líneas finales: {len(corrected_lines)}")
if __name__ == "__main__":
input_file = "downloads/1_5134218813469886295.txt"
output_file = "downloads/1_5134218813469886295_corregido.txt"
corregir_texto_gallego(input_file, output_file)

View File

@@ -5,9 +5,8 @@ Interfaz web simple para reprocesar archivos MP3 con 1 click
""" """
import os import os
import json
import logging import logging
import subprocess import sys
from datetime import datetime from datetime import datetime
from pathlib import Path from pathlib import Path
from typing import List, Dict, Any from typing import List, Dict, Any
@@ -15,9 +14,10 @@ from typing import List, Dict, Any
from flask import Flask, render_template, request, jsonify, send_from_directory from flask import Flask, render_template, request, jsonify, send_from_directory
from flask_cors import CORS from flask_cors import CORS
# Importar configuraciones del main.py # Importar configuraciones del main.py sin rutas absolutas
import sys PROJECT_ROOT = Path(__file__).resolve().parent
sys.path.append('/home/ren/cbc') if str(PROJECT_ROOT) not in sys.path:
sys.path.append(str(PROJECT_ROOT))
from main import ( from main import (
AUDIO_EXTENSIONS, LOCAL_DOWNLOADS_PATH, PROCESSED_FILES_PATH, AUDIO_EXTENSIONS, LOCAL_DOWNLOADS_PATH, PROCESSED_FILES_PATH,
load_processed_files, save_processed_file, process_audio_file, load_processed_files, save_processed_file, process_audio_file,

88
docker-compose.yml Executable file → Normal file
View File

@@ -1,86 +1,24 @@
version: '3.8'
services: services:
app: app:
build: build:
context: . context: .
dockerfile: Dockerfile dockerfile: Dockerfile
container_name: nextcloud_ai_app container_name: nextcloud_ai_app
env_file:
- .env
environment:
- NVIDIA_VISIBLE_DEVICES=all
- CLAUDE_DANGEROUSLY_SKIP_PERMISSIONS=1
volumes: volumes:
- ./downloads:/app/downloads - ./downloads:/app/downloads
- ./resumenes_docx:/app/resumenes_docx - ./resumenes_docx:/app/resumenes_docx
env_file:
- .env
environment:
- NVIDIA_VISIBLE_DEVICES=all
- OLLAMA_HOST=http://ollama:11434
- CLAUDE_DANGEROUSLY_SKIP_PERMISSIONS=1
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
depends_on:
- ollama
restart: always
ollama:
build:
context: .
dockerfile: Dockerfile
container_name: ollama_server
volumes:
- ./ollama_data:/root/.ollama
ports:
- "11434:11434"
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
restart: always
dashboard:
build:
context: .
dockerfile: Dockerfile.dashboard
container_name: audio_dashboard
volumes:
- ./downloads:/app/downloads
- ./templates:/app/templates
- ./processed_files.txt:/app/processed_files.txt
- ./.main_service.lock:/app/.main_service.lock
env_file:
- .env
environment:
- DASHBOARD_SECRET_KEY=${DASHBOARD_SECRET_KEY:-dashboard-secret-key-change-me}
- NVIDIA_VISIBLE_DEVICES=all
- ANTHROPIC_BASE_URL=${ANTHROPIC_BASE_URL:-https://api.z.ai/api/anthropic}
- ANTHROPIC_AUTH_TOKEN=${ANTHROPIC_AUTH_TOKEN}
ports: ports:
- "5000:5000" - "5000:5000"
depends_on: deploy:
- app resources:
restart: always reservations:
devices:
filebrowser: - driver: nvidia
image: filebrowser/filebrowser count: 1
container_name: downloads_filebrowser capabilities: [gpu]
volumes: restart: unless-stopped
- ./downloads:/srv
- ./filebrowser_config:/config
command: [
"--address", "0.0.0.0",
"--port", "8080",
"--root", "/srv",
"--database", "/config/filebrowser.db",
"--username", "ren",
"--password", "$$2b$$10$$KbFwEuIb3g26kYCxVzl0Ju81OxhK1KHQNUZCLAPDg298XQBOvhoHS"
]
ports:
- "8080:8080"
restart: always

View File

@@ -1,8 +0,0 @@
{
"port": 80,
"baseURL": "",
"address": "",
"log": "stdout",
"database": "/database/filebrowser.db",
"root": "/srv"
}

17
main.py
View File

@@ -103,8 +103,6 @@ DEFAULT_GEMINI_API_KEY = "AIzaSyDWOgyAJqscuPU6iSpS6gxupWBm4soNw5o"
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY") or DEFAULT_GEMINI_API_KEY GEMINI_API_KEY = os.getenv("GEMINI_API_KEY") or DEFAULT_GEMINI_API_KEY
TELEGRAM_TOKEN = os.getenv("TELEGRAM_TOKEN") TELEGRAM_TOKEN = os.getenv("TELEGRAM_TOKEN")
TELEGRAM_CHAT_ID = os.getenv("TELEGRAM_CHAT_ID") TELEGRAM_CHAT_ID = os.getenv("TELEGRAM_CHAT_ID")
OLLAMA_HOST = os.environ.get("OLLAMA_HOST", "http://ollama:11434")
OLLAMA_MODEL = "mistral:7b"
GEMINI_CLI_PATH = shutil.which("gemini") GEMINI_CLI_PATH = shutil.which("gemini")
CLAUDE_CLI_PATH = shutil.which("claude") CLAUDE_CLI_PATH = shutil.which("claude")
GEMINI_FLASH_MODEL = os.getenv("GEMINI_FLASH_MODEL") GEMINI_FLASH_MODEL = os.getenv("GEMINI_FLASH_MODEL")
@@ -1209,21 +1207,6 @@ def run_gemini_summary(prompt):
"""Genera resumen usando GLM-4.6 (compatibilidad).""" """Genera resumen usando GLM-4.6 (compatibilidad)."""
return run_gemini(prompt, use_flash=True) return run_gemini(prompt, use_flash=True)
def run_ollama(prompt):
"""Genera contenido usando Ollama"""
payload = {
"model": OLLAMA_MODEL,
"messages": [{"role": "user", "content": prompt}],
"stream": False
}
try:
r = requests.post(f"{OLLAMA_HOST}/api/chat", json=payload, timeout=120)
r.raise_for_status()
response = r.json()
return response['message']['content']
except Exception as e:
return f"Error Ollama: {e}"
# --- CLASIFICACIÓN INTELIGENTE DE CONTENIDO --- # --- CLASIFICACIÓN INTELIGENTE DE CONTENIDO ---
def classify_content_intelligent(text_content): def classify_content_intelligent(text_content):
"""Clasifica el contenido del resumen en categorías temáticas usando IA""" """Clasifica el contenido del resumen en categorías temáticas usando IA"""

View File

@@ -1,18 +0,0 @@
Flask==2.3.3
Flask-CORS==4.0.0
requests==2.31.0
webdavclient3
opencv-python-headless
python-dotenv
easyocr
pytesseract
Pillow
python-docx
openai
ollama
pdf2image
transformers
pypdf
reportlab
torch
numpy

View File

@@ -1,17 +1,17 @@
webdavclient3 Flask
Flask-CORS
Pillow
easyocr
numpy
openai-whisper
opencv-python-headless
pdf2image
pypdf
python-docx
python-dotenv
pytesseract
reportlab
requests requests
torch torch
openai-whisper
pytesseract
Pillow
python-docx
openai
ollama
pdf2image
easyocr
opencv-python-headless
numpy
transformers transformers
pypdf webdavclient3
python-dotenv
reportlab

View File

@@ -1,158 +0,0 @@
#!/usr/bin/env python3
"""
Script mejorado para iniciar el servicio completo con mejor información
"""
import sys
import os
import time
# Añadir path
sys.path.append('/home/ren/cbc')
def print_banner():
"""Muestra banner de inicio"""
print("\n" + "=" * 70)
print("🚀 NEXTCLOUD AI SERVICE - DASHBOARD INTEGRADO")
print("=" * 70)
print()
def print_step(step, message):
"""Imprime un paso con formato"""
print(f" [{step}] {message}")
def check_dependencies():
"""Verifica dependencias"""
print_step("1", "Verificando dependencias...")
try:
import flask
print_step("", f"Flask {flask.__version__}")
except ImportError:
print_step("", "Flask no está instalado")
print("\n 💡 Instalar: pip3 install flask flask-cors")
return False
try:
import flask_cors
print_step("", "Flask-CORS")
except ImportError:
print_step("", "Flask-CORS no está instalado")
print("\n 💡 Instalar: pip3 install flask-cors")
return False
return True
def check_dashboard():
"""Verifica dashboard"""
print_step("2", "Verificando dashboard...")
try:
import dashboard
print_step("", "Dashboard importado correctamente")
return True
except Exception as e:
print_step("", f"Error importando dashboard: {e}")
return False
def check_main():
"""Verifica main.py"""
print_step("3", "Verificando servicio principal...")
try:
import main
print_step("", "Servicio principal importado")
return True
except Exception as e:
print_step("", f"Error importando servicio principal: {e}")
return False
def start_dashboard():
"""Inicia dashboard en hilo separado"""
print_step("4", "Iniciando dashboard en hilo separado...")
try:
import dashboard
import threading
def run_dashboard():
"""Función para ejecutar dashboard"""
print("\n 🌐 Iniciando servidor Flask...")
dashboard.app.run(
host='0.0.0.0',
port=5000,
debug=False,
threaded=True,
use_reloader=False
)
# Crear hilo
dashboard_thread = threading.Thread(target=run_dashboard, daemon=True)
dashboard_thread.start()
# Dar tiempo para que inicie
time.sleep(2)
print_step("", "Dashboard iniciado")
print("\n 📱 Dashboard disponible en:")
print(" http://localhost:5000")
print()
return dashboard_thread
except Exception as e:
print_step("", f"Error iniciando dashboard: {e}")
import traceback
traceback.print_exc()
return None
def start_main_service():
"""Inicia servicio principal"""
print_step("5", "Iniciando servicio principal...")
try:
import main
print("\n ⏳ Iniciando bucle principal...")
print(" 📊 El servicio procesará archivos automáticamente")
print(" ⏹️ Para detener: Ctrl+C")
print()
print("=" * 70)
# Iniciar servicio
main.main()
except KeyboardInterrupt:
print("\n\n🛑 Servicio detenido por el usuario")
except Exception as e:
print(f"\n\n❌ Error en servicio principal: {e}")
import traceback
traceback.print_exc()
return False
return True
def main():
"""Función principal"""
print_banner()
# Verificar todo
if not check_dependencies():
sys.exit(1)
if not check_dashboard():
sys.exit(1)
if not check_main():
sys.exit(1)
# Iniciar dashboard
dashboard_thread = start_dashboard()
if not dashboard_thread:
print("\n⚠️ Continuando sin dashboard...")
# Iniciar servicio principal
start_main_service()
if __name__ == '__main__':
main()