def plaintext_freqlimit_handler(bot, message):
    limits = message['text'].strip().split('/')

    if len(limits) == 1 and limits[0] == '0':
        yield bot.update_settings(message['from']['id'], msg_freq_limit=None)
        yield bot.send_message(pgettext('Limits reset', 'Limits reset'),
                               reply_to_message=message)
        return True
    elif len(limits) == 2 and limits[0].isdigit() and limits[1].isdigit():
        limits[0] = int(limits[0])
        limits[1] = int(limits[1])

        if limits[0] < 1:
            yield bot.send_message(pgettext('Msg limit is too low', 'Messages count limit must be greater than 0'),
                                   reply_to_message=message, reply_markup=ForceReply(True))
        elif limits[1] < 1:
            yield bot.send_message(pgettext('Days limit is too low', 'Days count must be greater than 0'),
                                   reply_to_message=message, reply_markup=ForceReply(True))
        else:
            yield bot.update_settings(message['from']['id'], msg_freq_limit=[limits[0], limits[1]])
            yield bot.send_message(pgettext('Limits changed successfully', 'Limits updated'),
                                   reply_to_message=message)
            return True
    else:
        yield bot.send_message(pgettext('Non-well formatted freq limits provided',
                                        'Please use following format: `{messages_count}/{days}` (e.g. `1/7`), or '
                                        'send /cancel'), reply_to_message=message,
                               parse_mode=bot.PARSE_MODE_MD, reply_markup=ForceReply(True))
Exemple #2
0
def ban_command(bot, callback_query, user_id, chat_id=None, message_id=None):
    report_botan(callback_query, 'slave_ban_cmd')

    if int(user_id) == callback_query['from']['id']:
        yield bot.answer_callback_query(callback_query['id'],
                                        pgettext('Somebody trying to ban himself', 'It\'s not allowed to ban yourself'))
        return None

    if int(user_id) == bot.owner_id:
        yield bot.answer_callback_query(callback_query['id'],
                                        pgettext('Somebody trying to ban the owner',
                                                 'It\'s not allowed to ban the bot owner'))
        return None

    cur = yield bot.db.execute('SELECT banned_at FROM users WHERE bot_id = %s AND user_id = %s', (bot.bot_id, user_id))
    row = cur.fetchone()
    if row and row[0]:
        yield bot.answer_callback_query(callback_query['id'], pgettext('User already banned', 'User already banned'))
        return None

    msg = pgettext('Ban reason request', 'Please enter a ban reason for the user, @{moderator_username}')\
        .format(moderator_username=callback_query['from']['username'])

    if chat_id and message_id:
        fwd_id = yield bot.get_message_fwd_id(chat_id, message_id)
    else:
        fwd_id = None

    yield bot.send_message(msg, chat_id=bot.moderator_chat_id, reply_markup=ForceReply(True),
                           reply_to_message_id=fwd_id)
    yield bot.answer_callback_query(callback_query['id'])
    return {
        'user_id': user_id
    }
Exemple #3
0
def plaintext_reject_handler(bot, message, chat_id, message_id):
    msg = message['text'].strip()
    if len(msg) < 10:
        report_botan(message, 'slave_reply_short_msg')
        yield bot.send_message(pgettext(
            'Reject message is too short',
            'Reject message is too short (10 symbols required), try '
            'again or send /cancel'),
                               reply_to_message=message,
                               reply_markup=ForceReply(True))
    else:
        yield bot.decline_message(
            {
                'chat': {
                    'id': chat_id
                },
                'message_id': message_id
            }, 0, False)
    try:
        yield bot.send_message(pgettext(
            'Message to user in case of rejection',
            "Your post has been rejected. "
            "Reason:\n> {reject_reason}").format(reject_reason=msg),
                               chat_id=chat_id,
                               reply_to_message_id=message_id)
        yield bot.send_message(pgettext('Rejection delivery confirmation',
                                        'Message sent and post rejected'),
                               reply_to_message=message)
    except Exception as e:
        yield bot.send_message(
            pgettext('Rejection failed',
                     'Message sending failed: {reason}').format(reason=str(e)),
            reply_to_message=message)

    return True
Exemple #4
0
 def build_voting_keyboard(message_owner_id, message_id, chat_id):
     return InlineKeyboardMarkup([
         [
             InlineKeyboardButton(Emoji.THUMBS_UP_SIGN,
                                  callback_data='vote_%s_%s_yes' %
                                  (chat_id, message_id)),
             InlineKeyboardButton(Emoji.THUMBS_DOWN_SIGN,
                                  callback_data='vote_%s_%s_no' %
                                  (chat_id, message_id)),
         ],
         [
             InlineKeyboardButton(pgettext('Reply to user button', 'Reply'),
                                  callback_data='reply_%s_%s' %
                                  (chat_id, message_id)),
             InlineKeyboardButton(pgettext('Ban user button',
                                           'Ban this ass'),
                                  callback_data='ban_%s_%s_%s' %
                                  (message_owner_id, chat_id, message_id)),
         ],
         [
             InlineKeyboardButton(pgettext('Reject post button', 'Reject'),
                                  callback_data='reject_%s_%s' %
                                  (chat_id, message_id)),
         ],
     ])
Exemple #5
0
def ban_command(bot, callback_query, user_id):
    report_botan(callback_query, 'slave_ban_cmd')

    if int(user_id) == bot.owner_id:
        yield bot.answer_callback_query(
            callback_query['id'],
            pgettext('Somebody trying to ban the owner',
                     'It\'s not allowed to ban the bot owner'))
        return None

    if int(user_id) == callback_query['from']['id']:
        yield bot.answer_callback_query(
            callback_query['id'],
            pgettext('Somebody trying to ban himself',
                     'It\'s not allowed to ban yourself'))
        return None

    cur = yield bot.db.execute(
        'SELECT banned_at FROM users WHERE bot_id = %s AND user_id = %s',
        (bot.bot_id, user_id))
    row = cur.fetchone()
    if row and row[0]:
        yield bot.answer_callback_query(
            callback_query['id'],
            pgettext('User already banned', 'User already banned'))
        return None

    msg = pgettext('Ban reason request', 'Please enter a ban reason for the user, @{moderator_username}')\
        .format(moderator_username=callback_query['from']['username'])
    yield bot.send_message(msg,
                           chat_id=bot.moderator_chat_id,
                           reply_markup=ForceReply(True))
    yield bot.answer_callback_query(callback_query['id'])
    return {'user_id': user_id}
