Compare commits

...

5 Commits

Author SHA1 Message Date
marcos 3c49356a7c Link video 2026-02-24 19:14:04 +01:00
marcos 0c235f0c9f docs: Add in-depth technical analysis of bomb duplicate detection system
- Add mathematical foundations (set theory) explanation
- Document internal workings of Python set() with hash tables
- Include algorithmic complexity analysis (O(1) vs O(n))
- Explain step-by-step validation process with memory state
- Add race condition scenarios and threading.Lock solution
- Provide mathematical proofs (idempotence, state consistency)
- Compare client vs server validation architectures
- Include memory and performance optimization analysis
- Add 800+ lines of detailed technical documentation
2026-02-19 20:19:04 +01:00
marcos 1ad9ac98db docs: Add file and line references to all code blocks in README
- Add specific line references to servidor.py code blocks
- Add specific line references to app.py code blocks
- Improve code traceability for email client documentation
- Improve code traceability for game server documentation
- Make documentation more navigable with precise locations
2026-02-19 20:15:50 +01:00
marcos 1006498c94 docs: Add comprehensive email client documentation and bomb duplicate detection explanation
- Add complete email architecture section with IMAP/SMTP protocol details
- Document credential system with Base64 encoding flow
- Explain email reading, sending, and IMAP server sync
- Add multiple recipient validation and attachment handling
- Document visual indicators and error handling
- Add bomb duplicate detection with set() data structure
- Include 15+ diagrams, code examples, and technical explanations
- Expand README from 698 to 1600+ lines
2026-02-19 20:07:57 +01:00
marcos f1906ec18e correo 2026-02-19 20:02:35 +01:00
11 changed files with 4166 additions and 15 deletions

44
.gitignore vendored Normal file
View File

@ -0,0 +1,44 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# Virtual Environment
.venv/
venv/
ENV/
# IDEs
.vscode/
.idea/
*.swp
*.swo
*~
# Configuración de correo (contiene credenciales)
.mail_config.json
# Backups
*.backup*
*.bak
# OS
.DS_Store
Thumbs.db

246
ARQUITECTURA_CORREO.md Normal file
View File

