Exemplo n.º 1
0
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)
Exemplo n.º 2
0
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)
Exemplo n.º 3
0
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,
        )
Exemplo n.º 4
0
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"))
Exemplo n.º 5
0
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"))
Exemplo n.º 6
0
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)
Exemplo n.º 7
0
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"
Exemplo n.º 8
0
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)
Exemplo n.º 9
0
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)
Exemplo n.º 10
0
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"
Exemplo n.º 11
0
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"}
Exemplo n.º 12
0
def test_text_type_matches_all():
    assert Binding("x", type=Text).get_matching_types(
        ATestEvent.variables) == set(ATestEvent.variables.keys())
Exemplo n.º 13
0
def test_simple_type_matching():
    assert Binding("x", type=Language).get_matching_types(
        ATestEvent.variables) == {"order_language"}
Exemplo n.º 14
0
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)