Esempio n. 1
0
    def after_submit(self):
        try:
            """Here we conclude the submission of the form and then we start or not a new
            dialogue. If we start a new dialogue, we restart from the beginning.
            Each time, the state is saved to write the final report"""
            # we increment the nunmer of iteration
            self.iteration_number += 1

            newPageTitle = self.driver.title
            good_style = styles.get_good()
            text = f"{good_style} you have been moved to the page with title {newPageTitle}"
            self.chatbot_view.show_text(self.counter, text)
            self.counter += 1
            # we conclude this log
            self.conclude_log()
            # we add the state to the list
            state = self.current_bot.get_state()
            # we insert the number of not properly handled messages inside the state
            state.constructs[u.form_construct][
                u.number_not_handled] = self.number_not_handled
            self.states_list.append(state)
            # we sample the reports not to loose everything in case of problem
            if self.iteration_number in [50]:
                # write the report
                w.ReportWriter(self.states_list).start()
                self.write_log()
            if self.iteration_number >= self.total_iterations:
                self.restart = False
                self.in_session = False
                return
            restart = None
            while restart is None:
                text = '\n[ALERT: Would you like to start a new dialogue ?\t1- Yes\t0- No\n>>> Response: '
                if u.simulation_enabled:
                    dialogue_state = self.get_dialogue_state()
                    answer, _ = self.user.get_answer(dialogue_state)
                else:
                    answer = input(text)
                try:
                    restart = int(fn.convert_to_int(answer))
                    if restart is None:
                        sorry_style = styles.get_sorry()
                        print(f'{sorry_style} your input is not valid')
                except:
                    sorry_style = styles.get_sorry()
                    print(f'{sorry_style} your input is not valid')
            if restart:
                good_style = styles.get_good()
                print(f'{good_style} we are going to start a new dialogue')
                self.restart = True
                # in any case here in_session should be False to stop the dialogue
                # then we can restart a new dialogue or completely finish
                self.update_parameters()
            else:
                self.restart = False
                self.in_session = False
        except:
            print('Fail to manage the after submission')
            raise Exception
Esempio n. 2
0
 def affirm(self):
     try:
         # we have to verify the state to know what is the affirm for. the variable to check
         # is possible_next_action.
         action_name = self.state.get_possible_next_action()
         if action_name in [u.submit_action, u.reset_all_fields_action]:
             action = self.get_action(action_name)
             string = action(self)
             return string
         elif action_name is None:
             sorry_style = styles.get_sorry()
             text = f'{sorry_style} what exactly do you want to do? If you want, you can:\n{fn.get_functionalities_list()}'
             self.state.set_warning_message(text)
             raise Exception
         string = self.state.manage_next_step()
         _, required = self.state.get_next_slot()
         if not required:
             string = f'{string} otherwise, you can {u.fun_all_fields}, {u.fun_remaining_required_fields} or {u.fun_skip} '
         else:
             string = f'{string} otherwise, you can {u.fun_remaining_required_fields} or {u.fun_form_title}'
         return string
     except:
         if not self.state.get_warning_present():
             print(
                 "A problem occured while a registration form bot tries to get an affirmation"
             )
         raise Exception
Esempio n. 3
0
def verify_compatibility_integer(value,
                                 min_value=-float('inf'),
                                 max_value=float('inf')):
    try:
        value = value.replace(' ', '')
        int_value = get_integer(value)
        sorry_style = styles.get_sorry()
        insert_style = styles.get_insert()
        please_style = styles.get_please()
        if int_value is None:
            text = f'{sorry_style} the value {value} is not an integer, {please_style} {insert_style} a valid value.'
            return False, text
        number = int(int_value)
        if number < min_value or number > max_value:
            if number < min_value:
                text = f'{sorry_style} the value inserted is less than the minimum value acceptable {min_value}.'
            else:
                text = f'{sorry_style} the value inserted is more than the maximum value acceptable {max_value}.'
            return False, text
        return True, int_value
    except:
        print(
            f'Fail to verify the compatibility of the value {value} for the type integer'
        )
        raise Exception
