Ejemplo n.º 1
0
    def test_regular(self):
        handler = Mock(name="handler_value")
        handler.context_id = "context_id_value"
        handler.user_id = "user_id_value"
        handler.application_id = "application_id_value"
        handler.session_id = "session_id_value"
        handler.locale = "locale_value"
        handler.suggest_id = "suggest_id_value"
        handler.page_size = "page_size_value"

        suggestions = Mock()
        sender = MagicMock()
        target = Target(suggestions, sender)

        target.on_next_page_message(
            handler,
            {
                "suggest_id": "suggest_id_value",
                "offset": "original_offset_value"
            }
        )

        self.assertEqual(1, target.suggestions.get_suggestion_items.call_count)
        self.assertEqual("user_id_value", target.suggestions.get_suggestion_items.call_args_list[0][0][0])
        self.assertEqual("application_id_value", target.suggestions.get_suggestion_items.call_args_list[0][0][1])
        self.assertEqual("session_id_value", target.suggestions.get_suggestion_items.call_args_list[0][0][2])
        self.assertEqual("locale_value", target.suggestions.get_suggestion_items.call_args_list[0][0][3])
        self.assertEqual("suggest_id_value", target.suggestions.get_suggestion_items.call_args_list[0][0][4])
        self.assertEqual("page_size_value", target.suggestions.get_suggestion_items.call_args_list[0][0][5])
        self.assertEqual("original_offset_value", target.suggestions.get_suggestion_items.call_args_list[0][0][6])

        self.assertEqual("context_id_value", handler.context_id)
        self.assertEqual("suggest_id_value", handler.suggest_id)
Ejemplo n.º 2
0
    def __init__(self, product_content: ProductDetailCache, client_handlers,
                 user_info_cache, favorites_cache):
        self.sender = Sender(client_handlers)
        self.context = ContextLogic()
        self.detect = DetectLogic(self.sender)
        self.suggestions = Suggestions(product_content=product_content,
                                       sender=self.sender,
                                       favorites_cache=favorites_cache)
        self.user = UserLogic(user_info_cache=user_info_cache,
                              favorites_cache=favorites_cache)

        self.next_page_message_handler = NextPageMessageHandler(
            self.suggestions, self.sender)
        self.new_message_handler = NewMessageHandler(self.sender, self.detect,
                                                     self.context,
                                                     self.suggestions)

        self._client_handlers = client_handlers
Ejemplo n.º 3
0
    def test_regular(self):
        handler = Mock(name="handler_value")
        handler.context_id = "context_id_value"
        handler.user_id = "user_id_value"
        handler.application_id = "application_id_value"
        handler.session_id = "session_id_value"
        handler.locale = "locale_value"
        handler.suggest_id = "suggest_id_value"
        handler.page_size = "page_size_value"

        suggestions = Mock()
        sender = MagicMock()
        target = Target(suggestions, sender)

        target.on_next_page_message(handler, {
            "suggest_id": "suggest_id_value",
            "offset": "original_offset_value"
        })

        self.assertEqual(1, target.suggestions.get_suggestion_items.call_count)
        self.assertEqual(
            "user_id_value",
            target.suggestions.get_suggestion_items.call_args_list[0][0][0])
        self.assertEqual(
            "application_id_value",
            target.suggestions.get_suggestion_items.call_args_list[0][0][1])
        self.assertEqual(
            "session_id_value",
            target.suggestions.get_suggestion_items.call_args_list[0][0][2])
        self.assertEqual(
            "locale_value",
            target.suggestions.get_suggestion_items.call_args_list[0][0][3])
        self.assertEqual(
            "suggest_id_value",
            target.suggestions.get_suggestion_items.call_args_list[0][0][4])
        self.assertEqual(
            "page_size_value",
            target.suggestions.get_suggestion_items.call_args_list[0][0][5])
        self.assertEqual(
            "original_offset_value",
            target.suggestions.get_suggestion_items.call_args_list[0][0][6])

        self.assertEqual("context_id_value", handler.context_id)
        self.assertEqual("suggest_id_value", handler.suggest_id)
Ejemplo n.º 4
0
    def test_regular(self):
        suggestions = MagicMock()

        sender = MagicMock()
        target = Target(suggestions, sender)
        target.bson_json_decode_and_load = MagicMock(return_value="decoded_response")
        target.suggest_responder.suggestion_items = MagicMock()

        response = MagicMock()
        response.body = "response_body"
        response.headers = {"next_offset": "next_offset_value"}

        target.get_suggestion_items_callback(response, "handler", {'offset': "offset_value"})

        target.bson_json_decode_and_load.assert_called_once_with('response_body')
        suggestions.write_suggestion_items.assert_called_once_with('handler', 'decoded_response', "offset_value",
                                                                   "next_offset_value")
        target.suggest_responder.suggestion_items.assert_called_once_with('handler', {'offset': 'offset_value'},
                                                                          'decoded_response')
Ejemplo n.º 5
0
    def __init__(self, product_content: ProductDetailCache, client_handlers, user_info_cache, favorites_cache):
        self.sender = Sender(client_handlers)
        self.context = ContextLogic()
        self.detect = DetectLogic(self.sender)
        self.suggestions = Suggestions(product_content=product_content, sender=self.sender,
                                       favorites_cache=favorites_cache)
        self.user = UserLogic(user_info_cache=user_info_cache, favorites_cache=favorites_cache)

        self.next_page_message_handler = NextPageMessageHandler(self.suggestions, self.sender)
        self.new_message_handler = NewMessageHandler(self.sender, self.detect, self.context, self.suggestions)

        self._client_handlers = client_handlers
Ejemplo n.º 6
0
    def test_regular(self):
        suggestions = MagicMock()

        sender = MagicMock()
        target = Target(suggestions, sender)
        target.bson_json_decode_and_load = MagicMock(
            return_value="decoded_response")
        target.suggest_responder.suggestion_items = MagicMock()

        response = MagicMock()
        response.body = "response_body"
        response.headers = {"next_offset": "next_offset_value"}

        target.get_suggestion_items_callback(response, "handler",
                                             {'offset': "offset_value"})

        target.bson_json_decode_and_load.assert_called_once_with(
            'response_body')
        suggestions.write_suggestion_items.assert_called_once_with(
            'handler', 'decoded_response', "offset_value", "next_offset_value")
        target.suggest_responder.suggestion_items.assert_called_once_with(
            'handler', {'offset': 'offset_value'}, 'decoded_response')