Exemple #6
0
    def get_verification_message(self,
                                 message_id,
                                 chat_id,
                                 voting_finished=False):
        msg = yield self._build_voting_status(message_id, chat_id,
                                              voting_finished)

        if voting_finished:
            voting_keyboard = None
        else:
            cur = yield self.db.execute(
                'SELECT owner_id FROM incoming_messages WHERE bot_id = %s AND id = %s AND '
                'original_chat_id = %s', (self.bot_id, message_id, chat_id))
            row = cur.fetchone()
            if row and row[0]:
                message_owner_id = row[0]
            else:
                message_owner_id = chat_id
            m = pgettext('Verification message',
                         'What will we do with this message?')
            tags = ''
            if self.settings.get('tag_polls'):
                tags = ' #open'
            msg.insert(0, pgettext('Ignore', '{}{}').format(m, tags))
            voting_keyboard = self.build_voting_keyboard(
                message_owner_id, message_id, chat_id)

        return '\n'.join(set_locale_recursive(msg,
                                              self.locale)), voting_keyboard
Exemple #7
0
    def format_top(rows, f: callable):
        ret = []
        for row_id, row in enumerate(rows):
            user_id, first_name, last_name = row[:3]
            row = row[3:]
            if first_name and last_name:
                user = first_name + ' ' + last_name
            elif first_name:
                user = first_name
            else:
                user = '******' % user_id

            ret.append(
                pgettext('Stats user item',
                         '{row_id}. {user} - {rating_details}').format(
                             row_id=row_id + 1,
                             user=user,
                             rating_details=f(row)))

        if not ret:
            ret.append(
                pgettext('No data for stats report',
                         '{cross_mark} no data').format(
                             cross_mark=Emoji.CROSS_MARK))

        return ret
    def _init_handlers(self):
        self.cancellation_handler = cancel_command
        self.unknown_command_handler = unknown_command
        self._add_handler(validate_user)
        self._add_handler(setlanguage, is_final=False)
        self._add_handler(emoji_end, None, setlanguage)
        self._add_handler(setlanguage_plaintext, None, setlanguage)
        self._add_handler(setlanguage_at_start, is_final=False)
        self._add_handler(setlanguage_at_start_plaintext, None, setlanguage_at_start)
        self._add_handler(start_command)
        self._add_handler(cancel_command)
        self._add_handler(reg_command, pgettext('Command name', '/reg - register a new bot'), is_final=False)
        self._add_handler(plaintext_token, pgettext('Action description', 'Waiting for the token'),
                          previous_handler=reg_command, is_final=False)

        self._add_handler(change_hello_command, None, previous_handler=plaintext_token, is_final=False)
        self._add_handler(plaintext_set_hello, None, previous_handler=change_hello_command, is_final=False)
        self._add_handler(change_hello_command, None, previous_handler=plaintext_set_hello, is_final=False)
        self._add_handler(change_start_command, None, previous_handler=plaintext_set_hello, is_final=False)
        self._add_handler(plaintext_channel_name, None, previous_handler=plaintext_set_hello, is_final=True)

        self._add_handler(change_start_command, None, previous_handler=plaintext_token, is_final=False)
        self._add_handler(plaintext_set_start_message, None, previous_handler=change_start_command, is_final=False)
        self._add_handler(change_start_command, None, previous_handler=plaintext_set_start_message, is_final=False)
        self._add_handler(change_hello_command, None, previous_handler=plaintext_set_start_message, is_final=False)
        self._add_handler(plaintext_channel_name, None, previous_handler=plaintext_set_start_message, is_final=True)

        self._add_handler(plaintext_channel_name, pgettext('Action description', 'Waiting for the channel name'),
                          previous_handler=plaintext_token, is_final=True)
Exemple #9
0
def check_freq(bot, **kwargs):
    if 'message' not in kwargs or not bot.settings.get('msg_freq_limit') or \
                    kwargs['message']['chat']['id'] == bot.moderator_chat_id:
        return False

    fl = bot.settings['msg_freq_limit']

    msgs = yield get_messages_count(bot.db, kwargs['message']['from']['id'],
                                    bot.bot_id, fl[1])
    if msgs < fl[0]:
        return False

    freq_limit_msg_str = npgettext('Messages count', '{msg} message',
                                   '{msg} messages', fl[0]).format(msg=fl[0])
    freq_limit_days_str = npgettext('Days', '{n} day', '{n} days',
                                    fl[1]).format(n=fl[1])
    freq_limit_str = pgettext('Frequency limit', '{messages_str} per {days_str}') \
        .format(messages_str=freq_limit_msg_str, days_str=freq_limit_days_str)

    msg = pgettext(
        'Out of limits',
        'Unfortunately, you\'re out of limits! You can send only {freq_limit_str}'
    )

    yield bot.send_message(msg.format(freq_limit_str=freq_limit_str),
                           reply_to_message=kwargs['message'])
Exemple #10
0
def plaintext_post_handler(bot, message):
    if bot.settings['content_status']['text'] is False:
        yield bot.bot.send_message(pgettext('User send text message for verification while texts is disabled',
                                            'Accepting text messages are disabled'),
                                   reply_to_message=message)
        return

    mes = message['text']
    if mes.strip() != '':
        if bot.settings['text_min'] <= len(mes) <= bot.settings['text_max']:
            yield _request_message_confirmation(bot, message)
            report_botan(message, 'slave_message')
            return {
                'sent_message': message
            }
        else:
            report_botan(message, 'slave_message_invalid')
            yield bot.send_message(pgettext('Incorrect text message received', 'Sorry, but we can proceed only '
                                                                               'messages with length between '
                                                                               '{min_msg_length} and {max_msg_length} '
                                                                               'symbols.')
                                   .format(min_msg_length=format_number(bot.settings['text_min'], bot.language),
                                           max_msg_length=format_number(bot.settings['text_max'], bot.language)),
                                   reply_to_message=message)
    else:
        report_botan(message, 'slave_message_empty')
        yield bot.send_message(pgettext('User sent empty message', 'Seriously??? 8===3'),
                               reply_to_message=message)
def togglevoteswitch_command(bot, message):
    report_botan(message, 'slave_togglevoteswitch_cmd')
    if bot.settings.get('allow_vote_switch'):
        yield bot.update_settings(message['from']['id'], allow_vote_switch=False)
        yield bot.send_message(pgettext('Vote switching disabled', 'From now Moderators can NOT switch their votes'),
                               reply_to_message=message)
    else:
        yield bot.update_settings(message['from']['id'], allow_vote_switch=True)
        yield bot.send_message(pgettext('Vote switching enabled', 'From now Moderators can switch their votes'),
                               reply_to_message=message)
Exemple #12
0
def unban_command(bot, message, user_id):
    report_botan(message, 'slave_unban_cmd')
    yield bot.db.execute('UPDATE users SET banned_at = NULL, ban_reason = NULL WHERE user_id = %s AND '
                         'bot_id = %s', (user_id, bot.id))
    yield bot.send_message(pgettext('Unban confirmation', 'User unbanned'), reply_to_message=message)
    try:
        yield bot.send_message(pgettext('User notification in case of unban', 'Access restored'),
                               chat_id=user_id)
    except:
        pass
