Esempio n. 1
0
    def generate_sub_rem_btn(self,
                             chat_id,
                             res_id,
                             menu_id,
                             prev_msg_type,
                             name=None):
        """
        Returns a subscription button. Its value depends of subscription status for this chat and menu

        :param chat_id: Id of chat
        :param res_id: Id of restaurant
        :param menu_id: Id of menu
        :param prev_msg_type: Callback data of the type of message that calls the [un]subscription
        :param name: Extra text button
        :return: The subscription button
        """
        if InfoManager.check_subscription(chat_id, res_id, menu_id):
            msg = labels.REM_BTN
            if name is not None:
                msg = name + labels.SUBS_SEPARATOR + msg
            return InlineKeyboardButton(
                msg,
                callback_data=public_parameters.CBDATA_UNSUBS_REQ +
                self.generate_menu_cb(res_id, menu_id) +
                public_parameters.CBDATA_PREVIOUS_TYPE + prev_msg_type)
        else:
            msg = labels.SUB_BTN
            if name is not None:
                msg = name + labels.SUBS_SEPARATOR + msg
            return InlineKeyboardButton(
                msg,
                callback_data=public_parameters.CBDATA_SUBS_REQ +
                self.generate_menu_cb(res_id, menu_id) +
                public_parameters.CBDATA_PREVIOUS_TYPE + prev_msg_type)
Esempio n. 2
0
    def send_menu_report(self, chat_id, msg_id, res_id, menu_id):
        """
        Send the info of the requested menu

        :param chat_id: Id of chat
        :param msg_id: Id of previous message
        :param res_id: Id of the restaurant
        :param menu_id: Id of the menu
        """
        keypad = [
            InlineKeyboardButton(
                labels.AGAIN_BTN,
                callback_data=public_parameters.CBDATA_START_CMD),
            self.generate_sub_rem_btn(chat_id, res_id, menu_id,
                                      public_parameters.CBDATA_MENU)
        ]
        available_restaurants_ids = [
            res.res_id for res in InfoManager.get_available_restaurants()
        ]
        available_menu_codes = [
            menu_id if menu.today_menu is not None else None
            for menu_id, menu in InfoManager.restaurants[res_id].menus.items()
        ]

        if res_id in available_restaurants_ids and menu_id in available_menu_codes:
            info = self.menu_today_to_show(res_id, menu_id)
            if msg_id is None:
                # It is a subscription message
                self.send_msg(chat_id, info, keypad, with_cancel=False)
                InfoManager.report_menu(chat_id,
                                        res_id,
                                        menu_id,
                                        mode=ReportMode.AUTO)
            else:
                # It is a regular message
                self.edit_msg(chat_id, msg_id, info, keypad, with_cancel=False)
                InfoManager.report_menu(chat_id,
                                        res_id,
                                        menu_id,
                                        mode=ReportMode.MANUAL)
        elif msg_id is not None:
            self.edit_msg(chat_id,
                          msg_id,
                          labels.NO_INFO,
                          keypad,
                          with_cancel=False)
Esempio n. 3
0
    def send_start_keypad(self, chat_id):
        """
        Send a keypad with all menus available

        :param chat_id: If of char to write
        """
        ar = InfoManager.get_available_restaurants()
        if not ar:
            self.send_msg(chat_id, labels.NO_INFO)
        else:
            keyboard = [
                InlineKeyboardButton(
                    restaurant.name,
                    callback_data=public_parameters.CBDATA_REP_REQ +
                    self.generate_restaurant_cb(restaurant.res_id))
                for restaurant in ar
            ]
            self.send_msg(chat_id, labels.CHOOSE_RESTAURANT, keyboard)
Esempio n. 4
0
 def check_scheduled_task(self):
     """
     Method executed by the subscription checker thread.
     Send the info a subscribed menu if there are no previous messages for this user and menu today.
     It only works at parametrized days and hours
     """
     stopped = threading.Event()
     while not stopped.wait(public_parameters.THREAD_TIMER_SECONDS):
         # Execute below code each THREAD_TIMER_SECONDS seconds
         # Check time
         try:
             logging.getLogger(__name__).info('Checking scheduled task...')
             weekday = datetime.datetime.today().weekday()
             hour = datetime.datetime.today().hour + (
                 datetime.datetime.today().minute / 60)
             if weekday in public_parameters.SUBS_WEEKDAY_LIST and \
                     public_parameters.SUBS_HOUR_INTERVAL[0] <= hour < public_parameters.SUBS_HOUR_INTERVAL[
                 1]:  # Valid day and hout
                 self.reload()  # Reload info
                 with InfoManager.report_lock.reader():
                     reports = InfoManager.read_menu_reports(
                     )  # Get actual reports
                 with InfoManager.data_lock.reader():
                     for chat in InfoManager.chats.values():
                         for sub in chat.subscriptions:
                             if sub.chat_id not in reports.keys() \
                                     or sub.res_id not in reports[sub.chat_id].keys() \
                                     or sub.menu_id not in reports[sub.chat_id][sub.res_id]:  # No previous report
                                 try:
                                     self.report_busy(sub.chat_id)
                                     self.send_menu_report(
                                         sub.chat_id, None, sub.res_id,
                                         sub.menu_id)
                                 except Exception as err:
                                     logging.getLogger(__name__).exception(
                                         err)
             logging.getLogger(__name__).info(
                 'Checking scheduled task... Done')
         except Exception as err:
             logging.getLogger(__name__).exception(err)
