Ejemplo n.º 1
0
    def event_alteration_start(update, context):
        """Starts the event alteration process."""
        query = update.callback_query
        query.answer()

        altering_type = query.data.split("_")[-1:][0]

        user_id = query.from_user['id']
        events = DatabaseController.load_user_events(user_id)
        user_language = DatabaseController.load_selected_language(user_id)

        message = None
        if altering_type == 'change':
            message = receive_translation("event_alteration_change_header",
                                          user_language)
        elif altering_type == 'delete':
            message = receive_translation("event_alteration_delete_header",
                                          user_language)

        if UserEventAlterationMachine.receive_state_of_user(
                user_id
        ) == 0 or UserEventAlterationMachine.receive_state_of_user(
                user_id) == -1:
            bot = BotControl.get_bot()
            bot.send_message(
                user_id,
                text=message,
                parse_mode=ParseMode.MARKDOWN_V2,
                reply_markup=Event.event_keyboard_alteration_action(
                    events, user_language, mode=altering_type))
Ejemplo n.º 2
0
    def handle_configuration_language_change(update, context):
        """Handles the change of language."""
        query = update.callback_query
        query.answer()

        user_id = query.from_user['id']

        selected_language = query.data.split("_")[-1:][0]
        DatabaseController.save_user_language(user_id, selected_language)

        query.edit_message_text(
            receive_translation("config_language_changed", selected_language))
Ejemplo n.º 3
0
    def check_ping_needed(user_id, event, today=True):
        """Checks if an event needs to be pinged.
        Args:
            user_id (int): ID of the user.
            event (Event): Contains the event that should be checked.
            today (bool, optional): Indicates whether today or tomorrow is checked.
        Returns:
            bool: True if a ping has to be sent. False if not.
        """
        current_time = datetime.now()
        ping_times = event.ping_times

        event_month = current_time.month
        event_day = current_time.day
        if not today:
            event_date = current_time + timedelta(days=1)
            event_day = event_date.day
            event_month = event_date.month

        event_time = datetime(year=current_time.year, month=event_month, day=event_day,
                              hour=event.event_time_hours, minute=event.event_time_minutes)

        needs_ping = False

        for ping_time in ping_times:
            # If multiple ping times are already reached ping one time and disable all "used" times.
            if ping_times[ping_time]:
                delta = timedelta(hours=int(ping_time.split(':')[0]), minutes=int(ping_time.split(':')[1]))
                if event_time - delta < current_time:
                    event.ping_times[ping_time] = False
                    needs_ping = True

                    # Save ping times for regularly events
                    if event.event_type == EventType.REGULARLY:
                        event.ping_times_to_refresh[ping_time] = True

        event_deleted = False

        # Cleanup event if it is passed
        if event_time < current_time and not event.start_ping_done:
            needs_ping = True
            if event.event_type == EventType.SINGLE:
                DatabaseController.delete_event_of_user(user_id, event.uuid)
                event_deleted = True
            event.start_ping_done = True

        if needs_ping and not event_deleted:
            # Save the changes on the event
            DatabaseController.save_event_data_user(user_id, event)

        return needs_ping, event_deleted
Ejemplo n.º 4
0
    def _check_event_ping(self, user_id, events, today=True):
        """Check which events are not already passed and pings the user.
        Args:
            user_id (int): ID of the user.
            events (list of 'Event'): Contains all events of the user for a single day.
            today (bool, optional): Indicates whether the events of today or tomorrow are checked.
                Checking today by default.
        """
        bot = BotControl.get_bot()

        ping_list = []
        logger.info("Checking %s | %s", user_id, events)
        for event in events:
            ping_needed, event_delete = self.check_ping_needed(user_id, event, today)
            if ping_needed:
                event.deleted = event_delete
                ping_list.append(event)

        # Only ping if there are events to notify about
        if ping_list:
            for event in ping_list:
                message = self.build_ping_message(user_id, event)
                if event.deleted:
                    bot.send_message(user_id, text=message, parse_mode=ParseMode.MARKDOWN_V2)
                else:
                    language = DatabaseController.load_selected_language(user_id)
                    postfix = "_{}".format(event.uuid)
                    bot.send_message(user_id, text=message, parse_mode=ParseMode.MARKDOWN_V2,
                                     reply_markup=Event.event_keyboard_alteration(language, "event", postfix))
