From f381954358fa5605f13b956d6d769d3b52445455 Mon Sep 17 00:00:00 2001 From: rimu <3310831+rimu@users.noreply.github.com> Date: Sat, 5 Aug 2023 21:26:44 +1200 Subject: [PATCH] misc boilerplate --- app/__init__.py | 11 +++++--- app/email.py | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ config.py | 8 +++--- requirements.txt | 4 +++ 4 files changed, 82 insertions(+), 7 deletions(-) create mode 100644 app/email.py diff --git a/app/__init__.py b/app/__init__.py index c34cc777..4c92cd10 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -13,9 +13,9 @@ from config import Config db = SQLAlchemy(session_options={"autoflush": False}) migrate = Migrate() -#login = LoginManager() -#login.login_view = 'auth.login' -#login.login_message = _l('Please log in to access this page.') +login = LoginManager() +login.login_view = 'auth.login' +login.login_message = _l('Please log in to access this page.') mail = Mail() moment = Moment() babel = Babel() @@ -27,7 +27,7 @@ def create_app(config_class=Config): db.init_app(app) migrate.init_app(app, db, render_as_batch=True) - #login.init_app(app) + login.init_app(app) mail.init_app(app) moment.init_app(app) babel.init_app(app, locale_selector=get_locale) @@ -41,6 +41,9 @@ def create_app(config_class=Config): from app.admin import bp as admin_bp app.register_blueprint(admin_bp, url_prefix='/admin') + from app.activitypub import bp as activitypub_bp + app.register_blueprint(activitypub_bp) + def get_resource_as_string(name, charset='utf-8'): with app.open_resource(name) as f: return f.read().decode(charset) diff --git a/app/email.py b/app/email.py new file mode 100644 index 00000000..83e256ad --- /dev/null +++ b/app/email.py @@ -0,0 +1,66 @@ +from flask import current_app, render_template, escape +from app import db +from flask_babel import _, lazy_gettext as _l # todo: set the locale based on account_id so that _() works +import boto3 +from botocore.exceptions import ClientError +from typing import List + +AWS_REGION = "ap-southeast-2" +CHARSET = "UTF-8" + + +def send_async_email(subject, sender, recipients, text_body, html_body, reply_to): + if type(recipients) == str: + recipients = [recipients] + with current_app.app_context(): + try: + # Create a new SES resource and specify a region. + amazon_client = boto3.client('ses', region_name=AWS_REGION) + # Provide the contents of the email. + if reply_to is None: + response = amazon_client.send_email( + Destination={'ToAddresses': recipients}, + Message={ + 'Body': { + 'Html': { + 'Charset': CHARSET, 'Data': html_body, + }, + 'Text': { + 'Charset': CHARSET, 'Data': text_body, + }, + }, + 'Subject': { + 'Charset': CHARSET, 'Data': subject, + }, + }, + Source=sender, + ReturnPath='bounces@chorebuster.net') + else: + response = amazon_client.send_email( + Destination={'ToAddresses': recipients}, + Message={ + 'Body': { + 'Html': { + 'Charset': CHARSET, 'Data': html_body, + }, + 'Text': { + 'Charset': CHARSET, 'Data': text_body, + }, + }, + 'Subject': { + 'Charset': CHARSET, 'Data': subject, + }, + }, + Source=sender, + ReturnPath='bounces@chorebuster.net', + ReplyToAddresses=[reply_to]) + # message.attach_alternative("...AMPHTML content...", "text/x-amp-html") + + except ClientError as e: + current_app.logger.error('Failed to send email. ' + e.response['Error']['Message']) + return e.response['Error']['Message'] + + +def send_email(subject, sender, recipients: List[str], text_body, html_body, reply_to=None): + # todo: make async or threaded + send_async_email(subject, sender, recipients, text_body, html_body, reply_to) diff --git a/config.py b/config.py index 2a5ce82e..d004d5f1 100644 --- a/config.py +++ b/config.py @@ -6,8 +6,8 @@ load_dotenv(os.path.join(basedir, '.env')) class Config(object): - SERVER_NAME = os.environ.get('SERVER_NAME') or 'app.chorebuster.net' - SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess' + SERVER_NAME = os.environ.get('SERVER_NAME') or 'localhost' + SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guesss' SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \ 'sqlite:///' + os.path.join(basedir, 'app.db') SQLALCHEMY_TRACK_MODIFICATIONS = False @@ -15,4 +15,6 @@ class Config(object): MAIL_PORT = int(os.environ.get('MAIL_PORT') or 25) MAIL_USE_TLS = os.environ.get('MAIL_USE_TLS') is not None MAIL_USERNAME = os.environ.get('MAIL_USERNAME') - MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD') \ No newline at end of file + MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD') + #SQLALCHEMY_ECHO = True # set to true to see debugging SQL in console + diff --git a/requirements.txt b/requirements.txt index f762766f..b31dea58 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,3 +9,7 @@ flask-mail==0.9.1 flask-moment==1.0.5 flask-babel==3.1.0 psycopg2-binary +requests==2.31.0 +pyjwt==2.8.0 +SQLAlchemy-Searchable==1.4.1 +SQLAlchemy-Utils==0.41.1