def toggletagpolls_command(bot, message):
    report_botan(message, 'slave_toggletagpolls_cmd')
    if bot.settings.get('tag_polls'):
        yield bot.update_settings(message['from']['id'], tag_polls=False)
        yield bot.send_message(pgettext('Polls tagging disabled', 'State tags shall not pass.'),
                               reply_to_message=message)
    else:
        yield bot.update_settings(message['from']['id'], tag_polls=True)
        yield bot.send_message(pgettext('Polls tagging enabled', 'State tags will be added to future polls.'),
                               reply_to_message=message)
Exemple #14
0
def plaintext_ban_handler(bot, message, user_id):
    chat_id = message['chat']['id']

    cur = yield bot.db.execute(
        'SELECT banned_at FROM users WHERE bot_id = %s AND user_id = %s',
        (bot.bot_id, user_id))
    row = cur.fetchone()
    if row and row[0]:
        yield bot.send_message(pgettext(
            'Somebody banned a user faster than another one',
            'Somebody already banned the user. Be faster next time.'),
                               reply_to_message=message)
        return True

    msg = message['text'].strip()
    if len(msg) < 5:
        report_botan(message, 'slave_ban_short_msg')
        yield bot.send_message(pgettext(
            'Ban reason too short',
            'Reason is too short (5 symbols required), '
            'try again or send /cancel'),
                               reply_to_message=message,
                               reply_markup=ForceReply(True))
    else:
        report_botan(message, 'slave_ban_success')
        yield bot.send_chat_action(chat_id, bot.CHAT_ACTION_TYPING)
        try:
            yield bot.send_message(pgettext(
                'Message to user in case of ban',
                "You've been banned from further communication with this bot. "
                "Reason:\n> {ban_reason}").format(ban_reason=msg),
                                   chat_id=user_id)
        except:
            pass
        cur = yield bot.db.execute(
            'SELECT message FROM incoming_messages WHERE bot_id = %s AND owner_id = %s AND '
            'is_voting_success = FALSE AND is_voting_fail = FALSE AND is_published = FALSE',
            (
                bot.id,
                user_id,
            ))
        while True:
            row = cur.fetchone()
            if not row:
                break
            yield bot.decline_message(row[0], 0, False)

        yield bot.db.execute(
            'UPDATE users SET banned_at = NOW(), ban_reason = %s WHERE user_id = %s AND '
            'bot_id = %s', (msg, user_id, bot.id))
        yield bot.send_message(pgettext('Ban confirmation', 'User banned'),
                               reply_to_message=message)

        return True
def togglepower_command(bot, message):
    report_botan(message, 'slave_togglepower_cmd')
    if bot.settings.get('power'):
        yield bot.update_settings(message['from']['id'], power=False)
        yield bot.send_message(pgettext('Power mode disabled', 'From now other chat users can not modify bot settings'),
                               reply_to_message=message)
    else:
        yield bot.update_settings(message['from']['id'], power=True)
        yield bot.send_message(pgettext('Power mode enabled', 'From now other chat users can modify bot settings (only '
                                                              'inside moderators chat)'),
                               reply_to_message=message)
Exemple #16
0
def togglevote_command(bot, message):
    report_botan(message, 'slave_togglevote_cmd')
    if bot.settings.get('public_vote'):
        yield bot.update_settings(message['from']['id'], public_vote=False)
        yield bot.send_message(pgettext('Vote status displaying disabled', 'From now other chat users WILL NOT see '
                                                                           'current votes distribution.'),
                               reply_to_message=message)
    else:
        yield bot.update_settings(message['from']['id'], public_vote=True)
        yield bot.send_message(pgettext('Vote status displaying enabled', 'From now other chat users WILL see current '
                                                                          'votes distribution.'),
                               reply_to_message=message)
def plaintext_timeout_handler(bot, message):
    if message['text'].isdigit() and int(message['text']) > 0:
        report_botan(message, 'slave_settimeout')
        yield bot.update_settings(message['from']['id'], vote_timeout=int(message['text']))
        yield bot.send_message(pgettext('Voting duration successfully changed', 'Voting duration updated'),
                               reply_to_message=message)
        return True
    else:
        report_botan(message, 'slave_settimeout_invalid')
        yield bot.send_message(pgettext('Invalid voting duration value', 'Invalid voting duration value. Try again or '
                                                                         'type /cancel'),
                               reply_to_message=message, reply_markup=ForceReply(True))
def toggleselfvote_command(bot, message):
    report_botan(message, 'slave_toggleselfvote_cmd')
    if bot.settings.get('selfvote'):
        yield bot.update_settings(message['from']['id'], selfvote=False)
        yield bot.send_message(pgettext('Self-vote disabled', 'From now moderators WILL NOT be able to vote for own '
                                                              'messages.'),
                               reply_to_message=message)
    else:
        yield bot.update_settings(message['from']['id'], selfvote=True)
        yield bot.send_message(pgettext('Self-vote enabled', 'From now moderators WILL BE able to vote for own '
                                                             'messages.'),
                               reply_to_message=message)
def toggle_start_web_preview_command(bot, message):
    report_botan(message, 'slave_toggle_start_web_preview_cmd')
    if bot.settings.get('start_web_preview'):
        yield bot.update_settings(message['from']['id'], start_web_preview=False)
        yield bot.send_message(pgettext('Web preview disabled in /start', 'From now web previews WILL NOT BE generated '
                                                                          'for links in /start message.'),
                               reply_to_message=message)
    else:
        yield bot.update_settings(message['from']['id'], start_web_preview=True)
        yield bot.send_message(pgettext('Web preview enabled in /start', 'From now web previews WILL BE generated for '
                                                                         'links in /start message.'),
                               reply_to_message=message)
Exemple #20
0
def plaintext_votes_handler(bot, message):
    if message['text'].isdigit() and int(message['text']) > 0:
        report_botan(message, 'slave_setvotes')
        yield bot.update_settings(message['from']['id'], votes=int(message['text']))
        yield bot.send_message(pgettext('Required votes count successfully changed', 'Required votes '
                                                                                     'amount updated'),
                               reply_to_message=message)
        return True
    else:
        report_botan(message, 'slave_setvotes_invalid')
        yield bot.send_message(pgettext('Invalid votes amount value', 'Invalid votes amount value. Try again or type '
                                                                      '/cancel'),
                               reply_to_message=message, reply_markup=ForceReply(True))
Exemple #21
0
def plaintext_startmessage_handler(bot, message):
    if message['text'] and len(message['text'].strip()) > 10:
        report_botan(message, 'slave_setstartmessage')
        yield bot.update_settings(message['from']['id'], start=message['text'].strip())
        yield bot.send_message(pgettext('Start message successfully changed', 'Start message updated'),
                               reply_to_message=message)
        return True
    else:
        report_botan(message, 'slave_setstartmessage_invalid')
        yield bot.send_message(pgettext('Too short start message entered', 'Invalid start message, you should write at '
                                                                           'least 10 symbols. Try again or type '
                                                                           '/cancel'),
                               reply_to_message=message, reply_markup=ForceReply(True))
