Exemple #1
0
async def callback_calendar_selector(query,
                                     calendar_type='user',
                                     move='next',
                                     notify_list=None):
    chat_id = query.message.chat.id

    if calendar_type == 'user':
        key = 'user_calendar_selected'
    elif calendar_type == 'history':
        key = 'user_calendar_selected_history'

    selected_date = ctx.get_dispatcher().get(key)

    if selected_date is not None:
        if move == 'next':
            date = next_month(selected_date)
        elif move == 'prev':
            date = previous_month(selected_date)
        year, month = date

        ctx.get_dispatcher()[key] = date
        calendar = Calendar(context_data['user_time'])

        if calendar_type == 'user':
            markup = calendar.create_selected(year, month)
        elif calendar_type == 'history':
            markup = calendar.create_history(year, month, notify_list)
        return EditMessageReplyMarkup(chat_id=chat_id,
                                      message_id=query.message.message_id,
                                      reply_markup=markup)
    else:
        # Do something to inform of the error
        pass
    async def on_process_message(self, message: types.Message):
        """
        Этот обработчик вызывается, когда диспетчер получает сообщение
        """
        # Получить текущий обработчик
        handler = context.get_value('handler')

        # Получить диспетчер из контекста
        dispatcher = ctx.get_dispatcher()

        # Если обработчик был настроен, получить ограничение скорости и ключ от обработчика
        if handler:
            limit = getattr(handler, 'throttling_rate_limit', self.rate_limit)
            key = getattr(handler, 'throttling_key',
                          f"{self.prefix}_{handler.__name__}")
        else:
            limit = self.rate_limit
            key = f"{self.prefix}_message"

        # Использовать Dispatcher.throttle метод
        try:
            await dispatcher.throttle(key, rate=limit)
        except Throttled as t:
            response = await bot.get_chat_member(message.chat.id,
                                                 message.from_user.id)
            if response.status not in admins:
                # Выполнять действия
                await self.message_throttled(message, t)

                # Отменить текущий обработчик
                raise CancelHandler()
    async def on_pre_process_callback_query(call: types.CallbackQuery):
        """
        Этот обработчик вызывается, когда диспетчер получает обновление о нажатии кнопки
        """
        if call.message:
            if call.message.from_user:
                # Получить диспетчер из контекста
                dispatcher = ctx.get_dispatcher()

                # Использовать Dispatcher.throttle метод
                try:
                    await dispatcher.throttle('settings_callback', rate=0.5)
                except Throttled as throttled:
                    response = await bot.get_chat_member(
                        call.message.chat.id, call.from_user.id)
                    if response.status not in admins:

                        # Заблокировать
                        if throttled.exceeded_count <= 2:
                            name = call.from_user.full_name
                            user_id = call.from_user.id
                            await bot.kick_chat_member(
                                call.message.chat.id,
                                user_id,
                                until_date=math.floor(time.time()) + 10 * 60)
                            await bot.send_message(
                                call.message.chat.id,
                                f'[{name}](tg://user?id={user_id}) заблокирован '
                                'на 10 минут за бездумное нажатие по кнопкам :).'
                            )
                        # Отменить текущий обработчик
                        raise CancelHandler()
Exemple #4
0
    async def message_throttled(self, message: types.Message,
                                throttled: Throttled):
        """
        Notify user only on first exceed and notify about unlocking only on last exceed

        :param message:
        :param throttled:
        """
        from engine import moder

        chat = message.chat
        user = message.from_user
        handler = context.get_value('handler')
        dispatcher = ctx.get_dispatcher()

        if handler:
            key = getattr(handler, 'throttling_key',
                          f"{self.prefix}_{handler.__name__}")
        else:
            key = f"{self.prefix}_message"

        # Calculate how many time is left till the block ends
        delta = throttled.rate - throttled.delta

        # Prevent flooding
        if throttled.exceeded_count <= 2:
            await moder.restrict_user(chat.id, user.id, FLOOD_MUTE_TIME)
            await message.reply(FLOOD_LOCK_MESSAGE)

        # Sleep.
        await asyncio.sleep(delta)

        # Check lock status
        thr = await dispatcher.check_key(key)
