예제 #1
0
    def __media_processor(self, data):

        message_type = MessageType.get_value("SIMPLE")
        section_type = data.get("SectionType")
        if section_type in ["Image", "Gif"]:
            media_type = MediaType.get_value("IMAGE")
        elif section_type == "Video":
            media_type = MediaType.get_value("VIDEO")

        url = data.get("Url", "")
        url = AnaHelper.verb_replacer(text=url, state=self.state)
        url = furl(url).url
        preview_url = data.get("PreviewUrl", "")
        preview_url = AnaHelper.verb_replacer(text=preview_url,
                                              state=self.state)
        preview_url = furl(preview_url).url
        text = data.get("Title", "")
        text = AnaHelper.verb_replacer(text=text, state=self.state)
        media_content = Media(type=media_type, url=url,
                              previewUrl=preview_url).trim()
        message_content = MessageContent(text=text,
                                         media=media_content,
                                         mandatory=1).trim()
        message_data = MessageData(type=message_type,
                                   content=message_content).trim()

        return message_data
예제 #2
0
    def __get_next_node_id(cls, data, state, node_data):

        next_node_id = node_data.get('NextNodeId', '')  # Fallback node id

        for button in node_data.get('Buttons', []):
            try:
                root_key = re.split(r'\.|\[',
                                    button.get("ConditionMatchKey"))[0]

                if data.get(root_key) is None:
                    data[root_key] = None

                logger.debug("rootKey " + root_key)

                path = button.get("ConditionMatchKey")
                obj = {root_key: data[root_key]}
                variable_value = Util.deep_find(obj, path)

                match_operator = button.get("ConditionOperator")
                match_value = AnaHelper.verb_replacer(text=button.get(
                    "ConditionMatchValue", ""),
                                                      state=state)

                condition_matched = AnaHelper.is_condition_match(
                    variable_value, match_operator, match_value)

                if condition_matched:
                    next_node_id = button["NextNodeId"]
                    break
            except:
                logger.error("error in btn " + str(button))
                pass

        return next_node_id
예제 #3
0
    def __process_carousel_item(self, section_item):

        media_type = MediaType.get_value("IMAGE")
        image_url = section_item.get("ImageUrl", "")
        image_url = furl(image_url).url

        title = section_item.get("Title", "")
        title = AnaHelper.verb_replacer(text=title, state=self.state)
        description = section_item.get("Caption", "")
        description = AnaHelper.verb_replacer(text=description,
                                              state=self.state)

        media_content = Media(type=media_type, url=image_url).trim()
        buttons = section_item.get("Buttons", [])

        options = []
        options = [
            self.__process_carousel_button(button) for button in buttons
        ]

        item_element = Item(title=title,
                            desc=description,
                            media=media_content,
                            options=options).trim()

        return item_element
예제 #4
0
    def get_next_node(self, node_data):

        next_node_id = node_data.get('NextNodeId', '')  #Fallback node id
        variable_data = self.state.get("var_data", {})
        buttons = node_data.get("Buttons")

        for button in buttons:

            root_key = re.split(r'\.|\[', button.get("ConditionMatchKey"))[0]
            logger.debug(
                f"Variable Data received for condition call is {variable_data}"
            )

            # if isinstance(variable_data, str):
            # try:
            # variable_data = json.loads(variable_data)
            # except Exception as err:
            # logger.error(f"Error parsing variable_data {variable_data}")
            # variable_data = {}

            logger.debug(
                f"Variable Data after dict conversion is {variable_data}")
            if variable_data.get(root_key) is None:
                continue

            path = button.get("ConditionMatchKey")
            obj = {root_key: variable_data[root_key]}
            variable_value = Util.deep_find(obj, path)

            match_operator = button.get("ConditionOperator")
            match_value = AnaHelper.verb_replacer(text=button.get(
                "ConditionMatchValue", ""),
                                                  state=self.state)

            logger.debug(
                f"variable_value {variable_value} {variable_value.__class__} match_operator {match_operator} match_value {match_value}"
            )

            condition_matched = AnaHelper.is_condition_match(
                variable_value, match_operator, match_value)
            logger.debug(f"Condition matched is {condition_matched}")
            if condition_matched:
                variable_data = self.state.get("var_data", {})
                node_variable_name = node_data.get("VariableName")
                if node_variable_name:
                    button_variable_value = button.get("VariableValue")
                    button_variable_value = AnaHelper.verb_replacer(
                        text=button_variable_value, state=self.state)
                    variable_data[node_variable_name] = button_variable_value
                next_node_id = button["NextNodeId"]
                break

        next_node_key = self.state.get("flow_id", "") + "." + next_node_id
        node_data = AnaNode(next_node_key).get_contents()
        return {"id": next_node_key, "data": node_data}
