def __init__(self, port=DEFAULT_PORT, local=False, verbose=False):
     self.verbose = verbose
     # Set up callback
     try:
         CallbackSocket.__init__(self, port, MSG_SEP, local)
     except socket.error:
         raise IOError("Port {} requested by PipelineHost is already in use".format(port))
     self.register_callback(self.parse_text)
     # Start up the pipeline
     self.pipeline = PennPipeline()
Example #2
0
class PipelineHost(CallbackSocket):
    """Provides a connection to pipeline over a listening socket."""
    name = "pipelinehost"

    def __init__(self, port=DEFAULT_PORT, local=False, verbose=False):
        self.verbose = verbose
        # Set up callback
        try:
            CallbackSocket.__init__(self, port, MSG_SEP, local)
        except socket.error:
            raise IOError("Port {} requested by PipelineHost is already in use".format(port))
        self.register_callback(self.parse_text)
        # Start up the pipeline
        self.pipeline = PennPipeline()

    def parse_text(self, message, client):
        """Receive a parse request for the pipeline."""
        try:
            data = json.loads(message)
        except ValueError:
            # Make a default set of arguments
            data = {'text': message}
        if self.verbose:
            print "Message:", repr(data)
            print "Parsing..."
        # Add verbose flag to args
        data['verbose'] = self.verbose
        # pylint: disable=W0142,E1101
        response = self.pipeline.parse_text(**data)
        if self.verbose:
            print "Sending:", repr(response)
        client.send(response)
Example #3
0
    def __init__(self, port, msg_sep="\n"):
        self.msg_sep = msg_sep
        self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self._sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self._sock.bind(('', port))
        self._sock.listen(1)

        # Initialize pipeline
        self._pipeline = PennPipeline()

        # Make a thread that keeps the connection alive
        accept_thread = threading.Thread(target=self._accept)
        accept_thread.name = "Listener"
        accept_thread.daemon = True
        print "Starting listening thread on port %d..." % port
        accept_thread.start()
class PipelineHost(CallbackSocket):
    """Provides a connection to pipeline over a listening socket."""
    name = "pipelinehost"

    def __init__(self, port=DEFAULT_PORT, local=False, verbose=False):
        self.verbose = verbose
        # Set up callback
        try:
            CallbackSocket.__init__(self, port, MSG_SEP, local)
        except socket.error:
            raise IOError("Port {} requested by PipelineHost is already in use".format(port))
        self.register_callback(self.parse_text)
        # Start up the pipeline
        self.pipeline = PennPipeline()

    def parse_text(self, message, client):
        """Receive a parse request for the pipeline."""
        try:
            data = json.loads(message)
        except ValueError:
            # Make a default set of arguments
            data = {'text': message}
        if self.verbose:
            print "Message:", repr(data)
            print "Parsing..."
        # Add verbose flag to args
        data['verbose'] = self.verbose
        # pylint: disable=W0142,E1101
        response = self.pipeline.parse_text(**data)
        if self.verbose:
            print "Sending:", repr(response)
        client.send(response)
Example #5
0
 def __init__(self, port=DEFAULT_PORT, local=False, verbose=False):
     self.verbose = verbose
     # Set up callback
     try:
         CallbackSocket.__init__(self, port, MSG_SEP, local)
     except socket.error:
         raise IOError("Port {} requested by PipelineHost is already in use".format(port))
     self.register_callback(self.parse_text)
     # Start up the pipeline
     self.pipeline = PennPipeline()
Example #6
0
class PipelineService():
    """Provides a connection to the pipeline via a ROS service."""
    
    def __init__(self):
        self._pipeline = PennPipeline()

    def parse_text(self, request):
        """Return a parse response."""
        text = request.in_
        rospy.loginfo("NLP pipeline request: %r" % text)
        response = self._pipeline.parse_text(text)
        rospy.loginfo("NLP pipeline response: %r" % response)
        return response