Exemple #5
0
    async def on_process_message(self, message: types.Message):
        """
        This handler is called when dispatcher receives a message

        :param message:
        """
        # Get current handler
        handler = context.get_value('handler')

        # Get dispatcher from context
        dispatcher = ctx.get_dispatcher()

        # If handler was configured, get rate limit and key from handler
        if handler:
            limit = getattr(handler, 'throttling_rate_limit', self.rate_limit)
            key = getattr(handler, 'throttling_key',
                          f"{self.prefix}_{handler.__name__}")
        else:
            limit = self.rate_limit
            key = f"{self.prefix}_message"

        # Use Dispatcher.throttle method.
        try:
            await dispatcher.throttle(key, rate=limit)
        except Throttled as t:
            # Execute action
            await self.message_throttled(message, t)

            # Cancel current handler
            raise CancelHandler()
    async def message_throttled(self, message: types.Message,
                                throttled: Throttled):
        """
        Notify user only on first exceed and notify about unlocking only on last exceed

        :param message:
        :param throttled:
        """
        handler = context.get_value('handler')
        dispatcher = ctx.get_dispatcher()
        if handler:
            key = getattr(handler, 'throttling_key',
                          f"{self.prefix}_{handler.__name__}")
        else:
            key = f"{self.prefix}_message"

        # Calculate how many time left to the end of block.
        delta = throttled.rate - throttled.delta

        # Prevent flooding
        if throttled.exceeded_count <= 2:
            await message.reply('Too many requests! ')

        # Sleep.
        await asyncio.sleep(delta)

        # Check lock status
        thr = await dispatcher.check_key(key)

        # If current message is not last with current key - do not send message
        if thr.exceeded_count == throttled.exceeded_count:
            await message.reply('Unlocked.')
Exemple #7
0
async def get_my_calendar_markup():
    now = context_data['user_time']
    ctx.get_dispatcher()['user_calendar_selected_history'] = (now.year,
                                                              now.month)
    calendar = Calendar(now)
    list_notifications = await get_list_notification_dates(
        context_data['user_id'])
    markup = calendar.create_history(now.year, now.month, list_notifications)
    return markup
Exemple #8
0
async def callback_calendar_select_day_history(query: CallbackQuery):
    search = re.search('^calendar-day-history-([0-9]{1,2})$', query.data)
    day = search.group(1)
    selected_date = ctx.get_dispatcher().get('user_calendar_selected_history')

    if selected_date is not None:
        t_selected = datetime.datetime(int(selected_date[0]),
                                       int(selected_date[1]), int(day))
        ctx.get_dispatcher()['user_calendar_history_date'] = t_selected

        watch = Watch()
        notification_list = await get_list_notification_times(
            context_data['user_id'])
        markup = watch.create_history_watch(t_selected, notification_list)
        text = 'Все голосовые заметки на {0}\nВыберите время напоминания:'.format(
            t_selected.strftime("%Y-%m-%d"))
        return EditMessageText(chat_id=query.message.chat.id,
                               message_id=query.message.message_id,
                               text=_(text),
                               reply_markup=markup)
Exemple #9
0
async def send_location(message: Message, state_loc=STATE_LOCATION):
    keyboard_button = KeyboardButton(_('Отправить местоположение'),
                                     request_location=True)
    markup = ReplyKeyboardMarkup([[keyboard_button]], one_time_keyboard=True)

    state = ctx.get_dispatcher().current_state(chat=message.chat.id,
                                               user=message.from_user.id)
    await state.reset_state()
    await state.set_state(state_loc)

    text = _(
        'Задайте свой часовой пояс с помощью отправки вашего местоположения.\n'
        'Данный функционал доступен только для мобильных устройств')
    return SendMessage(chat_id=message.chat.id, text=text, reply_markup=markup)