Esempio n. 4
0
def verify_compatibility_number(value,
                                min_value=-float('inf'),
                                max_value=float('inf')):
    try:
        value = value.replace(' ', '')
        int_value = int(get_integer(value))
        interval_text = ''
        if min_value != -float('inf'):
            interval_text = f'The minimum value for this field is {min_value}. '
        if max_value != float('inf'):
            interval_text = f'{interval_text}The maximum value for this field is {max_value}.'
        if int_value is None:
            sorry_style = styles.get_sorry()
            insert_style = styles.get_insert()
            please_style = styles.get_please()
            text = f'{sorry_style} the value {value} is not a number, {please_style} {insert_style} a valid value.'
            return False, text
        if int_value < min_value or int_value > max_value:
            if int_value < min_value:
                text = f'{sorry_style} the value inserted is less than the minimum value acceptable {min_value}.'
            else:
                text = f'{sorry_style} the value inserted is more than the maximum value acceptable {max_value}.'
            return False, text
        return True, value
    except:
        print(
            f'Fail to verify the compatibility of the value {value} for the type number'
        )
        raise Exception
Esempio n. 5
0
def verify_compatibility_tel(value):
    try:
        text = value
        # we should not have the space in the final value
        if ' ' in value:
            text = text.replace(' ', '')
        if '-' in value:
            text = text.replace('-', '')
        plus_sign = "+"
        num_occur = value.count(plus_sign)
        if num_occur == 1:
            if value[0] != plus_sign:
                text = f'The character < {plus_sign} > could only be at the beginning of the number'
                return False, text
        elif num_occur > 1:
            text = f'A telephone number should not contain the character < {plus_sign} > several times'
            return False, text
        # we remove the eventual plus sign at the beginning
        number = value.replace(plus_sign, '')
        # we verify if the remaining string only contains digits from 0 to 9
        number = fn.convert_to_int(number)
        if number is None or len(value) < u.min_length_phone_number:
            sorry_style = styles.get_sorry()
            insert_style = styles.get_insert()
            please_style = styles.get_please()
            text = f'{sorry_style} the value {value} is not valid, {please_style} {insert_style} a valid phone number'
            return False, text
        return True, text
    except:
        print(
            f'Fail to verify the compatibility of {value} for the type phone number'
        )
        raise Exception
Esempio n. 6
0
 def get_form_description(self):
     try:
         requested_slot = self.get_slot(u.REQUESTED_SLOT)
         desc = requested_slot[u.description]
         if desc is None:
             sorry_style = styles.get_sorry()
             text = f"{sorry_style} there is no explanation provided for this form"
             return text
         # the description is present in the html file
         return desc
     except:
         print('ERROR: Fail to get the description of the form')
         raise Exception
Esempio n. 7
0
 def get_form_title(self):
     try:
         requested_slot = self.get_slot(u.REQUESTED_SLOT)
         title = requested_slot[u.title]
         if title is None:
             sorry_style = styles.get_sorry()
             text = f"{sorry_style} there is no title provided for this form"
             return text
         # the title is present in the html file
         return title
     except:
         print('ERROR: Fail to get the title of the form')
         raise Exception
Esempio n. 8
0
 def get_field_description(self, field):
     try:
         slot = self.get_slot(field)
         desc = slot[u.description]
         if desc is None:
             sorry_style = styles.get_sorry()
             text = f"There is no explanation provided for the field {field} {sorry_style}"
             return text
         # the description is present in the html file
         text = f'Here is the explanation provided for the {field}: {desc}'
         return text
     except:
         print(f'ERROR: Fail to get the description of the field {field}')
         raise Exception
def verify_presence(name, slots, only_presence=False, only_text=False):
    try:
        possible_names = []
        for slot in slots:
            slot_name = slot[u.slot_name]
            possible_names.append(slot_name)
        if name in possible_names:
            text = f"The field {name} is present."
            if only_presence:
                return True
            elif only_text:
                return text
            else:
                return text, True
        alternatives = []
        for pos in possible_names:
            if name in pos:
                alternatives.append(pos)
        if len(alternatives) > 0:
            string_alt = get_string_from_list(alternatives)
            if len(alternatives) == 1:
                text = f"The field {name} is not present but you have this alternative {string_alt}."
            else:
                text = f"The field {name} is not present but you have these alternatives {string_alt}."
            if only_presence:
                return False
            elif only_text:
                return text
            else:
                return text, False
        sorry_style = styles.get_sorry()
        text = f"The field {name} is not present {sorry_style}"
        if only_presence:
            return False
        elif only_text:
            return text
        else:
            return text, False
    except:
        print(f'Fail to verify the presence of {name}')
        raise Exception
