implement mailer with task queue
This commit is contained in:
33
atst/app.py
33
atst/app.py
@@ -22,7 +22,8 @@ from atst.domain.authz import Authorization
|
||||
from atst.models.permissions import Permissions
|
||||
from atst.eda_client import MockEDAClient
|
||||
from atst.uploader import Uploader
|
||||
from atst.utils.mailer import make_mailer
|
||||
from atst.utils.mailer import Mailer, RedisMailer
|
||||
from atst.queue import queue
|
||||
|
||||
|
||||
ENV = os.getenv("FLASK_ENV", "dev")
|
||||
@@ -37,11 +38,11 @@ def make_app(config):
|
||||
template_folder=parent_dir.child("templates").absolute(),
|
||||
static_folder=parent_dir.child("static").absolute(),
|
||||
)
|
||||
redis = make_redis(config)
|
||||
make_redis(app, config)
|
||||
csrf = CSRFProtect()
|
||||
|
||||
app.config.update(config)
|
||||
app.config.update({"SESSION_REDIS": redis})
|
||||
app.config.update({"SESSION_REDIS": app.redis})
|
||||
|
||||
make_flask_callbacks(app)
|
||||
make_crl_validator(app)
|
||||
@@ -49,6 +50,7 @@ def make_app(config):
|
||||
make_eda_client(app)
|
||||
make_upload_storage(app)
|
||||
make_mailer(app)
|
||||
queue.init_app(app)
|
||||
|
||||
db.init_app(app)
|
||||
csrf.init_app(app)
|
||||
@@ -95,6 +97,7 @@ def map_config(config):
|
||||
"PERMANENT_SESSION_LIFETIME": config.getint(
|
||||
"default", "PERMANENT_SESSION_LIFETIME"
|
||||
),
|
||||
"RQ_REDIS_URL": config["default"]["REDIS_URI"],
|
||||
}
|
||||
|
||||
|
||||
@@ -143,8 +146,9 @@ def make_config():
|
||||
return map_config(config)
|
||||
|
||||
|
||||
def make_redis(config):
|
||||
return redis.Redis.from_url(config["REDIS_URI"])
|
||||
def make_redis(app, config):
|
||||
r = redis.Redis.from_url(config["REDIS_URI"])
|
||||
app.redis = r
|
||||
|
||||
|
||||
def make_crl_validator(app):
|
||||
@@ -166,3 +170,22 @@ def make_upload_storage(app):
|
||||
secret=app.config.get("STORAGE_SECRET"),
|
||||
)
|
||||
app.uploader = uploader
|
||||
|
||||
|
||||
def _map_config(config):
|
||||
return {
|
||||
"server": config.get("MAIL_SERVER"),
|
||||
"port": config.get("MAIL_PORT"),
|
||||
"sender": config.get("MAIL_SENDER"),
|
||||
"password": config.get("MAIL_PASSWORD"),
|
||||
"use_tls": config.get("MAIL_TLS", False),
|
||||
}
|
||||
|
||||
|
||||
def make_mailer(app):
|
||||
config = _map_config(app.config)
|
||||
if app.config["DEBUG"]:
|
||||
mailer = RedisMailer(redis=app.redis, **config)
|
||||
else:
|
||||
mailer = Mailer(**config)
|
||||
app.mailer = mailer
|
||||
|
9
atst/queue.py
Normal file
9
atst/queue.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from flask_rq2 import RQ
|
||||
from flask import current_app as app
|
||||
|
||||
queue = RQ()
|
||||
|
||||
|
||||
@queue.job
|
||||
def send_mail(to, subject, body):
|
||||
app.mailer.send(to, subject, body)
|
@@ -10,6 +10,7 @@ from flask import (
|
||||
|
||||
from . import redirect_after_login_url
|
||||
from atst.domain.users import Users
|
||||
from atst.queue import send_mail
|
||||
|
||||
bp = Blueprint("dev", __name__)
|
||||
|
||||
@@ -77,7 +78,7 @@ def login_dev():
|
||||
|
||||
@bp.route("/test-email")
|
||||
def test_email():
|
||||
app.mailer.send(
|
||||
send_mail.queue(
|
||||
[request.args.get("to")], request.args.get("subject"), request.args.get("body")
|
||||
)
|
||||
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import smtplib
|
||||
from email.message import EmailMessage
|
||||
from collections import deque
|
||||
|
||||
|
||||
class _HostConnection:
|
||||
@@ -25,18 +24,13 @@ class _HostConnection:
|
||||
self.host.quit()
|
||||
|
||||
|
||||
class Mailer:
|
||||
def __init__(self, server, port, sender, password, use_tls=False, debug=False):
|
||||
class BaseMailer:
|
||||
def __init__(self, server, port, sender, password, use_tls=False):
|
||||
self.server = server
|
||||
self.port = port
|
||||
self.sender = sender
|
||||
self.password = password
|
||||
self.use_tls = use_tls
|
||||
self.debug = debug
|
||||
self.messages = deque(maxlen=50)
|
||||
|
||||
def connection(self):
|
||||
return _HostConnection(self.server, self.port, self.sender, self.password)
|
||||
|
||||
def _message(self, recipients, subject, body):
|
||||
msg = EmailMessage()
|
||||
@@ -47,27 +41,33 @@ class Mailer:
|
||||
|
||||
return msg
|
||||
|
||||
def send(self, recipients, subject, body):
|
||||
pass
|
||||
|
||||
|
||||
class Mailer(BaseMailer):
|
||||
def connection(self):
|
||||
return _HostConnection(self.server, self.port, self.sender, self.password)
|
||||
|
||||
def send(self, recipients, subject, body):
|
||||
message = self._message(recipients, subject, body)
|
||||
if self.debug:
|
||||
self.messages.appendleft(message)
|
||||
else:
|
||||
with self.connection() as conn:
|
||||
conn.send_message(message)
|
||||
with self.connection() as conn:
|
||||
conn.send_message(message)
|
||||
|
||||
|
||||
def _map_config(config):
|
||||
return {
|
||||
"server": config.get("MAIL_SERVER"),
|
||||
"port": config.get("MAIL_PORT"),
|
||||
"sender": config.get("MAIL_SENDER"),
|
||||
"password": config.get("MAIL_PASSWORD"),
|
||||
"use_tls": config.get("MAIL_TLS", False),
|
||||
"debug": config.get("DEBUG", False),
|
||||
}
|
||||
class RedisMailer(BaseMailer):
|
||||
def __init__(self, redis, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.redis = redis
|
||||
self._reset()
|
||||
|
||||
def _reset(self):
|
||||
self.redis.delete("atat_inbox")
|
||||
|
||||
def make_mailer(app):
|
||||
config = _map_config(app.config)
|
||||
mailer = Mailer(**config)
|
||||
app.mailer = mailer
|
||||
@property
|
||||
def messages(self):
|
||||
return [msg.decode() for msg in self.redis.lrange("atat_inbox", 0, -1)]
|
||||
|
||||
def send(self, recipients, subject, body):
|
||||
message = self._message(recipients, subject, body)
|
||||
self.redis.lpush("atat_inbox", str(message))
|
||||
|
Reference in New Issue
Block a user