Esempio n. 1
0
def telegram_output(ctx: ContextWrapper):
    """
    If all telegram chats should be in the same context, sends the content of rawio:out to every currently active chat.
    Otherwise it only sends output using the Pipe if it is a child process
    """
    if ctx.conf(key=ALL_IN_ONE_CONTEXT_CONFIG_KEY):
        # TODO don't instantiate the updater every time
        token = ctx.conf(key=TOKEN_CONFIG_KEY)
        if not token:
            logger.error('telegram-token is not set. Shutting down telegramio')
            return Delete()

        updater: Updater = Updater(token)
        for chat_id in active_chats.keys():
            updater.bot.send_message(chat_id=chat_id,
                                     text=ctx["rawio:out:changed"])
    else:
        child_conn = ctx.conf(key=CHILD_CONN_CONFIG_KEY)

        if child_conn:
            # Child Process -> write to Pipe
            child_conn.send(ctx["rawio:out:changed"])
        else:
            # Master Process -> State not needed
            return Delete()
Esempio n. 2
0
 def hello_world_genqa(ctx):
     server = ctx.conf(key=DRQA_SERVER_ADDRESS)
     if not server:
         logger.error('Server address is not set. Shutting down GenQA.')
         return Delete()
     if not server_up(server):
         return Delete()
Esempio n. 3
0
    def _bootstrap_telegram_master():
        """
        Handle TelegramIO as the Master Process.
        Start the bot, and handle incoming telegram messages.
        """
        token = ctx.conf(key=TOKEN_CONFIG_KEY)
        if not token:
            logger.error(
                f'{TOKEN_CONFIG_KEY} is not set. Shutting down telegramio')
            return Delete()
        child_config_paths_list = ctx.conf(key=CHILD_FILES_CONFIG_KEY)
        if not ctx.conf(key=ALL_IN_ONE_CONTEXT_CONFIG_KEY) and (
                not child_config_paths_list
                or not isinstance(child_config_paths_list, list) or not all(
                    os.path.isfile(child_config_path)
                    for child_config_path in child_config_paths_list)):
            logger.error(
                f'{CHILD_FILES_CONFIG_KEY} is not set (correctly). Shutting down telegramio'
            )
            return Delete()

        updater: Updater = Updater(token)
        # Get the dispatcher to register handlers
        dispatcher: Dispatcher = updater.dispatcher
        if ctx.conf(key=ALL_IN_ONE_CONTEXT_CONFIG_KEY):
            # handle noncommand-messages with the matching handler
            dispatcher.add_handler(MessageHandler(Filters.text, handle_text))
            dispatcher.add_handler(MessageHandler(Filters.photo, handle_photo))
        else:
            dispatcher.add_handler(
                MessageHandler(Filters.text | Filters.photo,
                               handle_input_multiprocess))
        # log all errors
        dispatcher.add_error_handler(error)
        # Start the Bot
        updater.start_polling()  # non blocking

        if not ctx.conf(key=ALL_IN_ONE_CONTEXT_CONFIG_KEY):
            _manage_children(updater)
Esempio n. 4
0
def telegram_output(ctx: ContextWrapper):
    """
    Sends the content of rawio:out to every currently active chat
    """
    # TODO don't instantiate the updater every time
    token = ctx.conf(key=TOKEN_CONFIG_KEY)
    if not token:
        logger.error('telegram-token is not set. Shutting down telegramio')
        return Delete()

    updater: Updater = Updater(token)
    for chat_id in active_chats:
        updater.bot.send_message(chat_id=chat_id, text=ctx["rawio:out"])
Esempio n. 5
0
 def drqa_module(ctx):
     """
     general question answering using DrQA through a HTTP server
     connection check to server
     post input question and get DrQA answer through the HTTP interface
     depending on the answer score the answer is introduced as sane or insane/unsure :)
     """
     server = ctx.conf(key=DRQA_SERVER_ADDRESS)
     if not server_up(server):
         return Delete(resign=True)
     params = {'question': ctx["rawio:in"]}
     response = requests.get(server, params=params)
     response_json = response.json()
     certainty = response_json["answers"][0]["span_score"]
     # sane answer
     if certainty > ctx.conf(key=ROBOY_ANSWER_SANITY):
         ctx["rawio:out"] = verbaliser.get_random_phrase("question-answering-starting-phrases") + " " + \
                            response_json["answers"][0]["span"]
     # insane/unsure answer
     else:
         ctx["rawio:out"] = verbaliser.get_random_phrase("unsure-question-answering-phrases") \
                            % response_json["answers"][0]["span"] \
                            + "\n" + "Maybe I can find out more if your rephrase the question for me."