@ -0,0 +1,246 @@
# Arquitectura del Cliente de Correo - Proyecto1AVApsp
## Estructura de la aplicación
```
┌──────────────────────────────────────────────────────────────┐
│ Proyecto1AVApsp │
│ Panel de Laboratorio │
└──────────────────────────────────────────────────────────────┘
┌─────────────────────┼─────────────────────┐
│ │ │
┌────▼────┐ ┌────▼────┐ ┌────▼────┐
│ Tareas │ │ Correos │ │ Juegos │
└─────────┘ └────┬────┘ └─────────┘
┌─────────────────┴─────────────────┐
│ │
┌────▼────────┐ ┌───────▼───────┐
│ IMAP │ │ SMTP │
│ Cliente │ │ Cliente │
└─────┬───────┘ └───────┬───────┘
│ │
│ ┌──────────────┐ │
└─────────► Servidor ◄─────────┘
│ Webmin │
│ 10.10.0.101 │
└──────────────┘
```
## Componentes principales
### 1. Interfaz de Usuario (app.py:631-753)
- Panel de configuración del servidor
- Lista de correos (bandeja de entrada)
- Visor de correos
- Ventana de composición de correos
### 2. Gestión IMAP (app.py:1380-1540)
**Funciones:**
- `_connect_mail_server()`: Conecta al servidor IMAP
- `_disconnect_mail_server()`: Desconecta del servidor
- `_refresh_mail_list()`: Carga la lista de correos
- `_on_mail_select()`: Maneja la selección de correos
- `_display_mail()`: Muestra el contenido de un correo
**Protocolo:** IMAP (Puerto 143)
### 3. Gestión SMTP (app.py:1585-1620)
**Funciones:**
- `_open_compose_window()`: Abre ventana de redacción
- `_send_mail()`: Envía correos usando SMTP
**Protocolo:** SMTP (Puerto 25)
## Flujo de datos
### Lectura de correos (IMAP)
```
Usuario → Clic "Conectar"
_connect_mail_server()
imaplib.IMAP4(host, 143)
imap.login(usuario, contraseña)
imap.select('INBOX')
_refresh_mail_list()
imap.search(None, 'ALL')
imap.fetch(mail_id, 'RFC822')
email.message_from_bytes()
Mostrar en Listbox
Usuario selecciona correo
_display_mail()
Parsear contenido (texto/HTML)
Mostrar en ScrolledText
```
### Envío de correos (SMTP)
```
Usuario → Clic "Nuevo correo"
_open_compose_window()
Usuario completa campos (Para, Asunto, Mensaje)
Usuario → Clic "Enviar"
_send_mail()
MIMEMultipart()
MIMEText(body, 'plain')
smtplib.SMTP(host, 25)
server.send_message(msg)
Confirmación al usuario
```
## Protocolos de comunicación
### IMAP (Internet Message Access Protocol)
- **Puerto**: 143 (sin cifrar) / 993 (cifrado)
- **Uso**: Leer correos del servidor
- **Ventajas**:
- Los correos permanecen en el servidor
- Acceso desde múltiples dispositivos
- Sincronización de carpetas
### SMTP (Simple Mail Transfer Protocol)
- **Puerto**: 25 (sin cifrar) / 587 (TLS) / 465 (SSL)
- **Uso**: Enviar correos
- **Autenticación**: Opcional según configuración del servidor
## Configuración del servidor Webmin
### Servicios necesarios:
```
┌─────────────────────────────────────────┐
│ Webmin (http://10.10.0.101:20000) │
├─────────────────────────────────────────┤
│ Servicios de correo: │
│ • Postfix (SMTP) → Puerto 25 │
│ • Dovecot (IMAP) → Puerto 143 │
│ • Dovecot (POP3) → Puerto 110 │
└─────────────────────────────────────────┘
```
### Pasos en Webmin:
1. **Servers → Dovecot IMAP/POP3 Server**
- Habilitar servicio IMAP en puerto 143
- Configurar usuarios y contraseñas
2. **Servers → Postfix Mail Server**
- Habilitar servicio SMTP en puerto 25
- Configurar dominio y relay
3. **System → Users and Groups**
- Crear usuarios del sistema para correo
- Asignar contraseñas
## Seguridad
### Advertencias actuales:
⚠️ **La implementación actual usa conexiones sin cifrar**
### Recomendaciones:
1. Usar IMAPS (puerto 993) en lugar de IMAP (143)
2. Usar SMTPS (puerto 465/587) en lugar de SMTP (25)
3. Implementar SSL/TLS en las conexiones
4. No usar contraseñas en texto plano en el código
5. Usar autenticación del servidor SMTP
### Mejora de seguridad (código):
```python
# IMAP con SSL
import imaplib
imap = imaplib.IMAP4_SSL('10.10.0.101', 993)
# SMTP con TLS
import smtplib
smtp = smtplib.SMTP('10.10.0.101', 587)
smtp.starttls()
smtp.login(username, password)
```
## Estructura de archivos
```
Proyecto1AVApsp/
├── app.py # Aplicación principal con cliente de correo
├── CORREO_README.md # Documentación de usuario
├── test_mail_server.py # Script de prueba de conectividad
├── requirements.txt # Dependencias (smtplib/imaplib incluidos en Python)
└── README.md # Documentación general del proyecto
```
## Variables de estado
```python
# Variables del cliente de correo (en DashboardApp)
self.mail_connected = False # Estado de conexión
self.imap_connection = None # Objeto de conexión IMAP
self.current_mailbox = 'INBOX' # Bandeja actual
self.mail_list = [] # Lista de correos cargados
# Widgets de UI
self.mail_imap_host # Entry: servidor IMAP
self.mail_imap_port # Entry: puerto IMAP
self.mail_smtp_host # Entry: servidor SMTP
self.mail_smtp_port # Entry: puerto SMTP
self.mail_username # Entry: usuario
self.mail_password # Entry: contraseña
self.mail_listbox # Listbox: lista de correos
self.mail_body_text # ScrolledText: cuerpo del correo
```
## Testing
### Script de prueba de conectividad:
```bash
python3 test_mail_server.py
```
Este script verifica:
- Conexión a Webmin (puerto 20000)
- Disponibilidad de SMTP (puerto 25)
- Disponibilidad de IMAP (puerto 143)
- Disponibilidad de POP3 (puerto 110)
## Próximas mejoras
1. **Seguridad**
- [ ] Implementar SSL/TLS
- [ ] Autenticación segura
- [ ] Gestión de certificados
2. **Funcionalidad**
- [ ] Soporte para adjuntos
- [ ] Vista HTML mejorada
- [ ] Múltiples carpetas
- [ ] Búsqueda de correos
- [ ] Responder/Reenviar
3. **UI/UX**
- [ ] Indicador de correos no leídos
- [ ] Filtros y ordenamiento
- [ ] Marcadores/etiquetas
- [ ] Vista previa de adjuntos
4. **Performance**
- [ ] Carga asíncrona de correos
- [ ] Cache de correos
- [ ] Paginación