Exemple #22
0
def setlanguage_plaintext(bot, message, **kwargs):
    languages = {
        lang_name: lang_code
        for lang_code, lang_name in LANGUAGE_LIST
    }

    if message['text'] in languages:
        yield bot.update_settings(message['from']['id'], locale=languages[message['text']])
        yield bot.send_message(pgettext('Language changed', 'Language changed'),
                               reply_to_message=message, reply_markup=ReplyKeyboardHide())
        return True
    else:
        yield bot.send_message(pgettext('Invalid user response', 'Wrong input'), reply_to_message=message)
def toggletagpolls_command(bot, message):
    report_botan(message, 'slave_toggletagpolls_cmd')
    if bot.settings.get('tag_polls'):
        yield bot.update_settings(message['from']['id'], tag_polls=False)
        yield bot.send_message(pgettext('Polls tagging disabled',
                                        'State tags shall not pass.'),
                               reply_to_message=message)
    else:
        yield bot.update_settings(message['from']['id'], tag_polls=True)
        yield bot.send_message(pgettext(
            'Polls tagging enabled',
            'State tags will be added to future polls.'),
                               reply_to_message=message)
def setlanguage_plaintext(bot, message, **kwargs):
    languages = {
        lang_name: lang_code
        for lang_code, lang_name in LANGUAGE_LIST
    }

    if message['text'] in languages:
        yield bot.update_settings(message['from']['id'], locale=languages[message['text']])
        yield bot.send_message(pgettext('Language changed', 'Language changed'),
                               reply_to_message=message, reply_markup=ReplyKeyboardHide())
        return True
    else:
        yield bot.send_message(pgettext('Invalid user response', 'Wrong input'), reply_to_message=message)
Exemple #25
0
def _request_message_confirmation(bot, message):
    yield bot.forward_message(message['from']['id'], message['chat']['id'], message['message_id'])
    yield bot.send_message(pgettext('Message received, requesting the user to check the message once again',
                                    'Looks good for me. I\'ve printed the message in exact same way as it '
                                    'will be publised. Please, take a look on your message one more time. And '
                                    'click Confirm button if everything is fine'),
                           reply_to_message=message,
                           reply_markup=InlineKeyboardMarkup([
                               [InlineKeyboardButton(pgettext('`Confirm` button on message review keyboard',
                                                              'Confirm'), callback_data='confirm_publishing'),
                                InlineKeyboardButton(pgettext('`Cancel` button on message review keyboard',
                                                              'Cancel'), callback_data='cancel_publishing'),
                                ]
                           ]))
Exemple #26
0
def help_command(bot, message):
    report_botan(message, 'slave_help')
    delay_str = npgettext('Delay between channel messages', '{delay} minute',
                          '{delay} minutes', bot.settings['delay'])
    timeout_str = npgettext('Voting timeout', '{timeout} hour',
                            '{timeout} hours', bot.settings['vote_timeout'])
    power_state = 'on' if bot.settings.get('power') else 'off'
    power_state_str = pgettext('Boolean settings', power_state)
    public_vote_state = 'on' if bot.settings.get('public_vote') else 'off'
    public_vote_state_str = pgettext('Boolean settings', public_vote_state)
    selfvote_state = 'on' if bot.settings.get('selfvote') else 'off'
    selfvote_state_str = pgettext('Boolean settings', selfvote_state)
    start_web_preview_state = 'on' if bot.settings.get(
        'start_web_preview') else 'off'
    start_web_preview_state_str = pgettext('Boolean settings',
                                           start_web_preview_state)
    voteswitch_state = 'on' if bot.settings.get('allow_vote_switch') else 'off'
    voteswitch_state_str = pgettext('Boolean settings', voteswitch_state)
    tag_polls_state = 'on' if bot.settings.get('tag_polls') else 'off'
    tag_polls_state_str = pgettext('Boolean settings', tag_polls_state)

    if bot.settings.get('msg_freq_limit'):
        fl = bot.settings['msg_freq_limit']
        freq_limit_msg_str = npgettext('Messages count', '{msg} message',
                                       '{msg} messages',
                                       fl[0]).format(msg=fl[0])
        freq_limit_days_str = npgettext('Days', '{n} day', '{n} days',
                                        fl[1]).format(n=fl[1])
        freq_limit_str = pgettext('Frequency limit', '{messages_str} per {days_str}') \
            .format(messages_str=freq_limit_msg_str, days_str=freq_limit_days_str)
    else:
        freq_limit_str = pgettext('No frequency limit', 'unlimited')

    msg = pgettext('/help command response', 'bot.help.response') \
        .format(current_delay_with_minutes=delay_str.format(delay=bot.settings['delay']),
                current_votes_required=bot.settings['votes'],
                current_timeout_with_hours=timeout_str.format(timeout=bot.settings['vote_timeout']),
                thumb_up_sign=Emoji.THUMBS_UP_SIGN, thumb_down_sign=Emoji.THUMBS_DOWN_SIGN,
                current_start_message=bot.settings['start'], power_state=power_state_str,
                public_vote_state=public_vote_state_str,
                current_text_limit={'min': bot.settings['text_min'], 'max': bot.settings['text_max']},
                selfvote_state=selfvote_state_str, start_web_preview_state=start_web_preview_state_str,
                current_freqlimit=freq_limit_str, voteswitch_state=voteswitch_state_str,
                tag_polls_state=tag_polls_state_str)

    try:
        yield bot.send_message(msg,
                               reply_to_message=message,
                               parse_mode=bot.PARSE_MODE_MD,
                               disable_web_page_preview=True)
    except:
        yield bot.send_message(msg,
                               reply_to_message=message,
                               disable_web_page_preview=True)
Exemple #27
0
def togglepower_command(bot, message):
    report_botan(message, 'slave_togglepower_cmd')
    if bot.settings.get('power'):
        yield bot.update_settings(message['from']['id'], power=False)
        yield bot.send_message(pgettext(
            'Power mode disabled',
            'From now other chat users can not modify bot settings'),
                               reply_to_message=message)
    else:
        yield bot.update_settings(message['from']['id'], power=True)
        yield bot.send_message(pgettext(
            'Power mode enabled',
            'From now other chat users can modify bot settings (only '
            'inside moderators chat)'),
                               reply_to_message=message)
