def construct_simple(base, var_type): identifier = "%s_%s" % (var_type.identifier, base.identifier_suffix) class_name = str(camel_case(identifier)) suffixed_type_name = lazy(lambda s: "%s %s" % (var_type.name, s), six.text_type) class_ns = { "bindings": { "v1": Binding(suffixed_type_name("1"), type=var_type), "v2": Binding(suffixed_type_name("2"), type=var_type, constant_use=ConstantUse.VARIABLE_OR_CONSTANT), }, "identifier": identifier } return type(class_name, (base,), class_ns)
class AddOrderLogEntry(Action): identifier = "add_order_log_entry" order = Binding("Order", Model("shuup.Order"), constant_use=ConstantUse.VARIABLE_ONLY) message = Binding("Message", Text, constant_use=ConstantUse.VARIABLE_OR_CONSTANT) message_identifier = Binding("Message Identifier", Text, constant_use=ConstantUse.VARIABLE_OR_CONSTANT) def execute(self, context): order = self.get_value(context, "order") if not order: # pragma: no cover return message = self.get_value(context, "message") message_identifier = self.get_value(context, "message_identifier") or None assert isinstance(order, Order) order.add_log_entry(message=message, identifier=message_identifier)
class AddNotification(Action): identifier = "add_notification" recipient_type = Binding("Recipient Type", type=Enum(RecipientType), constant_use=ConstantUse.CONSTANT_ONLY, default=RecipientType.ADMINS) recipient = Binding("Recipient", type=Model(settings.AUTH_USER_MODEL), constant_use=ConstantUse.VARIABLE_OR_CONSTANT, required=False) priority = Binding("Priority", type=Enum(Priority), constant_use=ConstantUse.CONSTANT_ONLY, default=Priority.NORMAL) message = TemplatedBinding("Message", type=Text, constant_use=ConstantUse.CONSTANT_ONLY, required=True) message_identifier = Binding("Message Identifier", Text, constant_use=ConstantUse.CONSTANT_ONLY, required=False) url = Binding("URL", type=URL, constant_use=ConstantUse.VARIABLE_OR_CONSTANT) def execute(self, context): """ :type context: shuup.notify.script.Context """ values = self.get_values(context) if values["recipient_type"] == RecipientType.SPECIFIC_USER: if not values["recipient"]: context.log( logging.WARN, "Warning! Misconfigured AddNotification -- no recipient for specific user." ) return Notification.objects.create( recipient_type=values["recipient_type"], recipient=values["recipient"], priority=values["priority"], identifier=values.get("message_identifier"), message=values["message"][:140], url=values["url"], shop=context.shop, )
class Empty(Condition): identifier = "empty" description = _(u"Check whether the bound value `value` is empty or zero.") name = _("Empty") v = Binding("Value") def test(self, context): return not bool(self.get_value(context, "v"))
class NonEmpty(Condition): identifier = "non_empty" description = _(u"Check whether the bound value `value` exists and is non-empty and non-zero.") name = _("Non-Empty") v = Binding("Value") def test(self, context): return bool(self.get_value(context, "v"))
class SetDebugFlag(Action): identifier = "set_debug_flag" flag_name = Binding("Flag Name", Text, constant_use=ConstantUse.CONSTANT_ONLY, default="debug") def execute(self, context): context.set(self.get_value(context, "flag_name"), True)
class SendEmail(Action): EMAIL_CONTENT_TYPE_CHOICES = (("html", _("HTML")), ("plain", _("Plain text"))) identifier = "send_email" template_use = TemplateUse.MULTILINGUAL template_fields = { "subject": forms.CharField(required=True, label=_("Subject")), "email_template": forms.ChoiceField(choices=[(None, "-----")], label=_("Email Template"), required=False), "body": forms.CharField(required=True, label=_("Email Body"), widget=CodeEditorWithHTMLPreview), "content_type": forms.ChoiceField( required=True, label=_("Content type"), choices=EMAIL_CONTENT_TYPE_CHOICES, initial=EMAIL_CONTENT_TYPE_CHOICES[0][0], ), } recipient = Binding(_("Recipient"), type=Email, constant_use=ConstantUse.VARIABLE_OR_CONSTANT, required=True) reply_to_address = Binding(_("Reply-To"), type=Email, constant_use=ConstantUse.VARIABLE_OR_CONSTANT) cc = Binding( _("Carbon Copy (CC)"), type=Email, constant_use=ConstantUse.VARIABLE_OR_CONSTANT, ) bcc = Binding(_("Blind Carbon Copy (BCC)"), type=Email, constant_use=ConstantUse.VARIABLE_OR_CONSTANT) from_email = Binding( _("From email"), type=Text, constant_use=ConstantUse.VARIABLE_OR_CONSTANT, required=False, help_text=_( "Override the default from email to be used. " "It can either be binded to a variable or be a constant like " '[email protected] or even "Store Support" <*****@*****.**>.' ), ) language = Binding(_("Language"), type=Language, constant_use=ConstantUse.VARIABLE_OR_CONSTANT, required=True) fallback_language = Binding( _("Fallback language"), type=Language, constant_use=ConstantUse.CONSTANT_ONLY, default=settings.PARLER_DEFAULT_LANGUAGE_CODE, ) send_identifier = Binding( _("Send Identifier"), type=Text, constant_use=ConstantUse.CONSTANT_ONLY, required=False, help_text=_( "If set, this identifier will be logged into the event's log target. If the identifier has already " "been logged, the e-mail won't be sent again." ), ) def __init__(self, *args, **kwargs): # force refresh the lis of options self.template_fields["email_template"].choices = [(None, "-----")] + [ (template.pk, template.name) for template in EmailTemplate.objects.all() ] super().__init__(*args, **kwargs) def execute(self, context): """ :param context: Script Context. :type context: shuup.notify.script.Context """ recipient = get_email_list(self.get_value(context, "recipient")) if not recipient: context.log(logging.INFO, "Info! %s: Not sending mail, no recipient.", self.identifier) return send_identifier = self.get_value(context, "send_identifier") if send_identifier and context.log_entry_queryset.filter(identifier=send_identifier).exists(): context.log( logging.INFO, "Info! %s: Not sending mail, it was already sent (%r).", self.identifier, send_identifier ) return languages = [ language for language in [ self.get_value(context, "language"), self.get_value(context, "fallback_language"), ] if language and language in dict(settings.LANGUAGES).keys() ] if not languages: languages = [settings.PARLER_DEFAULT_LANGUAGE_CODE] strings = self.get_template_values(context, languages) subject = unescape(strings.get("subject")) body = unescape(strings.get("body")) email_template_id = strings.get("email_template") if email_template_id: email_template = EmailTemplate.objects.filter(pk=email_template_id).first() if email_template and "%html_body%" in email_template.template: body = email_template.template.replace("%html_body%", body) content_type = strings.get("content_type") if not (subject and body): context.log( logging.INFO, "Info! %s: Not sending mail to %s, either subject or body empty.", self.identifier, recipient, ) return reply_to = get_email_list(self.get_value(context, "reply_to_address")) from_email = self.get_value(context, "from_email") bcc = get_email_list(self.get_value(context, "bcc")) cc = get_email_list(self.get_value(context, "cc")) subject = " ".join(subject.splitlines()) # Email headers may not contain newlines message = EmailMessage( subject=subject, body=body, to=recipient, reply_to=reply_to, from_email=from_email, bcc=bcc, cc=cc ) message.content_subtype = content_type notification_email_before_send.send(sender=type(self), action=self, message=message, context=context) message.send() context.log(logging.INFO, "Info! %s: Mail sent to %s.", self.identifier, recipient) notification_email_sent.send(sender=type(self), message=message, context=context) if send_identifier: context.add_log_entry_on_log_target("Info! Email sent to %s: %s" % (recipient, subject), send_identifier)
class SendEmail(Action): EMAIL_CONTENT_TYPE_CHOICES = (('plain', _('Plain text')), ('html', _('HTML'))) identifier = "send_email" template_use = TemplateUse.MULTILINGUAL template_fields = { "subject": forms.CharField(required=True, label=_(u"Subject")), "body": forms.CharField(required=True, label=_(u"Email Body"), widget=forms.Textarea()), "content_type": forms.ChoiceField(required=True, label=_(u"Content type"), choices=EMAIL_CONTENT_TYPE_CHOICES) } recipient = Binding(_("Recipient"), type=Email, constant_use=ConstantUse.VARIABLE_OR_CONSTANT, required=True) language = Binding(_("Language"), type=Language, constant_use=ConstantUse.VARIABLE_OR_CONSTANT, required=True) fallback_language = Binding(_("Fallback language"), type=Language, constant_use=ConstantUse.CONSTANT_ONLY, default="en") send_identifier = Binding( _("Send Identifier"), type=Text, constant_use=ConstantUse.CONSTANT_ONLY, required=False, help_text=_( "If set, this identifier will be logged into the event's log target. If the identifier has already " "been logged, the e-mail won't be sent again.")) def execute(self, context): """ :param context: Script Context :type context: shuup.notify.script.Context """ recipient = self.get_value(context, "recipient") if not recipient: context.log(logging.INFO, "%s: Not sending mail, no recipient", self.identifier) return send_identifier = self.get_value(context, "send_identifier") if send_identifier and context.log_entry_queryset.filter( identifier=send_identifier).exists(): context.log(logging.INFO, "%s: Not sending mail, have sent it already (%r)", self.identifier, send_identifier) return languages = [ language for language in [ self.get_value(context, "language"), self.get_value(context, "fallback_language"), ] if language ] strings = self.get_template_values(context, languages) subject = strings.get("subject") body = strings.get("body") content_type = strings.get("content_type") if not (subject and body): context.log( logging.INFO, "%s: Not sending mail to %s, either subject or body empty", self.identifier, recipient) return subject = " ".join( subject.splitlines()) # Email headers may not contain newlines message = EmailMessage(subject=subject, body=body, to=[recipient]) message.content_subtype = content_type message.send() context.log(logging.INFO, "%s: Mail sent to %s :)", self.identifier, recipient) if send_identifier: context.add_log_entry_on_log_target( "Email sent to %s: %s" % (recipient, subject), send_identifier)
def test_binding_fallthrough(): ctx = Context.from_variables() b = Binding("x", default="foo") assert b.get_value(ctx, {"variable": "var"}) == "foo" assert b.get_value(ctx, {}) == "foo"
def test_model_type_matching(): assert empty_iterable( Binding("x", type=Model("shuup.Contact")).get_matching_types( ATestEvent.variables)) assert Binding("x", type=Model("shuup.Order")).get_matching_types( ATestEvent.variables) == {"order"}
def test_text_type_matches_all(): assert Binding("x", type=Text).get_matching_types( ATestEvent.variables) == set(ATestEvent.variables.keys())
def test_simple_type_matching(): assert Binding("x", type=Language).get_matching_types( ATestEvent.variables) == {"order_language"}
class SendEmail(Action): EMAIL_CONTENT_TYPE_CHOICES = (('plain', _('Plain text')), ('html', _('HTML'))) identifier = "send_email" template_use = TemplateUse.MULTILINGUAL template_fields = { "subject": forms.CharField(required=True, label=_(u"Subject")), "body_template": forms.CharField( required=False, label=_("Body Template"), help_text=_( "You can use this template to wrap the HTML body with your custom static template." "Mark the spot for the HTML body with %html_body%."), widget=forms.Textarea()), "body": forms.CharField(required=True, label=_("Email Body"), widget=TextEditorWidget()), "content_type": forms.ChoiceField(required=True, label=_(u"Content type"), choices=EMAIL_CONTENT_TYPE_CHOICES, initial=EMAIL_CONTENT_TYPE_CHOICES[0][0]) } recipient = Binding(_("Recipient"), type=Email, constant_use=ConstantUse.VARIABLE_OR_CONSTANT, required=True) reply_to_address = Binding(_("Reply-To"), type=Email, constant_use=ConstantUse.VARIABLE_OR_CONSTANT) cc = Binding( _("Carbon Copy (CC)"), type=Email, constant_use=ConstantUse.VARIABLE_OR_CONSTANT, ) bcc = Binding(_("Blind Carbon Copy (BCC)"), type=Email, constant_use=ConstantUse.VARIABLE_OR_CONSTANT) from_email = Binding( _("From email"), type=Text, constant_use=ConstantUse.VARIABLE_OR_CONSTANT, required=False, help_text=_( 'Override the default from email to be used. ' 'It can either be binded to a variable or be a constant like ' '[email protected] or even "Store Support" <*****@*****.**>.')) language = Binding(_("Language"), type=Language, constant_use=ConstantUse.VARIABLE_OR_CONSTANT, required=True) fallback_language = Binding(_("Fallback language"), type=Language, constant_use=ConstantUse.CONSTANT_ONLY, default=settings.PARLER_DEFAULT_LANGUAGE_CODE) send_identifier = Binding( _("Send Identifier"), type=Text, constant_use=ConstantUse.CONSTANT_ONLY, required=False, help_text=_( "If set, this identifier will be logged into the event's log target. If the identifier has already " "been logged, the e-mail won't be sent again.")) def execute(self, context): """ :param context: Script Context. :type context: shuup.notify.script.Context """ recipient = get_email_list(self.get_value(context, "recipient")) if not recipient: context.log(logging.INFO, "Info! %s: Not sending mail, no recipient.", self.identifier) return send_identifier = self.get_value(context, "send_identifier") if send_identifier and context.log_entry_queryset.filter( identifier=send_identifier).exists(): context.log( logging.INFO, "Info! %s: Not sending mail, it was already sent (%r).", self.identifier, send_identifier) return languages = [ language for language in [ self.get_value(context, "language"), self.get_value(context, "fallback_language"), ] if language and language in dict(settings.LANGUAGES).keys() ] if not languages: languages = [settings.PARLER_DEFAULT_LANGUAGE_CODE] strings = self.get_template_values(context, languages) subject = strings.get("subject") body = strings.get("body") body_template = strings.get("body_template") if body_template and "%html_body%" in body_template: body = body_template.replace("%html_body%", body) content_type = strings.get("content_type") if not (subject and body): context.log( logging.INFO, "Info! %s: Not sending mail to %s, either subject or body empty.", self.identifier, recipient) return reply_to = get_email_list(self.get_value(context, "reply_to_address")) from_email = self.get_value(context, "from_email") bcc = get_email_list(self.get_value(context, "bcc")) cc = get_email_list(self.get_value(context, "cc")) subject = " ".join( subject.splitlines()) # Email headers may not contain newlines message = EmailMessage(subject=subject, body=body, to=recipient, reply_to=reply_to, from_email=from_email, bcc=bcc, cc=cc) message.content_subtype = content_type message.send() context.log(logging.INFO, "Info! %s: Mail sent to %s.", self.identifier, recipient) if send_identifier: context.add_log_entry_on_log_target( "Info! Email sent to %s: %s" % (recipient, subject), send_identifier)