import json import typing from enum import Enum, auto from liquid import Template from wtforms import fields, validators from core_notifications.helpers.forms import BaseForm from core_notifications.logs import logger class TemplateForm(BaseForm): class Actions(Enum): SAVE = auto() SEND = auto() action = fields.SelectField( choices=[action.name for action in Actions], default=Actions.SAVE.name, ) name = fields.StringField("Name", validators=[validators.DataRequired()]) subject = fields.StringField( "Subject", validators=[validators.DataRequired()] ) source = fields.StringField("Source", validators=[validators.Optional()]) context = fields.StringField("Source", validators=[validators.Optional()]) email = fields.EmailField( "Test email", validators=[validators.Optional(), validators.Email()] ) is_active = fields.BooleanField("Is active") def validate(self, *args, **kwargs): is_valid = super().validate(*args, **kwargs) test_context_data = {} if self["context"].data: try: test_context_data = json.loads(self["context"].data) if test_context_data and not isinstance( test_context_data, typing.Mapping ): test_context_data = {} raise ValueError("Not a mapping") except Exception as e: is_valid = False self["context"].errors.append("Invalid context data") logger.bind(error=e).warning("Invalid context data") try: template = Template(self["subject"].data) template.render(**test_context_data) except Exception as e: is_valid = False self["subject"].errors.append("Invalid template code") logger.bind(error=e).warning("Invalid template code") try: template = Template(self["source"].data) template.render(**test_context_data) except Exception as e: is_valid = False self["source"].errors.append("Invalid template code") logger.bind(error=e).warning("Invalid template code") return is_valid @property def errors_messages(self): messages = [] email_errors = self.errors.get("email") if email_errors: messages.extend(email_errors) return ", ".join(messages)