Exemple #28
0
def toggleselfvote_command(bot, message):
    report_botan(message, 'slave_toggleselfvote_cmd')
    if bot.settings.get('selfvote'):
        yield bot.update_settings(message['from']['id'], selfvote=False)
        yield bot.send_message(pgettext(
            'Self-vote disabled',
            'From now moderators WILL NOT be able to vote for own '
            'messages.'),
                               reply_to_message=message)
    else:
        yield bot.update_settings(message['from']['id'], selfvote=True)
        yield bot.send_message(pgettext(
            'Self-vote enabled',
            'From now moderators WILL BE able to vote for own '
            'messages.'),
                               reply_to_message=message)
def setfreqlimit_command(bot, message):
    yield bot.send_message(pgettext('New frequency limits request', 'Please enter new value for messages frequency '
                                                                    'limits formatted like `{messages_count}/{days}`, '
                                                                    'or `0` to disable limits '
                                                                    '(e.g. `1/7` to set limit to 1 message per week)'),
                           reply_to_message=message, parse_mode=bot.PARSE_MODE_MD, reply_markup=ForceReply(True))
    return True
Exemple #30
0
    def decline_message(self, message, yes_votes, notify=True):
        cur = yield self.db.execute('SELECT moderation_message_id FROM incoming_messages WHERE bot_id = %s AND '
                                    'original_chat_id = %s AND id = %s', (self.bot_id, message['chat']['id'],
                                                                          message['message_id']))

        row = cur.fetchone()

        if row and row[0]:
            moderation_message_id = row[0]

            msg, keyboard = yield self.get_verification_message(message['message_id'], message['chat']['id'], True)
            try:
                yield self.edit_message_text(msg, chat_id=self.moderator_chat_id, message_id=moderation_message_id,
                                             reply_markup=keyboard)
            except ApiError as e:
                # Ignore few errors while declining errors
                if e.code != 400 or ('message is not modified' not in e.description
                                     and 'message not found' not in e.description
                                     and 'message to edit not found' not in e.description
                                     and 'bot was blocked by the user' not in e.description):
                    raise

        yield self.db.execute('UPDATE incoming_messages SET is_voting_fail = TRUE WHERE bot_id = %s AND '
                              'is_voting_success = FALSE AND is_voting_fail = FALSE AND original_chat_id = %s '
                              'AND id = %s',
                              (self.bot_id, message['chat']['id'], message['message_id']))

        if notify:
            try:
                yield self.send_message(pgettext('Voting failed', 'Unfortunately your message not passed moderation and '
                                                                  'won\'t be published to the channel.'),
                                        chat_id=message['chat']['id'], reply_to_message=message)
            except ApiError as e:
                if e.code != 403 or ('bot was blocked by the user' not in e.description):
                    raise
def setlanguage_at_start(bot, message):
    if bot.get_settings(message['from']['id']) != {}:
        return False

    yield bot.send_message(pgettext('Change language prompt', 'Select your language'),
                           reply_to_message=message, reply_markup=get_keyboard(False))
    return True
Exemple #32
0
def plaintext_delay_handler(bot, message):
    if message['text'].isdigit() and int(message['text']) >= 0:
        report_botan(message, 'slave_setdelay')
        yield bot.update_settings(message['from']['id'],
                                  delay=int(message['text']))
        yield bot.send_message(pgettext('Messages delay successfully changed',
                                        'Delay value updated'),
                               reply_to_message=message)
        return True
    else:
        report_botan(message, 'slave_setdelay_invalid')
        yield bot.send_message(pgettext(
            'Invalid delay value',
            'Invalid delay value. Try again or type /cancel'),
                               reply_to_message=message,
                               reply_markup=ForceReply(True))
Exemple #33
0
def setvotes_command(bot, message):
    report_botan(message, 'slave_setvotes_cmd')
    yield bot.send_message(pgettext('New required votes count request',
                                    'Set new amount of required votes'),
                           reply_to_message=message,
                           reply_markup=ForceReply(True))
    return True
Exemple #34
0
def plaintext_reply_handler(bot, message, chat_id, message_id):
    msg = message['text'].strip()
    if len(msg) < 10:
        report_botan(message, 'slave_reply_short_msg')
        yield bot.send_message(pgettext('Reply message is too short', 'Message is too short (10 symbols required), try '
                                                                      'again or send /cancel'),
                               reply_to_message=message, reply_markup=ForceReply(True))
    else:
        try:
            yield bot.send_message(msg, chat_id=chat_id, reply_to_message_id=message_id)
            yield bot.send_message(pgettext('Reply delivery confirmation', 'Message sent'), reply_to_message=message)
        except Exception as e:
            yield bot.send_message(pgettext('Reply failed', 'Failed: {reason}').format(reason=str(e)),
                                   reply_to_message=message)

        return True
Exemple #35
0
    def send_moderation_request(self, chat_id, message_id):
        try:
            yield self.forward_message(self.moderator_chat_id, chat_id, message_id)
        except ApiError as e:
            if 'migrated' in e.description and 'migrate_to_chat_id' in e.parameters:
                yield migrate(self, e.parameters['migrate_to_chat_id'])
                yield self.send_moderation_request(chat_id, message_id)
                return
            else:
                raise

        msg, voting_keyboard = yield self.get_verification_message(message_id, chat_id)

        moderation_msg = yield self.send_message(msg, chat_id=self.moderator_chat_id, reply_markup=voting_keyboard)
        cur = yield self.db.execute('SELECT moderation_message_id FROM incoming_messages WHERE id = %s AND '
                                    'original_chat_id = %s AND bot_id = %s', (message_id, chat_id, self.bot_id))
        row = cur.fetchone()
        if row and row[0]:
            self.edit_message_text(pgettext('Newer poll for this message posted below', '_Outdated_'),
                                   chat_id=self.moderator_chat_id, message_id=row[0], parse_mode=self.PARSE_MODE_MD)

        yield self.db.execute('UPDATE incoming_messages SET moderation_message_id = %s WHERE id = %s AND '
                              'original_chat_id = %s AND bot_id = %s',
                              (moderation_msg['message_id'], message_id, chat_id,
                               self.bot_id))
        yield self.db.execute('UPDATE registered_bots SET last_moderation_message_at = NOW() WHERE id = %s',
                              (self.bot_id,))
Exemple #36
0
    def send_moderation_request(self, chat_id, message_id):
        try:
            fwd = yield self.forward_message(self.moderator_chat_id, chat_id, message_id)
        except ApiError as e:
            if 'migrated' in e.description and 'migrate_to_chat_id' in e.parameters:
                yield migrate(self, e.parameters['migrate_to_chat_id'])
                yield self.send_moderation_request(chat_id, message_id)
                return
            else:
                raise

        msg, voting_keyboard = yield self.get_verification_message(message_id, chat_id)

        moderation_msg = yield self.send_message(msg, chat_id=self.moderator_chat_id, reply_markup=voting_keyboard)
        cur = yield self.db.execute('SELECT moderation_message_id FROM incoming_messages WHERE id = %s AND '
                                    'original_chat_id = %s AND bot_id = %s', (message_id, chat_id, self.bot_id))
        row = cur.fetchone()
        if row and row[0]:
            self.edit_message_text(pgettext('Newer poll for this message posted below', '_Outdated_'),
                                   chat_id=self.moderator_chat_id, message_id=row[0], parse_mode=self.PARSE_MODE_MD)

        yield self.db.execute('UPDATE incoming_messages SET moderation_message_id = %s, moderation_fwd_message_id = %s '
                              'WHERE id = %s AND original_chat_id = %s AND bot_id = %s',
                              (moderation_msg['message_id'], fwd['message_id'], message_id, chat_id, self.bot_id))
        yield self.db.execute('UPDATE registered_bots SET last_moderation_message_at = NOW() WHERE id = %s',
                              (self.bot_id,))