Ejemplo n.º 5
0
    def list_all_events_of_user(update, context):
        """Lists all events of the user."""
        user = User.resolve_user(update)

        message = "*{}:*\n\n".format(
            receive_translation("event_list_header", user.language))
        event_data = DatabaseController.load_user_events(user.user_id)
        has_content = False

        for day in DayEnum:
            events = [event for event in event_data if event.day == day]

            if not events:
                continue

            has_content = True
            message += "*{}:*\n".format(
                day.receive_day_translation(user.language))

            for event in events:
                message += event.pretty_print_formatting(user.language)
                message += "\n"

        if not has_content:
            message += "{}".format(
                receive_translation("no_events", user.language))
        bot = BotControl.get_bot()
        bot.send_message(user.user_id,
                         text=message,
                         parse_mode=ParseMode.MARKDOWN_V2,
                         reply_markup=Event.event_keyboard_alteration(
                             user.language))
Ejemplo n.º 6
0
    def _refresh_start_pings(user_ids, day):
        """Refreshes the "start ping done" booleans inside the user data for regularly events on the given day.
        Args:
            user_ids (dict): Contains all users and their events.
            day (int): Day which should be refreshed.
        """
        for user_id in user_ids:
            events = [event for event in DatabaseController.load_user_events(user_id) if event.day == day]
            for event in events:
                event.start_ping_done = False

                # Restore ping times for regularly events
                for event_ping in event.ping_times_to_refresh:
                    event.ping_times[event_ping] = True
                event.ping_times_to_refresh = {}

                DatabaseController.save_event_data_user(user_id, event)
Ejemplo n.º 7
0
    def start_configuration_dialog(update, context):
        """Starts the configuration dialog."""
        user_id = update.message.from_user.id
        user_language = DatabaseController.load_selected_language(user_id)
        Configurator.config_options_keyboard(user_language)

        update.message.reply_text(
            receive_translation("config_dialog_started", user_language),
            reply_markup=Configurator.config_options_keyboard(user_language))
Ejemplo n.º 8
0
 def __init__(self, user_id, telegram_user=None):
     """Constructor.
     Args:
         user_id (int): ID of the user.
         telegram_user (telegram.User, optional): Telegram user object.
     """
     self.telegram_user = telegram_user
     self.user_id = user_id
     self.user_config = DatabaseController.load_user_config(self.user_id)
     self.language = self.user_config["language"]
Ejemplo n.º 9
0
    def check_events(self):
        """Checks the events of all user regularly and pings them."""
        while True:
            user_ids = DatabaseController.load_all_user_ids()
            today = datetime.today().weekday()
            self._ping_users(user_ids, today)

            time.sleep(self.interval)

            # Check if a new day has begun
            current_day = datetime.today().weekday()
            if today != current_day:
                # Use fresh userdata
                user_ids = DatabaseController.load_all_user_ids()
                self._daily_ping_users(user_ids, current_day)

            # Refresh pings of all events of yesterday
            user_ids = DatabaseController.load_all_user_ids()
            self._refresh_start_pings(user_ids, (datetime.today() - timedelta(days=1)).weekday())
Ejemplo n.º 10
0
 def add_new_event_title(update, context):
     """Handles the title of the new event."""
     user = User.resolve_user(update)
     user_language = DatabaseController.load_selected_language(user.user_id)
     if UserEventCreationMachine.receive_state_of_user(user.user_id) != 1:
         return
     title = replace_reserved_characters(update.message.text)
     EventHandler.events_in_creation[user.user_id]["title"] = title
     update.message.reply_text(
         receive_translation("event_creation_content", user_language))
