26
26
except ImportError :
27
27
Envelope = None
28
28
29
+ try :
30
+ import jinja2
31
+ jinja_env = jinja2 .Environment ()
32
+ except ImportError :
33
+ jinja2 = None
34
+
29
35
30
36
def hash_arbitrary (value : Any ) -> bytes :
31
37
value_bytes = None
@@ -48,6 +54,7 @@ class Mail:
48
54
class SMTPBatchOutputBot (Bot ):
49
55
# configurable parameters
50
56
additional_grouping_keys : Optional [list ] = [] # refers to the event directly
57
+ templating : Optional [dict [str , bool ]] = {'subject' : False , 'body' : False , 'attachment' : False }
51
58
alternative_mails : Optional [str ] = None
52
59
bcc : Optional [list ] = None
53
60
email_from : str = ""
@@ -115,6 +122,10 @@ def set_cache(self):
115
122
def init (self ):
116
123
if Envelope is None :
117
124
raise MissingDependencyError ('envelope' , '>=2.0.0' )
125
+ if jinja2 is None :
126
+ self .logger .warning ("No jinja2 installed. Thus, the templating is deactivated." )
127
+ if self .additional_grouping_keys and len (self .additional_grouping_keys ) > 0 :
128
+ self .additional_grouping_keys_trans = {self .fieldnames_translation .get (k , k ) for k in self .additional_grouping_keys }
118
129
self .set_cache ()
119
130
self .key = f"{ self ._Bot__bot_id } :"
120
131
@@ -153,7 +164,7 @@ def cli_run(self):
153
164
154
165
print ("Preparing mail queue..." )
155
166
self .timeout = []
156
- mails = [m for m in self .prepare_mails () if m ]
167
+ mails = [m for m in self .prepare_mails () if m [ 0 ] ]
157
168
158
169
print ("" )
159
170
if self .limit_results :
@@ -194,7 +205,9 @@ def cli_run(self):
194
205
count = 0
195
206
exit_code = 0
196
207
for mail in mails :
197
- succ = self .build_mail (mail , send = True )
208
+ template_data = mail [1 ]
209
+ mail = mail [0 ]
210
+ succ = self .build_mail (mail , send = True , template_data = template_data )
198
211
if not succ :
199
212
exit_code = 1
200
213
else :
@@ -215,6 +228,7 @@ def cli_run(self):
215
228
sys .exit (exit_code )
216
229
elif i == "clear" :
217
230
for mail in mails :
231
+ mail = mail [0 ]
218
232
self .cache .redis .delete (mail .key )
219
233
print ("Queue cleared." )
220
234
sys .exit (0 )
@@ -226,6 +240,7 @@ def cli_run(self):
226
240
self .send_mails_to_tester (mails )
227
241
else :
228
242
for mail in mails :
243
+ mail = mail [0 ]
229
244
if mail .to == i :
230
245
self .send_mails_to_tester ([mail ])
231
246
break
@@ -244,7 +259,7 @@ def send_mails_to_tester(self, mails):
244
259
:param mails: list
245
260
"""
246
261
self .set_tester (False )
247
- count = sum ([1 for mail in mails if self .build_mail (mail , send = True , override_to = self .testing_to )])
262
+ count = sum ([1 for mail in mails if self .build_mail (mail [ 0 ] , send = True , override_to = self .testing_to , template_data = mail [ 1 ] )])
248
263
print (f"{ count } × mail sent to: { self .testing_to } \n " )
249
264
250
265
def prepare_mails (self ):
@@ -342,10 +357,10 @@ def prepare_mails(self):
342
357
343
358
mail = Mail (mail_record , email_to , path , count )
344
359
# build_mail only used to output metadata of the mail -> send=False -> return None
345
- self .build_mail (mail , send = False )
346
- yield mail
360
+ self .build_mail (mail , send = False , template_data = template_data )
361
+ yield ( mail , template_data if jinja2 and self . templating and any ( self . templating . values ()) else {})
347
362
348
- def build_mail (self , mail , send = False , override_to = None ):
363
+ def build_mail (self , mail , send = False , override_to = None , template_data : dict [ str , Any ] = {} ):
349
364
""" creates a MIME message
350
365
:param mail: Mail object
351
366
:param send: True to send through SMTP, False for just printing the information
@@ -360,15 +375,30 @@ def build_mail(self, mail, send=False, override_to=None):
360
375
intended_to = None
361
376
email_to = mail .to
362
377
email_from = self .email_from
378
+
363
379
text = self .mail_contents
364
- try :
365
- subject = time .strftime (self .subject )
366
- except ValueError :
367
- subject = self .subject
368
- try :
369
- attachment_name = time .strftime (self .attachment_name )
370
- except ValueError :
371
- attachment_name = self .attachment_name
380
+ if jinja2 and self .templating and self .templating .get ('body' , False ):
381
+ jinja_tmpl = jinja_env .from_string (text )
382
+ text = jinja_tmpl .render (current_time = datetime .datetime .now (), ** template_data )
383
+
384
+ if jinja2 and self .templating and self .templating .get ('subject' , False ):
385
+ jinja_tmpl = jinja_env .from_string (self .subject )
386
+ subject = jinja_tmpl .render (current_time = datetime .datetime .now (), ** template_data )
387
+ else :
388
+ try :
389
+ subject = time .strftime (self .subject )
390
+ except ValueError :
391
+ subject = self .subject
392
+
393
+ if jinja2 and self .templating and self .templating .get ('attachment' , False ):
394
+ jinja_tmpl = jinja_env .from_string (self .attachment_name )
395
+ attachment_name = jinja_tmpl .render (current_time = datetime .datetime .now (), ** template_data )
396
+ else :
397
+ try :
398
+ attachment_name = time .strftime (self .attachment_name )
399
+ except ValueError :
400
+ attachment_name = self .attachment_name
401
+
372
402
if intended_to :
373
403
subject += f" (intended for { intended_to } )"
374
404
else :
0 commit comments