Exemple #37
0
    def decline_message(self, message, yes_votes, notify=True):
        cur = yield self.db.execute('SELECT moderation_message_id FROM incoming_messages WHERE bot_id = %s AND '
                                    'original_chat_id = %s AND id = %s', (self.bot_id, message['chat']['id'],
                                                                          message['message_id']))

        row = cur.fetchone()

        if row and row[0]:
            moderation_message_id = row[0]

            msg, keyboard = yield self.get_verification_message(message['message_id'], message['chat']['id'], True)
            try:
                yield self.edit_message_text(msg, chat_id=self.moderator_chat_id, message_id=moderation_message_id,
                                             reply_markup=keyboard)
            except ApiError as e:
                # Ignore few errors while declining errors
                if e.code != 400 or ('message is not modified' not in e.description
                                     and 'message not found' not in e.description
                                     and 'message to edit not found' not in e.description
                                     and 'bot was blocked by the user' not in e.description):
                    raise

        yield self.db.execute('UPDATE incoming_messages SET is_voting_fail = TRUE WHERE bot_id = %s AND '
                              'is_voting_success = FALSE AND is_voting_fail = FALSE AND original_chat_id = %s '
                              'AND id = %s',
                              (self.bot_id, message['chat']['id'], message['message_id']))

        if notify:
            try:
                yield self.send_message(pgettext('Voting failed', 'Unfortunately your message not passed moderation and '
                                                                  'won\'t be published to the channel.'),
                                        chat_id=message['chat']['id'], reply_to_message=message)
            except ApiError as e:
                if e.code != 403 or ('bot was blocked by the user' not in e.description):
                    raise
Exemple #38
0
def setdelay_command(bot, message):
    report_botan(message, 'slave_setdelay_cmd')
    yield bot.send_message(pgettext(
        'New delay request',
        'Set new delay value for messages posting (in minutes)'),
                           reply_to_message=message,
                           reply_markup=ForceReply(True))
    return True
def types_translations(bot):
    ret = {}
    for t in TYPES:
        ret[t] = pgettext('Content type', t[0].upper() + t[1:])
        ret[t].locale = bot.locale
        ret[t] = str(ret[t])

    return ret
Exemple #40
0
def types_translations(bot):
    ret = {}
    for t in TYPES:
        ret[t] = pgettext('Content type', t[0].upper() + t[1:])
        ret[t].locale = bot.locale
        ret[t] = str(ret[t])

    return ret
Exemple #41
0
def plaintext_timeout_handler(bot, message):
    if message['text'].isdigit() and int(message['text']) > 0:
        report_botan(message, 'slave_settimeout')
        yield bot.update_settings(message['from']['id'],
                                  vote_timeout=int(message['text']))
        yield bot.send_message(pgettext('Voting duration successfully changed',
                                        'Voting duration updated'),
                               reply_to_message=message)
        return True
    else:
        report_botan(message, 'slave_settimeout_invalid')
        yield bot.send_message(pgettext(
            'Invalid voting duration value',
            'Invalid voting duration value. Try again or '
            'type /cancel'),
                               reply_to_message=message,
                               reply_markup=ForceReply(True))
Exemple #42
0
    def _build_voting_status(self, message_id, chat_id, voting_finished):
        cur = yield self.db.execute('SELECT count(*), sum(vote_yes::int) FROM votes_history WHERE message_id = %s AND '
                                    'original_chat_id = %s', (message_id, chat_id))

        total_votes, approves = cur.fetchone()
        if total_votes == 0:
            percent_yes = 0
            percent_no = 0
            approves = 0
        else:
            percent_yes = approves / total_votes
            percent_no = 1 - percent_yes

        max_thumbs = 8

        thumb_ups = Emoji.THUMBS_UP_SIGN * round(max_thumbs * percent_yes)
        thumb_downs = Emoji.THUMBS_DOWN_SIGN * round(max_thumbs * percent_no)

        message = [pgettext('Beginning of poll message', 'Current poll progress:'),
                   npgettext('Count of voted moderators', '{cnt} vote', '{cnt} votes', total_votes).format(
                       cnt=total_votes)]

        if voting_finished or self.settings.get('public_vote', True):
            if voting_finished:
                more_yes = more_no = ''
            else:
                to_win_yes = self.settings['votes'] - approves
                more_yes = npgettext('Votes left to make a decision', '{cnt} more to win', '{cnt} more to win', to_win_yes) \
                    .format(cnt=to_win_yes)
                to_win_no = self.settings['votes'] - total_votes + approves
                more_no = npgettext('Votes left to make a decision', '{cnt} more to win', '{cnt} more to win', to_win_no) \
                    .format(cnt=to_win_no)

                more_yes = pgettext('ignore', ' ({})').format(more_yes)
                more_no = pgettext('ignore', ' ({})').format(more_no)
                more_yes.locale = self.locale
                more_no.locale = self.locale

            message.append("{thumb_up}{thumbs_up} — {percent_yes}%{more_yes}\n"
                           "{thumb_down}{thumbs_down} — {percent_no}%{more_no}\n"
                           .format(thumb_up=Emoji.THUMBS_UP_SIGN, thumbs_up=thumb_ups,
                                   percent_yes=round(percent_yes * 100), thumb_down=Emoji.THUMBS_DOWN_SIGN,
                                   thumbs_down=thumb_downs, percent_no=round(percent_no * 100), more_yes=more_yes,
                                   more_no=more_no))

        if voting_finished:
            message.append(pgettext('Poll finished', 'Poll is closed.'))
            if approves >= self.settings['votes']:
                cur = yield self.db.execute('SELECT is_published FROM incoming_messages WHERE bot_id = %s AND '
                                            'id = %s AND original_chat_id = %s', (self.bot_id, message_id, chat_id))

                row = cur.fetchone()
                if row and row[0]:
                    message.append(pgettext('Vote successful, message is published', 'The message is published.'))
                else:
                    message.append(pgettext('Vote successful', 'The message will be published soon.'))
            else:
                message.append(pgettext('Vote failed', 'The message will not be published.'))

        return message