Ejemplo n.º 11
0
    def handle_configuration_daily_ping_change(update, context):
        """Handles the change of daily ping."""
        query = update.callback_query
        query.answer()

        user_id = query.from_user['id']
        user_language = DatabaseController.load_selected_language(user_id)

        selected_daily_ping = query.data.split("_")[-1:][0]

        if selected_daily_ping == "yes":
            config_value = True
            answer = receive_translation("config_daily_ping_enable",
                                         user_language)
        else:
            config_value = False
            answer = receive_translation("config_daily_ping_disable",
                                         user_language)
        DatabaseController.save_daily_ping(user_id, config_value)
        query.edit_message_text(answer)
Ejemplo n.º 12
0
 def add_new_event_content(update, context):
     """Handles the addition of content of a new event."""
     user = User.resolve_user(update)
     user_language = DatabaseController.load_selected_language(user.user_id)
     if UserEventCreationMachine.receive_state_of_user(user.user_id) != 1:
         return
     content = replace_reserved_characters(update.message.text)
     EventHandler.events_in_creation[user.user_id]["content"] = content
     update.message.reply_text(
         receive_translation("event_creation_type", user_language),
         reply_markup=Event.event_keyboard_type(user_language))
Ejemplo n.º 13
0
 def _ping_users(self, user_ids, day):
     """Pings all users inside userdata with the events of the given day
     Args:
         user_ids (list of 'str'): Contains all users.
         day (int): Represents the day which should be pinged for.
     """
     tomorrow = day + 1 if day < 6 else 0
     for user_id in user_ids:
         user_events = DatabaseController.load_user_events(user_id)
         events_of_today = [event for event in user_events if event.day.value == day]
         events_of_tomorrow = [event for event in user_events if event.day.value == tomorrow]
         self._check_event_ping(user_id, events_of_today)
         self._check_event_ping(user_id, events_of_tomorrow, today=False)
Ejemplo n.º 14
0
    def _daily_ping_users(self, user_ids, day):
        """Pings all users inside the user id list with all of their events of the given day.
        Args:
            user_ids (list of 'str'): Contains all users.
            day (int): Represents the day which should be pinged for.
        """
        bot = BotControl.get_bot()

        for user_id in user_ids:
            user_events = DatabaseController.load_user_events(user_id)
            language = DatabaseController.load_selected_language(user_id)
            events_of_today = [event for event in user_events if event.day.value == day and event.in_daily_ping]
            message = ""
            if events_of_today:
                message += "*{}*\n\n".format(receive_translation("event_daily_ping_header", language))
            for event in events_of_today:
                message_event = self.build_ping_message(user_id, event)
                postfix = "_{}".format(event.uuid)
                bot.send_message(user_id, text=message + message_event, parse_mode=ParseMode.MARKDOWN_V2,
                                 reply_markup=Event.event_keyboard_alteration(language, "event", postfix))
                # Clear so that the header is only printed once
                message = ""
Ejemplo n.º 15
0
    def retrieve_all_events(self):
        """Retrieve all events of the user.
        Returns:
            dict: Contains all events of the user.
        """
        event_list = []

        for event in DatabaseController.load_user_events(self.user_id):
            name = event["name"]
            day = DayEnum(event["day"])
            content = event["content"]
            event_type = EventType(event["event_type"])
            ping_time = event["event_time"]
            event_list.append(Event(name, day, content, event_type, ping_time))

        return event_list
Ejemplo n.º 16
0
    def build_ping_message(user_id, event):
        """Generates the ping message for the user.
        Args:
            user_id (int): ID of the user - needed for localization.
            event (Event): Contains all events of a user for a given day that are not passed yet.
        Returns:
            str: Formatted message.
        """
        user_language = DatabaseController.load_selected_language(user_id)
        message = "*{}*\n\n".format(receive_translation("event_reminder", user_language))

        message += "*{}:* {}\n".format(receive_translation("event", user_language), event.name)
        message += "*{}:* {}\n".format(receive_translation("event_content", user_language), event.content)
        message += "*{}:* {}\n".format(receive_translation("event_start", user_language), event.event_time)
        message += "\n"

        return message
