import json import logging import smtplib import os from email.message import EmailMessage from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from pyexecplugins.pyexecplugins import PyExecPlugin class Plugin(PyExecPlugin): name = "Mail" taskdef = { "name" : "pymail", "description" : "Send mail with pymail worker", "inputKeys" : ["from", "to", "bcc", "cc", "text", "html", "extra_vars"], "outputKeys" : [], "ownerEmail" : "m.lettere@gmail.com" } def getProtocol(self, config): if config is not None and config["pymail"] is not None: return (config["pymail"].get("protocol") or "plain") else: return "plain" def getConfig(self, config, key): if config is not None and config["pymail"] is not None: return (config["pymail"].get(key) or self.defaults[key]) else: return self.defaults[key] def getDefaults(self, protocol): defaults = {"server" : "localhost", "user" : None, "password" : None} if protocol == "ssl": defaults["port"] = 465 elif protocol == "starttls": defaults["port"] = 587 else: defaults["port"] = 25 return defaults def __init__(self, data, config): super().__init__(data) if config is not None: self.protocol = self.getProtocol(config) self.defaults = self.getDefaults(self.protocol) self.server = self.getConfig(config, "server") self.port = self.getConfig(config, "port") self.user = os.environ.get('smtp_user', self.getConfig(config, "user")) self.password = os.environ.get('smtp_pass', self.getConfig(config, "password")) logging.getLogger("pyexec").debug("Parsed config" + self.password) self.frm = data.get("from") or "noreply@noreply.org" self.to = data.get("to") or [] self.to = [self.to] if isinstance(self.to, str) else self.to self.bcc = data.get("bcc") or [] self.bcc = [self.bcc] if isinstance(self.bcc, str) else self.bcc self.cc = data.get("cc") or [] self.cc = [self.cc] if isinstance(self.cc, str) else self.cc self.subject = (data.get("subject") or "No subject").format_map(data.get("extra_vars") or {}) self.extra_vars = data.get("extra_vars") or {} self.text = data.get("text") if self.text is not None: self.text = self.text.format_map(data.get("extra_vars") or {}) self.html = data.get("html") if self.html is not None: self.html = self.html.format_map(data.get("extra_vars") or {}) def sendMail(self): logging.getLogger("pyexec").info("Sending mail from %s to %s subj %s ", self.frm, self.to, self.subject) m = self.buildMessage() if self.protocol == "ssl": self.sendSSLMail(m) elif self.protocol == "starttls": self.sendSTARTTLSMail(m) else: self.sendPlainMail(m) logging.getLogger("pyexec").debug("Mail sent.") def buildMessage(self): if self.html is not None: m = MIMEMultipart("alternative") if self.text is not None: m.attach(MIMEText(self.text, "plain")) else: m.preamble = "You won't be reading this email without multipart/html support" m.attach(MIMEText(self.html, "html")) else: m = EmailMessage() m.set_content(self.text) m["Subject"] = self.subject m["From"] = self.frm m["To"] = ', '.join(self.to) m["Cc"] = ', '.join(self.cc) m["Bcc"] = ', '.join(self.bcc) logging.getLogger("pyexec").debug("Message built") return m def sendPlainMail(self, m): logging.getLogger("pyexec").debug("Sending mail %s - %s - %s",self.server, self.port, self.user) s = smtplib.SMTP(host=self.server, port=self.port) s.send_message(m) s.quit() def sendSSLMail(self): raise Exception("Not yet supported") def sendSTARTTLSMail(self, m): logging.getLogger("pyexec").debug("Sending STARTTLS mail %s - %s - %s",self.server, self.port, self.user) s = smtplib.SMTP(host=self.server, port=self.port) s.starttls() s.login(self.user, self.password) s.send_message(m) s.quit() def execute(self): return self.sendMail()