Esempio n. 6
0
def sync_ros_properties(ctx: ContextWrapper):
    """
    State that creates a ROS2-Node, registers all Ros2SubProperties and Ros2PubProperties in ROS2 and keeps them synced
    """
    # check for ROS2 availability
    if not ROS2_AVAILABLE:
        logger.error(
            "ROS2 is not available, therefore all ROS2-Properties "
            "will be just normal properties without connection to ROS2!")
        return Delete()

    # get config stuff
    node_name = ctx.conf(key=NODE_NAME_CONFIG_KEY)
    if not node_name:
        logger.error(
            f"{NODE_NAME_CONFIG_KEY} is not set. Shutting down ravestate_ros2")
        return Delete()
    spin_frequency = ctx.conf(key=SPIN_FREQUENCY_CONFIG_KEY)
    if spin_frequency is None or spin_frequency < 0:
        logger.error(
            f"{SPIN_FREQUENCY_CONFIG_KEY} is not set or less than 0. Shutting down ravestate_ros2"
        )
        return Delete()
    if spin_frequency == 0:
        spin_sleep_time = 0
    else:
        spin_sleep_time = 1 / spin_frequency

    # init ROS
    rclpy.init()
    node = rclpy.create_node(node_name)

    global global_prop_set
    # current_props: hash -> subscription/publisher
    current_props: Dict = dict()

    # ROS-Context Sync Loop
    while not ctx.shutting_down():
        # remove deleted props
        removed_props = current_props.keys() - global_prop_set
        for prop_hash in removed_props:
            item = current_props[prop_hash]
            if isinstance(item, rclpy.subscription.Subscription):
                node.destroy_subscription(item)
            elif isinstance(item, rclpy.publisher.Publisher):
                node.destroy_publisher(item)
            elif isinstance(item, rclpy.client.Client):
                node.destroy_client(item)
            current_props.pop(prop_hash)

        # add new props
        new_props = global_prop_set - current_props.keys()
        for prop in new_props:
            # register subscribers in ROS
            if isinstance(prop, Ros2SubProperty):
                # register in context
                @receptor(ctx_wrap=ctx, write=prop.id())
                def ros_to_ctx_callback(ctx, msg, prop_name: str):
                    ctx[prop_name] = msg

                prop.ros_to_ctx_callback = ros_to_ctx_callback
                prop.subscription = node.create_subscription(
                    prop.msg_type, prop.topic, prop.ros_subscription_callback)
                current_props[prop.__hash__()] = prop.subscription
            # register publishers in ROS
            if isinstance(prop, Ros2PubProperty):
                prop.publisher = node.create_publisher(prop.msg_type,
                                                       prop.topic)
                current_props[prop.__hash__()] = prop.publisher
            # register clients in ROS
            if isinstance(prop, Ros2CallProperty):
                prop.client = node.create_client(prop.service_type,
                                                 prop.service_name)
                current_props[prop.__hash__()] = prop.client

            # replace prop with hash in global_props
            global_prop_set.remove(prop)
            global_prop_set.add(prop.__hash__())

        # spin once
        rclpy.spin_once(node, timeout_sec=0)
        time.sleep(spin_sleep_time)

    node.destroy_node()
    rclpy.shutdown()
Esempio n. 7
0
def telegram_run(ctx: ContextWrapper):
    """
    Starts up the telegram bot and adds a handler to write incoming messages to rawio:in
    """

    @receptor(ctx_wrap=ctx, write="rawio:in")
    def telegram_callback(ctx: ContextWrapper, message_text: str):
        """
        Writes the message_text to rawio:in
        """
        ctx["rawio:in"] = message_text

    @receptor(ctx_wrap=ctx, write="interloc:all")
    def push_telegram_interloc(ctx: ContextWrapper, telegram_node: Node, name: str):
        """
        Push the telegram_node into interloc:all:name
        """
        if ctx.push(parentpath="interloc:all", child=PropertyBase(name=name, default_value=telegram_node)):
            logger.debug(f"Pushed {telegram_node} to interloc:all")

    def handle_input(bot: Bot, update: Update):
        """
        Handler for incoming messages
        Adds the chat/user of the incoming message to the set of active_chats/active_users
        Calls the telegram_callback receptor to process the incoming message
        Retrieves scientio Node of User if it exists, otherwise creates it in the scientio session
        Calls the push_telegram_interloc receptor to push the scientio node into interloc:all
        """
        telegram_callback(update.effective_message.text)
        active_chats.add(update.effective_chat.id)

        if update.effective_user not in active_users:
            # set up scientio
            sess: Session = ravestate_ontology.get_session()
            onto: Ontology = ravestate_ontology.get_ontology()

            # create scientio Node of type TelegramPerson
            query = Node(metatype=onto.get_type("TelegramPerson"))
            prop_dict = {'telegram_id': update.effective_user.id}
            if update.effective_user.username:
                prop_dict['name'] = update.effective_user.username
            if update.effective_user.full_name:
                prop_dict['full_name'] = update.effective_user.full_name
            query.set_properties(prop_dict)

            node_list = sess.retrieve(query)
            if not node_list:
                telegram_node = sess.create(query)
                logger.info(f"Created new Node in scientio session: {telegram_node}")
            elif len(node_list) == 1:
                telegram_node = node_list[0]
            else:
                logger.error(f'Found multiple TelegramPersons that matched query: {update.message.chat_id} '
                             f'in scientio session. Cannot push node to interloc:all!')
                return

            # push chat-Node
            push_telegram_interloc(telegram_node, update.effective_chat.id)
            active_users.add(update.effective_user)

    def error(bot: Bot, update: Update, error: TelegramError):
        """
        Log Errors caused by Updates.
        """
        logger.warning('Update "%s" caused error "%s"', update, error)

    """Start the bot."""
    # Create the EventHandler and pass it your bots token.
    token = ctx.conf(key=TOKEN_CONFIG_KEY)
    if not token:
        logger.error('telegram-token is not set. Shutting down telegramio')
        return Delete()

    updater: Updater = Updater(token)
    # Get the dispatcher to register handlers
    dp: Dispatcher = updater.dispatcher
    # handle noncommand-messages with handle_input
    dp.add_handler(MessageHandler(Filters.text, handle_input))
    # log all errors
    dp.add_error_handler(error)
    # Start the Bot
    updater.start_polling()