Example #1
0
async def welcome_security_handler_pm(message, strings, regexp=None, state=None, **kwargs):
    args = message.get_args().split('_')
    chat_id = int(args[2])
    user_id = message.from_user.id

    async with state.proxy() as data:
        data['chat_id'] = chat_id
        data['msg_id'] = int(args[4])

    if not message.from_user.id == int(args[3]):
        if not (rkey := redis.get(f'welcomesecurity_users_{user_id}')) and not chat_id == rkey:
            await message.reply(strings['not_allowed'])  # TODO
            return
Example #2
0
async def export_chat_data(message, chat, strings):
    chat_id = chat['chat_id']
    key = 'export_lock:' + str(chat_id)
    if redis.get(key) and message.from_user.id not in OPERATORS:
        ttl = format_timedelta(timedelta(seconds=redis.ttl(key)),
                               strings['language_info']['babel'])
        await message.reply(strings['exports_locked'] % ttl)
        return

    redis.set(key, 1)
    redis.expire(key, 7200)

    msg = await message.reply(strings['started_exporting'])
    data = {
        'general': {
            'chat_name': chat['chat_title'],
            'chat_id': chat_id,
            'timestamp': datetime.now(),
            'version': VERSION
        }
    }

    for module in [m for m in LOADED_MODULES if hasattr(m, '__export__')]:
        await asyncio.sleep(0.2)
        if k := await module.__export__(chat_id):
            data.update(k)
Example #3
0
async def leave_silent(message):
    if not message.from_user.id == BOT_ID:
        return

    if int(redis.get('leave_silent:' +
                     str(message.chat.id))) == message.left_chat_member.id:
        await message.delete()
Example #4
0
async def importfbans_cmd(message, fed, strings):
    fed_id = fed['fed_id']
    key = 'importfbans_lock:' + str(fed_id)
    if redis.get(key) and message.from_user.id not in OPERATORS:
        ttl = format_timedelta(timedelta(seconds=redis.ttl(key)), strings['language_info']['babel'])
        await message.reply(strings['importfbans_locked'] % ttl)
        return

    redis.set(key, 1)
    redis.expire(key, 7200)

    if 'document' in message:
        document = message.document
    else:
        if 'reply_to_message' not in message:
            await ImportFbansFileWait.waiting.set()
            await message.reply(strings['send_import_file'])
            return

        elif 'document' not in message.reply_to_message:
            await message.reply(strings['rpl_to_file'])
            return
        document = message.reply_to_message.document

    await importfbans_func(message, fed, document=document)
Example #5
0
async def all_errors_handler(message, error):
    message = (message.message if message.message is not None else
               message.callback_query.message
               if message.callback_query is not None else message)
    chat_id = message.chat.id
    err_tlt = sys.exc_info()[0].__name__
    err_msg = str(sys.exc_info()[1])

    log.warn('Error caused update is: \n' +
             html.escape(str(parse_update(message))))

    if redis.get(chat_id) == str(error):
        # by err_tlt we assume that it is same error
        return

    if err_tlt == 'BadRequest' and err_msg == 'Have no rights to send a message':
        return True

    if err_tlt in ('FloodWaitError', 'RetryAfter', 'SlowModeWaitError'):
        return True

    text = "<b>Sorry, I encountered a error!</b>\n"
    text += f'<code>{html.escape(err_tlt)}: {html.escape(err_msg)}</code>'
    redis.set(chat_id, str(error), ex=600)
    await bot.send_message(chat_id, text)
Example #6
0
async def register_action(event, chat, callback_data=None, state=None, **kwargs):
    filter_id = callback_data['filter_id']
    action = FILTERS_ACTIONS[filter_id]

    user_id = event.from_user.id
    chat_id = chat['chat_id']

    handler = redis.get(f'add_filter:{user_id}:{chat_id}')

    data = {
        'chat_id': chat_id,
        'handler': handler,
        'action': filter_id
    }

    if 'setup' in action:
        await NewFilter.setup.set()
        async with state.proxy() as proxy:
            proxy['data'] = data
            proxy['filter_id'] = filter_id

        await action['setup']['start'](event.message)
        return

    await save_filter(event.message, data)
Example #7
0
async def export_chat_data(message, chat, strings):
    chat_id = chat['chat_id']
    key = 'export_lock:' + str(chat_id)
    if redis.get(key) and message.from_user.id not in OPERATORS:
        ttl = format_timedelta(timedelta(seconds=redis.ttl(key)),
                               strings['language_info']['babel'])
        await message.reply(strings['exports_locked'] % ttl)
        return

    redis.set(key, 1)
    redis.expire(key, 7200)

    msg = await message.reply(strings['started_exporting'])
    data = {
        'general': {
            'chat_name': chat['chat_title'],
            'chat_id': chat_id,
            'timestamp': datetime.now(),
            'version': 1
        }
    }

    for module in [m for m in LOADED_MODULES if hasattr(m, '__export__')]:
        await asyncio.sleep(0.2)
        data.update(await module.__export__(chat_id))

    jfile = InputFile(io.StringIO(ujson.dumps(data, indent=2)),
                      filename=f'{chat_id}_export.json')
    text = strings['export_done'] % chat['chat_title']
    await message.answer_document(jfile, text, reply=message.message_id)
    await msg.delete()
