Compare commits
2 commits
d75a61b4e8
...
39555d41f9
Author | SHA1 | Date | |
---|---|---|---|
|
39555d41f9 | ||
|
f393f1b522 |
4 changed files with 131 additions and 25 deletions
|
@ -8,6 +8,8 @@ disable=invalid-name,
|
||||||
too-many-nested-blocks,
|
too-many-nested-blocks,
|
||||||
too-many-instance-attributes,
|
too-many-instance-attributes,
|
||||||
too-many-lines,
|
too-many-lines,
|
||||||
|
too-many-statements,
|
||||||
|
logging-too-many-args,
|
||||||
duplicate-code,
|
duplicate-code,
|
||||||
|
|
||||||
[FORMAT]
|
[FORMAT]
|
||||||
|
|
|
@ -177,7 +177,7 @@ class EmailClient(
|
||||||
|
|
||||||
def forge_message(
|
def forge_message(
|
||||||
self,
|
self,
|
||||||
rcpt_to,
|
recipients,
|
||||||
subject=None,
|
subject=None,
|
||||||
html_body=None,
|
html_body=None,
|
||||||
text_body=None, # pylint: disable=too-many-arguments,too-many-locals
|
text_body=None, # pylint: disable=too-many-arguments,too-many-locals
|
||||||
|
@ -187,13 +187,14 @@ class EmailClient(
|
||||||
sender_email=None,
|
sender_email=None,
|
||||||
encoding=None,
|
encoding=None,
|
||||||
template=None,
|
template=None,
|
||||||
|
cc=None,
|
||||||
**template_vars,
|
**template_vars,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Forge a message
|
Forge a message
|
||||||
|
|
||||||
:param rcpt_to: The recipient of the email. Could be a tuple(name, email) or
|
:param recipients: The recipient(s) of the email. List of tuple(name, email) or
|
||||||
just the email of the recipient.
|
just the email of the recipients.
|
||||||
:param subject: The subject of the email.
|
:param subject: The subject of the email.
|
||||||
:param html_body: The HTML body of the email
|
:param html_body: The HTML body of the email
|
||||||
:param text_body: The plain text body of the email
|
:param text_body: The plain text body of the email
|
||||||
|
@ -203,11 +204,29 @@ class EmailClient(
|
||||||
:param sender_email: Custom sender email (default: as defined on initialization)
|
:param sender_email: Custom sender email (default: as defined on initialization)
|
||||||
:param encoding: Email content encoding (default: as defined on initialization)
|
:param encoding: Email content encoding (default: as defined on initialization)
|
||||||
:param template: The name of a template to use to forge this email
|
:param template: The name of a template to use to forge this email
|
||||||
|
:param cc: Optional list of CC recipient addresses.
|
||||||
|
List of tuple(name, email) or just the email of the recipients.
|
||||||
|
|
||||||
All other parameters will be consider as template variables.
|
All other parameters will be consider as template variables.
|
||||||
"""
|
"""
|
||||||
|
recipients = [recipients] if not isinstance(recipients, list) else recipients
|
||||||
msg = MIMEMultipart("alternative")
|
msg = MIMEMultipart("alternative")
|
||||||
msg["To"] = email.utils.formataddr(rcpt_to) if isinstance(rcpt_to, tuple) else rcpt_to
|
msg["To"] = ", ".join(
|
||||||
|
[
|
||||||
|
email.utils.formataddr(recipient) if isinstance(recipient, tuple) else recipient
|
||||||
|
for recipient in recipients
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
if cc:
|
||||||
|
cc = [cc] if not isinstance(cc, list) else cc
|
||||||
|
msg["Cc"] = ", ".join(
|
||||||
|
[
|
||||||
|
email.utils.formataddr(recipient) if isinstance(recipient, tuple) else recipient
|
||||||
|
for recipient in cc
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
msg["From"] = email.utils.formataddr(
|
msg["From"] = email.utils.formataddr(
|
||||||
(
|
(
|
||||||
sender_name or self._get_option("sender_name"),
|
sender_name or self._get_option("sender_name"),
|
||||||
|
@ -280,36 +299,64 @@ class EmailClient(
|
||||||
msg.attach(part)
|
msg.attach(part)
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
def send(self, rcpt_to, msg=None, subject=None, just_try=False, **forge_args):
|
def send(
|
||||||
|
self, recipients, msg=None, subject=None, just_try=False, cc=None, bcc=None, **forge_args
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Send an email
|
Send an email
|
||||||
|
|
||||||
:param rcpt_to: The recipient of the email. Could be a tuple(name, email)
|
:param recipients: The recipient(s) of the email. List of tuple(name, email) or
|
||||||
or just the email of the recipient.
|
just the email of the recipients.
|
||||||
:param msg: The message of this email (as MIMEBase or derivated classes)
|
:param msg: The message of this email (as MIMEBase or derivated classes)
|
||||||
:param subject: The subject of the email (only if the message is not provided
|
:param subject: The subject of the email (only if the message is not provided
|
||||||
using msg parameter)
|
using msg parameter)
|
||||||
:param just_try: Enable just try mode (do not really send email, default: as defined on
|
:param just_try: Enable just try mode (do not really send email, default: as defined on
|
||||||
initialization)
|
initialization)
|
||||||
|
:param cc: Optional list of CC recipient addresses. List of tuple(name, email) or
|
||||||
|
just the email of the recipients.
|
||||||
|
:param bcc: Optional list of BCC recipient addresses. List of tuple(name, email) or
|
||||||
|
just the email of the recipients.
|
||||||
|
|
||||||
All other parameters will be consider as parameters to forge the message
|
All other parameters will be consider as parameters to forge the message
|
||||||
(only if the message is not provided using msg parameter).
|
(only if the message is not provided using msg parameter).
|
||||||
"""
|
"""
|
||||||
msg = msg if msg else self.forge_message(rcpt_to, subject, **forge_args)
|
recipients = [recipients] if not isinstance(recipients, list) else recipients
|
||||||
|
msg = msg if msg else self.forge_message(recipients, subject, cc=cc, **forge_args)
|
||||||
|
catch_addr = self._get_option("catch_all_addr")
|
||||||
|
if catch_addr:
|
||||||
|
log.debug(
|
||||||
|
"Catch email originaly send to %s (CC:%s, BCC:%s) to %s",
|
||||||
|
", ".join(recipients),
|
||||||
|
", ".join(cc) if isinstance(cc, list) else cc,
|
||||||
|
", ".join(bcc) if isinstance(cc, list) else bcc,
|
||||||
|
catch_addr,
|
||||||
|
cc,
|
||||||
|
)
|
||||||
|
recipients = catch_addr if isinstance(catch_addr, list) else list(catch_addr)
|
||||||
|
else:
|
||||||
|
if cc:
|
||||||
|
recipients.extend(
|
||||||
|
[
|
||||||
|
recipient[1] if isinstance(recipient, tuple) else recipient
|
||||||
|
for recipient in (cc if isinstance(cc, list) else [cc])
|
||||||
|
]
|
||||||
|
)
|
||||||
|
if bcc:
|
||||||
|
recipients.extend(
|
||||||
|
[
|
||||||
|
recipient[1] if isinstance(recipient, tuple) else recipient
|
||||||
|
for recipient in (bcc if isinstance(bcc, list) else [bcc])
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
if just_try or self._get_option("just_try"):
|
if just_try or self._get_option("just_try"):
|
||||||
log.debug(
|
log.debug(
|
||||||
'Just-try mode: do not really send this email to %s (subject="%s")',
|
'Just-try mode: do not really send this email to %s (subject="%s")',
|
||||||
rcpt_to,
|
", ".join(recipients),
|
||||||
subject or msg.get("subject", "No subject"),
|
subject or msg.get("subject", "No subject"),
|
||||||
)
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
catch_addr = self._get_option("catch_all_addr")
|
|
||||||
if catch_addr:
|
|
||||||
log.debug("Catch email originaly send to %s to %s", rcpt_to, catch_addr)
|
|
||||||
rcpt_to = catch_addr
|
|
||||||
|
|
||||||
smtp_host = self._get_option("smtp_host")
|
smtp_host = self._get_option("smtp_host")
|
||||||
smtp_port = self._get_option("smtp_port")
|
smtp_port = self._get_option("smtp_port")
|
||||||
try:
|
try:
|
||||||
|
@ -347,15 +394,18 @@ class EmailClient(
|
||||||
|
|
||||||
error = False
|
error = False
|
||||||
try:
|
try:
|
||||||
log.info("Sending email to %s", rcpt_to)
|
log.info("Sending email to %s", ", ".join(recipients))
|
||||||
server.sendmail(
|
server.sendmail(
|
||||||
self._get_option("sender_email"),
|
self._get_option("sender_email"),
|
||||||
[rcpt_to[1] if isinstance(rcpt_to, tuple) else rcpt_to],
|
[
|
||||||
|
recipient[1] if isinstance(recipient, tuple) else recipient
|
||||||
|
for recipient in recipients
|
||||||
|
],
|
||||||
msg.as_string(),
|
msg.as_string(),
|
||||||
)
|
)
|
||||||
except smtplib.SMTPException:
|
except smtplib.SMTPException:
|
||||||
error = True
|
error = True
|
||||||
log.error("Error sending email to %s", rcpt_to, exc_info=True)
|
log.error("Error sending email to %s", ", ".join(recipients), exc_info=True)
|
||||||
finally:
|
finally:
|
||||||
server.quit()
|
server.quit()
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,8 @@ def main(argv=None): # pylint: disable=too-many-locals,too-many-statements
|
||||||
action="store",
|
action="store",
|
||||||
type=str,
|
type=str,
|
||||||
dest="test_to",
|
dest="test_to",
|
||||||
help="Test email recipient",
|
help="Test email recipient(s)",
|
||||||
|
nargs="+",
|
||||||
)
|
)
|
||||||
|
|
||||||
test_opts.add_argument(
|
test_opts.add_argument(
|
||||||
|
@ -50,10 +51,28 @@ def main(argv=None): # pylint: disable=too-many-locals,too-many-statements
|
||||||
help="Test mako templating",
|
help="Test mako templating",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
test_opts.add_argument(
|
||||||
|
"--cc",
|
||||||
|
action="store",
|
||||||
|
type=str,
|
||||||
|
dest="test_cc",
|
||||||
|
help="Test CC email recipient(s)",
|
||||||
|
nargs="+",
|
||||||
|
)
|
||||||
|
|
||||||
|
test_opts.add_argument(
|
||||||
|
"--bcc",
|
||||||
|
action="store",
|
||||||
|
type=str,
|
||||||
|
dest="test_bcc",
|
||||||
|
help="Test BCC email recipient(s)",
|
||||||
|
nargs="+",
|
||||||
|
)
|
||||||
|
|
||||||
options = parser.parse_args()
|
options = parser.parse_args()
|
||||||
|
|
||||||
if not options.test_to:
|
if not options.test_to:
|
||||||
parser.error("You must specify test email recipient using -t/--to parameter")
|
parser.error("You must specify at least one test email recipient using -t/--to parameter")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Initialize logs
|
# Initialize logs
|
||||||
|
@ -64,8 +83,19 @@ def main(argv=None): # pylint: disable=too-many-locals,too-many-statements
|
||||||
|
|
||||||
email_client = init_email_client(options)
|
email_client = init_email_client(options)
|
||||||
|
|
||||||
log.info("Send a test email to %s", options.test_to)
|
log.info(
|
||||||
if email_client.send(options.test_to, template="test", sent_date=datetime.datetime.now()):
|
"Send a test email to %s (CC: %s / BCC: %s)",
|
||||||
|
", ".join(options.test_to),
|
||||||
|
", ".join(options.test_cc) if options.test_cc else None,
|
||||||
|
", ".join(options.test_bcc) if options.test_bcc else None,
|
||||||
|
)
|
||||||
|
if email_client.send(
|
||||||
|
options.test_to,
|
||||||
|
cc=options.test_cc,
|
||||||
|
bcc=options.test_bcc,
|
||||||
|
template="test",
|
||||||
|
sent_date=datetime.datetime.now(),
|
||||||
|
):
|
||||||
log.info("Test email sent")
|
log.info("Test email sent")
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
log.error("Fail to send test email")
|
log.error("Fail to send test email")
|
||||||
|
|
|
@ -35,7 +35,8 @@ def main(argv=None): # pylint: disable=too-many-locals,too-many-statements
|
||||||
action="store",
|
action="store",
|
||||||
type=str,
|
type=str,
|
||||||
dest="test_to",
|
dest="test_to",
|
||||||
help="Test email recipient",
|
help="Test email recipient(s)",
|
||||||
|
nargs="+",
|
||||||
)
|
)
|
||||||
|
|
||||||
test_opts.add_argument(
|
test_opts.add_argument(
|
||||||
|
@ -55,14 +56,37 @@ def main(argv=None): # pylint: disable=too-many-locals,too-many-statements
|
||||||
help="Test mako templating",
|
help="Test mako templating",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
test_opts.add_argument(
|
||||||
|
"--cc",
|
||||||
|
action="store",
|
||||||
|
type=str,
|
||||||
|
dest="test_cc",
|
||||||
|
help="Test CC email recipient(s)",
|
||||||
|
nargs="+",
|
||||||
|
)
|
||||||
|
|
||||||
|
test_opts.add_argument(
|
||||||
|
"--bcc",
|
||||||
|
action="store",
|
||||||
|
type=str,
|
||||||
|
dest="test_bcc",
|
||||||
|
help="Test BCC email recipient(s)",
|
||||||
|
nargs="+",
|
||||||
|
)
|
||||||
|
|
||||||
options = config.parse_arguments_options()
|
options = config.parse_arguments_options()
|
||||||
|
|
||||||
if not options.test_to:
|
if not options.test_to:
|
||||||
parser.error("You must specify test email recipient using -t/--to parameter")
|
parser.error("You must specify at least one test email recipient using -t/--to parameter")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
logging.info("Send a test email to %s", options.test_to)
|
if email_client.send(
|
||||||
if email_client.send(options.test_to, template="test", sent_date=datetime.datetime.now()):
|
options.test_to,
|
||||||
|
cc=options.test_cc,
|
||||||
|
bcc=options.test_bcc,
|
||||||
|
template="test",
|
||||||
|
sent_date=datetime.datetime.now(),
|
||||||
|
):
|
||||||
logging.info("Test email sent")
|
logging.info("Test email sent")
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
logging.error("Fail to send test email")
|
logging.error("Fail to send test email")
|
||||||
|
|
Loading…
Reference in a new issue