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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. import logging
  2. from django.core.mail import EmailMessage, EmailMultiAlternatives
  3. from django.core.urlresolvers import reverse
  4. from django.conf import settings
  5. from django.db.models import get_model
  6. from django.utils.http import int_to_base36
  7. from django.contrib.auth.tokens import default_token_generator
  8. CommunicationEvent = get_model('order', 'CommunicationEvent')
  9. Email = get_model('customer', 'Email')
  10. class Dispatcher(object):
  11. def __init__(self, logger=None):
  12. if not logger:
  13. logger = logging.getLogger(__name__)
  14. self.logger = logger
  15. # Public API methods
  16. def dispatch_direct_messages(self, recipient, messages):
  17. """
  18. Dispatch one-off messages to explicitly specified recipient(s).
  19. """
  20. if messages['subject'] and messages['body']:
  21. self.send_email_messages(recipient, messages)
  22. def dispatch_order_messages(self, order, messages, event_type=None,
  23. **kwargs):
  24. """
  25. Dispatch order-related messages to the customer
  26. """
  27. if order.is_anonymous:
  28. if 'email_address' in kwargs:
  29. self.send_email_messages(kwargs['email_address'], messages)
  30. elif order.guest_email:
  31. self.send_email_messages(order.guest_email, messages)
  32. else:
  33. return
  34. else:
  35. self.dispatch_user_messages(order.user, messages)
  36. # Create order comms event for audit
  37. if event_type:
  38. CommunicationEvent._default_manager.create(order=order,
  39. event_type=event_type)
  40. def dispatch_user_messages(self, user, messages):
  41. """
  42. Send messages to a site user
  43. """
  44. if messages['subject'] and (messages['body'] or messages['html']):
  45. self.send_user_email_messages(user, messages)
  46. if messages['sms']:
  47. self.send_text_message(user, messages['sms'])
  48. # Internal
  49. def send_user_email_messages(self, user, messages):
  50. """
  51. Sends message to the registered user / customer and collects data in database
  52. """
  53. if not user.email:
  54. self.logger.warning("Unable to send email messages as user #%d has no email address", user.id)
  55. return
  56. email = self.send_email_messages(user.email, messages)
  57. # Is user is signed in, record the event for audit
  58. if email and user.is_authenticated():
  59. Email._default_manager.create(user=user,
  60. subject=email.subject,
  61. body_text=email.body,
  62. body_html=messages['html'])
  63. def send_email_messages(self, recipient, messages):
  64. """
  65. Plain email sending to the specified recipient
  66. """
  67. if hasattr(settings, 'OSCAR_FROM_EMAIL'):
  68. from_email = settings.OSCAR_FROM_EMAIL
  69. else:
  70. from_email = None
  71. # Determine whether we are sending a HTML version too
  72. if messages['html']:
  73. email = EmailMultiAlternatives(messages['subject'],
  74. messages['body'],
  75. from_email=from_email,
  76. to=[recipient])
  77. email.attach_alternative(messages['html'], "text/html")
  78. else:
  79. email = EmailMessage(messages['subject'],
  80. messages['body'],
  81. from_email=from_email,
  82. to=[recipient])
  83. self.logger.info("Sending email to %s" % recipient)
  84. email.send()
  85. return email
  86. def send_text_message(self, user, event_type):
  87. raise NotImplementedError
  88. def get_password_reset_url(user, token_generator=default_token_generator):
  89. """
  90. Generate a password-reset URL for a given user
  91. """
  92. return reverse('password-reset-confirm', kwargs={
  93. 'uidb36': int_to_base36(user.id),
  94. 'token': default_token_generator.make_token(user)})
  95. def normalise_email(email):
  96. """
  97. The local part of an email address is case-sensitive, the domain part isn't.
  98. This function lowercases the host and should be used in all email handling.
  99. """
  100. clean_email = email.strip()
  101. if '@' in clean_email:
  102. local, host = clean_email.split('@')
  103. return local + '@' + host.lower()
  104. return clean_email