diff --git a/main.py b/main.py index e0554d3..f4cce94 100644 --- a/main.py +++ b/main.py @@ -13,16 +13,45 @@ from email.mime.text import MIMEText import cherrypy import logging +import threading + logging.basicConfig(stream=sys.stdout, format='%(name)s - %(levelname)s - %(message)s') +def soft_return(msg): + time.sleep(0.2) + return(msg) + + class SMTPWebhookApp: """ SMTP webhook server """ + def create_new_client(self, response): + try: + mythread.client = smtplib.SMTP(host=SMTP_SERVER_HOST, + port=SMTP_SERVER_PORT) + mythread.client.starttls() + return True + except (smtplib.SMTPException, TimeoutError) as e: + soft_return("can't connect") + response = {"status": 500, # noqa:F841 + "message": "some error: {}".format(e)} + return False + + def smtp_login(self, response, msg): + try: + mythread.client.login(msg["From"], FROM_MAIL_PASSWORD) + return True + except smtplib.SMTPException as e: + soft_return(e) + response = {"status": 500, # noqa:F841 + "message": "some error: {}".format(e)} + return False + def _send_mail(self): if not cherrypy.request.headers.get('Content-Length'): @@ -49,33 +78,36 @@ class SMTPWebhookApp: body = req_body['body'] to_mail = req_body['to_mail'] - try: - client = smtplib.SMTP(host=SMTP_SERVER_HOST, port=SMTP_SERVER_PORT) - except (smtplib.SMTPConnectionError, TimeoutError) as e: - time.sleep(0.2) - logging.error("To: {}, error: {}".format(to_mail, e)) - return {"status": 400, "message": "SMTP client error: {}.".format( - e)} - msg = MIMEText(body, 'plain', 'utf-8') msg['Subject'] = Header(subject, 'utf-8') msg['From'] = FROM_MAIL msg['To'] = to_mail - try: - client.ehlo() - client.starttls() - client.ehlo() - client.login(msg["From"], FROM_MAIL_PASSWORD) - client.sendmail(msg['From'], msg['To'], msg.as_string()) - response = {"status": 200, "message": "mail sent successfully"} - logging.info("To: {}, mail sent successfully".format(to_mail)) - except smtplib.SMTPException as e: - time.sleep(0.2) - logging.error("To: {}, error: {}".format(to_mail, e)) - response = {"status": 500, "message": "some error: {}".format(e)} - finally: - client.quit() - return response + + c = 0 + response = {} + while (c < 2): + try: + mythread.client.sendmail(msg['From'], + msg['To'], msg.as_string()) + response = {"status": 200, "message": "mail sent successfully"} + except (AttributeError, ValueError, + smtplib.SMTPServerDisconnected): + if (c == 1): + soft_return("can't connect") + + if not self.create_new_client(response): + break + if not self.smtp_login(response, msg): + break + + except smtplib.SMTPException as e: + soft_return("can't send for some reason") + response = {"status": 500, + "message": "some error: {}".format(e)} + finally: + c += 1 + + return response @cherrypy.expose def send_mail(self): @@ -89,7 +121,6 @@ class SMTPWebhookApp: ROOT = SMTPWebhookApp() - SMTP_SERVER_PORT = 587 CHERRYPY_SERVER_HOST = "0.0.0.0" CHERRYPY_SERVER_PORT = 8081 @@ -109,7 +140,8 @@ if __name__ == "__main__": ENGINE = cherrypy.engine cherrypy.tree.mount(ROOT, config={}) - + mythread = threading.local() + mythread.client = None if hasattr(ENGINE, "signal_handler"): ENGINE.signal_handler.subscribe() if hasattr(ENGINE, "console_control_handler"):