Esempio n. 10
0
 def verifyValueFilledFields(self):
     try:
         slots = self.state.form_slots()
         filled_string = fn.get_pairs(slots, only_filled=True)
         next_step_string = self.state.manage_next_step()
         if filled_string == '':
             sorry_style = styles.get_sorry()
             string = f'{sorry_style} up to now you did not complete any field\n{next_step_string}'
         else:
             string = (
                 f"The fields you already completed are the following: \n{filled_string}\n"
                 +
                 f"If you see some stars, they indicate the required fields.\n{next_step_string}"
             )
         return string
     except:
         if not self.state.get_warning_present():
             print(
                 "A problem occured while a registration form bot tries to verify the value of the filled camps"
             )
         raise Exception
Esempio n. 11
0
def verify_compatibility_decimal(value,
                                 precision=2,
                                 min_value=-float('inf'),
                                 max_value=float('inf')):
    try:
        value = value.replace(' ', '')
        dec_value = get_decimal(value)
        sorry_style = styles.get_sorry()
        insert_style = styles.get_insert()
        please_style = styles.get_please()
        if dec_value is None:
            text = f'{sorry_style} the value {value} is not a decimal, {please_style} {insert_style} a valid value.'
            return False, text
        # float takes the 'dot' as separator, so we should transform it before getting the float
        number = float(dec_value.replace(',', '.'))
        if number < min_value or number > max_value:
            if number < min_value:
                text = f'{sorry_style} the value inserted is less than the minimum value acceptable {min_value}.'
            else:
                text = f'{sorry_style} the value inserted is more than the maximum value acceptable {max_value}.'
            return False, text
        if ',' not in dec_value:
            return True, dec_value
        # the value has a decimal part
        if precision == float('inf'):
            return True, dec_value
        dec_part = dec_value[dec_value.index(',') + 1:]
        if len(dec_part) <= 2:
            # the precision is respected
            return True, dec_value
        # the precision is more accurate then what required, we decide to troncate, no rounding
        dec_value = dec_value[:dec_value.index(',') + precision + 1]
        return True, dec_value
    except:
        print(
            f'Fail to verify the compatibility of the value {value} for the type decimal with precision {precision}'
        )
        raise Exception
Esempio n. 12
0
 def repeatFormExplanation(self):
     try:
         form_desc = self.state.get_form_description()
         next_step_string = self.state.manage_next_step()
         if form_desc is None:
             sorry_style = styles.get_sorry()
             string = f"{sorry_style} this form does not have a description.\n{next_step_string}"
             _, required = self.state.get_next_slot()
             if not required:
                 string = f'{string} otherwise, you can {u.fun_skip}'
             else:
                 string = f'{string} otherwise, you can {u.fun_recap} or {u.fun_verify_value}. In any case you will have to complete this field in order to submit'
         else:
             sure_style = styles.get_sure()
             string = f"{sure_style} here it is: {form_desc}."
             string = f'{string}\n{next_step_string}'
         return string
     except:
         if not self.state.get_warning_present():
             print(
                 "A problem occured while a registration form bot tries to repeat the form's explanation"
             )
         raise Exception
Esempio n. 13
0
 def all_fields_present(self, slot_name_list):
     try:
         # returns True if all the fields are present and False otherwise. In ca of false retruns also the next_step string
         string = ''
         for slot_name in slot_name_list:
             present = fn.verify_presence(slot_name.lower(),
                                          self.form_slots(),
                                          only_presence=True)
             if not present:
                 sorry_style = styles.get_sorry()
                 list_fields = self.get_fields_list()
                 string_fields = fn.get_string_from_list(list_fields)
                 text = (
                     f"{sorry_style} the field {slot_name} is not present in this form.\nThe fields of this form are"
                     + f" the following: {string_fields}")
                 next_step_string = self.manage_next_step()
                 string = f'{text}\n{next_step_string}'
                 return False, string
         return True, string
     except:
         if not self.get_warning_present():
             print('ERROR: Fail to verify presence of all fields')
         raise Exception