Ejemplo n.º 17
0
    def handle_configuration_dialog(update, context):
        """Handles the configuration dialog."""
        query = update.callback_query
        query.answer()

        user_id = query.from_user['id']
        user_language = DatabaseController.load_selected_language(user_id)

        bot = BotControl.get_bot()

        if query.data == CONFIG_LANGUAGE:
            query.edit_message_text(
                text=receive_translation("config_language_which",
                                         user_language),
                reply_markup=Configurator.config_language_keyboard())
        elif query.data == CONFIG_DAILY_PING:
            query.edit_message_text(
                text=receive_translation("config_daily_ping_decide",
                                         user_language),
                reply_markup=Configurator.config_daily_ping_keyboard(
                    user_language))
Ejemplo n.º 18
0
    def event_alteration_handle_reply(update, context):
        """Handles the replies of the event alteration."""
        user_id = update.message.from_user.id
        user_language = DatabaseController.load_selected_language(user_id)

        state = UserEventAlterationMachine.receive_state_of_user(user_id)

        bot = BotControl.get_bot()
        logging.info(EventHandler.events_in_alteration[user_id]['old'])
        event_suffix = "{}".format(
            EventHandler.events_in_alteration[user_id]['old']['id'])

        # State: Alter name
        if state == 11:
            title = replace_reserved_characters(update.message.text)
            EventHandler.events_in_alteration[user_id]['new']['title'] = title
            UserEventAlterationMachine.set_state_of_user(user_id, 99)
            bot.send_message(
                user_id,
                text=receive_translation("event_alteration_change_decision",
                                         user_language),
                reply_markup=Event.event_keyboard_alteration_change_start(
                    user_language, "event_change_{}".format(event_suffix)))

        # State: Alter content
        elif state == 12:
            content = replace_reserved_characters(update.message.text)
            EventHandler.events_in_alteration[user_id]['new'][
                'content'] = content
            UserEventAlterationMachine.set_state_of_user(user_id, 99)
            bot.send_message(
                user_id,
                text=receive_translation("event_alteration_change_decision",
                                         user_language),
                reply_markup=Event.event_keyboard_alteration_change_start(
                    user_language, "event_change_{}".format(event_suffix)))
