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.

90 lines
2.3 KiB

  1. import smtplib
  2. from threading import Thread
  3. from django.conf import settings
  4. from django.core.mail import EmailMultiAlternatives
  5. from django.template.loader import render_to_string as render
  6. class EmailThread(Thread):
  7. MAX_TRIES = 3
  8. def __init__(self, subject, text, html, to, headers):
  9. Thread.__init__(self)
  10. self.subject = subject
  11. self.text = text
  12. self.html = html
  13. self.to = to
  14. self.headers = headers
  15. def run(self):
  16. for attempt in range(0, self.MAX_TRIES):
  17. try:
  18. msg = EmailMultiAlternatives(
  19. self.subject, self.text, to=(self.to,), headers=self.headers
  20. )
  21. msg.attach_alternative(self.html, "text/html")
  22. msg.send()
  23. except smtplib.SMTPServerDisconnected as e:
  24. if attempt + 1 == self.MAX_TRIES:
  25. # This was the last attempt and it failed:
  26. # re-raise the exception
  27. raise e
  28. else:
  29. # There was no exception, break out of the retry loop
  30. break
  31. def send(name, to, ctx, headers={}):
  32. ctx["SITE_ROOT"] = settings.SITE_ROOT
  33. subject = render("emails/%s-subject.html" % name, ctx).strip()
  34. text = render("emails/%s-body-text.html" % name, ctx)
  35. html = render("emails/%s-body-html.html" % name, ctx)
  36. t = EmailThread(subject, text, html, to, headers)
  37. if hasattr(settings, "BLOCKING_EMAILS"):
  38. # In tests, we send emails synchronously
  39. # so we can inspect the outgoing messages
  40. t.run()
  41. else:
  42. # Outside tests, we send emails on thread,
  43. # so there is no delay for the user.
  44. t.start()
  45. def login(to, ctx):
  46. send("login", to, ctx)
  47. def transfer_request(to, ctx):
  48. send("transfer-request", to, ctx)
  49. def alert(to, ctx, headers={}):
  50. send("alert", to, ctx, headers)
  51. def verify_email(to, ctx):
  52. send("verify-email", to, ctx)
  53. def report(to, ctx, headers={}):
  54. send("report", to, ctx, headers)
  55. def deletion_notice(to, ctx, headers={}):
  56. send("deletion-notice", to, ctx, headers)
  57. def sms_limit(to, ctx):
  58. send("sms-limit", to, ctx)
  59. def call_limit(to, ctx):
  60. send("phone-call-limit", to, ctx)
  61. def sudo_code(to, ctx):
  62. send("sudo-code", to, ctx)