You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

98 lines
2.7 KiB

  1. import smtplib
  2. from threading import Thread
  3. import time
  4. from django.conf import settings
  5. from django.templatetags.static import static
  6. from django.core.mail import EmailMultiAlternatives
  7. from django.template.loader import render_to_string as render
  8. class EmailThread(Thread):
  9. MAX_TRIES = 3
  10. def __init__(self, message):
  11. Thread.__init__(self)
  12. self.message = message
  13. def run(self):
  14. for attempt in range(0, self.MAX_TRIES):
  15. try:
  16. # Make sure each retry creates a new connection:
  17. self.message.connection = None
  18. self.message.send()
  19. # No exception--great! Return from the retry loop
  20. return
  21. except smtplib.SMTPServerDisconnected as e:
  22. if attempt + 1 == self.MAX_TRIES:
  23. # This was the last attempt and it failed:
  24. # re-raise the exception
  25. raise e
  26. # Wait 1s before retrying
  27. time.sleep(1)
  28. def make_message(name, to, ctx, headers={}):
  29. ctx["site_logo_url"] = settings.SITE_LOGO_URL or static("img/logo.png")
  30. if ctx["site_logo_url"].startswith("/"):
  31. # If it's a relative URL, prepend SITE_ROOT
  32. ctx["site_logo_url"] = settings.SITE_ROOT + ctx["site_logo_url"]
  33. subject = render("emails/%s-subject.html" % name, ctx).strip()
  34. body = render("emails/%s-body-text.html" % name, ctx)
  35. html = render("emails/%s-body-html.html" % name, ctx)
  36. msg = EmailMultiAlternatives(subject, body, to=(to,), headers=headers)
  37. msg.attach_alternative(html, "text/html")
  38. return msg
  39. def send(msg, block=False):
  40. t = EmailThread(msg)
  41. if block or hasattr(settings, "BLOCKING_EMAILS"):
  42. # In tests, we send emails synchronously
  43. # so we can inspect the outgoing messages
  44. t.run()
  45. else:
  46. # Outside tests, we send emails on thread,
  47. # so there is no delay for the user.
  48. t.start()
  49. def login(to, ctx):
  50. send(make_message("login", to, ctx))
  51. def transfer_request(to, ctx):
  52. send(make_message("transfer-request", to, ctx))
  53. def alert(to, ctx, headers={}):
  54. send(make_message("alert", to, ctx, headers=headers))
  55. def verify_email(to, ctx):
  56. send(make_message("verify-email", to, ctx))
  57. def report(to, ctx, headers={}):
  58. m = make_message("report", to, ctx, headers=headers)
  59. send(m, block=True)
  60. def deletion_notice(to, ctx, headers={}):
  61. m = make_message("deletion-notice", to, ctx, headers=headers)
  62. send(m, block=True)
  63. def sms_limit(to, ctx):
  64. send(make_message("sms-limit", to, ctx))
  65. def call_limit(to, ctx):
  66. send(make_message("phone-call-limit", to, ctx))
  67. def sudo_code(to, ctx):
  68. send(make_message("sudo-code", to, ctx))