155
CORREO_README.md Normal file
View File

@ -0,0 +1,155 @@
# Cliente de Correo Electrónico - Proyecto1AVApsp
## Descripción
Se ha implementado un cliente de correo electrónico completo en la pestaña "Correos" de la aplicación. Este cliente permite conectarse a tu servidor Webmin para leer y enviar correos electrónicos.
## Características
- **Conexión IMAP**: Lee correos desde tu servidor (Puerto 143)
- **Conexión SMTP**: Envía correos nuevos (Puerto 25)
- **Interfaz tipo Outlook**: Panel dividido con lista de correos y visor
- **Redacción de correos**: Ventana dedicada para componer nuevos mensajes
## Configuración del Servidor Webmin
### Datos de conexión predeterminados:
- **Servidor IMAP**: `10.10.0.101`
- **Puerto IMAP**: `143`
- **Servidor SMTP**: `10.10.0.101`
- **Puerto SMTP**: `25`
### Puertos configurados en Webmin:
- SMTP (envío de correo): 25
- IMAP (consulta de correo): 143
- POP (descarga de correo): 110 (no usado en esta implementación)
- Interfaz web Webmin: http://10.10.0.101:20000
## Cómo usar el cliente de correo
### 1. Ejecutar la aplicación
```bash
python3 app.py
```
### 2. Ir a la pestaña "Correos"
La pestaña está ubicada en el panel central de la aplicación.
### 3. Configurar la conexión
En el panel "Configuración del servidor":
- **Servidor IMAP**: Ya está configurado como `10.10.0.101`
- **Puerto IMAP**: Ya está configurado como `143`
- **Servidor SMTP**: Ya está configurado como `10.10.0.101`
- **Puerto SMTP**: Ya está configurado como `25`
- **Usuario**: Introduce tu nombre de usuario del servidor de correo
- **Contraseña**: Introduce tu contraseña
### 4. Conectar al servidor
Haz clic en el botón **"Conectar"**. Si la conexión es exitosa:
- El estado cambiará a "Conectado" en verde
- Se cargarán automáticamente los correos de la bandeja de entrada
### 5. Leer correos
- Los correos aparecen en la lista de la izquierda
- Haz clic en un correo para ver su contenido completo
- Se muestran:
- Remitente (De)
- Asunto
- Fecha
- Cuerpo del mensaje
### 6. Actualizar la lista de correos
Haz clic en el botón **"Actualizar"** para recargar la lista de correos desde el servidor.
### 7. Enviar un nuevo correo
1. Haz clic en el botón **"Nuevo correo"**
2. Se abrirá una ventana de composición
3. Completa los campos:
- **Para**: Dirección del destinatario
- **Asunto**: Título del correo
- **Mensaje**: Contenido del correo
4. Haz clic en **"Enviar"**
### 8. Desconectar
Cuando termines, haz clic en **"Desconectar"** para cerrar la conexión con el servidor.
## Notas técnicas
### Bibliotecas utilizadas
El cliente utiliza las bibliotecas estándar de Python:
- `imaplib`: Para leer correos (protocolo IMAP)
- `smtplib`: Para enviar correos (protocolo SMTP)
- `email`: Para parsear y crear mensajes de correo
### Limitaciones actuales
1. **Seguridad**:
- La conexión IMAP es sin cifrado (puerto 143 en lugar de 993 IMAPS)
- La conexión SMTP es sin cifrado (puerto 25 en lugar de 465/587 SMTPS)
- Para producción, se recomienda usar conexiones cifradas
2. **Funcionalidades**:
- Solo se muestran los últimos 50 correos
- No hay soporte para adjuntos aún
- Solo se muestra la bandeja de entrada (INBOX)
- Los correos HTML se muestran como texto crudo
3. **Autenticación SMTP**:
- El código actual no utiliza autenticación para SMTP
- Si tu servidor Webmin requiere autenticación, necesitarás descomentar estas líneas en el código:
```python
# server.starttls()
# server.login(username, password)
```
## Solución de problemas
### Error: "No se pudo conectar al servidor"
1. Verifica que el servidor Webmin esté en ejecución
2. Comprueba que puedes hacer ping a `10.10.0.101`
3. Verifica que los puertos 143 y 25 estén abiertos:
```bash
telnet 10.10.0.101 143
telnet 10.10.0.101 25
```
### Error: "Login failed"
- Verifica que el usuario y contraseña sean correctos
- Comprueba que la cuenta de correo esté configurada en Webmin
### No se cargan los correos
- Haz clic en "Actualizar" para recargar
- Verifica la configuración de la bandeja INBOX en el servidor
- Revisa el panel de notas para ver mensajes de error
## Mejoras futuras
- [ ] Soporte para conexiones cifradas (IMAPS/SMTPS)
- [ ] Gestión de adjuntos
- [ ] Múltiples carpetas/bandejas
- [ ] Búsqueda de correos
- [ ] Marcado como leído/no leído
- [ ] Eliminación de correos
- [ ] Responder y reenviar correos
- [ ] Vista HTML mejorada
- [ ] Configuración persistente
## Contacto
Para más información sobre la configuración del servidor Webmin, consulta:
- Interfaz web Webmin: http://10.10.0.101:20000

