Compare commits
No commits in common. "3c49356a7c6bd719fe7edd3985491de16eede8f4" and "f0dc49b62e7ccb6afb1db6bf55028c07be9c9e2d" have entirely different histories.
3c49356a7c
...
f0dc49b62e
|
|
@ -1,44 +0,0 @@
|
||||||
# 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
|
|
||||||
|
|
@ -1,246 +0,0 @@
|
||||||
# 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
155
CORREO_README.md
|
|
@ -1,155 +0,0 @@
|
||||||
# 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
|
|
||||||
286
TESTING_GUIDE.md
286
TESTING_GUIDE.md
|
|
@ -1,286 +0,0 @@
|
||||||
# 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.
|
|
@ -5,4 +5,3 @@ pillow>=9.0.0
|
||||||
pygame>=2.1.0
|
pygame>=2.1.0
|
||||||
requests>=2.32.0
|
requests>=2.32.0
|
||||||
beautifulsoup4>=4.12.0
|
beautifulsoup4>=4.12.0
|
||||||
# Email libraries are part of Python standard library (smtplib, imaplib, email)
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
#!/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")
|
|
||||||
|
|
@ -1,74 +0,0 @@
|
||||||
#!/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)
|
|
||||||
Loading…
Reference in New Issue