2626except ImportError :
2727 Envelope = None
2828
29+ try :
30+ import jinja2
31+ jinja_env = jinja2 .Environment ()
32+ except ImportError :
33+ jinja2 = None
34+
2935
3036def hash_arbitrary (value : Any ) -> bytes :
3137 value_bytes = None
@@ -48,6 +54,7 @@ class Mail:
4854class SMTPBatchOutputBot (Bot ):
4955 # configurable parameters
5056 additional_grouping_keys : Optional [list ] = [] # refers to the event directly
57+ templating : Optional [dict [str , bool ]] = {'subject' : False , 'body' : False , 'attachment' : False }
5158 alternative_mails : Optional [str ] = None
5259 bcc : Optional [list ] = None
5360 email_from : str = ""
@@ -115,6 +122,10 @@ def set_cache(self):
115122 def init (self ):
116123 if Envelope is None :
117124 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 }
118129 self .set_cache ()
119130 self .key = f"{ self ._Bot__bot_id } :"
120131
@@ -153,7 +164,7 @@ def cli_run(self):
153164
154165 print ("Preparing mail queue..." )
155166 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 ] ]
157168
158169 print ("" )
159170 if self .limit_results :
@@ -194,7 +205,9 @@ def cli_run(self):
194205 count = 0
195206 exit_code = 0
196207 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 )
198211 if not succ :
199212 exit_code = 1
200213 else :
@@ -215,6 +228,7 @@ def cli_run(self):
215228 sys .exit (exit_code )
216229 elif i == "clear" :
217230 for mail in mails :
231+ mail = mail [0 ]
218232 self .cache .redis .delete (mail .key )
219233 print ("Queue cleared." )
220234 sys .exit (0 )
@@ -226,6 +240,7 @@ def cli_run(self):
226240 self .send_mails_to_tester (mails )
227241 else :
228242 for mail in mails :
243+ mail = mail [0 ]
229244 if mail .to == i :
230245 self .send_mails_to_tester ([mail ])
231246 break
@@ -244,7 +259,7 @@ def send_mails_to_tester(self, mails):
244259 :param mails: list
245260 """
246261 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 ] )])
248263 print (f"{ count } × mail sent to: { self .testing_to } \n " )
249264
250265 def prepare_mails (self ):
@@ -342,10 +357,10 @@ def prepare_mails(self):
342357
343358 mail = Mail (mail_record , email_to , path , count )
344359 # 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 {})
347362
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 ] = {} ):
349364 """ creates a MIME message
350365 :param mail: Mail object
351366 :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):
360375 intended_to = None
361376 email_to = mail .to
362377 email_from = self .email_from
378+
363379 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+
372402 if intended_to :
373403 subject += f" (intended for { intended_to } )"
374404 else :
0 commit comments