Esempio n. 14
0
 def skipField(self):
     try:
         # we set the actual slot to campare it later with the next slot
         actual_slot_name = self.state.get_next_slot(
             only_name=True
         )  # return also if the next slot is required or not
         # we get the next slot without having filled the current slot and we verify if it is the last field
         self.state.set_next_slot_basic()
         next_slot_name, next_slot_required = self.state.get_next_slot(
         )  # return also if the next slot is required or not
         if actual_slot_name == next_slot_name:
             sorry_style = styles.get_sorry()
             text = f"{sorry_style} this field is the last one remaining."
             if not next_slot_required:
                 opt = "Do you want to submit now?"
                 self.state.set_possible_next_action(u.submit_action)
                 string = f'{text}{opt} If yes, give an affirmative response otherwise {self.state.manage_next_step()}'
             else:
                 string = (
                     f"{text} it is required to be able to submit the Web Form.\n"
                     + f"{self.fillForm()}")
             return string
         # we got to the next step
         string = self.state.manage_next_step()
         fields_remaining = self.state.get_fields_list(remaining=True)
         if self.state.get_all_required_filled(
         ) and len(fields_remaining) <= 2:
             string = f'If you want, you can {u.fun_submit}, otherwise {string}'
         else:
             string = f'The {actual_slot_name} has been skipped.\n{string}'
         return string
     except:
         if not self.state.get_warning_present():
             print(
                 "A problem occured while a registration form bot tries to skip a camp"
             )
         raise Exception
Esempio n. 15
0
 def set_choices_checkbox(self, slot_name, choice_values):
     try:
         slot = self.get_slot(slot_name)
         choice_name = slot[u.value_name].lower()
         choices_lower = []
         for choice_value in choice_values:
             choices_lower.append(choice_value.lower())
         elems = self.form_element.find_elements_by_name(choice_name)
         value_present = False
         for elem in elems:
             value = elem.get_attribute("value")
             if value in choices_lower:
                 if not elem.is_selected():
                     elem.click()
                     value_present = True
             else:
                 if elem.is_selected():
                     elem.click()
                     value_present = True
         if not value_present:
             choices_string = fn.get_string_from_list(choice_values)
             sorry_style = styles.get_sorry()
             please_style = styles.get_please()
             text = (
                 f"{sorry_style} none of the choices {choices_string} you proposed is valid for the field {slot_name}"
                 +
                 f"{please_style} choose them in the following list: {choice_list}"
             )
             self.set_warning_message(text)
             raise Exception
     except:
         if not self.get_warning_present():
             choices_list = fn.get_string_from_list(choice_values)
             print(
                 f"ERROR: A problem occured while trying to set the choices {choices_list} in the checkbox with name {choice_name}"
             )
         raise Exception
Esempio n. 16
0
 def fill_input(self, slot_name, slot_value):
     # returns the slot value eventually modified to be in the right format, and a string to
     # eventuelly mention some incopatibilities
     try:
         string = ""
         # substitute the underscores with spaces to outpu the right message
         input_type_list = u.input_type_list
         slot = self.get_slot(slot_name)
         value_type = slot[u.value_type]
         value_name = slot[u.value_name]
         # the slot_value is not None
         if u.DEBUG:
             print(f"value_name: {value_name}, value_type: {value_type}")
         compatible, text = fn.is_compatible(slot_value, slot)
         if not compatible:
             next_step_string = self.manage_next_step()
             string = f'{text}\n{next_step_string}'
             return None, string
         # the value and the type are compatible so it is pssible that the value has been converted
         # to an appropriate form contained in text
         slot_value = text
         if value_type in input_type_list:
             elem = self.form_element.find_element_by_name(value_name)
             elem.clear()
             if slot_value is None:
                 return "", string
             elem.send_keys(slot_value)
             return slot_value, string
         # the value_type is in u.choices_list
         # the value is put in lowercase to coincide with the choice
         slot_value = slot_value.lower()
         if u.DEBUG:
             print(f"choice: {slot_value}")
         # we verify that slot_value is in the list of choices
         choice_list = slot[u.choice_list]
         length = len(choice_list)
         for index in range(length):
             choice_list[index] = choice_list[index].lower()
         if slot_value not in choice_list:
             sorry_style = styles.get_sorry()
             please_style = styles.get_please()
             string = (
                 f"{sorry_style} the choice {slot_value} is not valid for the field {slot_name}"
                 +
                 f"{please_style} choose one in the following list: {choice_list}"
             )
             self.set_possible_next_action(u.fill_field_action)
             return None, string
         # we are sure that the choice of the user is in the list of choices
         if value_type == u.dropdown:
             self.set_choice_dropdown(slot_name=slot_name,
                                      choice_value=slot_value)
         elif value_type == u.checkbox:
             self.set_choice_checkbox(slot_name=slot_name,
                                      choice_value=slot_value)
         elif value_type == u.radio:
             self.set_choice_radio(slot_name=slot_name,
                                   choice_value=slot_value)
         return slot_value, string
     except:
         next_step_string = self.manage_next_step()
         string = f'The value {slot_value} is not valid for the field {slot_name}.\n{next_step_string}'
         return None, string