1517
README.md

File diff suppressed because it is too large Load Diff

286
TESTING_GUIDE.md Normal file
View File

@ -0,0 +1,286 @@
# Guía de Pruebas - Cliente de Correo Electrónico
## Proyecto1AVApsp - Sesión del 16-19 de Febrero 2026
Esta guía te ayudará a probar todas las funcionalidades recién implementadas en el cliente de correo.
---
## 🔧 CORRECCIÓN APLICADA (19 Feb 2026)
**Problema**: Error `AttributeError: '_tkinter.tkapp' object has no attribute 'notes'` al iniciar la aplicación
**Causa**: La función `_load_mail_credentials()` intentaba escribir en el log antes de que el widget `notes` se hubiera creado
**Solución**: Modificada la función `_log()` (app.py:4304) para verificar si el widget existe antes de usarlo
**Estado**: ✅ **CORREGIDO** - La aplicación ahora arranca sin errores
---
## ✅ FUNCIONALIDADES IMPLEMENTADAS EN ESTA SESIÓN
### 1. **Guardado automático de credenciales**
### 2. **Envío a múltiples destinatarios**
### 3. **Guardado de correos enviados en el servidor IMAP**
### 4. **Eliminación del botón "Actualizar"**
### 5. **Corrección visual de indicadores de correos no leídos**
---
## 🧪 PLAN DE PRUEBAS
### PRUEBA 1: Guardado de Credenciales
**Objetivo**: Verificar que las credenciales se guarden y carguen automáticamente
**Pasos**:
1. Ejecuta la aplicación: `python3 app.py`
2. Ve a la pestaña "Correos"
3. Observa si los campos están precargados con tus credenciales
4. Si es la primera vez, introduce:
- Usuario: `marcos@psp.es`
- Contraseña: tu contraseña
5. Marca la casilla "💾 Recordar credenciales" (debe estar marcada por defecto)
6. Haz clic en "🔌 Conectar"
7. Verifica que aparezca el mensaje "Credenciales guardadas correctamente" en el log
8. **CIERRA completamente la aplicación**
9. Vuelve a ejecutar: `python3 app.py`
10. Ve a la pestaña "Correos"
**Resultado esperado**:
- ✅ Los campos de usuario, contraseña y servidores deben estar precargados
- ✅ El archivo `.mail_config.json` existe en el directorio del proyecto
- ✅ Puedes conectarte sin volver a escribir las credenciales
**Para probar el borrado de credenciales**:
1. Conecta al servidor
2. Desconecta
3. Desmarca "💾 Recordar credenciales"
4. Vuelve a conectar
5. Cierra la aplicación
6. Al abrir de nuevo, los campos deben estar vacíos
---
### PRUEBA 2: Múltiples Destinatarios
**Objetivo**: Verificar que se pueden enviar correos a varios destinatarios simultáneamente
**Pasos**:
1. Conecta al servidor de correo
2. Haz clic en "✉️ Nuevo correo"
3. En el campo "Para:", introduce **múltiples correos separados por comas**:
```
marcos@psp.es, destinatario2@ejemplo.com, destinatario3@ejemplo.com
```
4. También puedes usar **punto y coma**:
```
marcos@psp.es; destinatario2@ejemplo.com
```
5. Introduce un asunto: "Prueba múltiples destinatarios"
6. Escribe un mensaje: "Este es un correo de prueba"
7. Haz clic en "📤 ENVIAR CORREO"
**Resultado esperado**:
- ✅ Aparece un diálogo de confirmación mostrando los 3 destinatarios
- ✅ El mensaje dice: "¿Enviar correo a 3 destinatarios?"
- ✅ Se listan todos los correos con un • al inicio
- ✅ Al confirmar, el correo se envía correctamente
- ✅ El mensaje de éxito indica "enviado a 3 destinatarios"
**Prueba con email inválido**:
1. Intenta enviar a: `marcos@psp.es, correo-invalido, otro@ejemplo.com`
2. Haz clic en "📤 ENVIAR CORREO"
**Resultado esperado**:
- ✅ Aparece advertencia: "Los siguientes emails no son válidos: correo-invalido"
- ✅ NO se envía el correo hasta que corrijas el formato
---
### PRUEBA 3: Guardado en Carpeta "Enviados" del Servidor
**Objetivo**: Verificar que los correos enviados se guardan en el servidor IMAP y son visibles en Webmin
**Pasos**:
1. Conecta al servidor de correo en la aplicación
2. Envía un correo de prueba:
- **Para**: marcos@psp.es
- **Asunto**: "Prueba guardado en servidor"
- **Mensaje**: "Verificando que este correo se guarda en IMAP"
3. Observa el log en la parte inferior de la aplicación
4. Busca mensajes como:
```
Correo guardado en carpeta: Sent
```
5. Haz clic en el botón "📧 Enviados" en la aplicación
6. **Verifica que el correo aparece en la lista**
7. Ahora abre tu navegador y ve a: `http://10.10.0.101:20000`
8. Inicia sesión en Webmin
9. Ve a "Correo" → "Usermin" → "Read Email" o accede directamente a tu cliente de correo Webmin
10. Busca la carpeta "Sent" o "Enviados"
**Resultado esperado**:
- ✅ El correo aparece en la pestaña "📧 Enviados" de la aplicación
- ✅ El correo también aparece en Webmin en la carpeta de enviados
- ✅ Si abres el correo en Webmin, debe tener el contenido correcto
- ✅ Los adjuntos (si los había) también están presentes
**Si falla**:
- Revisa el log de la aplicación para ver qué carpeta se intentó usar
- Las carpetas probadas automáticamente son:
- `Sent`
- `INBOX.Sent`
- `Enviados`
- `INBOX.Enviados`
- `Sent Items`
- Si tu servidor usa otro nombre, aparecerá un mensaje de error en el log
---
### PRUEBA 4: Interfaz sin Botón "Actualizar"
**Objetivo**: Verificar que la interfaz se actualiza automáticamente sin necesidad del botón
**Pasos**:
1. Conecta al servidor
2. Observa la barra de herramientas (arriba de la lista de correos)
3. Verifica que solo hay **un botón**: "✉️ Nuevo correo"
4. El botón "🔄 Actualizar" ya **NO debe existir**
5. Haz clic en "📧 Enviados"
6. Observa que la lista se actualiza automáticamente
7. Haz clic en "📬 Entrada"
8. Nuevamente, la lista se actualiza sin necesidad de botón
**Resultado esperado**:
- ✅ No existe el botón "🔄 Actualizar"
- ✅ La lista se actualiza automáticamente al cambiar de carpeta
- ✅ La interfaz se ve más limpia
---
### PRUEBA 5: Indicadores Visuales de Correos No Leídos
**Objetivo**: Verificar que los correos no leídos se distinguen visualmente sin errores
**Pasos**:
1. Conecta al servidor
2. Ve a "📬 Entrada"
3. Observa la lista de correos
4. Identifica correos no leídos y leídos
**Resultado esperado**:
- ✅ **Correos NO leídos**: Tienen el emoji 🔵 al inicio y texto en **negro**
- ✅ **Correos leídos**: **NO** tienen emoji y el texto está en **gris**
- ✅ NO aparece el error: "unknown option '-font'"
- ✅ La lista se carga sin errores en el log
**Apariencia visual**:
```
🔵 [01/02/25] De: remitente@ejemplo.com | Asunto: Correo nuevo ← No leído
[31/01/25] De: otro@ejemplo.com | Asunto: Correo antiguo ← Leído (gris)
```
---
## 🔍 PRUEBAS ADICIONALES RECOMENDADAS
### Prueba de Adjuntos con Múltiples Destinatarios
1. Envía un correo a 2-3 destinatarios
2. Incluye 1-2 archivos adjuntos (imágenes, PDFs)
3. Verifica que todos los destinatarios reciben los adjuntos
### Prueba de Imágenes Pegadas (Ctrl+V)
1. Copia una imagen del portapapeles
2. En la ventana de composición, presiona Ctrl+V
3. Verifica que la imagen se muestra en la vista previa
4. Envía el correo
5. Verifica en "Enviados" que el correo tiene el adjunto
### Prueba de Longitud de Lista de Destinatarios
1. Intenta enviar a 10+ destinatarios
2. Verifica que el diálogo de confirmación muestra todos
3. Confirma que se envía correctamente
---
## 🐛 QUÉ HACER SI ENCUENTRAS ERRORES
### Error: "No se puede guardar en carpeta Sent"
**Solución**:
1. Revisa el log para ver qué carpetas se intentaron
2. Conéctate a Webmin y verifica el nombre exacto de tu carpeta de enviados
3. Si tiene un nombre diferente, avísame para ajustar el código
### Error: "Los siguientes emails no son válidos"
**Causa**: Formato incorrecto de email
**Solución**: Verifica que todos los emails tengan el formato: `usuario@dominio.ext`
### Error: "unknown option '-font'"
**Causa**: Este error ya fue corregido
**Solución**: Si aún aparece, verifica que estás usando la versión más reciente de `app.py`
### Credenciales no se cargan automáticamente
**Solución**:
1. Verifica que el archivo `.mail_config.json` existe
2. Ejecuta: `cat .mail_config.json` para ver su contenido
3. Verifica que la casilla "💾 Recordar credenciales" esté marcada al conectar
---
## 📊 REGISTRO DE PRUEBAS
Usa esta tabla para registrar tus pruebas:
| Prueba | Estado | Observaciones |
|--------|--------|---------------|
| Guardado de credenciales | ⬜ Pendiente / ✅ OK / ❌ Error | |
| Múltiples destinatarios | ⬜ Pendiente / ✅ OK / ❌ Error | |
| Guardado en servidor IMAP | ⬜ Pendiente / ✅ OK / ❌ Error | |
| Sin botón "Actualizar" | ⬜ Pendiente / ✅ OK / ❌ Error | |
| Indicadores visuales | ⬜ Pendiente / ✅ OK / ❌ Error | |
---
## 📝 NOTAS IMPORTANTES
### Seguridad de Credenciales
- Las contraseñas se guardan con codificación Base64 (NO es encriptación real)
- Cualquiera con acceso al archivo `.mail_config.json` puede decodificar la contraseña
- El archivo está excluido de Git para no subirlo accidentalmente
- Para mayor seguridad en producción, considera usar `cryptography.fernet`
### Limitaciones Conocidas
- El servidor IMAP/SMTP debe estar accesible en `10.10.0.101`
- No se usa TLS/SSL (puerto 25 y 143 son sin cifrado)
- Los correos HTML se muestran como texto plano
- No hay soporte para CC/BCC (se puede agregar si lo necesitas)
---
## ✨ PRÓXIMAS MEJORAS SUGERIDAS
Si todo funciona correctamente, estas son funcionalidades que se pueden agregar:
1. **Campos CC y BCC** para copias de correos
2. **Responder y Reenviar** correos existentes
3. **Búsqueda de correos** por remitente, asunto o contenido
4. **Firma automática** al final de cada correo
5. **Plantillas de correo** predefinidas
6. **Encriptación real** de contraseñas con Fernet
7. **Soporte TLS/SSL** para conexiones seguras
8. **Carpetas personalizadas** (Borradores, Papelera, etc.)
9. **Exportar correos** a PDF o HTML
10. **Notificaciones de escritorio** para correos nuevos
---
## 🚀 EJECUTAR PRUEBAS
Para empezar a probar, simplemente ejecuta:
```bash
cd /home/marcos/Documentos/Proyecto1AVApsp
python3 app.py
```
Y sigue las pruebas en orden del 1 al 5.
**¡Buena suerte con las pruebas!** Si encuentras algún problema, avísame con el mensaje de error del log.

