Skip to content
Snippets Groups Projects
Commit 257611a5 authored by Timm Fitschen's avatar Timm Fitschen Committed by Henrik tom Wörden
Browse files

F send mail

parent e4ca479b
Branches
Tags
1 merge request!22Release 0.3
...@@ -316,7 +316,8 @@ def get_shared_filename(filename): ...@@ -316,7 +316,8 @@ def get_shared_filename(filename):
return filename, filepath return filename, filepath
def send_mail(from_addr, to, subject, body, cc=None, bcc=None): def send_mail(from_addr, to, subject, body, cc=None, bcc=None,
send_mail_bin=None):
""" Send an email via the configured send_mail client. """ Send an email via the configured send_mail client.
The relevant options in the pycaosdb.ini are: The relevant options in the pycaosdb.ini are:
...@@ -324,8 +325,8 @@ def send_mail(from_addr, to, subject, body, cc=None, bcc=None): ...@@ -324,8 +325,8 @@ def send_mail(from_addr, to, subject, body, cc=None, bcc=None):
[Misc] [Misc]
sendmail = ... sendmail = ...
Parameters: Parameters
----------- ----------
from_addr : str from_addr : str
The sender's email address. The sender's email address.
to : str or list of str to : str or list of str
...@@ -338,10 +339,19 @@ def send_mail(from_addr, to, subject, body, cc=None, bcc=None): ...@@ -338,10 +339,19 @@ def send_mail(from_addr, to, subject, body, cc=None, bcc=None):
Single or list of cc-recipients. Defaults to None. Single or list of cc-recipients. Defaults to None.
bcc : str or list of str (optional) bcc : str or list of str (optional)
Single or list of bcc-recipients. Defaults to None. Single or list of bcc-recipients. Defaults to None.
send_mail_bin : str (optional)
Path of sendmail client. Defaults to config["Misc"]["sendmail"].
Raises
------
subprocess.CalledProcessError
If the sendmail client returned with a non-zero code.
caosdb.ConfigurationException
If the caosdb configuration has no `Misc.sendmail` configured while the
`send_mail_bin` parameter is None.
""" """
caosdb_config = db.configuration.get_config() # construct the mail
sendmail = caosdb_config["Misc"]["sendmail"]
mail = message.EmailMessage(policy=policy.SMTP) mail = message.EmailMessage(policy=policy.SMTP)
mail.set_content(body) mail.set_content(body)
mail["From"] = from_addr mail["From"] = from_addr
...@@ -354,6 +364,44 @@ def send_mail(from_addr, to, subject, body, cc=None, bcc=None): ...@@ -354,6 +364,44 @@ def send_mail(from_addr, to, subject, body, cc=None, bcc=None):
if bcc is not None: if bcc is not None:
mail["BCC"] = bcc if isinstance(cc, str) else ", ".join(cc) mail["BCC"] = bcc if isinstance(cc, str) else ", ".join(cc)
p = subprocess.Popen([sendmail, "-t", "-oi"], # construct the call
stdin=subprocess.PIPE) if send_mail_bin is not None:
p.communicate(mail.as_bytes()) sendmail = send_mail_bin
else:
caosdb_config = db.configuration.get_config()
if not "Misc" in caosdb_config or not "sendmail" in caosdb_config["Misc"]:
err_msg = ("No sendmail executable configured. "
"Please configure `Misc.sendmail` "
"in your pycaosdb.ini.")
raise db.ConfigurationException(err_msg)
sendmail = caosdb_config["Misc"]["sendmail"]
# construct sendmail command
# options explained (from `man sendmail`):
# -t Read message for recipients. To:, Cc:, and Bcc: lines will be
# scanned for recipient addresses. The Bcc: line will be deleted
# before transmission.
# -i Ignore dots alone on lines by themselves in incoming messages. This
# should be set if you are reading data from a file.
# -f Sets the name of the ''from'' person (i.e., the envelope sender of
# the mail). This address may also be used in the From: header if
# that header is missing during initial submission. The envelope
# sender address is used as the recipient for delivery status
# notifications and may also appear in a Return-Path: header. -f
# should only be used by ''trusted'' users (normally root, daemon,
# and network) or if the person you are trying to become is the same
# as the person you are. Otherwise, an X-Authentication-Warning
# header will be added to the message.
command = [sendmail, "-t", "-i", "-f", from_addr]
# execute and handle return code
p = subprocess.Popen(command,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = p.communicate(mail.as_bytes())
return_code = p.wait()
if return_code != 0:
raise subprocess.CalledProcessError(return_code, command,
output=stdout.decode("utf8"),
stderr=stderr.decode("utf8"))
from os.path import abspath, dirname, join, isfile, exists from os.path import abspath, dirname, join, isfile, exists
from os import listdir, remove from os import listdir, remove
import subprocess
from email import message_from_file, policy from email import message_from_file, policy
from pytest import mark from pytest import mark, raises
from caosdb import configure_connection, RecordType, get_config from caosdb import configure_connection, RecordType, get_config
from caosdb.connection.mockup import (MockUpServerConnection, MockUpResponse) from caosdb.connection.mockup import (MockUpServerConnection, MockUpResponse)
from caosadvancedtools.serverside.helper import (parse_arguments, get_data, from caosadvancedtools.serverside.helper import (parse_arguments, get_data,
...@@ -77,3 +78,9 @@ def test_send_mail(): ...@@ -77,3 +78,9 @@ def test_send_mail():
assert msg["To"] == "you@example.com" assert msg["To"] == "you@example.com"
assert msg["Subject"] == "the subject" assert msg["Subject"] == "the subject"
assert msg.get_content() == "hello!\n" assert msg.get_content() == "hello!\n"
def test_send_mail_error():
with raises(subprocess.CalledProcessError):
send_mail("me@example.com", "you@example.com", "the subject", "hello!",
send_mail_bin="/bin/cat")
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment