Esempio n. 1
0
class LisaClient(LineReceiver):
    """
    Lisa TCP client
    """

    def __init__(self):
        self.factory = None
        self.configuration = ConfigManagerSingleton.get().getConfiguration()
        self.listener = None
        self.debug_input = False
        self.debug_output = False
        if self.configuration.has_key("debug"):
            if self.configuration["debug"].has_key("debug_input"):
                self.debug_input = self.configuration["debug"]["debug_input"]
            if self.configuration["debug"].has_key("debug_output"):
                self.debug_output = self.configuration["debug"]["debug_output"]
        self.zone = ""
        if self.configuration.has_key("zone"):
            self.zone = self.configuration["zone"]

    def sendMessage(self, message, type="chat", dict=None):
        if dict:
            line = json.dumps(
                {
                    "from": unicode(platform.node()),
                    "type": type,
                    "body": unicode(message),
                    "zone": self.zone,
                    "outcome": dict,
                }
            )
        else:
            line = json.dumps(
                {"from": unicode(platform.node()), "type": type, "body": unicode(message), "zone": self.zone}
            )

        if self.debug_output:
            log.msg("OUTPUT: %s" % line)

        # send line to the server
        self.sendLine(line)

    def lineReceived(self, data):
        """
        Data received callback
        The nolistener in configuration is here to let the travis build pass without loading gst
        """

        datajson = json.loads(data)
        if self.debug_input == True:
            log.msg("INPUT: " + unicode(datajson))

        if datajson.has_key("type"):
            if datajson["type"] == "chat":
                if datajson.has_key("nolistener") == False:
                    Speaker.speak(datajson["body"])

            elif datajson["type"] == "command":
                if datajson["command"] == "LOGIN":
                    # Get Bot name
                    botname = unicode(datajson["bot_name"])
                    log.msg("setting botname to %s" % botname)
                    self.botname = botname

                    # Send TTS
                    if datajson.has_key("nolistener") == False:
                        Speaker.start()
                        Speaker.speak(datajson["body"])

                    # Create listener
                    if datajson.has_key("nolistener") == False and not self.listener:
                        self.listener = Listener(lisa_client=self, botname=botname)

                # TODO seems a bit more complicated than I thought. I think the reply will be another type like "answer"
                # TODO and will contains a unique ID. On server side, the question will be stored in mongodb so it will
                # TODO let possible the multi user / multi client. Questions need to implement a lifetime too.
                # TODO For the soundqueue, I will need a callback system to be sure to play the audio before recording
                elif datajson["command"] == "ASK":
                    if datajson.has_key("nolistener") == False:
                        Speaker.speak(datajson["body"])

                    # Start record
                    if datajson.has_key("nolistener") == False and self.listener:
                        self.listener.record()

        else:
            # Send to TTS queue
            if datajson.has_key("nolistener") == False:
                Speaker.speak(datajson["body"])

    def connectionMade(self):
        """
        Callback on established connections
        """
        log.msg("Connected to the server.")

        # Set SSL encryption
        if self.configuration.has_key("enable_secure_mode") and self.configuration["enable_secure_mode"] == True:
            ctx = ClientTLSContext()
            self.transport.startTLS(ctx, self.factory)

        # Login to server
        self.sendMessage(message="LOGIN", type="command")

    def connectionLost(self, reason):
        """
        Callback on connection loss
        """
        # Stop listener
        log.msg("Lost connection with server : " + reason.getErrorMessage())
        if self.listener:
            self.listener.stop()
Esempio n. 2
0
class LisaClientFactory(ReconnectingClientFactory):
    #-----------------------------------------------------------------------------
    def __init__(self):
        self.configuration = ConfigManager.getConfiguration()
        self._ = self.configuration['trans']
        self.active_protocol = None
        self.warn_on_connect = False
        self.running_state = True
        self.listener = None

    #-----------------------------------------------------------------------------
    def startFactory(self):
        # Create workers
        if self.listener is None:
            self.listener = Listener(factory = self)
            Speaker.start(listener = self.listener)

    #-----------------------------------------------------------------------------
    def setBotName(self, botname):
        # Restart listener with new botname
        self.listener.setBotName(botname)

    #-----------------------------------------------------------------------------
    def sendChatToServer(self, message, outcome = None):
        # If not connected to the server
        if self.active_protocol is None:
            Speaker.speak(self._('no_server'))
            self.warn_on_connect = True
            return

        # Send chat to server
        self.active_protocol.sendChatToServer(message = message, outcome = outcome)

    #-----------------------------------------------------------------------------
    def setContinuousMode(self, enabled, wit_context = None):
        # Change continuous mode in recorder
        self.listener.setContinuousMode(enabled = enabled, wit_context = wit_context)

    #-----------------------------------------------------------------------------
    def buildProtocol(self, addr):
        # Reset retry delay
        self.resetDelay()

        # Warn on connection
        if self.warn_on_connect == True:
            Speaker.speak(self._('back_ready'))
            self.warn_on_connect = False

        # Return protocol
        self.active_protocol = LisaClient(factory = self)
        return self.active_protocol

    #-----------------------------------------------------------------------------
    def clientConnectionLost(self, connector, reason):
        # Delete current connection
        self.active_protocol = None

        # Retry connection to the server
        log.err('Lost connection.  Reason: {0}'.format(reason.getErrorMessage()))
        if self.running_state == True:
            ReconnectingClientFactory.clientConnectionLost(self, connector, reason)

    #-----------------------------------------------------------------------------
    def clientConnectionFailed(self, connector, reason):
        # Retry
        self.resetDelay()
        log.err('Connection failed. Reason: {0}'.format(reason.getErrorMessage()))
        if self.running_state == True:
            ReconnectingClientFactory.clientConnectionFailed(self, connector, reason)

    #-----------------------------------------------------------------------------
    def stop(self):
        # Stop workers
        self.running_state = False
        self.listener.stop()
        self.listener = None
        Speaker.stop()