145 lines
4.7 KiB
Python
145 lines
4.7 KiB
Python
from sanic import Sanic
|
|
from sanic.log import logger
|
|
import ssl
|
|
from ssl import SSLContext
|
|
from email.mime.text import MIMEText
|
|
from email.mime.multipart import MIMEMultipart
|
|
from messages import ROOM_ERROR_TYPES
|
|
import smtplib
|
|
from messages import *
|
|
from config import *
|
|
from jinja2 import Environment, FileSystemLoader
|
|
from threading import Timer, Lock
|
|
|
|
def killSmptClient():
|
|
global sslLock
|
|
global sslTimer
|
|
global smptSender
|
|
logger.info(f"[SMPT] killSmptClient: Lock status: {self.updating.locked()}")
|
|
sslTimer.cancel()
|
|
sslLock.acquire()
|
|
exp = None
|
|
if(smptSender is not None):
|
|
logger.debug('[SMPT] Closing smpt client')
|
|
try:
|
|
smptSender.quit() # it calls close() inside
|
|
except Exception as e:
|
|
exp = e
|
|
smptSender = None
|
|
sslLock.release()
|
|
if(exp != None):
|
|
raise exp
|
|
|
|
async def openSmptClient():
|
|
global sslLock
|
|
global sslTimer
|
|
global sslContext
|
|
global smptSender
|
|
logger.info(f"[SMPT] openSmptClient: Lock status: {self.updating.locked()}")
|
|
sslTimer.cancel()
|
|
sslLock.acquire()
|
|
exp = None
|
|
try:
|
|
if(smptSender is None):
|
|
logger.debug('[SMPT] Opening smpt client')
|
|
client : smtplib.SMTP = smtplib.SMTP(SMTP_HOST, SMTP_PORT)
|
|
client.starttls(context=sslContext)
|
|
client.login(SMTP_USER, SMTP_PASSWORD)
|
|
smptSender = client
|
|
except Exception as e:
|
|
exp = e
|
|
sslLock.release()
|
|
sslTimer = createTimer()
|
|
sslTimer.start()
|
|
if(exp != None):
|
|
raise exp
|
|
|
|
def createTimer():
|
|
return Timer(SMPT_CLIENT_CLOSE_TIMEOUT, killSmptClient)
|
|
sslLock : Lock = Lock()
|
|
sslTimer : Timer = createTimer()
|
|
sslContext : SSLContext = ssl.create_default_context()
|
|
smptSender : smtplib.SMTP = None
|
|
|
|
async def sendEmail(message : MIMEMultipart):
|
|
message['From'] = f'{EMAIL_SENDER_NAME} <{EMAIL_SENDER_MAIL}>'
|
|
await openSmptClient()
|
|
logger.debug(f"[SMPT] Sending mail {message['From']} -> {message['to']} '{message['Subject']}'")
|
|
logger.info(f"[SMPT] sendEmail: Lock status: {self.updating.locked()}")
|
|
exp = None
|
|
sslLock.acquire()
|
|
try:
|
|
smptSender.sendmail(message['From'], message['to'], message.as_string())
|
|
except Exception as e:
|
|
exp = e
|
|
sslLock.release()
|
|
if(exp != None):
|
|
raise exp
|
|
|
|
def render_email_template(title = "", body = ""):
|
|
tpl = Environment(loader=FileSystemLoader("tpl"), autoescape=False).get_template('email/comunication.html')
|
|
return str(tpl.render(title=title, body=body))
|
|
|
|
|
|
|
|
|
|
async def send_unconfirm_message(room_order, orders):
|
|
memberMessages = []
|
|
|
|
issues_plain = ""
|
|
issues_html = "<ul>"
|
|
|
|
for err in room_order.room_errors:
|
|
errId = err[1]
|
|
order = err[0]
|
|
orderStr = ""
|
|
if order is not None:
|
|
orderStr = f"{order}: "
|
|
if errId in ROOM_ERROR_TYPES.keys():
|
|
issues_plain += f" • {orderStr}{ROOM_ERROR_TYPES[errId]}\n"
|
|
issues_html += f"<li>{orderStr}{ROOM_ERROR_TYPES[errId]}</li>"
|
|
issues_html += "</ul>"
|
|
|
|
for member in orders:
|
|
if(member.status != 'canceled'):
|
|
plain_body = EMAILS_TEXT["ROOM_UNCONFIRM_TEXT"]['plain'].format(member.name, room_order.room_name, issues_plain)
|
|
html_body = render_email_template(EMAILS_TEXT["ROOM_UNCONFIRM_TITLE"], EMAILS_TEXT["ROOM_UNCONFIRM_TEXT"]['html'].format(member.name, room_order.room_name, issues_html))
|
|
plain_text = MIMEText(plain_body, "plain")
|
|
html_text = MIMEText(html_body, "html")
|
|
message = MIMEMultipart("alternative")
|
|
message.attach(plain_text)
|
|
message.attach(html_text)
|
|
message['Subject'] = f'[{EMAIL_SENDER_NAME}] Your room cannot be confirmed'
|
|
message['To'] = f"{member.name} <{member.email}>"
|
|
memberMessages.append(message)
|
|
|
|
if len(memberMessages) == 0: return
|
|
|
|
for message in memberMessages:
|
|
await sendEmail(message)
|
|
|
|
async def send_missing_propic_message(order, missingPropic, missingFursuitPropic):
|
|
t = []
|
|
if(missingPropic): t.append("your propic")
|
|
if(missingFursuitPropic): t.append("your fursuit's badge")
|
|
missingText = " and ".join(t)
|
|
|
|
plain_body = EMAILS_TEXT["MISSING_PROPIC_TEXT"]['plain'].format(order.name, missingText)
|
|
html_body = render_email_template(EMAILS_TEXT["MISSING_PROPIC_TITLE"], EMAILS_TEXT["MISSING_PROPIC_TEXT"]['html'].format(order.name, missingText))
|
|
plain_text = MIMEText(plain_body, "plain")
|
|
html_text = MIMEText(html_body, "html")
|
|
message = MIMEMultipart("alternative")
|
|
message.attach(plain_text)
|
|
message.attach(html_text)
|
|
message['Subject'] = f"[{EMAIL_SENDER_NAME}] You haven't uploaded your badges yet!"
|
|
message['To'] = f"{order.name} <{order.email}>"
|
|
|
|
await sendEmail(message)
|
|
|
|
async def send_app_login_attempt(user, loginCode):
|
|
#TODO: Format a proper email and add it to messages.py
|
|
msg = MIMEText(f"Hello {user.name}!\n\nWe have received a request to login in the app. If you didn't do this, please ignore this email. Somebody is probably playing with you.\n\nYour login code is: {loginCode}\n\nPlease do not tell this to anybody!")
|
|
msg['Subject'] = '[Furizon] Your login code'
|
|
msg['To'] = f"{user.name} <{user.email}>"
|
|
|
|
await sendEmail(msg) |