Exemple #10
0
async def set_timezone_by_location_from_voice(message: Message):
    if hasattr(message.location, 'longitude') & hasattr(
            message.location, 'latitude'):
        timezone = utils_timezone.get_by_location(message.location.longitude,
                                                  message.location.latitude)
        text = 'Ваш часовой пояс {0}'.format(timezone)
    else:
        timezone = utils_timezone.get_default()
        text = 'Часовой пояс установлен по-умолчанию {0}'.format(timezone)

    await update_timezone(context_data['user_id'], timezone)

    now = context_data['user_time']
    ctx.get_dispatcher()['user_calendar_selected'] = (now.year, now.month)
    calendar = Calendar(now)
    markup = calendar.create_selected(now.year, now.month)

    state = ctx.get_dispatcher().current_state(chat=message.chat.id,
                                               user=message.from_user.id)
    await state.reset_state()

    return SendMessage(chat_id=message.chat.id,
                       text=_(text + '\nВыберите дату заметки:'),
                       reply_markup=markup)
Exemple #11
0
async def received_voice(message: Message):
    now = context_data['user_time']
    ctx.get_dispatcher()['user_calendar_selected'] = (now.year, now.month)
    calendar = Calendar(now)
    markup = calendar.create_selected(now.year, now.month)

    if message.voice:
        voice_id = await create_user_voice_note(context_data['user_id'],
                                                message.voice)

        if context_data['request_timezone']:
            return await send_location(message, STATE_LOCATION_FROM_VOICE)

        return SendMessage(chat_id=message.chat.id,
                           text=_('Выберите дату заметки:'),
                           reply_markup=markup)
Exemple #12
0
async def set_timezone_by_location(message: Message):
    if hasattr(message.location, 'longitude') & hasattr(
            message.location, 'latitude'):
        timezone = utils_timezone.get_by_location(message.location.longitude,
                                                  message.location.latitude)
        text = 'Установлен часовой пояс: {0}'.format(timezone)
    else:
        timezone = utils_timezone.get_default()
        text = 'Нам не удалось определить часовой пояс по геолокации, по-умолчанию установлен {0}'.format(
            timezone)

    await update_timezone(context_data['user_id'], timezone)

    state = ctx.get_dispatcher().current_state(chat=message.chat.id,
                                               user=message.from_user.id)
    await state.reset_state()

    return SendMessage(chat_id=message.chat.id,
                       text=_(text),
                       reply_markup=ReplyKeyboardRemove())
Exemple #13
0
async def callback_watch_history_select_time(query: CallbackQuery):
    search = re.search('^calendar-time-history-([0-9]{1,2})$', query.data)
    hour = search.group(1)
    selected_date = ctx.get_dispatcher().get('user_calendar_history_date')
    if selected_date is not None:
        notify_date = selected_date.replace(hour=int(hour))

        files = await get_list_notes_by_date(context_data['user_id'],
                                             notify_date)

        for file_id in files:
            bot = ctx.get_bot()
            await bot.send_voice(chat_id=query.message.chat.id,
                                 caption=str(notify_date),
                                 voice=file_id)

        return EditMessageText(chat_id=query.message.chat.id,
                               message_id=query.message.message_id,
                               text=help_text,
                               reply_markup=InlineKeyboardMarkup(),
                               parse_mode=ParseMode.HTML,
                               disable_web_page_preview=True)
Exemple #14
0
async def callback_calendar_select_day(query: CallbackQuery):
    search = re.search('^calendar-day-([0-9]{1,2})$', query.data)
    day = search.group(1)
    selected_date = ctx.get_dispatcher().get('user_calendar_selected')

    if selected_date is not None:
        t_selected = datetime.datetime(int(selected_date[0]),
                                       int(selected_date[1]), int(day))
        note = await get_last_note(context_data['user_id'])
        if note is not None:
            notify_id = await create_notification(note.id, t_selected)
            if notify_id > 0:
                watch = Watch()
                markup = watch.create_note_watch()
                text = '{0}\nВыберите время напоминания:'.format(
                    t_selected.strftime("%Y-%m-%d"))
                return EditMessageText(chat_id=query.message.chat.id,
                                       message_id=query.message.message_id,
                                       text=_(text),
                                       reply_markup=markup)
        else:
            return SendMessage(chat_id=query.message.chat.id,
                               text=_('Ошибка запроса, попробуйте позже'))