def register(self, model, adapter_cls=EmailAdapter, **field_overrides):
     """
     Registers the given model with this email manager.
     
     If the given model is already registered with this email manager, a
     RegistrationError will be raised.
     """
     # Check for existing registration.
     if self.is_registered(model):
         raise RegistrationError(_("{model!r} is already registered with this email manager").format(
             model = model,
         ))
     # Perform any customization.
     if field_overrides:
         adapter_cls = type("Custom" + adapter_cls.__name__, (adapter_cls,), field_overrides)
     # Perform the registration.
     adapter_obj = adapter_cls(model)
     self._registered_models[model] = adapter_obj
     # Add in a generic relation, if not exists.
     if not hasattr(model, "dispatchedemail_set"):
         if has_int_pk(model):
             object_id_field = "object_id_int"
         else:
             object_id_field = "object_id"
         generic_relation = generic.GenericRelation(
             DispatchedEmail,
             object_id_field = object_id_field,
         )
         model.dispatchedemail_set = generic_relation
         generic_relation.contribute_to_class(model, "dispatchedemail_set")
 def dispatch_email(self, obj, subscriber, date_to_send=None):
     """Sends an email to the given subscriber."""
     self._assert_registered(obj.__class__)
     date_to_send = date_to_send or datetime.datetime.now()
     # Determine the integer object id.
     if has_int_pk(obj):
         object_id_int = int(obj.pk)
     else:
         object_id_int = None
     # Save the dispatched email.
     return DispatchedEmail.objects.create(
         manager_slug = self._manager_slug,
         content_type = ContentType.objects.get_for_model(obj),
         object_id = unicode(obj.pk),
         object_id_int = object_id_int,
         subscriber = subscriber,
         date_to_send = date_to_send,
     )
Example #3
0
 def do_allow_save_and_send(admin_cls, request, obj, *args, **kwargs):
     def make_error_redirect(warning=None):
         admin_cls.message_user(request, _(u"The {model} \"{obj}\" was saved successfully.").format(
                 model = obj._meta.verbose_name,
                 obj = obj,
             ))
         if warning:
             messages.warning(request, warning)
         return redirect("{site}:{app}_{model}_change".format(
             site = admin_cls.admin_site.name,
             app = obj._meta.app_label,
             model = obj.__class__.__name__.lower(),
         ), obj.pk)
     if "_saveandsend" in request.POST:
         # Get the default list of subscribers.
         subscribers = Subscriber.objects.filter(
             is_subscribed = True,
         )
         # Try filtering by mailing list.
         send_to = request.POST["_send_to"]
         if send_to == "_nobody":
             return make_error_redirect(_(u"Please select a mailing list to send this {model} to.").format(
                 model = obj._meta.verbose_name,
             ))
         elif send_to == "_all":
             pass
         else:
             mailing_list = MailingList.objects.get(id=send_to)
             subscribers = subscribers.filter(mailing_lists=mailing_list)
         # Get the send date.
         if request.POST["_send_on_date"]:
             send_on_date = None
             for format in formats.get_format("DATE_INPUT_FORMATS"):
                 try:
                     send_on_date = datetime.date(*time.strptime(request.POST["_send_on_date"], format)[:3])
                 except ValueError:
                     pass
                 else:
                     break
             if send_on_date is None:
                 return make_error_redirect(_(u"Your date format was incorrect, so the email was not sent."))
         else:
             send_on_date = datetime.datetime.now().date()
         # Get the send time.
         if request.POST["_send_on_time"]:
             send_on_time = None
             for format in formats.get_format("TIME_INPUT_FORMATS"):
                 try:
                     send_on_time = datetime.time(*time.strptime(request.POST["_send_on_time"], format)[3:6])
                 except ValueError:
                     pass
                 else:
                     break
             if send_on_time is None:
                 return make_error_redirect(_(u"Your time format was incorrect, so the email was not sent."))
         else:
             send_on_time = datetime.datetime.now().time()
         # Get the send datetime.
         send_on_datetime = datetime.datetime.combine(send_on_date, send_on_time)
         # Calculate potential subscriber count.    
         potential_subscriber_count = subscribers.count()
         # Exclude subscribers who have already received the email.
         if has_int_pk(obj.__class__):
             subscribers_to_send = subscribers.exclude(
                 dispatchedemail__object_id_int = obj.pk,
             )
         else:
             subscribers_to_send = subscribers.exclude(
                 dispatchedemail__object_id = obj.pk,
             )
         subscribers_to_send = subscribers_to_send.distinct()
         # Send the email!
         subscriber_count = 0
         for subscriber in subscribers_to_send.iterator():
             subscriber_count += 1
             admin_cls.email_manager.dispatch_email(obj, subscriber, send_on_datetime)
         # Message the user.
         admin_cls.message_user(request, _(u"The {model} \"{obj}\" was saved successfully. An email will be sent to {count} subscriber{pluralize}.").format(
             model = obj._meta.verbose_name,
             obj = obj,
             count = subscriber_count,
             pluralize = subscriber_count != 1 and "s" or "",
         ))
         # Warn about unsent emails.
         if potential_subscriber_count > subscriber_count:
             unsent_count = potential_subscriber_count - subscriber_count
             messages.warning(request, _(u"{count} subscriber{pluralize} ignored, as they have already received this email.").format(
                 count = unsent_count,
                 pluralize = unsent_count != 1 and "s were" or " was",
             ))
         # Redirect the user.
         return redirect("{site}:{app}_{model}_changelist".format(
             site = admin_cls.admin_site.name,
             app = obj._meta.app_label,
             model = obj.__class__.__name__.lower(),
         ))
     return func(admin_cls, request, obj, *args, **kwargs)