예제 #5
0
    def __make_api_call(self, node_data):

        logger.debug(f"State passed to replace api_url is {self.state}")

        api_url = node_data.get("ApiUrl", "")
        api_method = node_data.get("ApiMethod")
        api_url = AnaHelper.verb_replacer(text=api_url, state=self.state)

        logger.debug(f"URL after verb replacing is {api_url}")

        api_headers = {}
        headers = node_data.get("Headers", "").split("\n")
        for header_line in headers:
            header_key_values = header_line.split(":")[:2]
            if len(header_key_values) == 2:
                api_headers[header_key_values[0]] = header_key_values[1]

        logger.debug(f"api headers: {api_headers}")

        api_body = node_data.get("RequestBody", None)
        if api_body:
            api_body = AnaHelper.verb_replacer(text=api_body, state=self.state)
            try:
                api_body = json.loads(api_body)
            except ValueError:
                logger.error(f"Could not parse api body {api_body}")
                return {}

        logger.debug(f"api_body: {api_body}")

        response = requests.request(method=api_method,
                                    url=api_url,
                                    headers=api_headers,
                                    json=api_body)

        logger.debug(f"api response: {response}")

        if response.status_code in [200, 201]:
            try:
                api_response = response.json()
            except ValueError:
                api_response = response.text
        else:
            api_response = None
            logger.error(
                f"ApiCall did not return status code 200 {node_data['Id']}")

        return api_response
예제 #6
0
    def process(self, buttons):

        logger.info(f"btns before: {len(buttons)}")
        buttons = AnaHelper.process_repeatable(buttons, self.state)
        logger.info(f"btns after: {len(buttons)}")
        click_elements = [
            button for button in buttons
            if button["ButtonType"] in self.click_inputs
        ]
        text_elements = [
            button for button in buttons
            if button["ButtonType"] in self.text_inputs
        ]

        messages_data = []

        if click_elements != [] and text_elements == []:
            messages_data = self.__process_click_inputs(click_elements,
                                                        mandatory=1)
        elif click_elements != [] and text_elements != []:
            messages_data = self.__process_click_inputs(click_elements,
                                                        mandatory=0)
        elif click_elements == [] and text_elements != []:
            messages_data = self.__process_text_inputs(text_elements)

        return messages_data
예제 #7
0
    def _extract_button_elements(cls, data, state):

        node_buttons = data.get("Buttons", [])
        node_buttons = AnaHelper.process_repeatable(node_buttons, state)
        sections = data.get("Sections", [])
        all_section_buttons = []

        for section in sections:
            if section["SectionType"] == "Carousel":
                carousel_items = section["Items"]
                carousel_items = AnaHelper.process_repeatable(
                    carousel_items, state, True)
                for car_item in carousel_items:
                    carousel_buttons = car_item.get("Buttons", [])
                    carousel_buttons = AnaHelper.process_repeatable(
                        carousel_buttons, state)
                    all_section_buttons = all_section_buttons + carousel_buttons
        return node_buttons + all_section_buttons
예제 #8
0
    def __process_click_button(self, button):
        button_type = button.get("ButtonType", "")

        title = button.get("ButtonName", button.get("ButtonText", ""))
        title = AnaHelper.verb_replacer(text=title, state=self.state)

        if button_type == "OpenUrl":
            url = button.get("Url", "")
            url = AnaHelper.verb_replacer(text=url, state=self.state)
            value = json.dumps({"url": url, "value": button["_id"]})
            type_of_button = ButtonType.get_value("URL")
        elif button_type == "DeepLink":
            url = button.get("DeepLinkUrl", "")
            url = AnaHelper.verb_replacer(text=url, state=self.state)
            value = json.dumps({"url": url, "value": button["_id"]})
            type_of_button = ButtonType.get_value("DEEPLINK")
        elif button_type == "NextNode":
            value = button["_id"]
            type_of_button = ButtonType.get_value("QUICK_REPLY")

        option = Option(title=title, value=value, type=type_of_button).trim()
        return option
예제 #9
0
    def __text_processor(self, data):

        message_type = MessageType.get_value("SIMPLE")
        section_type = data.get("SectionType")
        if section_type == "Text":
            text = data.get("Text", "")
        elif section_type in ["EmbeddedHtml", "Link"]:
            text = data.get("Url", "")
        text = AnaHelper.verb_replacer(text=text, state=self.state)
        message_content = MessageContent(text=text, mandatory=1).trim()
        message_data = MessageData(type=message_type,
                                   content=message_content).trim()

        return message_data
예제 #10
0
    def __process_carousel_button(self, button):

        if button["Type"] == "OpenUrl":
            url = button.get("Url", "")
            url = AnaHelper.verb_replacer(text=url, state=self.state)
            button_value = json.dumps({"url": url, "value": button["_id"]})
            button_type = ButtonType.get_value("URL")
        elif button["Type"] == "DeepLink":
            url = button.get("Url", "")
            url = AnaHelper.verb_replacer(text=url, state=self.state)
            button_value = json.dumps({"url": url, "value": button["_id"]})
            button_type = ButtonType.get_value("DEEPLINK")
        else:
            button_value = button["_id"]
            button_type = ButtonType.get_value("ACTION")

        button_title = button.get("Text", "")
        button_title = AnaHelper.verb_replacer(text=button_title,
                                               state=self.state)
        option_element = Option(title=button_title,
                                value=button_value,
                                type=button_type).trim()

        return option_element