Esempio n. 5
0
    def send_restaurant_report(self, chat_id, msg_id, res_id):
        """
        Send a keypad with all menus available for this restaurant if there are more than one.
        Otherwise, it sends the info for the unique menu

        :param chat_id: Id of chat
        :param msg_id: Id of previous message
        :param res_id: Id of the restaurant
        """
        if res_id in [
                item.res_id
                for item in InfoManager.get_available_restaurants()
        ]:
            menu_list = []
            for menu in InfoManager.restaurants[res_id].menus.values():
                if menu.today_menu is not None:
                    menu_list.append(menu)

            if len(menu_list) == 1:
                # Just one menu for this restaurant - The bot sends its info
                self.send_menu_report(chat_id, msg_id, res_id,
                                      menu_list[0].menu_id)
            else:  # More than one menu. The Bot sends a new keypad of menus
                keyboard = [
                    InlineKeyboardButton(
                        menu.name,
                        callback_data=public_parameters.CBDATA_REP_REQ +
                        self.generate_menu_cb(res_id, menu.menu_id))
                    for menu in menu_list
                ]
                self.edit_msg(chat_id,
                              msg_id,
                              labels.CHOOSE_MENU,
                              keyboard,
                              cols=1)
        else:  # Restaurant not present in current available info
            self.edit_msg(chat_id, msg_id.message_id, labels.NO_INFO)
Esempio n. 6
0
 def __init__(self, bot):
     super(MenuBot, self).__init__(bot)
     InfoManager.initialize()
Esempio n. 7
0
 def reload():
     InfoManager.reload()
Esempio n. 8
0
    def button(self, bot, update):
        """
        Button handler

        :param bot: API's bot instance
        :param update: API's update instance
        """
        try:
            self.reload()  # Update info
            prev_update = update.callback_query  # Get previous update
            cb_info = prev_update.data  # Get callback info
            if cb_info == public_parameters.CBDATA_CANCEL:
                """ Cancel request """
                self.remove_msg(*self.get_ids_in_update(prev_update))

            elif cb_info == public_parameters.CBDATA_START_CMD:
                """ Start command """
                self.start_cmd(bot, prev_update)

            elif cb_info == public_parameters.CBDATA_INFO_CMD:
                """ Info command """
                self.info_cmd(bot, prev_update)

            elif cb_info.startswith(public_parameters.CBDATA_REP_REQ):
                """ Report request """
                cb_info = cb_info.split(
                    public_parameters.CBDATA_REP_REQ,
                    1)[-1]  # Get information below REQUEST code

                if cb_info.startswith(public_parameters.CBDATA_RESTAURANT):
                    """ Request restaurant info """
                    res_id = int(
                        cb_info.replace(public_parameters.CBDATA_RESTAURANT,
                                        '', 1))
                    # Info below restaurant Callback code is the restaurant id
                    with InfoManager.data_lock.reader():
                        self.send_restaurant_report(
                            *self.get_ids_in_update(prev_update), res_id)

                elif cb_info.startswith(public_parameters.CBDATA_MENU):
                    """ Request menu info """
                    res_id, menu_id, prev_cb = self.get_res_menu_id_in_request(
                        cb_info)
                    with InfoManager.data_lock.reader():
                        self.send_menu_report(
                            *self.get_ids_in_update(prev_update), res_id,
                            menu_id)

            elif cb_info.startswith(public_parameters.CBDATA_INFO_REQ):
                """ Info request """
                cb_info = cb_info.split(
                    public_parameters.CBDATA_INFO_REQ,
                    1)[-1]  # Get information below REQUEST code
                res_id = int(
                    cb_info.replace(public_parameters.CBDATA_RESTAURANT, '',
                                    1))
                with InfoManager.data_lock.reader():
                    self.send_info_restaurant(
                        *self.get_ids_in_update(prev_update), res_id)

            elif cb_info.startswith(public_parameters.CBDATA_SUBS_REQ):
                """ Subscription """
                cb_info = cb_info.replace(public_parameters.CBDATA_SUBS_REQ,
                                          '', 1)
                res_id, menu_id, prev_cb = self.get_res_menu_id_in_request(
                    cb_info)
                InfoManager.subscribe(update.effective_chat.id, res_id,
                                      menu_id)
                with InfoManager.data_lock.reader():
                    if prev_cb == public_parameters.CBDATA_MENU:
                        self.send_menu_report(
                            *self.get_ids_in_update(prev_update), res_id,
                            menu_id)
                    elif prev_cb == public_parameters.CBDATA_INFO_REQ:
                        self.send_info_restaurant(
                            *self.get_ids_in_update(prev_update), res_id)

            elif cb_info.startswith(public_parameters.CBDATA_UNSUBS_REQ):
                """ Unsubscription request """
                cb_info = cb_info.replace(public_parameters.CBDATA_UNSUBS_REQ,
                                          '', 1)
                res_id, menu_id, prev_cb = self.get_res_menu_id_in_request(
                    cb_info)
                InfoManager.unsubscribe(update.effective_chat.id, res_id,
                                        menu_id)
                with InfoManager.data_lock.reader():
                    if prev_cb == public_parameters.CBDATA_MENU:
                        self.send_menu_report(
                            *self.get_ids_in_update(prev_update), res_id,
                            menu_id)
                    elif prev_cb == public_parameters.CBDATA_INFO_REQ:
                        self.send_info_restaurant(
                            *self.get_ids_in_update(prev_update), res_id)

        except Exception as err:
            logging.getLogger(__name__).exception(err)