1
1
from dataclasses import dataclass
2
2
from email .mime .multipart import MIMEMultipart
3
3
from email .mime .text import MIMEText
4
+ from types import TracebackType
5
+ from typing import Any , Self
4
6
5
7
import aiosmtplib
6
8
7
9
from src .infrastructure .config import settings
8
10
9
11
12
+ class TemplateSyntaxError (SyntaxError ):
13
+ """Syntax problem in HTML template"""
14
+
15
+
16
+ class HTMLPage (str ):
17
+ """HTML email template type"""
18
+
19
+
10
20
@dataclass
11
21
class SMTPSessionMixin :
22
+ """
23
+ SMTPSessionMixin is a mixin class for email interface implementation
24
+ that should be used via an asynchronous
25
+ """
26
+
12
27
@staticmethod
13
- async def send_email (message : str , recipient : str , subject : str ) -> None :
28
+ async def send_email (message : HTMLPage , recipient : str , subject : str ) -> None :
14
29
sender = settings .email_address
15
30
password = settings .email_password
16
31
@@ -30,3 +45,55 @@ async def send_email(message: str, recipient: str, subject: str) -> None:
30
45
msg .attach (MIMEText (body , "plain" , "utf-8" ))
31
46
32
47
await server .sendmail (sender , recipient , msg .as_string ())
48
+
49
+
50
+ class Templater :
51
+ params : dict [str , Any ]
52
+
53
+ def replace (self , string_part : str ) -> str :
54
+ """
55
+ Auxiliary method for replacing parameter's placeholder with
56
+ parameter's value
57
+
58
+ :param string_part: part of a page after "{{"
59
+ :return str: same part, but parameter's value is filled
60
+ and ""{{"" & "}}" are removed
61
+ :raise IndexError: when brackets are used incorrectly
62
+ """
63
+
64
+ part : list [str ] = string_part .split ('}}' )
65
+ param : str = part [0 ]
66
+ right : str = part [1 ]
67
+ return f"{ self .params .get (param , '' )} { right } "
68
+
69
+ async def parse (self , html_page : HTMLPage , ** params : dict [str , Any ]) -> HTMLPage :
70
+ """
71
+ Main method that fills parameters' values into template page
72
+
73
+ :param html_page: text of an HTML template
74
+ :param params: parameters to fill
75
+ :return HTMLPage: ready-to-render HTML page with filled params
76
+ """
77
+
78
+ self .params : dict [str , Any ] = params
79
+
80
+ page : list [str ] = html_page .split ("{{" )
81
+ return HTMLPage (str ().join (list (map (self .replace , page ))))
82
+
83
+ async def __aenter__ (self ) -> Self :
84
+ return self
85
+
86
+ async def __aexit__ (
87
+ self ,
88
+ exc_type : type [Exception ] | None ,
89
+ exc_val : Exception | None ,
90
+ exc_tb : TracebackType | None ,
91
+ ) -> None :
92
+ """
93
+ :param exc_type: exception class
94
+ :param exc_val: exception instance
95
+ :param exc_tb: full traceback
96
+ :raise TemplateSyntaxError: when brackets are used incorrectly
97
+ """
98
+ if exc_type == IndexError :
99
+ raise TemplateSyntaxError ("Brackets are used incorrectly" )
0 commit comments