Ejemplo n.º 7
0
class WebSocket:
    logger = logging.getLogger(__name__)
    logger.setLevel(LOGGING_LEVEL)

    def __init__(self, product_content: ProductDetailCache, client_handlers,
                 user_info_cache, favorites_cache):
        self.sender = Sender(client_handlers)
        self.context = ContextLogic()
        self.detect = DetectLogic(self.sender)
        self.suggestions = Suggestions(product_content=product_content,
                                       sender=self.sender,
                                       favorites_cache=favorites_cache)
        self.user = UserLogic(user_info_cache=user_info_cache,
                              favorites_cache=favorites_cache)

        self.next_page_message_handler = NextPageMessageHandler(
            self.suggestions, self.sender)
        self.new_message_handler = NewMessageHandler(self.sender, self.detect,
                                                     self.context,
                                                     self.suggestions)

        self._client_handlers = client_handlers

    def open(self, handler: WebSocketHandler):
        self.logger.debug("context_id=%s,suggestion_id=%s",
                          str(handler.context_id), handler.suggest_id)

        if handler.context_id is None:
            handler.context_id, handler.context_rev = self.post_context(
                handler.user_id, handler.application_id, handler.session_id,
                handler.locale)
            new_context = True
        else:
            new_context = False

        if str(handler.context_id) not in self._client_handlers:
            self._client_handlers[str(handler.context_id)] = {}

        if handler.id not in self._client_handlers[str(handler.context_id)]:
            self.logger.debug("add handler, context_id=%s,handler_id=%s",
                              str(handler.context_id), handler.id)
            self._client_handlers[str(
                handler.context_id)][handler.id] = handler

        self.sender.write_to_context_handlers(
            handler, {
                "type": "connection_opened",
                "context_id": str(handler.context_id)
            })

        if new_context:

            def post_context_callback(response, handler):
                self.logger.debug("post_context_message")

            self.context.post_context_message(
                handler.context_id,
                0,
                "Hi, how can I help you?",
                callback=lambda res: post_context_callback(res, handler))

    def on_close(self, handler: WebSocketHandler):
        handler_id_in_client_handlers = str(
            handler.context_id) in self._client_handlers
        if handler_id_in_client_handlers and handler.id in self._client_handlers[
                str(handler.context_id)]:
            self.logger.debug(
                "remove_handler,close_code=%s,context_id=%s,context_rev=%s,handler_id=%s",
                handler.close_code, str(handler.context_id),
                str(handler.context_rev), handler.id)
            self._client_handlers[str(handler.context_id)].pop(
                handler.id, None)

    def write_jemboo_response_message(self, handler: WebSocketHandler,
                                      message: dict):
        message["type"] = "jemboo_chat_response"
        message["direction"] = 0  # jemboo
        # TODO store this message in the context too

        self.sender.write_to_context_handlers(handler, message)

    # def write_thinking_message(self, handler: WebSocketHandler, thinking_mode: str, meta_data: dict = None):
    #     message = {
    #         "type": "start_thinking",
    #         "thinking_mode": thinking_mode
    #     }
    #
    #     if meta_data is not None:
    #         message["meta_data"] = meta_data
    #
    #     self.sender.write_to_context_handlers(handler, message)

    def on_load_conversation_messages(self, handler: WebSocketHandler,
                                      message: dict):
        self.context.get_context_messages(
            handler,
            callback=lambda res: get_context_messages_callback(res, handler))

        def get_context_messages_callback(response, handler):
            profile_picture_url = self.user.get_profile_picture(
                handler.user_id)
            messages = [{
                "direction": x["direction"],
                "display_text": x["text"]
            } for x in loads(response.body.decode("utf-8"))["messages"]]
            if profile_picture_url is not None:
                for x in messages:
                    if x["direction"] == 1:  # user
                        x["profile_picture_url"] = profile_picture_url

            self.sender.write_to_context_handlers(handler, {
                "type": "conversation_messages",
                "messages": messages
            })

    def on_favorite_product_delete_message(self, handler: WebSocketHandler,
                                           message: dict):
        self.user.delete_favorite(handler, ObjectId(message["user_id"]),
                                  ObjectId(message["product_id"]))

    def on_favorite_product_save_message(self, handler: WebSocketHandler,
                                         message: dict):
        self.user.put_favorite(handler, ObjectId(message["user_id"]),
                               ObjectId(message["product_id"]))

    def on_view_product_details_message(self, handler: WebSocketHandler,
                                        message: dict):
        handler.context_rev = self.post_context_feedback(
            handler.context_id, handler.user_id, handler.application_id,
            handler.session_id, message["product_id"],
            message["feedback_type"],
            message["meta_data"] if "meta_data" in message else None)

    def on_message(self, handler: WebSocketHandler, message: dict):
        if "type" not in message:
            raise Exception("missing message type,message=%s", message)

        self.logger.debug("message_type=%s,message=%s", message["type"],
                          message)

        if message["type"] == "home_page_message":
            self.new_message_handler.on_new_message(handler,
                                                    message,
                                                    new_conversation=True)
        elif message["type"] == "new_message":
            self.new_message_handler.on_new_message(handler,
                                                    message,
                                                    new_conversation=False)
        elif message["type"] == "next_page":
            self.next_page_message_handler.on_next_page_message(
                handler, message)
        elif message["type"] == "view_product_details":
            self.on_view_product_details_message(handler, message)
        elif message["type"] == "load_conversation_messages":
            self.on_load_conversation_messages(handler, message)
        elif message["type"] == "favorite_product_save":
            self.on_favorite_product_save_message(handler, message)
        elif message["type"] == "favorite_product_delete":
            self.on_favorite_product_delete_message(handler, message)
        else:
            raise Exception("unknown message_type, type=%s,message=%s",
                            message["type"], message)
        pass

    def post_context(self, user_id: str, application_id: str, session_id: str,
                     locale: str) -> dict:
        self.logger.debug(
            "user_id=%s,application_id=%s,session_id=%s,locale=%s", user_id,
            application_id, session_id, locale)
        try:
            request_body = {}
            #     # this now goes at message level
            #     # if detection_response is not None:
            #     #     request_body["detection_response"] = detection_response
            url = "%s?session_id=%s&application_id=%s&locale=%s" % (
                CONTEXT_URL, session_id, application_id, locale)

            url += "&user_id=%s" % user_id if user_id is not None else ""

            http_client = HTTPClient()
            response = http_client.fetch(
                HTTPRequest(url=url,
                            body=json_encode(request_body),
                            method="POST"))
            http_client.close()

            return response.headers["_id"], response.headers["_rev"]
        except HTTPError as e:
            raise

    def post_context_feedback(self,
                              context_id: str,
                              user_id: str,
                              application_id: str,
                              session_id: str,
                              product_id: str,
                              _type: str,
                              meta_data: dict = None):
        self.logger.debug(
            "context_id=%s,user_id=%s,application_id=%s,session_id=%s,product_id=%s,"
            "_type=%s,meta_data=%s", context_id, user_id, application_id,
            session_id, product_id, _type, meta_data)
        try:
            url = "%s/%s/feedback/?application_id=%s&session_id=%s&product_id=%s&type=%s" % (
                CONTEXT_URL, context_id, application_id, session_id,
                product_id, _type)
            url += "&user_id=%s" if user_id is not None else ""

            request_body = {}
            if meta_data is not None:
                request_body["meta_data"] = meta_data

            http_client = HTTPClient()
            response = http_client.fetch(
                HTTPRequest(url=url, body=dumps(request_body), method="POST"))
            http_client.close()
            return response.headers["_rev"]
        except HTTPError:
            self.logger.error("post_context_feedback,url=%s", url)
            raise