Ejemplo n.º 19
0
    def event_alteration_perform(update, context):
        """Performs the event alteration."""
        query = update.callback_query
        query.answer()

        user_id = query.from_user['id']
        user_language = DatabaseController.load_selected_language(user_id)
        logging.info("data: %s | state: %s", query.data,
                     UserEventAlterationMachine.receive_state_of_user(user_id))

        event_id = query.data.split('_')[2]

        # Handle silencing of events
        if query.data.startswith("event_silence"):
            event = [
                event for event in DatabaseController.load_user_events(user_id)
                if event.uuid == event_id
            ][0]

            # For regularly events the ping times have to be marked as to be refreshed
            if event.event_type == EventType.REGULARLY:
                for ping_time in event.ping_times:
                    if event.ping_times[ping_time]:
                        event.ping_times_to_refresh[ping_time] = True

            event.ping_times = DEFAULT_PING_STATES.copy()
            DatabaseController.save_event_data_user(user_id, event)
            query.edit_message_text(
                text=receive_translation("event_silenced", user_language))
            UserEventAlterationMachine.set_state_of_user(user_id, 0)

        # Handle change of events
        elif query.data.startswith("event_change"):

            # State: Choice - Check which button the user clicked after change was started.
            if UserEventAlterationMachine.receive_state_of_user(user_id) == 99:
                choice = query.data.split('_')[-1]
                if choice == "name":
                    UserEventAlterationMachine.set_state_of_user(user_id, 1)
                elif choice == "content":
                    UserEventAlterationMachine.set_state_of_user(user_id, 2)
                elif choice == "type":
                    UserEventAlterationMachine.set_state_of_user(user_id, 3)
                elif choice == "start":
                    UserEventAlterationMachine.set_state_of_user(user_id, 4)
                elif choice == "pingtimes":
                    UserEventAlterationMachine.set_state_of_user(user_id, 5)
                elif choice == "day":
                    UserEventAlterationMachine.set_state_of_user(user_id, 6)
                elif choice == "done":
                    UserEventAlterationMachine.set_state_of_user(user_id, -1)

            # State: Initial - return options to the user.
            if UserEventAlterationMachine.receive_state_of_user(user_id) == 0:
                EventHandler.events_in_alteration[user_id] = {}
                EventHandler.events_in_alteration[user_id]['old'] = \
                    DatabaseController.read_event_of_user(user_id, event_id)
                EventHandler.events_in_alteration[user_id]['old'][
                    'id'] = event_id
                EventHandler.events_in_alteration[user_id]['new'] = \
                    EventHandler.events_in_alteration[user_id]['old'].copy()

                query.edit_message_text(
                    text=receive_translation(
                        "event_alteration_change_decision", user_language),
                    reply_markup=Event.event_keyboard_alteration_change_start(
                        user_language, query.data))
                UserEventAlterationMachine.set_state_of_user(user_id, 99)

            # State: Name - Change name of event.
            elif UserEventAlterationMachine.receive_state_of_user(
                    user_id) == 1:
                query.edit_message_text(text=receive_translation(
                    "event_alteration_change_name", user_language))
                UserEventAlterationMachine.set_state_of_user(user_id, 11)

            # State: Content - Change content of event.
            elif UserEventAlterationMachine.receive_state_of_user(
                    user_id) == 2:
                query.edit_message_text(text=receive_translation(
                    "event_alteration_change_content", user_language))
                UserEventAlterationMachine.set_state_of_user(user_id, 12)

            # State: Type - Change type of event.
            elif UserEventAlterationMachine.receive_state_of_user(
                    user_id) == 3:
                query.edit_message_text(
                    text=receive_translation("event_alteration_change_type",
                                             user_language),
                    reply_markup=Event.event_keyboard_type(
                        user_language,
                        callback_prefix="event_change_{}_type_".format(
                            event_id)))
                UserEventAlterationMachine.set_state_of_user(user_id, 13)

            # State: Start time - Change start time of event.
            elif UserEventAlterationMachine.receive_state_of_user(
                    user_id) == 4:
                query.edit_message_text(
                    text=receive_translation("event_alteration_change_hours",
                                             user_language),
                    reply_markup=Event.event_keyboard_hours(
                        callback_prefix="event_change_{}_hours_".format(
                            event_id)))
                UserEventAlterationMachine.set_state_of_user(user_id, 41)

            # State: Ping times - Change ping times of event.
            elif UserEventAlterationMachine.receive_state_of_user(
                    user_id) == 5:
                query.edit_message_text(
                    text=receive_translation(
                        "event_creation_ping_times_header", user_language),
                    reply_markup=Event.event_keyboard_ping_times(
                        user_language,
                        callback_prefix="event_change_{}".format(event_id),
                        states=EventHandler.events_in_alteration[user_id]
                        ["old"]["ping_times"]))
                UserEventAlterationMachine.set_state_of_user(user_id, 51)

            # State: Day - Change day of event.
            elif UserEventAlterationMachine.receive_state_of_user(
                    user_id) == 6:
                query.edit_message_text(
                    text=receive_translation("event_creation_day",
                                             user_language),
                    reply_markup=Event.event_keyboard_day(
                        user_language,
                        callback_prefix="event_change_{}_".format(event_id)))
                UserEventAlterationMachine.set_state_of_user(user_id, 16)

            # State: Alter event type
            elif UserEventAlterationMachine.receive_state_of_user(
                    user_id) == 13:
                EventHandler.events_in_alteration[user_id]['new'][
                    'event_type'] = int(query.data.split('_')[-1][0])
                UserEventAlterationMachine.set_state_of_user(user_id, 99)
                query.edit_message_text(
                    text=receive_translation(
                        "event_alteration_change_decision", user_language),
                    reply_markup=Event.event_keyboard_alteration_change_start(
                        user_language, "event_change_{}".format(event_id)))

            # State: Alter event day
            elif UserEventAlterationMachine.receive_state_of_user(
                    user_id) == 16:
                EventHandler.events_in_alteration[user_id]['new']['day'] = int(
                    query.data.split('_')[-1][1])
                UserEventAlterationMachine.set_state_of_user(user_id, 99)
                query.edit_message_text(
                    text=receive_translation(
                        "event_alteration_change_decision", user_language),
                    reply_markup=Event.event_keyboard_alteration_change_start(
                        user_language, "event_change_{}".format(event_id)))

            # State: Alter event hours
            elif UserEventAlterationMachine.receive_state_of_user(
                    user_id) == 41:
                EventHandler.events_in_alteration[user_id]['new']['event_time'] = \
                    "{}:{}".format(query.data.split('_')[-1][1:],
                                   EventHandler.events_in_alteration[user_id]['new']['event_time'].split(':')[1])
                UserEventAlterationMachine.set_state_of_user(user_id, 42)
                query.edit_message_text(
                    text=receive_translation("event_alteration_change_minutes",
                                             user_language),
                    reply_markup=Event.event_keyboard_minutes(
                        callback_prefix="event_change_{}_minutes_".format(
                            event_id)))

            # State: Alter event minutes
            elif UserEventAlterationMachine.receive_state_of_user(
                    user_id) == 42:
                EventHandler.events_in_alteration[user_id]['new']['event_time'] = \
                    "{}:{}".format(EventHandler.events_in_alteration[user_id]['new']['event_time'].split(':')[0],
                                   query.data.split('_')[-1][1:])
                UserEventAlterationMachine.set_state_of_user(user_id, 99)
                query.edit_message_text(
                    text=receive_translation(
                        "event_alteration_change_decision", user_language),
                    reply_markup=Event.event_keyboard_alteration_change_start(
                        user_language, "event_change_{}".format(event_id)))

            # State: Alter ping times - trigger chance on ping time
            elif UserEventAlterationMachine.receive_state_of_user(
                    user_id) == 51:
                toggle_data = query.data.split('_')[-1]
                if toggle_data == 'done':
                    UserEventAlterationMachine.set_state_of_user(user_id, 99)
                    query.edit_message_text(
                        text=receive_translation(
                            "event_alteration_change_decision", user_language),
                        reply_markup=Event.
                        event_keyboard_alteration_change_start(
                            user_language, "event_change_{}".format(event_id)))
                else:
                    EventHandler.events_in_alteration[user_id]["new"]["ping_times"][toggle_data] = \
                        not EventHandler.events_in_alteration[user_id]["new"]["ping_times"][toggle_data]
                    query.edit_message_text(
                        text=receive_translation(
                            "event_creation_ping_times_header", user_language),
                        reply_markup=Event.event_keyboard_ping_times(
                            user_language,
                            callback_prefix="event_change_{}".format(event_id),
                            states=EventHandler.events_in_alteration[user_id]
                            ["new"]["ping_times"]))

            # State: Done - Save changes and delete temporary object.
            elif UserEventAlterationMachine.receive_state_of_user(
                    user_id) == -1:
                event_dict = EventHandler.events_in_alteration[user_id]["new"]
                event = Event(event_dict['title'],
                              DayEnum(int(event_dict['day'])),
                              event_dict['content'],
                              EventType(int(event_dict['event_type'])),
                              event_dict['event_time'],
                              event_dict['ping_times'],
                              start_ping_done=event_dict['start_ping_done'])
                event.uuid = event_id
                DatabaseController.save_event_data_user(user_id, event)
                query.edit_message_text(text=receive_translation(
                    "event_alteration_change_done", user_language))
                EventHandler.events_in_alteration.pop(user_id)
                UserEventAlterationMachine.set_state_of_user(user_id, 0)

        elif query.data.startswith("event_delete"):

            # State: Initial - request confirmation from user
            if UserEventAlterationMachine.receive_state_of_user(user_id) == 0:

                message = receive_translation(
                    "event_alteration_delete_request_confirmation",
                    user_language)
                message += "\n"

                event_data = DatabaseController.read_event_of_user(
                    user_id, event_id)
                event = Event(event_data['title'], DayEnum(event_data['day']),
                              event_data['content'],
                              EventType(event_data['event_type']),
                              event_data['event_time'])

                message += event.pretty_print_formatting(user_language)

                query.edit_message_text(
                    text=message,
                    reply_markup=Event.event_keyboard_confirmation(
                        user_language, "event_delete_{}".format(event_id)),
                    parse_mode=ParseMode.MARKDOWN_V2)

                UserEventAlterationMachine.set_state_of_user(user_id, 101)

            elif UserEventAlterationMachine.receive_state_of_user(
                    user_id) == 101:

                if query.data.split('_')[-1] == 'yes':
                    DatabaseController.delete_event_of_user(user_id, event_id)
                    query.edit_message_text(text=receive_translation(
                        "event_alteration_delete_confirmed", user_language))
                elif query.data.split('_')[-1] == 'no':
                    query.edit_message_text(text=receive_translation(
                        "event_alteration_delete_aborted", user_language))

                UserEventAlterationMachine.set_state_of_user(user_id, 0)