def toggle_start_web_preview_command(bot, message):
    report_botan(message, 'slave_toggle_start_web_preview_cmd')
    if bot.settings.get('start_web_preview'):
        yield bot.update_settings(message['from']['id'],
                                  start_web_preview=False)
        yield bot.send_message(pgettext(
            'Web preview disabled in /start',
            'From now web previews WILL NOT BE generated '
            'for links in /start message.'),
                               reply_to_message=message)
    else:
        yield bot.update_settings(message['from']['id'],
                                  start_web_preview=True)
        yield bot.send_message(pgettext(
            'Web preview enabled in /start',
            'From now web previews WILL BE generated for '
            'links in /start message.'),
                               reply_to_message=message)
Exemple #44
0
def setlanguage_at_start(bot, message):
    if bot.get_settings(message['from']['id']) != {}:
        return False

    yield bot.send_message(pgettext('Change language prompt',
                                    'Select your language'),
                           reply_to_message=message,
                           reply_markup=get_keyboard(False))
    return True
Exemple #45
0
def settimeout_command(bot, message):
    report_botan(message, 'slave_settimeout_cmd')
    yield bot.send_message(pgettext(
        'New voting duration request',
        'Set new voting duration value (in hours, only a '
        'digits)'),
                           reply_to_message=message,
                           reply_markup=ForceReply(True))
    return True
Exemple #46
0
def change_allowed_command(bot, message):
    report_botan(message, 'slave_change_allowed_cmd')
    yield bot.send_message(pgettext(
        '/changeallowed response',
        'You can see current status on keyboard, just click on '
        'content type to change it\'s status'),
                           reply_to_message=message,
                           reply_markup=build_contenttype_keyboard(bot))
    return True
def validate_user(bot, **kwargs):
    if 'message' not in kwargs:
        return False

    allowed = yield is_allowed_user(bot.db, kwargs['message']['from'], bot.bot_id)
    if allowed:
        return False

    yield bot.send_message(pgettext('User banned', 'Access denied'), reply_to_message=kwargs['message'])
Exemple #48
0
def plaintext_votes_handler(bot, message):
    if message['text'].isdigit() and int(message['text']) > 0:
        report_botan(message, 'slave_setvotes')
        yield bot.update_settings(message['from']['id'],
                                  votes=int(message['text']))
        yield bot.send_message(pgettext(
            'Required votes count successfully changed', 'Required votes '
            'amount updated'),
                               reply_to_message=message)
        return True
    else:
        report_botan(message, 'slave_setvotes_invalid')
        yield bot.send_message(pgettext(
            'Invalid votes amount value',
            'Invalid votes amount value. Try again or type '
            '/cancel'),
                               reply_to_message=message,
                               reply_markup=ForceReply(True))
Exemple #49
0
def plaintext_contenttype_handler(bot, message):
    try:
        split = message['text'].split(' ')
        action_type, content_type = split[0], ' '.join(split[1:])

        if action_type == Emoji.MEDIUM_SMALL_WHITE_CIRCLE:
            action_type = True
        elif action_type == Emoji.CIRCLED_BULLET:
            action_type = False
        else:
            raise ValueError()

        updated_content_type = content_type[0].upper(
        ) + content_type[1:].lower()

        content_status = bot.settings['content_status']

        translations = types_translations(bot)
        content_types_list = dict(
            zip(translations.values(), translations.keys()))

        if updated_content_type in content_types_list:
            content_type_raw = content_types_list[updated_content_type]
            content_status[content_type_raw] = action_type
            yield bot.update_settings(message['from']['id'],
                                      content_status=content_status)
        else:
            raise ValueError()

        action_text = 'enable' if action_type else 'disable'

        report_botan(message,
                     'slave_content_' + content_type_raw + '_' + action_text)

        msg = content_type_raw[0].upper(
        ) + content_type_raw[1:] + 's ' + action_text + 'd'

        yield bot.send_message(pgettext('Content type enabled/disabled', msg),
                               reply_to_message=message,
                               reply_markup=build_contenttype_keyboard(bot))
    except:
        yield bot.send_message(pgettext('Invalid user response',
                                        'Wrong input'),
                               reply_to_message=message)
Exemple #50
0
 def build_voting_keyboard(message_owner_id, message_id, chat_id):
     return InlineKeyboardMarkup([
         [
             InlineKeyboardButton(Emoji.THUMBS_UP_SIGN,
                                  callback_data='vote_%s_%s_yes' % (chat_id, message_id)),
             InlineKeyboardButton(Emoji.THUMBS_DOWN_SIGN,
                                  callback_data='vote_%s_%s_no' % (chat_id, message_id)),
         ],
         [
             InlineKeyboardButton(pgettext('Reply to user button', 'Reply'),
                                  callback_data='reply_%s_%s' % (chat_id, message_id)),
             InlineKeyboardButton(pgettext('Ban user button', 'Ban this ass'),
                                  callback_data='ban_%s_%s_%s' % (message_owner_id, chat_id, message_id)),
         ],
         [
             InlineKeyboardButton(pgettext('Reject post button', 'Reject'),
                                  callback_data='reject_%s_%s' % (chat_id, message_id)),
         ],
     ])
Exemple #51
0
def plaintext_ban_handler(bot, message, user_id):
    chat_id = message['chat']['id']

    cur = yield bot.db.execute('SELECT banned_at FROM users WHERE bot_id = %s AND user_id = %s', (bot.bot_id, user_id))
    row = cur.fetchone()
    if row and row[0]:
        yield bot.send_message(pgettext('Somebody banned a user faster than another one',
                                        'Somebody already banned the user. Be faster next time.'),
                               reply_to_message=message)
        return True

    msg = message['text'].strip()
    if len(msg) < 5:
        report_botan(message, 'slave_ban_short_msg')
        yield bot.send_message(pgettext('Ban reason too short', 'Reason is too short (5 symbols required), '
                                                                'try again or send /cancel'),
                               reply_to_message=message, reply_markup=ForceReply(True))
    else:
        report_botan(message, 'slave_ban_success')
        yield bot.send_chat_action(chat_id, bot.CHAT_ACTION_TYPING)
        try:
            yield bot.send_message(pgettext('Message to user in case of ban',
                                            "You've been banned from further communication with this bot. "
                                            "Reason:\n> {ban_reason}").format(ban_reason=msg),
                                   chat_id=user_id)
        except:
            pass
        cur = yield bot.db.execute('SELECT message FROM incoming_messages WHERE bot_id = %s AND owner_id = %s AND '
                                   'is_voting_success = FALSE AND is_voting_fail = FALSE AND is_published = FALSE',
                                   (bot.id, user_id,))
        while True:
            row = cur.fetchone()
            if not row:
                break
            yield bot.decline_message(row[0], 0, False)

        yield bot.db.execute('UPDATE users SET banned_at = NOW(), ban_reason = %s WHERE user_id = %s AND '
                             'bot_id = %s', (msg, user_id, bot.id))
        yield bot.send_message(pgettext('Ban confirmation', 'User banned'), reply_to_message=message)

        return True