Binary file not shown.

Binary file not shown.

1810
app.py

File diff suppressed because it is too large Load Diff

View File

@ -4,4 +4,5 @@ pillow>=9.0.0
# pygame optional for direct mp3 playback; we use system player as fallback
pygame>=2.1.0
requests>=2.32.0
beautifulsoup4>=4.12.0
beautifulsoup4>=4.12.0
# Email libraries are part of Python standard library (smtplib, imaplib, email)

46
test_mail_server.py Executable file
View File

@ -0,0 +1,46 @@
#!/usr/bin/env python3
"""
Script de prueba para verificar la conexión con el servidor de correo Webmin
"""
import socket
def test_connection(host, port, service_name):
"""Prueba la conexión a un puerto específico"""
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5)
result = sock.connect_ex((host, port))
sock.close()
if result == 0:
print(f"{service_name} (puerto {port}): CONECTADO")
return True
else:
print(f"{service_name} (puerto {port}): NO DISPONIBLE")
return False
except Exception as e:
print(f"{service_name} (puerto {port}): ERROR - {e}")
return False
if __name__ == '__main__':
print("Probando conexión con servidor Webmin...")
print("=" * 50)
host = '10.10.0.101'
# Probar puertos
results = []
results.append(test_connection(host, 20000, 'Webmin Web Interface'))
results.append(test_connection(host, 25, 'SMTP'))
results.append(test_connection(host, 143, 'IMAP'))
results.append(test_connection(host, 110, 'POP3'))
print("=" * 50)
if all(results[1:]): # Ignorar webmin interface para el resultado
print("✓ Todos los servicios de correo están disponibles")
else:
print("⚠ Algunos servicios de correo no están disponibles")
print("\nSugerencias:")
print("1. Verifica que el servidor Webmin esté en ejecución")
print("2. Comprueba la configuración del firewall")
print("3. Verifica que los servicios de correo estén habilitados en Webmin")

