<s> import re <EOL> import json <EOL> from crispy_forms . bootstrap import StrictButton , InlineField , FormActions <EOL> from crispy_forms . helper import FormHelper <EOL> from crispy_forms . layout import Div <EOL> from django import forms <EOL> from django . core . urlresolvers import reverse <EOL> from django . forms . forms import Form <EOL> from django . forms . fields import * <EOL> from crispy_forms import layout as crispy <EOL> from crispy_forms import bootstrap as twbscrispy <EOL> from django . utils . safestring import mark_safe <EOL> from corehq . apps . hqwebapp . crispy import ( BootstrapMultiField , HiddenFieldWithErrors , FieldsetAccordionGroup ) <EOL> from corehq . apps . style . crispy import FieldWithHelpBubble <EOL> from corehq . apps . style import crispy as hqcrispy <EOL> from corehq . apps . app_manager . dbaccessors import get_built_app_ids <EOL> from corehq . apps . app_manager . models import Application <EOL> from corehq . apps . sms . models import FORWARD_ALL , FORWARD_BY_KEYWORD , SQLMobileBackend <EOL> from django . core . exceptions import ValidationError <EOL> from corehq . apps . reminders . forms import RecordListField , validate_time <EOL> from django . utils . translation import ugettext as _ , ugettext_noop , ugettext_lazy <EOL> from corehq . apps . sms . util import ( validate_phone_number , strip_plus , <EOL> get_sms_backend_classes ) <EOL> from corehq . apps . domain . models import DayTimeWindow <EOL> from corehq . apps . users . models import CommCareUser <EOL> from corehq . apps . groups . models import Group <EOL> from corehq . apps . hqwebapp . crispy import ErrorsOnlyField <EOL> from dimagi . utils . django . fields import TrimmedCharField <EOL> from dimagi . utils . couch . database import iter_docs <EOL> from django . conf import settings <EOL> FORWARDING_CHOICES = ( <EOL> ( FORWARD_ALL , ugettext_noop ( "<STR_LIT>" ) ) , <EOL> ( FORWARD_BY_KEYWORD , ugettext_noop ( "<STR_LIT>" ) ) , <EOL> ) <EOL> ENABLED = "<STR_LIT>" <EOL> DISABLED = "<STR_LIT>" <EOL> ENABLED_DISABLED_CHOICES = ( <EOL> ( DISABLED , ugettext_noop ( "<STR_LIT>" ) ) , <EOL> ( ENABLED , ugettext_noop ( "<STR_LIT>" ) ) , <EOL> ) <EOL> DEFAULT = "<STR_LIT>" <EOL> CUSTOM = "<STR_LIT>" <EOL> DEFAULT_CUSTOM_CHOICES = ( <EOL> ( DEFAULT , ugettext_noop ( "<STR_LIT>" ) ) , <EOL> ( CUSTOM , ugettext_noop ( "<STR_LIT>" ) ) , <EOL> ) <EOL> MESSAGE_COUNTER_CHOICES = ( <EOL> ( DEFAULT , ugettext_noop ( "<STR_LIT>" ) ) , <EOL> ( CUSTOM , ugettext_noop ( "<STR_LIT>" ) ) , <EOL> ) <EOL> SMS_CONVERSATION_LENGTH_CHOICES = ( <EOL> ( <NUM_LIT:5> , <NUM_LIT:5> ) , <EOL> ( <NUM_LIT:10> , <NUM_LIT:10> ) , <EOL> ( <NUM_LIT:15> , <NUM_LIT:15> ) , <EOL> ( <NUM_LIT:20> , <NUM_LIT:20> ) , <EOL> ( <NUM_LIT> , <NUM_LIT> ) , <EOL> ( <NUM_LIT:30> , <NUM_LIT:30> ) , <EOL> ) <EOL> SHOW_ALL = "<STR_LIT>" <EOL> SHOW_INVALID = "<STR_LIT>" <EOL> HIDE_ALL = "<STR_LIT>" <EOL> TIME_BEFORE = "<STR_LIT>" <EOL> TIME_AFTER = "<STR_LIT>" <EOL> TIME_BETWEEN = "<STR_LIT>" <EOL> WELCOME_RECIPIENT_NONE = '<STR_LIT>' <EOL> WELCOME_RECIPIENT_CASE = '<STR_LIT>' <EOL> WELCOME_RECIPIENT_MOBILE_WORKER = '<STR_LIT>' <EOL> WELCOME_RECIPIENT_ALL = '<STR_LIT>' <EOL> WELCOME_RECIPIENT_CHOICES = ( <EOL> ( WELCOME_RECIPIENT_NONE , ugettext_lazy ( '<STR_LIT>' ) ) , <EOL> ( WELCOME_RECIPIENT_CASE , ugettext_lazy ( '<STR_LIT>' ) ) , <EOL> ( WELCOME_RECIPIENT_MOBILE_WORKER , ugettext_lazy ( '<STR_LIT>' ) ) , <EOL> ( WELCOME_RECIPIENT_ALL , ugettext_lazy ( '<STR_LIT>' ) ) , <EOL> ) <EOL> class ForwardingRuleForm ( Form ) : <EOL> forward_type = ChoiceField ( choices = FORWARDING_CHOICES ) <EOL> keyword = CharField ( required = False ) <EOL> backend_id = CharField ( ) <EOL> def clean_keyword ( self ) : <EOL> forward_type = self . cleaned_data . get ( "<STR_LIT>" ) <EOL> keyword = self . cleaned_data . get ( "<STR_LIT>" , "<STR_LIT>" ) . strip ( ) <EOL> if forward_type == FORWARD_BY_KEYWORD : <EOL> if keyword == "<STR_LIT>" : <EOL> raise ValidationError ( _ ( "<STR_LIT>" ) ) <EOL> return keyword <EOL> else : <EOL> return None <EOL> class LoadBalancingBackendFormMixin ( Form ) : <EOL> phone_numbers = CharField ( required = False ) <EOL> def clean_phone_numbers ( self ) : <EOL> """<STR_LIT>""" <EOL> value = self . cleaned_data . get ( "<STR_LIT>" ) <EOL> result = [ ] <EOL> try : <EOL> value = json . loads ( value ) <EOL> assert isinstance ( value , list ) <EOL> for item in value : <EOL> assert isinstance ( item , dict ) <EOL> assert "<STR_LIT>" in item <EOL> result . append ( item [ "<STR_LIT>" ] ) <EOL> except ( AssertionError , ValueError ) : <EOL> raise ValidationError ( _ ( "<STR_LIT>" <EOL> "<STR_LIT>" ) ) <EOL> if len ( result ) == <NUM_LIT:0> : <EOL> raise ValidationError ( _ ( "<STR_LIT>" <EOL> "<STR_LIT>" ) ) <EOL> for phone_number in result : <EOL> validate_phone_number ( phone_number ) <EOL> return result <EOL> class SettingsForm ( Form ) : <EOL> use_default_sms_response = ChoiceField ( <EOL> required = False , <EOL> label = ugettext_noop ( "<STR_LIT>" ) , <EOL> choices = ENABLED_DISABLED_CHOICES , <EOL> ) <EOL> default_sms_response = TrimmedCharField ( <EOL> required = False , <EOL> label = "<STR_LIT>" , <EOL> ) <EOL> use_restricted_sms_times = ChoiceField ( <EOL> required = False , <EOL> label = ugettext_noop ( "<STR_LIT>" ) , <EOL> choices = ( <EOL> ( DISABLED , ugettext_noop ( "<STR_LIT>" ) ) , <EOL> ( ENABLED , ugettext_noop ( "<STR_LIT>" ) ) , <EOL> ) , <EOL> ) <EOL> restricted_sms_times_json = CharField ( <EOL> required = False , <EOL> widget = forms . HiddenInput , <EOL> ) <EOL> send_to_duplicated_case_numbers = ChoiceField ( <EOL> required = False , <EOL> label = ugettext_noop ( "<STR_LIT>" ) , <EOL> choices = ENABLED_DISABLED_CHOICES , <EOL> ) <EOL> use_custom_case_username = ChoiceField ( <EOL> required = False , <EOL> choices = DEFAULT_CUSTOM_CHOICES , <EOL> ) <EOL> custom_case_username = TrimmedCharField ( <EOL> required = False , <EOL> label = ugettext_noop ( "<STR_LIT>" ) , <EOL> ) <EOL> use_custom_message_count_threshold = ChoiceField ( <EOL> required = False , <EOL> choices = MESSAGE_COUNTER_CHOICES , <EOL> ) <EOL> custom_message_count_threshold = IntegerField ( <EOL> required = False , <EOL> label = ugettext_noop ( "<STR_LIT>" ) , <EOL> ) <EOL> use_sms_conversation_times = ChoiceField ( <EOL> required = False , <EOL> label = ugettext_noop ( "<STR_LIT>" ) , <EOL> choices = ENABLED_DISABLED_CHOICES , <EOL> ) <EOL> sms_conversation_times_json = CharField ( <EOL> required = False , <EOL> widget = forms . HiddenInput , <EOL> ) <EOL> sms_conversation_length = ChoiceField ( <EOL> required = False , <EOL> label = ugettext_noop ( "<STR_LIT>" ) , <EOL> choices = SMS_CONVERSATION_LENGTH_CHOICES , <EOL> ) <EOL> survey_traffic_option = ChoiceField ( <EOL> required = False , <EOL> label = ugettext_noop ( "<STR_LIT>" ) , <EOL> choices = ( <EOL> ( SHOW_ALL , ugettext_noop ( "<STR_LIT>" ) ) , <EOL> ( SHOW_INVALID , ugettext_noop ( "<STR_LIT>" <EOL> "<STR_LIT>" ) ) , <EOL> ( HIDE_ALL , ugettext_noop ( "<STR_LIT>" ) ) , <EOL> ) , <EOL> ) <EOL> count_messages_as_read_by_anyone = ChoiceField ( <EOL> required = False , <EOL> label = ugettext_noop ( "<STR_LIT>" ) , <EOL> choices = ( <EOL> ( ENABLED , ugettext_noop ( "<STR_LIT>" ) ) , <EOL> ( DISABLED , ugettext_noop ( "<STR_LIT>" ) ) , <EOL> ) , <EOL> ) <EOL> use_custom_chat_template = ChoiceField ( <EOL> required = False , <EOL> choices = DEFAULT_CUSTOM_CHOICES , <EOL> ) <EOL> custom_chat_template = TrimmedCharField ( <EOL> required = False , <EOL> label = ugettext_noop ( "<STR_LIT>" ) , <EOL> ) <EOL> sms_case_registration_enabled = ChoiceField ( <EOL> required = False , <EOL> choices = ENABLED_DISABLED_CHOICES , <EOL> label = ugettext_noop ( "<STR_LIT>" ) , <EOL> ) <EOL> sms_case_registration_type = TrimmedCharField ( <EOL> required = False , <EOL> label = ugettext_noop ( "<STR_LIT>" ) , <EOL> ) <EOL> sms_case_registration_owner_id = ChoiceField ( <EOL> required = False , <EOL> label = ugettext_noop ( "<STR_LIT>" ) , <EOL> ) <EOL> sms_case_registration_user_id = ChoiceField ( <EOL> required = False , <EOL> label = ugettext_noop ( "<STR_LIT>" ) , <EOL> ) <EOL> sms_mobile_worker_registration_enabled = ChoiceField ( <EOL> required = False , <EOL> choices = ENABLED_DISABLED_CHOICES , <EOL> label = ugettext_noop ( "<STR_LIT>" ) , <EOL> ) <EOL> registration_welcome_message = ChoiceField ( <EOL> choices = WELCOME_RECIPIENT_CHOICES , <EOL> label = ugettext_lazy ( "<STR_LIT>" ) , <EOL> ) <EOL> @ property <EOL> def section_general ( self ) : <EOL> fields = [ <EOL> hqcrispy . B3MultiField ( <EOL> _ ( "<STR_LIT>" ) , <EOL> crispy . Div ( <EOL> InlineField ( <EOL> "<STR_LIT>" , <EOL> data_bind = "<STR_LIT>" , <EOL> ) , <EOL> css_class = '<STR_LIT>' <EOL> ) , <EOL> crispy . Div ( <EOL> InlineField ( <EOL> "<STR_LIT>" , <EOL> css_class = "<STR_LIT>" , <EOL> placeholder = _ ( "<STR_LIT>" ) , <EOL> data_bind = "<STR_LIT>" , <EOL> ) , <EOL> css_class = '<STR_LIT>' <EOL> ) , <EOL> help_bubble_text = _ ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> css_id = "<STR_LIT>" , <EOL> field_class = '<STR_LIT>' <EOL> ) , <EOL> FieldWithHelpBubble ( <EOL> "<STR_LIT>" , <EOL> data_bind = "<STR_LIT>" , <EOL> help_bubble_text = _ ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> ) , <EOL> hqcrispy . B3MultiField ( <EOL> "<STR_LIT>" , <EOL> HiddenFieldWithErrors ( "<STR_LIT>" , <EOL> data_bind = "<STR_LIT>" ) , <EOL> crispy . Div ( <EOL> data_bind = "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT:}>" , <EOL> ) , <EOL> data_bind = "<STR_LIT>" , <EOL> field_class = '<STR_LIT>' <EOL> ) , <EOL> FieldWithHelpBubble ( <EOL> "<STR_LIT>" , <EOL> help_bubble_text = _ ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> ) , <EOL> ] <EOL> return crispy . Fieldset ( <EOL> _ ( "<STR_LIT>" ) , <EOL> * fields <EOL> ) <EOL> @ property <EOL> def section_registration ( self ) : <EOL> fields = [ <EOL> FieldWithHelpBubble ( <EOL> "<STR_LIT>" , <EOL> help_bubble_text = _ ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> data_bind = "<STR_LIT>" , <EOL> ) , <EOL> crispy . Div ( <EOL> FieldWithHelpBubble ( <EOL> "<STR_LIT>" , <EOL> placeholder = _ ( "<STR_LIT>" ) , <EOL> help_bubble_text = _ ( "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> ) , <EOL> FieldWithHelpBubble ( <EOL> "<STR_LIT>" , <EOL> help_bubble_text = _ ( "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> ) , <EOL> FieldWithHelpBubble ( <EOL> "<STR_LIT>" , <EOL> help_bubble_text = _ ( "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> ) , <EOL> data_bind = "<STR_LIT>" , <EOL> ) , <EOL> FieldWithHelpBubble ( <EOL> "<STR_LIT>" , <EOL> help_bubble_text = _ ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> ) , <EOL> FieldWithHelpBubble ( <EOL> '<STR_LIT>' , <EOL> help_bubble_text = _ ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> ) , <EOL> ] <EOL> return crispy . Fieldset ( <EOL> _ ( "<STR_LIT>" ) , <EOL> * fields <EOL> ) <EOL> @ property <EOL> def section_chat ( self ) : <EOL> fields = [ <EOL> hqcrispy . B3MultiField ( <EOL> _ ( "<STR_LIT>" ) , <EOL> crispy . Div ( <EOL> InlineField ( <EOL> "<STR_LIT>" , <EOL> data_bind = "<STR_LIT>" , <EOL> ) , <EOL> css_class = '<STR_LIT>' <EOL> ) , <EOL> crispy . Div ( <EOL> InlineField ( <EOL> "<STR_LIT>" , <EOL> css_class = "<STR_LIT>" , <EOL> data_bind = "<STR_LIT>" , <EOL> ) , <EOL> css_class = '<STR_LIT>' <EOL> ) , <EOL> help_bubble_text = _ ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> css_id = "<STR_LIT>" , <EOL> field_class = '<STR_LIT>' <EOL> ) , <EOL> hqcrispy . B3MultiField ( <EOL> _ ( "<STR_LIT>" ) , <EOL> crispy . Div ( <EOL> InlineField ( <EOL> "<STR_LIT>" , <EOL> data_bind = "<STR_LIT>" , <EOL> ) , <EOL> css_class = '<STR_LIT>' <EOL> ) , <EOL> crispy . Div ( <EOL> InlineField ( <EOL> "<STR_LIT>" , <EOL> css_class = "<STR_LIT>" , <EOL> data_bind = "<STR_LIT>" , <EOL> ) , <EOL> css_class = '<STR_LIT>' <EOL> ) , <EOL> help_bubble_text = _ ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> css_id = "<STR_LIT>" , <EOL> field_class = '<STR_LIT>' <EOL> ) , <EOL> FieldWithHelpBubble ( <EOL> "<STR_LIT>" , <EOL> data_bind = "<STR_LIT>" , <EOL> help_bubble_text = _ ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> ) , <EOL> hqcrispy . B3MultiField ( <EOL> "<STR_LIT>" , <EOL> HiddenFieldWithErrors ( "<STR_LIT>" , <EOL> data_bind = "<STR_LIT>" ) , <EOL> crispy . Div ( <EOL> data_bind = "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT:}>" , <EOL> ) , <EOL> data_bind = "<STR_LIT>" , <EOL> label_class = '<STR_LIT>' , <EOL> field_class = '<STR_LIT>' <EOL> ) , <EOL> crispy . Div ( <EOL> FieldWithHelpBubble ( <EOL> "<STR_LIT>" , <EOL> help_bubble_text = _ ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> ) , <EOL> data_bind = "<STR_LIT>" , <EOL> ) , <EOL> FieldWithHelpBubble ( <EOL> "<STR_LIT>" , <EOL> help_bubble_text = _ ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> ) , <EOL> FieldWithHelpBubble ( <EOL> "<STR_LIT>" , <EOL> help_bubble_text = _ ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> ) , <EOL> ] <EOL> if self . _cchq_is_previewer : <EOL> fields . append ( <EOL> hqcrispy . B3MultiField ( <EOL> _ ( "<STR_LIT>" ) , <EOL> crispy . Div ( <EOL> InlineField ( <EOL> "<STR_LIT>" , <EOL> data_bind = "<STR_LIT>" , <EOL> ) , <EOL> css_class = '<STR_LIT>' <EOL> ) , <EOL> crispy . Div ( <EOL> InlineField ( <EOL> "<STR_LIT>" , <EOL> data_bind = "<STR_LIT>" , <EOL> ) , <EOL> css_class = '<STR_LIT>' <EOL> ) , <EOL> help_bubble_text = _ ( "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> css_id = "<STR_LIT>" , <EOL> field_class = '<STR_LIT>' <EOL> ) <EOL> ) <EOL> return crispy . Fieldset ( <EOL> _ ( "<STR_LIT>" ) , <EOL> * fields <EOL> ) <EOL> def __init__ ( self , data = None , cchq_domain = None , cchq_is_previewer = False , <EOL> * args , ** kwargs ) : <EOL> self . _cchq_domain = cchq_domain <EOL> self . _cchq_is_previewer = cchq_is_previewer <EOL> super ( SettingsForm , self ) . __init__ ( data , * args , ** kwargs ) <EOL> self . populate_dynamic_choices ( ) <EOL> self . helper = FormHelper ( ) <EOL> self . helper . form_class = "<STR_LIT>" <EOL> self . helper . label_class = '<STR_LIT>' <EOL> self . helper . field_class = '<STR_LIT>' <EOL> self . helper . layout = crispy . Layout ( <EOL> self . section_general , <EOL> self . section_registration , <EOL> self . section_chat , <EOL> hqcrispy . FormActions ( <EOL> twbscrispy . StrictButton ( <EOL> _ ( "<STR_LIT>" ) , <EOL> type = "<STR_LIT>" , <EOL> css_class = "<STR_LIT>" , <EOL> ) , <EOL> ) , <EOL> ) <EOL> self . restricted_sms_times_widget_context = { <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : _ ( "<STR_LIT>" ) , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> } <EOL> self . sms_conversation_times_widget_context = { <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : _ ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> } <EOL> @ property <EOL> def enable_registration_welcome_sms_for_case ( self ) : <EOL> return ( self . cleaned_data . get ( '<STR_LIT>' ) in <EOL> ( WELCOME_RECIPIENT_CASE , WELCOME_RECIPIENT_ALL ) ) <EOL> @ property <EOL> def enable_registration_welcome_sms_for_mobile_worker ( self ) : <EOL> return ( self . cleaned_data . get ( '<STR_LIT>' ) in <EOL> ( WELCOME_RECIPIENT_MOBILE_WORKER , WELCOME_RECIPIENT_ALL ) ) <EOL> @ property <EOL> def current_values ( self ) : <EOL> current_values = { } <EOL> for field_name in self . fields . keys ( ) : <EOL> value = self [ field_name ] . value ( ) <EOL> if field_name in [ "<STR_LIT>" , <EOL> "<STR_LIT>" ] : <EOL> if isinstance ( value , basestring ) : <EOL> current_values [ field_name ] = json . loads ( value ) <EOL> else : <EOL> current_values [ field_name ] = value <EOL> else : <EOL> current_values [ field_name ] = value <EOL> return current_values <EOL> def populate_dynamic_choices ( self ) : <EOL> groups = Group . get_case_sharing_groups ( self . _cchq_domain ) <EOL> users = CommCareUser . by_domain ( self . _cchq_domain ) <EOL> domain_group_choices = [ ( group . _id , group . name ) for group in groups ] <EOL> domain_user_choices = [ ( user . _id , user . raw_username ) for user in users ] <EOL> domain_owner_choices = domain_group_choices + domain_user_choices <EOL> choose = [ ( "<STR_LIT>" , _ ( "<STR_LIT>" ) ) ] <EOL> self . fields [ "<STR_LIT>" ] . choices = ( <EOL> choose + domain_owner_choices ) <EOL> self . fields [ "<STR_LIT>" ] . choices = ( <EOL> choose + domain_user_choices ) <EOL> def _clean_dependent_field ( self , bool_field , field ) : <EOL> if self . cleaned_data . get ( bool_field ) : <EOL> value = self . cleaned_data . get ( field , None ) <EOL> if not value : <EOL> raise ValidationError ( _ ( "<STR_LIT>" ) ) <EOL> return value <EOL> else : <EOL> return None <EOL> def clean_use_default_sms_response ( self ) : <EOL> return self . cleaned_data . get ( "<STR_LIT>" ) == ENABLED <EOL> def clean_default_sms_response ( self ) : <EOL> return self . _clean_dependent_field ( "<STR_LIT>" , <EOL> "<STR_LIT>" ) <EOL> def clean_use_custom_case_username ( self ) : <EOL> return self . cleaned_data . get ( "<STR_LIT>" ) == CUSTOM <EOL> def clean_custom_case_username ( self ) : <EOL> return self . _clean_dependent_field ( "<STR_LIT>" , <EOL> "<STR_LIT>" ) <EOL> def clean_use_custom_message_count_threshold ( self ) : <EOL> return ( self . cleaned_data . get ( "<STR_LIT>" ) <EOL> == CUSTOM ) <EOL> def clean_custom_message_count_threshold ( self ) : <EOL> value = self . _clean_dependent_field ( "<STR_LIT>" , <EOL> "<STR_LIT>" ) <EOL> if value is not None and value <= <NUM_LIT:0> : <EOL> raise ValidationError ( _ ( "<STR_LIT>" ) ) <EOL> return value <EOL> def clean_use_custom_chat_template ( self ) : <EOL> if not self . _cchq_is_previewer : <EOL> return None <EOL> return self . cleaned_data . get ( "<STR_LIT>" ) == CUSTOM <EOL> def clean_custom_chat_template ( self ) : <EOL> if not self . _cchq_is_previewer : <EOL> return None <EOL> value = self . _clean_dependent_field ( "<STR_LIT>" , <EOL> "<STR_LIT>" ) <EOL> if value is not None and value not in settings . CUSTOM_CHAT_TEMPLATES : <EOL> raise ValidationError ( _ ( "<STR_LIT>" ) ) <EOL> return value <EOL> def _clean_time_window_json ( self , field_name ) : <EOL> try : <EOL> time_window_json = json . loads ( self . cleaned_data . get ( field_name ) ) <EOL> except ValueError : <EOL> raise ValidationError ( _ ( "<STR_LIT>" <EOL> "<STR_LIT>" ) ) <EOL> result = [ ] <EOL> for window in time_window_json : <EOL> day = window . get ( "<STR_LIT>" ) <EOL> start_time = window . get ( "<STR_LIT>" ) <EOL> end_time = window . get ( "<STR_LIT>" ) <EOL> time_input_relationship = window . get ( "<STR_LIT>" ) <EOL> try : <EOL> day = int ( day ) <EOL> assert day >= - <NUM_LIT:1> and day <= <NUM_LIT:6> <EOL> except ( ValueError , AssertionError ) : <EOL> raise ValidationError ( _ ( "<STR_LIT>" ) ) <EOL> if time_input_relationship == TIME_BEFORE : <EOL> end_time = validate_time ( end_time ) <EOL> result . append ( DayTimeWindow ( <EOL> day = day , <EOL> start_time = None , <EOL> end_time = end_time , <EOL> ) ) <EOL> elif time_input_relationship == TIME_AFTER : <EOL> start_time = validate_time ( start_time ) <EOL> result . append ( DayTimeWindow ( <EOL> day = day , <EOL> start_time = start_time , <EOL> end_time = None , <EOL> ) ) <EOL> else : <EOL> start_time = validate_time ( start_time ) <EOL> end_time = validate_time ( end_time ) <EOL> if start_time >= end_time : <EOL> raise ValidationError ( _ ( "<STR_LIT>" <EOL> "<STR_LIT>" ) ) <EOL> result . append ( DayTimeWindow ( <EOL> day = day , <EOL> start_time = start_time , <EOL> end_time = end_time , <EOL> ) ) <EOL> return result <EOL> def clean_use_restricted_sms_times ( self ) : <EOL> return self . cleaned_data . get ( "<STR_LIT>" ) == ENABLED <EOL> def clean_restricted_sms_times_json ( self ) : <EOL> if self . cleaned_data . get ( "<STR_LIT>" ) : <EOL> return self . _clean_time_window_json ( "<STR_LIT>" ) <EOL> else : <EOL> return [ ] <EOL> def clean_use_sms_conversation_times ( self ) : <EOL> return self . cleaned_data . get ( "<STR_LIT>" ) == ENABLED <EOL> def clean_sms_conversation_times_json ( self ) : <EOL> if self . cleaned_data . get ( "<STR_LIT>" ) : <EOL> return self . _clean_time_window_json ( "<STR_LIT>" ) <EOL> else : <EOL> return [ ] <EOL> def clean_send_to_duplicated_case_numbers ( self ) : <EOL> return ( self . cleaned_data . get ( "<STR_LIT>" ) <EOL> == ENABLED ) <EOL> def clean_count_messages_as_read_by_anyone ( self ) : <EOL> return ( self . cleaned_data . get ( "<STR_LIT>" ) <EOL> == ENABLED ) <EOL> def clean_sms_case_registration_enabled ( self ) : <EOL> return ( self . cleaned_data . get ( "<STR_LIT>" ) <EOL> == ENABLED ) <EOL> def clean_sms_case_registration_type ( self ) : <EOL> return self . _clean_dependent_field ( "<STR_LIT>" , <EOL> "<STR_LIT>" ) <EOL> def _clean_registration_id_field ( self , field_name ) : <EOL> if self . cleaned_data . get ( "<STR_LIT>" ) : <EOL> value = self . cleaned_data . get ( field_name ) <EOL> if not value : <EOL> raise ValidationError ( _ ( "<STR_LIT>" ) ) <EOL> return value <EOL> else : <EOL> return None <EOL> def clean_sms_case_registration_owner_id ( self ) : <EOL> return self . _clean_registration_id_field ( "<STR_LIT>" ) <EOL> def clean_sms_case_registration_user_id ( self ) : <EOL> return self . _clean_registration_id_field ( "<STR_LIT>" ) <EOL> def clean_sms_mobile_worker_registration_enabled ( self ) : <EOL> return ( self . cleaned_data . get ( "<STR_LIT>" ) <EOL> == ENABLED ) <EOL> def clean_sms_conversation_length ( self ) : <EOL> return int ( self . cleaned_data . get ( "<STR_LIT>" ) ) <EOL> class BackendForm ( Form ) : <EOL> _cchq_domain = None <EOL> _cchq_backend_id = None <EOL> name = CharField ( <EOL> label = ugettext_noop ( "<STR_LIT:Name>" ) <EOL> ) <EOL> description = CharField ( <EOL> label = ugettext_noop ( "<STR_LIT>" ) , <EOL> widget = forms . Textarea , <EOL> required = False , <EOL> ) <EOL> give_other_domains_access = BooleanField ( <EOL> required = False , <EOL> label = ugettext_noop ( "<STR_LIT>" ) <EOL> ) <EOL> authorized_domains = CharField ( <EOL> required = False , <EOL> label = ugettext_noop ( "<STR_LIT>" ) <EOL> ) <EOL> reply_to_phone_number = CharField ( <EOL> required = False , <EOL> label = ugettext_noop ( "<STR_LIT>" ) , <EOL> ) <EOL> @ property <EOL> def is_global_backend ( self ) : <EOL> return self . _cchq_domain is None <EOL> @ property <EOL> def general_fields ( self ) : <EOL> fields = [ <EOL> crispy . Field ( '<STR_LIT:name>' , css_class = '<STR_LIT>' ) , <EOL> crispy . Field ( '<STR_LIT:description>' , css_class = '<STR_LIT>' , rows = "<STR_LIT:3>" ) , <EOL> crispy . Field ( '<STR_LIT>' , css_class = '<STR_LIT>' ) , <EOL> ] <EOL> if not self . is_global_backend : <EOL> fields . extend ( [ <EOL> crispy . Field ( <EOL> twbscrispy . PrependedText ( <EOL> '<STR_LIT>' , '<STR_LIT>' , data_bind = "<STR_LIT>" <EOL> ) <EOL> ) , <EOL> crispy . Div ( <EOL> '<STR_LIT>' , <EOL> data_bind = "<STR_LIT>" , <EOL> ) , <EOL> ] ) <EOL> return fields <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> button_text = kwargs . pop ( '<STR_LIT>' , _ ( "<STR_LIT>" ) ) <EOL> self . _cchq_domain = kwargs . pop ( '<STR_LIT>' ) <EOL> self . _cchq_backend_id = kwargs . pop ( '<STR_LIT>' ) <EOL> super ( BackendForm , self ) . __init__ ( * args , ** kwargs ) <EOL> self . helper = FormHelper ( ) <EOL> self . helper . form_class = '<STR_LIT>' <EOL> self . helper . label_class = '<STR_LIT>' <EOL> self . helper . field_class = '<STR_LIT>' <EOL> self . helper . form_method = '<STR_LIT:POST>' <EOL> self . helper . layout = crispy . Layout ( <EOL> crispy . Fieldset ( <EOL> _ ( '<STR_LIT>' ) , <EOL> * self . general_fields <EOL> ) , <EOL> self . gateway_specific_fields , <EOL> crispy . Fieldset ( <EOL> _ ( "<STR_LIT>" ) , <EOL> crispy . Div ( <EOL> data_bind = "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT:}>" , <EOL> ) , <EOL> data_bind = "<STR_LIT>" , <EOL> ) , <EOL> hqcrispy . FormActions ( <EOL> StrictButton ( <EOL> button_text , <EOL> type = "<STR_LIT>" , <EOL> css_class = '<STR_LIT>' <EOL> ) , <EOL> ) , <EOL> ) <EOL> @ property <EOL> def gateway_specific_fields ( self ) : <EOL> return crispy . Div ( ) <EOL> def clean_name ( self ) : <EOL> value = self . cleaned_data . get ( "<STR_LIT:name>" ) <EOL> if value is not None : <EOL> value = value . strip ( ) . upper ( ) <EOL> if value is None or value == "<STR_LIT>" : <EOL> raise ValidationError ( _ ( "<STR_LIT>" ) ) <EOL> if re . compile ( "<STR_LIT>" ) . search ( value ) is not None : <EOL> raise ValidationError ( _ ( "<STR_LIT>" ) ) <EOL> if self . is_global_backend : <EOL> is_unique = SQLMobileBackend . name_is_unique ( <EOL> value , <EOL> backend_id = self . _cchq_backend_id <EOL> ) <EOL> else : <EOL> is_unique = SQLMobileBackend . name_is_unique ( <EOL> value , <EOL> domain = self . _cchq_domain , <EOL> backend_id = self . _cchq_backend_id <EOL> ) <EOL> if not is_unique : <EOL> raise ValidationError ( _ ( "<STR_LIT>" ) ) <EOL> return value <EOL> def clean_authorized_domains ( self ) : <EOL> if not self . cleaned_data . get ( "<STR_LIT>" ) : <EOL> return [ ] <EOL> else : <EOL> value = self . cleaned_data . get ( "<STR_LIT>" ) <EOL> if value is None or value . strip ( ) == "<STR_LIT>" : <EOL> return [ ] <EOL> else : <EOL> return [ domain . strip ( ) for domain in value . split ( "<STR_LIT:U+002C>" ) ] <EOL> def clean_reply_to_phone_number ( self ) : <EOL> value = self . cleaned_data . get ( "<STR_LIT>" ) <EOL> if value is None : <EOL> return None <EOL> else : <EOL> value = value . strip ( ) <EOL> if value == "<STR_LIT>" : <EOL> return None <EOL> else : <EOL> return value <EOL> class BackendMapForm ( Form ) : <EOL> catchall_backend_id = ChoiceField ( <EOL> label = ugettext_lazy ( "<STR_LIT>" ) , <EOL> required = False <EOL> ) <EOL> backend_map = CharField ( required = False ) <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> backends = kwargs . pop ( '<STR_LIT>' ) <EOL> super ( BackendMapForm , self ) . __init__ ( * args , ** kwargs ) <EOL> self . set_catchall_choices ( backends ) <EOL> self . setup_crispy ( ) <EOL> def set_catchall_choices ( self , backends ) : <EOL> backend_choices = [ ( '<STR_LIT>' , _ ( "<STR_LIT>" ) ) ] <EOL> backend_choices . extend ( [ <EOL> ( backend . pk , backend . name ) for backend in backends <EOL> ] ) <EOL> self . fields [ '<STR_LIT>' ] . choices = backend_choices <EOL> def setup_crispy ( self ) : <EOL> self . helper = FormHelper ( ) <EOL> self . helper . form_class = '<STR_LIT>' <EOL> self . helper . label_class = '<STR_LIT>' <EOL> self . helper . field_class = '<STR_LIT>' <EOL> self . helper . form_method = '<STR_LIT:POST>' <EOL> self . helper . layout = crispy . Layout ( <EOL> crispy . Fieldset ( <EOL> _ ( "<STR_LIT>" ) , <EOL> hqcrispy . B3MultiField ( <EOL> _ ( "<STR_LIT>" ) , <EOL> ErrorsOnlyField ( '<STR_LIT>' ) , <EOL> crispy . Div ( <EOL> data_bind = "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT:}>" <EOL> ) , <EOL> ) , <EOL> '<STR_LIT>' , <EOL> ) , <EOL> hqcrispy . FormActions ( <EOL> StrictButton ( <EOL> _ ( "<STR_LIT>" ) , <EOL> type = "<STR_LIT>" , <EOL> css_class = '<STR_LIT>' <EOL> ) , <EOL> ) , <EOL> ) <EOL> def _clean_prefix ( self , prefix ) : <EOL> try : <EOL> prefix = int ( prefix ) <EOL> if prefix <= <NUM_LIT:0> : <EOL> raise ValueError ( ) <EOL> except ( ValueError , TypeError ) : <EOL> raise ValidationError ( _ ( "<STR_LIT>" ) ) <EOL> return str ( prefix ) <EOL> def _clean_backend_id ( self , backend_id ) : <EOL> try : <EOL> backend_id = int ( backend_id ) <EOL> except ( ValueError , TypeError ) : <EOL> raise ValidationError ( _ ( "<STR_LIT>" ) ) <EOL> try : <EOL> backend = SQLMobileBackend . load ( backend_id ) <EOL> except : <EOL> raise ValidationError ( _ ( "<STR_LIT>" ) ) <EOL> if ( <EOL> backend . deleted or <EOL> not backend . is_global or <EOL> backend . backend_type != SQLMobileBackend . SMS <EOL> ) : <EOL> raise ValidationError ( _ ( "<STR_LIT>" ) ) <EOL> return backend_id <EOL> def clean_backend_map ( self ) : <EOL> value = self . cleaned_data . get ( '<STR_LIT>' ) <EOL> try : <EOL> value = json . loads ( value ) <EOL> except : <EOL> raise ValidationError ( _ ( "<STR_LIT>" ) ) <EOL> cleaned_value = { } <EOL> for mapping in value : <EOL> prefix = self . _clean_prefix ( mapping . get ( '<STR_LIT>' ) ) <EOL> if prefix in cleaned_value : <EOL> raise ValidationError ( _ ( "<STR_LIT>" ) % prefix ) <EOL> cleaned_value [ prefix ] = self . _clean_backend_id ( mapping . get ( '<STR_LIT>' ) ) <EOL> return cleaned_value <EOL> def clean_catchall_backend_id ( self ) : <EOL> value = self . cleaned_data . get ( '<STR_LIT>' ) <EOL> if not value : <EOL> return None <EOL> return self . _clean_backend_id ( value ) <EOL> class SendRegistrationInviationsForm ( Form ) : <EOL> phone_numbers = TrimmedCharField ( <EOL> label = ugettext_lazy ( "<STR_LIT>" ) , <EOL> required = True , <EOL> widget = forms . Textarea , <EOL> ) <EOL> app_id = ChoiceField ( <EOL> label = ugettext_lazy ( "<STR_LIT>" ) , <EOL> required = True , <EOL> ) <EOL> action = CharField ( <EOL> initial = '<STR_LIT>' , <EOL> widget = forms . HiddenInput ( ) , <EOL> ) <EOL> def set_app_id_choices ( self ) : <EOL> app_ids = get_built_app_ids ( self . domain ) <EOL> choices = [ ] <EOL> for app_doc in iter_docs ( Application . get_db ( ) , app_ids ) : <EOL> choices . append ( ( app_doc [ '<STR_LIT>' ] , app_doc [ '<STR_LIT:name>' ] ) ) <EOL> choices . sort ( key = lambda x : x [ <NUM_LIT:1> ] ) <EOL> self . fields [ '<STR_LIT>' ] . choices = choices <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> if '<STR_LIT>' not in kwargs : <EOL> raise Exception ( '<STR_LIT>' ) <EOL> self . domain = kwargs . pop ( '<STR_LIT>' ) <EOL> super ( SendRegistrationInviationsForm , self ) . __init__ ( * args , ** kwargs ) <EOL> self . set_app_id_choices ( ) <EOL> self . helper = FormHelper ( ) <EOL> self . helper . form_class = "<STR_LIT>" <EOL> self . helper . layout = crispy . Layout ( <EOL> FieldsetAccordionGroup ( <EOL> _ ( "<STR_LIT>" ) , <EOL> crispy . Field ( '<STR_LIT>' ) , <EOL> crispy . Field ( <EOL> '<STR_LIT>' , <EOL> placeholder = _ ( "<STR_LIT>" <EOL> "<STR_LIT>" ) , <EOL> ) , <EOL> InlineField ( '<STR_LIT:action>' ) , <EOL> FormActions ( <EOL> StrictButton ( <EOL> _ ( "<STR_LIT>" ) , <EOL> type = "<STR_LIT>" , <EOL> css_class = "<STR_LIT>" , <EOL> ) , <EOL> ) , <EOL> active = len ( args ) > <NUM_LIT:0> , <EOL> ) <EOL> ) <EOL> def clean_phone_numbers ( self ) : <EOL> value = self . cleaned_data . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> phone_list = [ strip_plus ( s . strip ( ) ) for s in value . split ( '<STR_LIT:U+002C>' ) ] <EOL> phone_list = [ phone for phone in phone_list if phone ] <EOL> if len ( phone_list ) == <NUM_LIT:0> : <EOL> raise ValidationError ( _ ( "<STR_LIT>" ) ) <EOL> for phone_number in phone_list : <EOL> validate_phone_number ( phone_number ) <EOL> return list ( set ( phone_list ) ) <EOL> class InitiateAddSMSBackendForm ( Form ) : <EOL> action = CharField ( <EOL> initial = '<STR_LIT>' , <EOL> widget = forms . HiddenInput ( ) , <EOL> ) <EOL> hq_api_id = ChoiceField ( <EOL> required = False , <EOL> label = "<STR_LIT>" , <EOL> ) <EOL> def __init__ ( self , is_superuser = False , * args , ** kwargs ) : <EOL> super ( InitiateAddSMSBackendForm , self ) . __init__ ( * args , ** kwargs ) <EOL> from corehq . messaging . smsbackends . telerivet . models import SQLTelerivetBackend <EOL> backend_classes = get_sms_backend_classes ( ) <EOL> backend_choices = [ ] <EOL> for api_id , klass in backend_classes . items ( ) : <EOL> if is_superuser or api_id == SQLTelerivetBackend . get_api_id ( ) : <EOL> friendly_name = klass . get_generic_name ( ) <EOL> backend_choices . append ( ( api_id , friendly_name ) ) <EOL> self . fields [ '<STR_LIT>' ] . choices = backend_choices <EOL> self . helper = FormHelper ( ) <EOL> self . helper . label_class = '<STR_LIT>' <EOL> self . helper . field_class = '<STR_LIT>' <EOL> self . helper . form_class = "<STR_LIT>" <EOL> self . helper . layout = crispy . Layout ( <EOL> hqcrispy . B3MultiField ( <EOL> _ ( "<STR_LIT>" ) , <EOL> InlineField ( '<STR_LIT:action>' ) , <EOL> Div ( InlineField ( '<STR_LIT>' ) , css_class = '<STR_LIT>' ) , <EOL> Div ( StrictButton ( <EOL> mark_safe ( '<STR_LIT>' ) , <EOL> css_class = '<STR_LIT>' , <EOL> type = '<STR_LIT>' , <EOL> style = "<STR_LIT>" <EOL> ) , css_class = '<STR_LIT>' ) , <EOL> ) , <EOL> ) <EOL> class SubscribeSMSForm ( Form ) : <EOL> stock_out_facilities = BooleanField ( <EOL> label = ugettext_lazy ( "<STR_LIT>" ) , <EOL> required = False , <EOL> help_text = ugettext_lazy ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> ) <EOL> ) <EOL> stock_out_commodities = BooleanField ( <EOL> label = ugettext_lazy ( "<STR_LIT>" ) , <EOL> required = False , <EOL> help_text = ugettext_lazy ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> ) <EOL> ) <EOL> stock_out_rates = BooleanField ( <EOL> label = ugettext_lazy ( "<STR_LIT>" ) , <EOL> required = False , <EOL> help_text = ugettext_lazy ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> ) <EOL> ) <EOL> non_report = BooleanField ( <EOL> label = ugettext_lazy ( "<STR_LIT>" ) , <EOL> required = False , <EOL> help_text = ugettext_lazy ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> ) <EOL> ) <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> super ( SubscribeSMSForm , self ) . __init__ ( * args , ** kwargs ) <EOL> self . helper = FormHelper ( ) <EOL> self . helper . form_class = '<STR_LIT>' <EOL> self . helper . label_class = '<STR_LIT>' <EOL> self . helper . field_class = '<STR_LIT>' <EOL> self . helper . layout = crispy . Layout ( <EOL> crispy . Fieldset ( <EOL> _ ( '<STR_LIT>' ) , <EOL> twbscrispy . PrependedText ( '<STR_LIT>' , '<STR_LIT>' ) , <EOL> twbscrispy . PrependedText ( '<STR_LIT>' , '<STR_LIT>' ) , <EOL> twbscrispy . PrependedText ( '<STR_LIT>' , '<STR_LIT>' ) , <EOL> twbscrispy . PrependedText ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> ) , <EOL> hqcrispy . FormActions ( <EOL> twbscrispy . StrictButton ( <EOL> _ ( "<STR_LIT>" ) , <EOL> type = "<STR_LIT>" , <EOL> css_class = "<STR_LIT>" , <EOL> ) , <EOL> ) <EOL> ) <EOL> def save ( self , commtrack_settings ) : <EOL> alert_config = commtrack_settings . alert_config <EOL> alert_config . stock_out_facilities = self . cleaned_data . get ( "<STR_LIT>" , False ) <EOL> alert_config . stock_out_commodities = self . cleaned_data . get ( "<STR_LIT>" , False ) <EOL> alert_config . stock_out_rates = self . cleaned_data . get ( "<STR_LIT>" , False ) <EOL> alert_config . non_report = self . cleaned_data . get ( "<STR_LIT>" , False ) <EOL> commtrack_settings . save ( ) <EOL> class ComposeMessageForm ( forms . Form ) : <EOL> recipients = forms . CharField ( widget = forms . Textarea , <EOL> help_text = ugettext_lazy ( "<STR_LIT>" ) ) <EOL> message = forms . CharField ( widget = forms . Textarea , help_text = ugettext_lazy ( '<STR_LIT>' ) ) <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> domain = kwargs . pop ( '<STR_LIT>' ) <EOL> super ( ComposeMessageForm , self ) . __init__ ( * args , ** kwargs ) <EOL> self . helper = FormHelper ( ) <EOL> self . helper . form_action = reverse ( '<STR_LIT>' , args = [ domain ] ) <EOL> self . helper . form_class = "<STR_LIT>" <EOL> self . helper . label_class = '<STR_LIT>' <EOL> self . helper . field_class = '<STR_LIT>' <EOL> self . helper . layout = crispy . Layout ( <EOL> crispy . Field ( '<STR_LIT>' , rows = <NUM_LIT:2> , css_class = '<STR_LIT>' ) , <EOL> crispy . Field ( '<STR_LIT:message>' , rows = <NUM_LIT:2> ) , <EOL> hqcrispy . FormActions ( <EOL> twbscrispy . StrictButton ( <EOL> _ ( "<STR_LIT>" ) , <EOL> type = "<STR_LIT>" , <EOL> css_class = "<STR_LIT>" , <EOL> ) , <EOL> ) , <EOL> ) </s>
