2017-05-02 01:15:58 +02:00
|
|
|
from django.conf import settings
|
2017-05-05 01:03:22 +02:00
|
|
|
from django.core.mail import EmailMultiAlternatives
|
2017-05-02 01:15:58 +02:00
|
|
|
from django.template import loader, TemplateDoesNotExist
|
2017-05-04 03:11:47 +02:00
|
|
|
from django.utils.timezone import now as timezone_now
|
2017-05-23 19:51:25 +02:00
|
|
|
from zerver.models import UserProfile, ScheduledJob
|
2017-05-02 01:15:58 +02:00
|
|
|
|
2017-05-04 03:11:47 +02:00
|
|
|
import datetime
|
2017-05-04 03:23:33 +02:00
|
|
|
from email.utils import parseaddr
|
2017-05-04 03:11:47 +02:00
|
|
|
import ujson
|
|
|
|
|
2017-05-05 01:31:07 +02:00
|
|
|
from typing import Any, Dict, Iterable, List, Mapping, Optional, Text
|
2017-05-02 01:15:58 +02:00
|
|
|
|
|
|
|
def display_email(user):
|
|
|
|
# type: (UserProfile) -> Text
|
|
|
|
# Change to '%s <%s>' % (user.full_name, user.email) once
|
|
|
|
# https://github.com/zulip/zulip/issues/4676 is resolved
|
|
|
|
return user.email
|
|
|
|
|
2017-06-10 06:19:32 +02:00
|
|
|
# Intended only for test code
|
|
|
|
def build_email(template_prefix, to_email, from_email=None, reply_to_email=None, context={}):
|
|
|
|
# type: (str, Text, Optional[Text], Optional[Text], Dict[str, Any]) -> EmailMultiAlternatives
|
2017-06-06 03:46:35 +02:00
|
|
|
subject = loader.render_to_string(template_prefix + '.subject',
|
|
|
|
context=context, using='Jinja2_plaintext').strip()
|
|
|
|
message = loader.render_to_string(template_prefix + '.txt',
|
|
|
|
context=context, using='Jinja2_plaintext')
|
2017-05-02 01:15:58 +02:00
|
|
|
# Remove try/expect once https://github.com/zulip/zulip/issues/4691 is resolved.
|
|
|
|
try:
|
|
|
|
html_message = loader.render_to_string(template_prefix + '.html', context)
|
|
|
|
except TemplateDoesNotExist:
|
|
|
|
html_message = None
|
|
|
|
if from_email is None:
|
|
|
|
from_email = settings.NOREPLY_EMAIL_ADDRESS
|
2017-05-05 01:03:22 +02:00
|
|
|
reply_to = None
|
|
|
|
if reply_to_email is not None:
|
|
|
|
reply_to = [reply_to_email]
|
|
|
|
|
|
|
|
mail = EmailMultiAlternatives(subject, message, from_email, [to_email], reply_to=reply_to)
|
|
|
|
if html_message is not None:
|
|
|
|
mail.attach_alternative(html_message, 'text/html')
|
2017-06-10 06:19:32 +02:00
|
|
|
return mail
|
|
|
|
|
|
|
|
def send_email(template_prefix, to_email, from_email=None, reply_to_email=None, context={}):
|
|
|
|
# type: (str, Text, Optional[Text], Optional[Text], Dict[str, Any]) -> bool
|
|
|
|
mail = build_email(template_prefix, to_email, from_email=from_email,
|
|
|
|
reply_to_email=reply_to_email, context=context)
|
2017-05-05 01:03:22 +02:00
|
|
|
return mail.send() > 0
|
2017-05-02 01:15:58 +02:00
|
|
|
|
|
|
|
def send_email_to_user(template_prefix, user, from_email=None, context={}):
|
|
|
|
# type: (str, UserProfile, Optional[Text], Dict[str, Text]) -> bool
|
|
|
|
return send_email(template_prefix, display_email(user), from_email=from_email, context=context)
|
2017-05-04 03:11:47 +02:00
|
|
|
|
2017-05-05 01:31:07 +02:00
|
|
|
# Returns None instead of bool so that the type signature matches the third
|
|
|
|
# argument of zerver.lib.queue.queue_json_publish
|
|
|
|
def send_email_from_dict(email_dict):
|
|
|
|
# type: (Mapping[str, Any]) -> None
|
|
|
|
send_email(**dict(email_dict))
|
|
|
|
|
2017-05-04 03:23:33 +02:00
|
|
|
def send_future_email(template_prefix, to_email, from_email=None, context={},
|
2017-05-04 06:51:05 +02:00
|
|
|
delay=datetime.timedelta(0)):
|
|
|
|
# type: (str, Text, Optional[Text], Dict[str, Any], datetime.timedelta) -> None
|
2017-05-04 06:42:23 +02:00
|
|
|
email_fields = {'template_prefix': template_prefix, 'to_email': to_email, 'from_email': from_email,
|
|
|
|
'context': context}
|
2017-05-04 03:23:33 +02:00
|
|
|
ScheduledJob.objects.create(type=ScheduledJob.EMAIL, filter_string=parseaddr(to_email)[1],
|
|
|
|
data=ujson.dumps(email_fields),
|
|
|
|
scheduled_timestamp=timezone_now() + delay)
|