74
test_startup.py Executable file
View File

@ -0,0 +1,74 @@
#!/usr/bin/env python3
"""
Script de prueba para verificar que la aplicación arranca correctamente
sin errores relacionados con el widget notes.
"""
import sys
import subprocess
import time
def test_startup():
"""Prueba que la aplicación arranca sin errores críticos"""
print("🧪 Probando inicio de aplicación...")
print("=" * 60)
# Ejecutar la aplicación por 3 segundos y capturar salida
try:
process = subprocess.Popen(
['python3', 'app.py'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
# Esperar 3 segundos para ver si hay errores iniciales
time.sleep(3)
# Intentar terminar el proceso
process.terminate()
# Esperar a que termine y capturar salida
try:
stdout, stderr = process.communicate(timeout=2)
except subprocess.TimeoutExpired:
process.kill()
stdout, stderr = process.communicate()
print("\n📤 Salida estándar:")
print("-" * 60)
if stdout:
print(stdout)
else:
print("(Sin salida)")
print("\n⚠️ Errores/Advertencias:")
print("-" * 60)
if stderr:
# Filtrar errores críticos
lines = stderr.split('\n')
critical_errors = [line for line in lines if 'AttributeError' in line or 'Traceback' in line or 'Error' in line]
if critical_errors:
print("❌ ERRORES CRÍTICOS ENCONTRADOS:")
for line in critical_errors:
print(f" {line}")
return False
else:
print("(Solo advertencias menores, no errores críticos)")
else:
print("(Sin errores)")
print("\n" + "=" * 60)
print("✅ La aplicación arrancó correctamente")
print("✅ No se detectaron errores de AttributeError con 'notes'")
print("✅ Puedes ejecutar: python3 app.py")
return True
except Exception as e:
print(f"\n❌ Error durante la prueba: {e}")
return False
if __name__ == '__main__':
success = test_startup()
sys.exit(0 if success else 1)