Example #7
0
class ServiceSocket:
    """Listen on a socket for messages and dispatch them appropriately."""
    name = "ServiceSocket"

    def __init__(self, port, msg_sep="\n"):
        self.msg_sep = msg_sep
        self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self._sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self._sock.bind(('', port))
        self._sock.listen(1)

        # Initialize pipeline
        self._pipeline = PennPipeline()

        # Make a thread that keeps the connection alive
        accept_thread = threading.Thread(target=self._accept)
        accept_thread.name = "Listener"
        accept_thread.daemon = True
        print "Starting listening thread on port %d..." % port
        accept_thread.start()

    def _accept(self):
        """Accept connections on the listening port."""
        print "Listening for connections..."
        while True:
            try:
                conn, addr = self._sock.accept()
                print "%s: Connected to %s" % (self.name, str(addr))

                # Start up a new thread to handle the client
                name = "Client " + str(addr)
                accept_thread = threading.Thread(target=self._handle_client, args=(conn, name))
                accept_thread.name = name
                accept_thread.daemon = True
                print "%s: Starting thread for client %s" % (self.name, accept_thread.name)
                accept_thread.start()
            except timeout:
                continue
            # pylint: disable=W0702
            except:  # Because any error can occur here during shutdown
                pass

    def _handle_client(self, conn, name):
        """Process requests from a client."""
        send_error = False
        while True:
            try:
                print "Waiting for data..."
                buff = conn.recv(4096)
            except timeout:
                continue
            # pylint: disable=W0702
            except:
                # Break the connection for all more serious errors
                break
            if not buff:
                break
            while buff:
                if self.msg_sep:
                    msg, buff = _parse_msg(buff, self.msg_sep)
                else:
                    msg, buff = buff, None
                if msg:
                    response = self._process_text(msg)
                    if response:
                        print "Sending:", response
                        try:
                            conn.sendall(json.dumps(response))
                        except:
                            # Give up on the client entirely
                            print "%s: Error sending message." % self.name
                            send_error = True
                            break
                else:
                    print "%s: Received an incomplete message: %s" % (self.name, repr(buff))
                    break

            # Break out if there was a sending error
            if send_error:
                break

        print "%s: %s disconnected." % (self.name, name)

    def _process_text(self, msg):
        """Run a string through the NLP pipeline."""
        # Remove backlashes since they are sometimes in the input for no good reason
        text = msg.strip().replace('\\', '')

        if text.startswith(SECRET_CODE):
            knowledge_demo = True
            text = text[len(SECRET_CODE):]
        else:
            knowledge_demo = False

        # Return nothing if there was not text
        if not text:
            return {}

        if knowledge_demo:
            print "Secret demo mode!"
            # pylint: disable=W0603
            global _WORLD_KNOWLEDGE
            if not _WORLD_KNOWLEDGE or text == "reset":
                _WORLD_KNOWLEDGE = knowledge.Knowledge()

            world_knowledge = _WORLD_KNOWLEDGE
        else:
            world_knowledge = knowledge.Knowledge()

        response = {}

        # Run the parse pipeline
        parse = self._pipeline.parse_text(text)
        response['parse'] = parse.replace('(', '[').replace(')', ']')

        # Get the results from semantics
        results = world_knowledge.process_parse_tree(parse, text)
        answer, frame_trees, new_commands = results[0], results[1], results[3]

        # Use the answer if there was one and it was a string
        user_response = answer if answer and isinstance(answer, str) else ""

        # Also, echo back any new commands
        command_echo = make_response(new_commands)

        # Combine the responses as needed.
        if not user_response:
            user_response = command_echo
        elif new_commands:
            user_response += " " + command_echo

        response['response'] = user_response

        if frame_trees is not None:
            modified_trees = [str(modified_parse_tree[1]).replace('(', '[').replace(')', ']')
                              for modified_parse_tree in frame_trees
                              if (len(modified_parse_tree) > 1 and
                                  isinstance(modified_parse_tree[1], tree.Tree))]
            response['trees'] = list(set(modified_trees))

            frames = [frame_dict for frame_dict in [frame[0] for frame in frame_trees
                                                    if isinstance(frame[0], dict)]]
            response['frames'] = frames
        else:
            response['trees'] = []
            response['frames'] = []

        # Extract the command queue and add it to the response.
        # This is turned off for now because better talkback makes it
        # unnecessary.
        # command_queue = world_knowledge.command_queue
        # if command_queue:
        #    response['response'] += " Commands: " + str(command_queue)

        return response

    def shutdown(self):
        """Shut down the listening socket."""
        print "%s: Shutting down socket." % self.name
        self._sock.shutdown(socket.SHUT_RDWR)
        self._sock.close()
        print "%s: Socket closed." % self.name
Example #8
0
 def __init__(self):
     self._pipeline = PennPipeline()