2020-07-12 17:34:25 +02:00
|
|
|
# ContentDB
|
2021-01-30 17:59:42 +01:00
|
|
|
# Copyright (C) 2018-21 rubenwardy
|
2018-05-17 16:18:20 +02:00
|
|
|
#
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
2021-01-30 17:59:42 +01:00
|
|
|
# it under the terms of the GNU Affero General Public License as published by
|
2018-05-17 16:18:20 +02:00
|
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2021-01-30 17:59:42 +01:00
|
|
|
# GNU Affero General Public License for more details.
|
2018-05-17 16:18:20 +02:00
|
|
|
#
|
2021-01-30 17:59:42 +01:00
|
|
|
# You should have received a copy of the GNU Affero General Public License
|
2018-05-17 16:18:20 +02:00
|
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
2020-12-04 03:23:04 +01:00
|
|
|
from flask import render_template
|
2018-05-14 01:40:34 +02:00
|
|
|
from flask_mail import Message
|
|
|
|
from app import mail
|
2020-12-06 16:02:02 +01:00
|
|
|
from app.models import Notification, db, EmailSubscription, User
|
2018-05-14 01:40:34 +02:00
|
|
|
from app.tasks import celery
|
2020-12-05 21:36:09 +01:00
|
|
|
from app.utils import abs_url_for, abs_url, randomString
|
|
|
|
|
|
|
|
|
|
|
|
def get_email_subscription(email):
|
|
|
|
assert type(email) == str
|
|
|
|
ret = EmailSubscription.query.filter_by(email=email).first()
|
|
|
|
if not ret:
|
|
|
|
ret = EmailSubscription(email)
|
|
|
|
ret.token = randomString(32)
|
|
|
|
db.session.add(ret)
|
|
|
|
db.session.commit()
|
|
|
|
|
|
|
|
return ret
|
2020-12-05 20:15:33 +01:00
|
|
|
|
2018-05-14 01:40:34 +02:00
|
|
|
|
|
|
|
@celery.task()
|
2020-12-06 16:02:02 +01:00
|
|
|
def send_verify_email(email, token):
|
2020-12-05 21:36:09 +01:00
|
|
|
sub = get_email_subscription(email)
|
|
|
|
if sub.blacklisted:
|
|
|
|
return
|
|
|
|
|
|
|
|
msg = Message("Confirm email address", recipients=[email])
|
2019-09-15 19:43:22 +02:00
|
|
|
|
|
|
|
msg.body = """
|
|
|
|
This email has been sent to you because someone (hopefully you)
|
|
|
|
has entered your email address as a user's email.
|
|
|
|
|
|
|
|
If it wasn't you, then just delete this email.
|
|
|
|
|
2020-12-05 01:27:26 +01:00
|
|
|
If this was you, then please click this link to confirm the address:
|
2019-09-15 19:43:22 +02:00
|
|
|
|
|
|
|
{}
|
2020-01-25 04:03:45 +01:00
|
|
|
""".format(abs_url_for('users.verify_email', token=token))
|
2019-09-15 19:43:22 +02:00
|
|
|
|
2020-12-05 21:36:09 +01:00
|
|
|
msg.html = render_template("emails/verify.html", token=token, sub=sub)
|
2018-07-06 23:52:19 +02:00
|
|
|
mail.send(msg)
|
|
|
|
|
2020-12-05 20:52:02 +01:00
|
|
|
|
2018-07-06 23:52:19 +02:00
|
|
|
@celery.task()
|
2020-12-06 16:02:02 +01:00
|
|
|
def send_unsubscribe_verify(email):
|
2020-12-05 21:36:09 +01:00
|
|
|
sub = get_email_subscription(email)
|
|
|
|
if sub.blacklisted:
|
|
|
|
return
|
|
|
|
|
|
|
|
msg = Message("Confirm unsubscribe", recipients=[email])
|
|
|
|
|
|
|
|
msg.body = """
|
|
|
|
We're sorry to see you go. You just need to do one more thing before your email is blacklisted.
|
|
|
|
|
|
|
|
Click this link to blacklist email: {}
|
|
|
|
""".format(abs_url_for('users.unsubscribe', token=sub.token))
|
|
|
|
|
|
|
|
msg.html = render_template("emails/verify_unsubscribe.html", sub=sub)
|
|
|
|
mail.send(msg)
|
|
|
|
|
|
|
|
|
|
|
|
@celery.task()
|
|
|
|
def send_email_with_reason(email, subject, text, html, reason):
|
|
|
|
sub = get_email_subscription(email)
|
|
|
|
if sub.blacklisted:
|
|
|
|
return
|
|
|
|
|
2018-07-06 23:52:19 +02:00
|
|
|
from flask_mail import Message
|
2020-12-05 21:36:09 +01:00
|
|
|
msg = Message(subject, recipients=[email])
|
2019-01-04 20:17:04 +01:00
|
|
|
|
2020-12-05 01:01:36 +01:00
|
|
|
msg.body = text
|
2019-01-04 20:17:04 +01:00
|
|
|
html = html or text
|
2020-12-05 21:36:09 +01:00
|
|
|
msg.html = render_template("emails/base.html", subject=subject, content=html, reason=reason, sub=sub)
|
2018-07-06 23:52:19 +02:00
|
|
|
mail.send(msg)
|
2020-12-05 20:15:33 +01:00
|
|
|
|
|
|
|
|
2020-12-05 20:52:02 +01:00
|
|
|
@celery.task()
|
2020-12-05 21:36:09 +01:00
|
|
|
def send_user_email(email: str, subject: str, text: str, html=None):
|
|
|
|
return send_email_with_reason(email, subject, text, html,
|
2020-12-05 20:52:02 +01:00
|
|
|
"You are receiving this email because you are a registered user of ContentDB.")
|
|
|
|
|
|
|
|
|
|
|
|
@celery.task()
|
2020-12-05 21:36:09 +01:00
|
|
|
def send_anon_email(email: str, subject: str, text: str, html=None):
|
|
|
|
return send_email_with_reason(email, subject, text, html,
|
2020-12-05 20:52:02 +01:00
|
|
|
"You are receiving this email because someone (hopefully you) entered your email address as a user's email.")
|
|
|
|
|
|
|
|
|
2020-12-06 16:02:02 +01:00
|
|
|
def send_single_email(notification):
|
2020-12-05 21:36:09 +01:00
|
|
|
sub = get_email_subscription(notification.user.email)
|
|
|
|
if sub.blacklisted:
|
|
|
|
return
|
|
|
|
|
2020-12-05 20:15:33 +01:00
|
|
|
msg = Message(notification.title, recipients=[notification.user.email])
|
|
|
|
|
|
|
|
msg.body = """
|
|
|
|
New notification: {}
|
|
|
|
|
|
|
|
View: {}
|
|
|
|
|
|
|
|
Manage email settings: {}
|
2020-12-05 21:36:09 +01:00
|
|
|
Unsubscribe: {}
|
2020-12-05 20:15:33 +01:00
|
|
|
""".format(notification.title, abs_url(notification.url),
|
2020-12-05 21:36:09 +01:00
|
|
|
abs_url_for("users.email_notifications", username=notification.user.username),
|
|
|
|
abs_url_for("users.unsubscribe", token=sub.token))
|
2020-12-05 20:15:33 +01:00
|
|
|
|
2020-12-05 21:36:09 +01:00
|
|
|
msg.html = render_template("emails/notification.html", notification=notification, sub=sub)
|
2020-12-05 20:15:33 +01:00
|
|
|
mail.send(msg)
|
|
|
|
|
|
|
|
|
2020-12-06 16:02:02 +01:00
|
|
|
def send_notification_digest(notifications: [Notification]):
|
|
|
|
user = notifications[0].user
|
|
|
|
|
|
|
|
sub = get_email_subscription(user.email)
|
|
|
|
if sub.blacklisted:
|
|
|
|
return
|
|
|
|
|
|
|
|
msg = Message("{} new notifications".format(len(notifications)), recipients=[user.email])
|
|
|
|
|
|
|
|
msg.body = "".join(["<{}> {}\nView: {}\n\n".format(notification.causer.display_name, notification.title, abs_url(notification.url)) for notification in notifications])
|
|
|
|
|
|
|
|
msg.body += "Manage email settings: {}\nUnsubscribe: {}".format(
|
|
|
|
abs_url_for("users.email_notifications", username=user.username),
|
|
|
|
abs_url_for("users.unsubscribe", token=sub.token))
|
|
|
|
|
|
|
|
msg.html = render_template("emails/notification_digest.html", notifications=notifications, user=user, sub=sub)
|
|
|
|
mail.send(msg)
|
|
|
|
|
|
|
|
|
|
|
|
@celery.task()
|
|
|
|
def send_pending_digests():
|
|
|
|
for user in User.query.filter(User.notifications.any(emailed=False)).all():
|
|
|
|
to_send = []
|
|
|
|
for notification in user.notifications:
|
|
|
|
if not notification.emailed and notification.can_send_digest():
|
|
|
|
to_send.append(notification)
|
|
|
|
notification.emailed = True
|
|
|
|
|
|
|
|
if len(to_send) > 0:
|
|
|
|
send_notification_digest(to_send)
|
|
|
|
|
|
|
|
db.session.commit()
|
|
|
|
|
|
|
|
|
2020-12-05 20:15:33 +01:00
|
|
|
@celery.task()
|
2020-12-06 16:02:02 +01:00
|
|
|
def send_pending_notifications():
|
|
|
|
for user in User.query.filter(User.notifications.any(emailed=False)).all():
|
|
|
|
to_send = []
|
|
|
|
for notification in user.notifications:
|
|
|
|
if not notification.emailed:
|
|
|
|
if notification.can_send_email():
|
|
|
|
to_send.append(notification)
|
|
|
|
notification.emailed = True
|
|
|
|
elif not notification.can_send_digest():
|
|
|
|
notification.emailed = True
|
2020-12-05 20:15:33 +01:00
|
|
|
|
|
|
|
db.session.commit()
|
2020-12-06 16:02:02 +01:00
|
|
|
|
|
|
|
if len(to_send) > 1:
|
|
|
|
send_notification_digest(to_send)
|
|
|
|
elif len(to_send) > 0:
|
|
|
|
send_single_email(to_send[0])
|