Ejemplo n.º 20
0
from control.bot_control import BotControl
from control.configurator import Configurator
from control.database_controller import DatabaseController
from control.event_checker import EventChecker
from control.event_handler import EventHandler
from models.user import User
from state_machines.user_event_alteration_machine import UserEventAlterationMachine
from state_machines.user_event_creation_machine import UserEventCreationMachine
from utils.localization_manager import receive_translation

logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
                    level=logging.INFO)

logger = logging.getLogger(__name__)

db_controller = DatabaseController()


# Define a few command handlers. These usually take the two arguments update and
# context. Error handlers also receive the raised TelegramError object in error.
def start(update, context):
    """Send a message when the command /start is issued."""
    user = User.resolve_user(update)
    update.message.reply_text(
        receive_translation("greeting", user.language).format(USERNAME=user.telegram_user.first_name))


def help_command(update, context):
    """Send a message when the command /help is issued."""
    user = User.resolve_user(update)
    update.message.reply_markdown_v2(receive_translation("help", user.language))
Ejemplo n.º 21
0
    def add_new_event_query_handler(update, context):
        """Creates a new event with help of the event creation state machine and keyboards."""
        query = update.callback_query
        query.answer()

        if query.message.chat['type'] == "group":
            user_id = query.message.chat['id']
        else:
            user_id = query.from_user['id']
        user_language = DatabaseController.load_selected_language(user_id)

        bot = BotControl.get_bot()

        # State: Requesting event type
        if UserEventCreationMachine.receive_state_of_user(user_id) == 1:
            EventHandler.events_in_creation[user_id]["event_type"] = int(
                query.data)
            if query.data == "{}".format(EventType.SINGLE.value):
                message = receive_translation("event_creation_type_single",
                                              user_language)
            elif query.data == "{}".format(EventType.REGULARLY.value):
                message = receive_translation("event_creation_type_regularly",
                                              user_language)
            else:
                message = receive_translation("undefined_error_response",
                                              user_language)
            query.edit_message_text(text=message)
            UserEventCreationMachine.set_state_of_user(user_id, 2)

        # State: Requesting day of the event
        if UserEventCreationMachine.receive_state_of_user(user_id) == 2:
            logging.info(query.data)
            if query.data[0] == 'd':
                EventHandler.events_in_creation[user_id]["day"] = query.data[
                    1:]
                UserEventCreationMachine.set_state_of_user(user_id, 3)
                bot.delete_message(user_id, query.message.message_id)
            else:
                bot.send_message(
                    user_id,
                    text=receive_translation("event_creation_day",
                                             user_language),
                    reply_markup=Event.event_keyboard_day(user_language))

        # State: Requesting start hours of the event
        if UserEventCreationMachine.receive_state_of_user(user_id) == 3:
            logging.info(query.data)
            if query.data[0] == 'h':
                EventHandler.events_in_creation[user_id]["hours"] = query.data[
                    1:]
                UserEventCreationMachine.set_state_of_user(user_id, 4)
                bot.delete_message(user_id, query.message.message_id)
            else:
                bot.send_message(user_id,
                                 text=receive_translation(
                                     "event_creation_hours", user_language),
                                 reply_markup=Event.event_keyboard_hours())

        # State: Requesting start minutes of the event
        if UserEventCreationMachine.receive_state_of_user(user_id) == 4:
            logging.info(query.data)
            if query.data[0] == 'm':
                EventHandler.events_in_creation[user_id]["event_time"] = \
                    "{}:{}".format(EventHandler.events_in_creation[user_id]["hours"], query.data[1:])
                UserEventCreationMachine.set_state_of_user(user_id, 10)
                query.edit_message_text(text=receive_translation(
                    "event_creation_finished", user_language))
            else:
                bot.send_message(user_id,
                                 text=receive_translation(
                                     "event_creation_minutes", user_language),
                                 reply_markup=Event.event_keyboard_minutes())

        # State: Start requesting ping times for the event - reset status.
        if UserEventCreationMachine.receive_state_of_user(user_id) == 10:
            ping_states = DEFAULT_PING_STATES.copy()
            EventHandler.events_in_creation[user_id][
                "ping_times"] = ping_states
            query.edit_message_text(
                text=receive_translation("event_creation_ping_times_header",
                                         user_language),
                reply_markup=Event.event_keyboard_ping_times(
                    user_language, "event_creation", ping_states))
            UserEventCreationMachine.set_state_of_user(user_id, 11)

        elif UserEventCreationMachine.receive_state_of_user(user_id) == 11:
            if "ping_times" in query.data:
                suffix = query.data.split('_')[-1]
                if suffix == "done":
                    UserEventCreationMachine.set_state_of_user(user_id, -1)
                    bot.delete_message(user_id, query.message.message_id)
                else:
                    EventHandler.events_in_creation[user_id]["ping_times"][suffix] = \
                        not EventHandler.events_in_creation[user_id]["ping_times"][suffix]
                    query.edit_message_text(
                        text=receive_translation(
                            "event_creation_ping_times_header", user_language),
                        reply_markup=Event.event_keyboard_ping_times(
                            user_language, "event_creation",
                            EventHandler.events_in_creation[user_id]
                            ["ping_times"]))

        # State: All data collected - creating event
        if UserEventCreationMachine.receive_state_of_user(user_id) == -1:
            event_in_creation = EventHandler.events_in_creation[user_id]
            event = Event(event_in_creation["title"],
                          DayEnum(int(event_in_creation["day"])),
                          event_in_creation["content"],
                          EventType(event_in_creation["event_type"]),
                          event_in_creation["event_time"],
                          event_in_creation["ping_times"])
            DatabaseController.save_event_data_user(user_id, event)
            UserEventCreationMachine.set_state_of_user(user_id, 0)
            EventHandler.events_in_creation.pop(user_id)

            # Needed because when an event is created on the current day but has already passed there
            # would be pings for it.
            event_hour, event_minute = event.event_time.split(":")
            current_time = datetime.now()
            if int(event_in_creation["day"]) == current_time.weekday() and int(event_hour) < current_time.hour or \
                    (int(event_hour) == current_time.hour and int(event_minute) < current_time.minute):
                event.start_ping_done = True
                event.ping_times_to_refresh = {}
                for ping_time in event.ping_times:
                    if event.ping_times[ping_time]:
                        event.ping_times_to_refresh[ping_time] = True

                event.ping_times = DEFAULT_PING_STATES.copy()
                DatabaseController.save_event_data_user(user_id, event)

            message = receive_translation("event_creation_summary_header",
                                          user_language)
            message += event.pretty_print_formatting(user_language)
            bot.send_message(user_id,
                             text=message,
                             parse_mode=ParseMode.MARKDOWN_V2)
Ejemplo n.º 22
0
 def setUpClass(cls):
     """Set up test."""
     cls.dbc = DatabaseController(config_file=TEST_CONFIG,
                                  userdata_path=TEST_USER_DATA)