Coverage for services\email\email_service.py: 85.7%

28 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-08-30 20:58 +0200

1from decouple import config 

2from typing import List, Optional 

3from pathlib import Path 

4 

5from django.core.mail import EmailMultiAlternatives 

6from typing import List, Optional 

7from pathlib import Path 

8 

9class Email: 

10 """ 

11 Servicio para el envio de emails 

12 """ 

13 

14 def __init__(self): 

15 self.sender = config('EMAIL_HOST_USER') 

16 

17 def send_email(self, to: List[str] | str, subject: str, html: str, cc: Optional[List[str]] = None, bcc: Optional[List[str]] = None): 

18 """ 

19 Funcion para enviar un email a una lista de destinatarios 

20 Args: 

21 to (List[str] | str): Lista de destinatarios  

22 subject (str): Asunto del email 

23 html (str): Cuerpo del email en formato HTML 

24 cc (Optional[List[str]], optional): Lista de destinatarios en copia 

25 bcc (Optional[List[str]], optional): Lista de destinatarios en copia oculta 

26 Raises: 

27 RuntimeError: Si ocurre un error al enviar el email 

28 Returns: 

29 status (dict): Estado del envío del email 

30 """ 

31 try: 

32 to_list = to if isinstance(to, list) else [to] 

33 email = EmailMultiAlternatives( 

34 subject=subject, 

35 body=html, 

36 from_email=self.sender, 

37 to=to_list, 

38 cc=cc, 

39 bcc=bcc, 

40 ) 

41 

42 email.attach_alternative(html, "text/html") 

43 email.send() 

44 

45 return {"status": "sent"} 

46 

47 except Exception as e: 

48 raise RuntimeError(f"Error enviando email: {e}") 

49 

50 def send_verification_email(self, to: str, token: str): 

51 """Funcion para enviar un email de verificacion al usuario con un codigo de verificacion 

52 

53 Args: 

54 to (str): Email del destinatario 

55 token (str): Codigo de verificación 

56 

57 Raises: 

58 RuntimeError: Si ocurre un error al enviar el email 

59 

60 Returns: 

61 status (dict): Estado del envío del email 

62 """ 

63 # Obtener la ruta de la plantilla HTML para el email de verificacion 

64 root_dir = Path(__file__).resolve().parents[2] 

65 path = root_dir / "templates" / "verification_email.html" 

66 

67 try: 

68 with open(path, "r", encoding="utf-8") as f: 

69 html = f.read() 

70 

71 html = html.replace("{TOKEN}", token) 

72 

73 return self.send_email( 

74 to=to, 

75 subject="Verificación de BlaBlaUCM", 

76 html=html 

77 ) 

78 

79 except Exception as e: 

80 raise RuntimeError(f"Error enviando email: {e}")