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, )
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)