Example #8
0
async def import_fun(message, document, chat, strings):
    chat_id = chat['chat_id']
    key = 'import_lock:' + str(chat_id)
    if redis.get(key) and message.from_user.id not in OPERATORS:
        ttl = format_timedelta(timedelta(seconds=redis.ttl(key)),
                               strings['language_info']['babel'])
        await message.reply(strings['imports_locked'] % ttl)
        return

    redis.set(key, 1)
    redis.expire(key, 7200)

    msg = await message.reply(strings['started_importing'])
    if document['file_size'] > 52428800:
        await message.reply(strings['big_file'])
        return
    data = await bot.download_file_by_id(document.file_id, io.BytesIO())
    data = ujson.load(data)

    if 'general' not in data:
        await message.reply(strings['bad_file'])
        return

    imported = []
    for module in [m for m in LOADED_MODULES if hasattr(m, '__import__')]:
        module_name = module.__name__.replace('sophie_bot.modules.', '')
        print(module_name)
        if module_name in data:
            imported.append(module_name)
            await asyncio.sleep(0.2)
            await module.__import__(chat_id, data[module_name])

    await msg.delete()
    await message.answer(strings['import_done'], reply=message.message_id)
Example #9
0
async def get_chat_lang(chat_id):
    r = redis.get('lang_cache_{}'.format(chat_id))
    if r:
        return r
    else:
        db_lang = await db.lang.find_one({'chat_id': chat_id})
        if db_lang:
            # Rebuild lang cache
            redis.set('lang_cache_{}'.format(chat_id), db_lang['lang'])
            return db_lang['lang']
        user_lang = await db.user_list.find_one({'user_id': chat_id})
        if user_lang and user_lang['user_lang'] in LANGUAGES:
            # Add telegram language in lang cache
            redis.set('lang_cache_{}'.format(chat_id), user_lang['user_lang'])
            return user_lang['user_lang']
        else:
            return 'en'
Example #10
0
async def fban_export(message, fed, strings):
    fed_id = fed['fed_id']
    key = 'fbanlist_lock:' + str(fed_id)
    if redis.get(key) and message.from_user.id not in OPERATORS:
        ttl = format_timedelta(timedelta(seconds=redis.ttl(key)), strings['language_info']['babel'])
        await message.reply(strings['fbanlist_locked'] % ttl)
        return

    redis.set(key, 1)
    redis.expire(key, 7200)

    msg = await message.reply(strings['creating_fbanlist'])
    fields = ['user_id', 'reason', 'by', 'time', 'banned_chats']
    with io.StringIO() as f:
        writer = csv.DictWriter(f, fields)
        writer.writeheader()
        async for banned_data in db.fed_bans.find({'fed_id': fed_id}):
            await asyncio.sleep(0)

            data = {'user_id': banned_data['user_id']}

            if 'reason' in banned_data:
                data['reason'] = banned_data['reason']

            if 'time' in banned_data:
                data['time'] = int(time.mktime(banned_data['time'].timetuple()))

            if 'by' in banned_data:
                data['by'] = banned_data['by']

            if 'banned_chats' in banned_data:
                data['banned_chats'] = banned_data['banned_chats']

            writer.writerow(data)

        text = strings['fbanlist_done'] % fed['fed_name']
        f.seek(0)
        await message.answer_document(
            InputFile(f, filename='fban_export.csv'),
            text
        )
    await msg.delete()
Example #11
0
async def import_fun(message, document, chat, strings):
    chat_id = chat['chat_id']
    key = 'import_lock:' + str(chat_id)
    if redis.get(key) and message.from_user.id not in OPERATORS:
        ttl = format_timedelta(timedelta(seconds=redis.ttl(key)),
                               strings['language_info']['babel'])
        await message.reply(strings['imports_locked'] % ttl)
        return

    redis.set(key, 1)
    redis.expire(key, 7200)

    msg = await message.reply(strings['started_importing'])
    if document['file_size'] > 52428800:
        await message.reply(strings['big_file'])
        return
    data = await bot.download_file_by_id(document.file_id, io.BytesIO())
    data = ujson.load(data)

    if 'general' not in data:
        await message.reply(strings['bad_file'])
        return

    file_version = data['general']['version']

    if file_version > VERSION:
        await message.reply(strings['file_version_so_new'])
        return

    imported = []
    for module in [m for m in LOADED_MODULES if hasattr(m, '__import__')]:
        module_name = module.__name__.replace('sophie_bot.modules.', '')
        if module_name not in data:
            continue
        if not data[module_name]:
            continue

        imported.append(module_name)
        await asyncio.sleep(0)  # Switch to other events before continue
        await module.__import__(chat_id, data[module_name])

    await msg.edit_text(strings['import_done'])
Example #12
0
async def connected_start_state(message, strings, chat):
    key = 'sophie_connected_start_state:' + str(message.from_user.id)
    if redis.get(key):
        await message.reply(strings['pm_connected'].format(chat_name=chat['chat_title']))
        redis.delete(key)