Exemple #52
0
    def get_verification_message(self, message_id, chat_id, voting_finished=False):
        msg = yield self._build_voting_status(message_id, chat_id, voting_finished)

        if voting_finished:
            voting_keyboard = None
        else:
            cur = yield self.db.execute('SELECT owner_id FROM incoming_messages WHERE bot_id = %s AND id = %s AND '
                                        'original_chat_id = %s', (self.bot_id, message_id, chat_id))
            row = cur.fetchone()
            if row and row[0]:
                message_owner_id = row[0]
            else:
                message_owner_id = chat_id
            m = pgettext('Verification message', 'What will we do with this message?')
            tags = ''
            if self.settings.get('tag_polls'):
                tags = ' #open'
            msg.insert(0, pgettext('Ignore', '{}{}').format(m, tags))
            voting_keyboard = self.build_voting_keyboard(message_owner_id, message_id, chat_id)

        return '\n'.join(set_locale_recursive(msg, self.locale)), voting_keyboard
Exemple #53
0
def reply_command(bot, callback_query, chat_id, message_id):
    report_botan(callback_query, 'slave_reply_cmd')
    msg = pgettext('Reply message request', 'What message should I send to user, @{moderator_username}?') \
        .format(moderator_username=callback_query['from'].get('username', callback_query['from']['id']))
    fwd_id = yield bot.get_message_fwd_id(chat_id, message_id)
    yield bot.send_message(msg, chat_id=bot.moderator_chat_id, reply_markup=ForceReply(True),
                           reply_to_message_id=fwd_id)
    yield bot.answer_callback_query(callback_query['id'])
    return {
        'chat_id': chat_id,
        'message_id': message_id,
    }
Exemple #54
0
def help_command(bot, message):
    report_botan(message, 'slave_help')
    delay_str = npgettext('Delay between channel messages', '{delay} minute', '{delay} minutes', bot.settings['delay'])
    timeout_str = npgettext('Voting timeout', '{timeout} hour', '{timeout} hours', bot.settings['vote_timeout'])
    power_state = 'on' if bot.settings.get('power') else 'off'
    power_state_str = pgettext('Boolean settings', power_state)
    public_vote_state = 'on' if bot.settings.get('public_vote') else 'off'
    public_vote_state_str = pgettext('Boolean settings', public_vote_state)
    selfvote_state = 'on' if bot.settings.get('selfvote') else 'off'
    selfvote_state_str = pgettext('Boolean settings', selfvote_state)
    start_web_preview_state = 'on' if bot.settings.get('start_web_preview') else 'off'
    start_web_preview_state_str = pgettext('Boolean settings', start_web_preview_state)
    voteswitch_state = 'on' if bot.settings.get('allow_vote_switch') else 'off'
    voteswitch_state_str = pgettext('Boolean settings', voteswitch_state)
    tag_polls_state = 'on' if bot.settings.get('tag_polls') else 'off'
    tag_polls_state_str = pgettext('Boolean settings', tag_polls_state)

    if bot.settings.get('msg_freq_limit'):
        fl = bot.settings['msg_freq_limit']
        freq_limit_msg_str = npgettext('Messages count', '{msg} message', '{msg} messages', fl[0]).format(msg=fl[0])
        freq_limit_days_str = npgettext('Days', '{n} day', '{n} days', fl[1]).format(n=fl[1])
        freq_limit_str = pgettext('Frequency limit', '{messages_str} per {days_str}') \
            .format(messages_str=freq_limit_msg_str, days_str=freq_limit_days_str)
    else:
        freq_limit_str = pgettext('No frequency limit', 'unlimited')

    msg = pgettext('/help command response', 'bot.help.response') \
        .format(current_delay_with_minutes=delay_str.format(delay=bot.settings['delay']),
                current_votes_required=bot.settings['votes'],
                current_timeout_with_hours=timeout_str.format(timeout=bot.settings['vote_timeout']),
                thumb_up_sign=Emoji.THUMBS_UP_SIGN, thumb_down_sign=Emoji.THUMBS_DOWN_SIGN,
                current_start_message=bot.settings['start'], power_state=power_state_str,
                public_vote_state=public_vote_state_str,
                current_text_limit={'min': bot.settings['text_min'], 'max': bot.settings['text_max']},
                selfvote_state=selfvote_state_str, start_web_preview_state=start_web_preview_state_str,
                current_freqlimit=freq_limit_str, voteswitch_state=voteswitch_state_str,
                tag_polls_state=tag_polls_state_str)

    try:
        yield bot.send_message(msg, reply_to_message=message, parse_mode=bot.PARSE_MODE_MD,
                               disable_web_page_preview=True)
    except:
        yield bot.send_message(msg, reply_to_message=message, disable_web_page_preview=True)
def unknown_command(bot, *args, **kwargs):
    if kwargs.get('message'):
        msg = kwargs['message']
        if hasattr(bot, 'moderator_chat_id') and msg['chat']['id'] == bot.moderator_chat_id and \
            msg.get('reply_to_message', {}).get('from', {}).get('id') != bot.id:
            return False

    message = pgettext('Unknown command', 'I have no idea what a hell do you want from me, sorry :(')
    if kwargs.get('message'):
        yield bot.send_message(message, reply_to_message=kwargs['message'])
    elif kwargs.get('callback_query'):
        yield bot.answer_callback_query(kwargs['callback_query']['id'], message)
    else:
        return False
def plaintext_textlimits_handler(bot, message):
    limits = message['text'].strip().split('..')

    if len(limits) == 2 and limits[0].isdigit() and limits[1].isdigit():
        limits[0] = int(limits[0])
        limits[1] = int(limits[1])

        if limits[0] < 1:
            yield bot.send_message(pgettext('Bottom limit is too low', 'Bottom limit must be greater than 0'),
                                   reply_to_message=message, reply_markup=ForceReply(True))
        elif limits[1] <= limits[0]:
            yield bot.send_message(pgettext('Top limit is too low', 'Top limit must be greater than bottom one'),
                                   reply_to_message=message, reply_markup=ForceReply(True))
        else:
            yield bot.update_settings(message['from']['id'], text_min=limits[0], text_max=limits[1])
            yield bot.send_message(pgettext('Text limits changed successfully', 'Limits updated'),
                                   reply_to_message=message)
            return True
    else:
        yield bot.send_message(pgettext('Non-well formated text limits provided',
                                        'Please use following format: `{min_length}..{max_length}` (e.g. `1..10`), or '
                                        'send /cancel'), reply_to_message=message,
                               parse_mode=bot.PARSE_MODE_MD, reply_markup=ForceReply(True))