import poplib import email import pymongo from email.utils import parsedate_to_datetime import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.base import MIMEBase from email import encoders from datetime import datetime import re import os class CorreoModelo: POP3_SERVER = "s1.ieslamar.org" #192.168.120.103 POP3_PORT = 110 #110 SMTP_SERVER = "s1.ieslamar.org" #s1.ieslamar.org SMTP_PORT = 25 #25 EMAIL_USER = "kevin@fp.ieslamar.org" EMAIL_PASS = "1234" MONGO_CLIENT = "mongodb://localhost:27017/" DB_NAME = "correo_db" COLLECTION_NAME = "correoc" #*s def __init__(self): self.client = pymongo.MongoClient(self.MONGO_CLIENT) self.db = self.client[self.DB_NAME] self.collection = self.db[self.COLLECTION_NAME] def correo_existe(self, remitente, asunto, fecha): return self.collection.find_one({"remitente": remitente, "asunto": asunto, "fecha": fecha}) is not None def guardar_correo(self, remitente, asunto, fecha, cuerpo): if self.correo_existe(remitente, asunto, fecha): return correo = {"remitente": remitente, "asunto": asunto, "fecha": fecha, "cuerpo": cuerpo} self.collection.insert_one(correo) def descargar_correos(self): try: mail = poplib.POP3(self.POP3_SERVER, self.POP3_PORT) mail.user(self.EMAIL_USER) mail.pass_(self.EMAIL_PASS) num_mensajes = len(mail.list()[1]) mensajes_nuevos = False for i in range(1, num_mensajes + 1): response, lines, octets = mail.retr(i) raw_email = b"\n".join(lines) msg = email.message_from_bytes(raw_email) remitente = msg["From"] asunto = msg["Subject"] fecha = msg["Date"] if fecha: try: fecha = parsedate_to_datetime(fecha).strftime("%Y-%m-%d %H:%M:%S") except Exception: pass cuerpo = "" if msg.is_multipart(): for part in msg.walk(): if part.get_content_type() == "text/plain": cuerpo = part.get_payload(decode=True).decode(errors="ignore") break else: cuerpo = msg.get_payload(decode=True).decode(errors="ignore") if not self.correo_existe(remitente, asunto, fecha): self.guardar_correo(remitente, asunto, fecha, cuerpo.strip()) mensajes_nuevos = True mail.quit() return True except Exception as e: return str(e) def obtener_correos(self): return list(self.collection.find()) def hay_mensajes_nuevos(self): try: mail = poplib.POP3(self.POP3_SERVER, self.POP3_PORT) mail.user(self.EMAIL_USER) mail.pass_(self.EMAIL_PASS) num_mensajes = len(mail.list()[1]) for i in range(1, num_mensajes + 1): response, lines, octets = mail.retr(i) raw_email = b"\n".join(lines) msg = email.message_from_bytes(raw_email) remitente = msg["From"] asunto = msg["Subject"] fecha = msg["Date"] if fecha: try: fecha = parsedate_to_datetime(fecha).strftime("%Y-%m-%d %H:%M:%S") except Exception: pass if not self.correo_existe(remitente, asunto, fecha): mail.quit() return True mail.quit() return False except Exception as e: return False @staticmethod def enviar_correo(destinatario, asunto, mensaje, archivos_adjuntos=[]): try: if not CorreoModelo.validar_correo(destinatario): return False, "Dirección de correo inválida" fecha_envio = datetime.now().strftime("%Y-%m-%d %H:%M:%S") msg = MIMEMultipart() msg["From"] = CorreoModelo.EMAIL_USER msg["To"] = destinatario msg["Subject"] = asunto msg["Date"] = fecha_envio mensaje_completo = f"{mensaje}" msg.attach(MIMEText(mensaje_completo, "plain")) # Agregar archivos adjuntos for archivo in archivos_adjuntos: if os.path.exists(archivo): with open(archivo, "rb") as adjunto: part = MIMEBase("application", "octet-stream") part.set_payload(adjunto.read()) encoders.encode_base64(part) part.add_header( "Content-Disposition", f"attachment; filename={os.path.basename(archivo)}", ) msg.attach(part) server = smtplib.SMTP(CorreoModelo.SMTP_SERVER, CorreoModelo.SMTP_PORT) server.ehlo() server.login(CorreoModelo.EMAIL_USER, CorreoModelo.EMAIL_PASS) server.sendmail(CorreoModelo.EMAIL_USER, destinatario, msg.as_string()) server.quit() return True, f"Correo enviado a {destinatario} el {fecha_envio}" except Exception as e: return False, f"Error enviando correo: {e}" @staticmethod def validar_correo(destinatario): patron = r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$" return re.match(patron, destinatario) is not None