Esempio n. 17
0
 def fillGenericField(self):
     try:
         entities = self.state.get_latest_message()["entities"]
         intent = self.state.get_latest_message()["intent"]["name"]
         count = len(entities)
         if count == 0:
             # the user wants to modify a field but did not specify which field
             modify_style = styles.get_modify()
             insert_style = styles.get_insert()
             string = (
                 f"Which field exactly do you want to {modify_style}, and which value"
                 + f" do you want to {insert_style} for that field?")
             self.state.set_possible_next_action(u.fill_field_action)
             return string
         slot_name_list, slot_value_list = fn.extract_fields_names_and_values(
             entities)
         # we first verify if each slot_name corresponds to a field in the dorm
         correct, string = self.state.all_fields_present(slot_name_list)
         if not correct:
             return string
         """we extract now the spelling field and we insert them in the spelling list
         after that we fill the generic fields before passing the floor to 
         fillSpellingField to complete the fields in spelling list."""
         slot_name_list, slot_value_list = self.state.set_spelling_list(
             slot_name_list, slot_value_list)
         # the spelling list have been set and we can continue
         if len(slot_value_list) + len(slot_name_list) == 0:
             string = self.fillSpellingField()
             return string
         if len(slot_value_list) + len(slot_name_list) >= 1:
             # there is at least one generic info
             # the use of possible_next_action here is to mitigate training error. with a perfect training they are not necessary
             if len(slot_value_list) == 1 and len(slot_name_list) == 0 and (
                     self.state.get_possible_next_action()
                     == u.fill_field_action
                     or intent == u.fill_field_action):
                 # we are inserting a value for the current field
                 slot_name = self.state.get_next_slot(
                     only_name=True
                 )  # return also if the next slot is required or not
                 # We make verify if the current field is spelling
                 spelling_fields = self.state.get_spelling_fields()
                 if slot_name in spelling_fields:
                     string = self.fillSpellingField()
                     return string
                 slot_value = slot_value_list[0]
                 # the slot value can change, being put in the right format
                 # we go to the filling procedure insuring that the field is not spelling
                 string = self.state.filling_procedure(
                     slot_name, slot_value)
             elif self.state.get_possible_next_action(
             ) != u.fill_field_action and intent != u.fill_field_action:
                 # probably bad destination due to misinterpretation
                 sorry_style = styles.get_sorry()
                 please_style = styles.get_please()
                 text = f'{sorry_style} i do not understand your request, could you reformulate {please_style}?'
                 _, required = self.state.get_next_slot()
                 if not required:
                     text = f'{text} otherwise, you can {u.fun_skip} or {u.fun_submit}'
                 else:
                     text = f'{text} otherwise, you can {u.fun_explain_field} or {u.fun_complete_field}'
                 self.state.set_warning_message(text)
                 raise Exception
             else:
                 # we have a list of fields with their values
                 string = self.state.fill_generic_slots(
                     slot_name_list=slot_name_list,
                     slot_value_list=slot_value_list)
         next_field_before = self.state.get_next_slot(only_name=True)
         # we verify if the spelling_list is empty or not
         if len(self.state.get_spelling_list()) != 0:
             string_spelling = self.fillSpellingField()
             next_field_after = self.state.get_next_slot(only_name=True)
             if next_field_before == next_field_after:
                 # the spelling did not modified the Web page, we return the string from the non spelling fields
                 return string
             # the spelling mofified the Web Form, so we use its string
             return string_spelling
         return string
     except:
         if not self.state.get_warning_present():
             print(
                 "A problem occured while a registration form bot tries to fill a camp"
             )
         raise Exception