Ejemplo n.º 8
0
class WebSocket:
    logger = logging.getLogger(__name__)
    logger.setLevel(LOGGING_LEVEL)

    def __init__(self, product_content: ProductDetailCache, client_handlers, user_info_cache, favorites_cache):
        self.sender = Sender(client_handlers)
        self.context = ContextLogic()
        self.detect = DetectLogic(self.sender)
        self.suggestions = Suggestions(product_content=product_content, sender=self.sender,
                                       favorites_cache=favorites_cache)
        self.user = UserLogic(user_info_cache=user_info_cache, favorites_cache=favorites_cache)

        self.next_page_message_handler = NextPageMessageHandler(self.suggestions, self.sender)
        self.new_message_handler = NewMessageHandler(self.sender, self.detect, self.context, self.suggestions)

        self._client_handlers = client_handlers

    def open(self, handler: WebSocketHandler):
        self.logger.debug(
            "context_id=%s,suggestion_id=%s",
            str(handler.context_id), handler.suggest_id
        )

        if handler.context_id is None:
            handler.context_id, handler.context_rev = self.post_context(
                handler.user_id, handler.application_id, handler.session_id, handler.locale
            )
            new_context = True
        else:
            new_context = False

        if str(handler.context_id) not in self._client_handlers:
            self._client_handlers[str(handler.context_id)] = {}

        if handler.id not in self._client_handlers[str(handler.context_id)]:
            self.logger.debug("add handler, context_id=%s,handler_id=%s", str(handler.context_id), handler.id)
            self._client_handlers[str(handler.context_id)][handler.id] = handler

        self.sender.write_to_context_handlers(
            handler,
            {
                "type": "connection_opened",
                "context_id": str(handler.context_id)
            }
        )

        if new_context:
            def post_context_callback(response, handler):
                self.logger.debug("post_context_message")

            self.context.post_context_message(
                handler.context_id,
                0,
                "Hi, how can I help you?",
                callback=lambda res: post_context_callback(res, handler)
            )

    def on_close(self, handler: WebSocketHandler):
        handler_id_in_client_handlers = str(handler.context_id) in self._client_handlers
        if handler_id_in_client_handlers and handler.id in self._client_handlers[str(handler.context_id)]:
            self.logger.debug(
                "remove_handler,close_code=%s,context_id=%s,context_rev=%s,handler_id=%s",
                handler.close_code, str(handler.context_id), str(handler.context_rev), handler.id
            )
            self._client_handlers[str(handler.context_id)].pop(handler.id, None)

    def write_jemboo_response_message(self, handler: WebSocketHandler, message: dict):
        message["type"] = "jemboo_chat_response"
        message["direction"] = 0  # jemboo
        # TODO store this message in the context too

        self.sender.write_to_context_handlers(handler, message)

    # def write_thinking_message(self, handler: WebSocketHandler, thinking_mode: str, meta_data: dict = None):
    #     message = {
    #         "type": "start_thinking",
    #         "thinking_mode": thinking_mode
    #     }
    #
    #     if meta_data is not None:
    #         message["meta_data"] = meta_data
    #
    #     self.sender.write_to_context_handlers(handler, message)

    def on_load_conversation_messages(self, handler: WebSocketHandler, message: dict):
        self.context.get_context_messages(
            handler,
            callback=lambda res: get_context_messages_callback(res, handler)
        )

        def get_context_messages_callback(response, handler):
            profile_picture_url = self.user.get_profile_picture(handler.user_id)
            messages = [
                {
                    "direction": x["direction"],
                    "display_text": x["text"]
                } for x in loads(response.body.decode("utf-8"))["messages"]
                ]
            if profile_picture_url is not None:
                for x in messages:
                    if x["direction"] == 1:  # user
                        x["profile_picture_url"] = profile_picture_url

            self.sender.write_to_context_handlers(
                handler,
                {
                    "type": "conversation_messages",
                    "messages": messages
                }
            )

    def on_favorite_product_delete_message(self, handler: WebSocketHandler, message: dict):
        self.user.delete_favorite(handler, ObjectId(message["user_id"]), ObjectId(message["product_id"]))

    def on_favorite_product_save_message(self, handler: WebSocketHandler, message: dict):
        self.user.put_favorite(handler, ObjectId(message["user_id"]), ObjectId(message["product_id"]))

    def on_view_product_details_message(self, handler: WebSocketHandler, message: dict):
        handler.context_rev = self.post_context_feedback(
            handler.context_id,
            handler.user_id,
            handler.application_id,
            handler.session_id,
            message["product_id"],
            message["feedback_type"],
            message["meta_data"] if "meta_data" in message else None
        )

    def on_message(self, handler: WebSocketHandler, message: dict):
        if "type" not in message:
            raise Exception("missing message type,message=%s", message)

        self.logger.debug("message_type=%s,message=%s", message["type"], message)

        if message["type"] == "home_page_message":
            self.new_message_handler.on_new_message(handler, message, new_conversation=True)
        elif message["type"] == "new_message":
            self.new_message_handler.on_new_message(handler, message, new_conversation=False)
        elif message["type"] == "next_page":
            self.next_page_message_handler.on_next_page_message(handler, message)
        elif message["type"] == "view_product_details":
            self.on_view_product_details_message(handler, message)
        elif message["type"] == "load_conversation_messages":
            self.on_load_conversation_messages(handler, message)
        elif message["type"] == "favorite_product_save":
            self.on_favorite_product_save_message(handler, message)
        elif message["type"] == "favorite_product_delete":
            self.on_favorite_product_delete_message(handler, message)
        else:
            raise Exception("unknown message_type, type=%s,message=%s", message["type"], message)
        pass

    def post_context(self, user_id: str, application_id: str, session_id: str, locale: str) -> dict:
        self.logger.debug(
            "user_id=%s,application_id=%s,session_id=%s,locale=%s",
            user_id, application_id, session_id, locale
        )
        try:
            request_body = {}
            #     # this now goes at message level
            #     # if detection_response is not None:
            #     #     request_body["detection_response"] = detection_response
            url = "%s?session_id=%s&application_id=%s&locale=%s" % (
                CONTEXT_URL, session_id, application_id, locale
            )

            url += "&user_id=%s" % user_id if user_id is not None else ""

            http_client = HTTPClient()
            response = http_client.fetch(HTTPRequest(url=url, body=json_encode(request_body), method="POST"))
            http_client.close()

            return response.headers["_id"], response.headers["_rev"]
        except HTTPError as e:
            raise

    def post_context_feedback(self, context_id: str, user_id: str, application_id: str, session_id: str,
                              product_id: str, _type: str, meta_data: dict = None):
        self.logger.debug(
            "context_id=%s,user_id=%s,application_id=%s,session_id=%s,product_id=%s,"
            "_type=%s,meta_data=%s",
            context_id, user_id, application_id, session_id, product_id, _type, meta_data
        )
        try:
            url = "%s/%s/feedback/?application_id=%s&session_id=%s&product_id=%s&type=%s" % (
                CONTEXT_URL, context_id, application_id, session_id, product_id, _type
            )
            url += "&user_id=%s" if user_id is not None else ""

            request_body = {
            }
            if meta_data is not None:
                request_body["meta_data"] = meta_data

            http_client = HTTPClient()
            response = http_client.fetch(HTTPRequest(url=url, body=dumps(request_body), method="POST"))
            http_client.close()
            return response.headers["_rev"]
        except HTTPError:
            self.logger.error("post_context_feedback,url=%s", url)
            raise