예제 #11
0
    def __process_getitem_button(self, data):

        source = data.get("ItemsSource")
        url = data.get("Url")
        values = list()
        if source:
            source = AnaHelper.verb_replacer(text=source, state=self.state)
            values = list(
                map(
                    lambda x: ListItem(text=x.split(":")[0],
                                       value=x.split(":")[1]).trim(),
                    source.split(",")))
        elif url:
            url = AnaHelper.verb_replacer(text=url, state=self.state)
            items_from_url = requests.get(url).json()
            values = []
            for key, value in items_from_url.items():
                values.append({'text': key, 'value': value})

        button_text = data.get("ButtonName")
        button_text = AnaHelper.verb_replacer(text=button_text,
                                              state=self.state)

        message_type = MessageType.get_value("INPUT")
        input_type = InputType.get_value("LIST")
        is_multiple = 1 if data.get("AllowMultiple") else 0

        content = MessageContent(inputType=input_type,
                                 text=button_text,
                                 multiple=is_multiple,
                                 mandatory=1,
                                 values=values).trim()

        message_data = MessageData(type=message_type, content=content).trim()

        return message_data
예제 #12
0
    def __carousel_processor(self, data):

        message_type = MessageType.get_value("CAROUSEL")
        section_items = data.get("Items", [])
        section_items = AnaHelper.process_repeatable(section_items, self.state,
                                                     True)
        item_elements = []
        item_elements = [
            self.__process_carousel_item(item) for item in section_items
        ]

        message_content = MessageContent(items=item_elements,
                                         mandatory=1).trim()
        message_data = MessageData(type=message_type,
                                   content=message_content).trim()

        return message_data
예제 #13
0
    def __process_input_button(self, button):

        button_type = button.get("ButtonType")

        if button_type == "GetItemFromSource":
            message_data = self.__process_getitem_button(button)
            return message_data

        message_type = ""
        input_type = ""
        input_attr = None
        content = None

        message_type = MessageType.get_value("INPUT")
        placeholder_text = button.get("PlaceholderText", "")
        placeholder_text = AnaHelper.verb_replacer(text=placeholder_text,
                                                   state=self.state)
        input_attr = TextInput(placeHolder=placeholder_text).trim()

        button_type_map = config["button_map"]

        elem_type = button_type_map.get(button_type)
        if elem_type is None:
            logger.warning(f"Undefined Input Type {button_type}")

        type_of_input = elem_type["input_type"]
        type_of_media = elem_type["media_type"]

        input_type = InputType.get_value(type_of_input)
        media_type = MediaType.get_value(type_of_media)

        content = MessageContent(
            inputType=input_type,
            mediaType=media_type,
            textInputAttr=input_attr,
            mandatory=1,
        ).trim()
        message_data = MessageData(type=message_type, content=content).trim()

        return message_data
예제 #14
0
    def __get_next_node_data(cls, input_data, node_content, state):

        # TODO cleanup required here too many loops and variables
        next_node_id = ""
        event_data = []
        user_input = {}
        var_name = node_content.get("VariableName", "")

        button_contents = cls._extract_button_elements(node_content, state)

        click_buttons = cls._get_button_elements(buttons=button_contents,
                                                 type_of_button="click")
        input_buttons = cls._get_button_elements(buttons=button_contents,
                                                 type_of_button="input")

        input_key = list(input_data.keys())[0]

        if input_key == "val":

            for button in click_buttons:
                input_button_id = input_data["val"]
                if button["_id"] == input_button_id:
                    if var_name:
                        var_val = button.get("VariableValue", "")
                        user_input[var_name] = AnaHelper.verb_replacer(
                            text=var_val, state=state)
                    next_node_id = button["NextNodeId"]
                    event_data.append({
                        "type_of_event": "click",
                        "node_data": node_content,
                        "event_data": button
                    })
                    break

            if next_node_id == "":
                for button in input_buttons:
                    button_type = button.get("ButtonType", button.get("Type"))

                    if button_type == "GetNumber":
                        input_value = float(input_data["val"])
                    else:
                        input_value = str(input_data["val"])

                    if var_name:
                        user_input[var_name] = input_value
                    next_node_id = button["NextNodeId"]
                    event_data.append({
                        "type_of_event": "click",
                        "node_data": node_content,
                        "event_data": button
                    })
                    break

        else:

            valid_button_types = cls.__get_button_types(input_key)

            for button in button_contents:
                button_type = button.get("ButtonType", button.get("Type"))
                if button_type in valid_button_types:
                    if button_type == "GetNumber":
                        input_value = int(input_data[input_key])
                    elif button_type in ["GetDate", "GetTime", "GetLocation"]:
                        if isinstance(input_data[input_key], str):
                            input_value = json.loads(input_data[input_key])
                        else:
                            input_value = input_data[input_key]
                    else:
                        input_value = str(input_data[input_key])

                    if var_name:
                        user_input[var_name] = input_value
                    next_node_id = button["NextNodeId"]
                    event_data.append({
                        "type_of_event": "click",
                        "node_data": node_content,
                        "event_data": button
                    })
                    break

        return {
            "node_id": next_node_id,
            "event_data": event_data,
            "user_input": user_input
        }