Exemple #1
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, 600)

    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)
Exemple #2
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, 600)

    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)
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,
            "date": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            "version": VERSION,
        }
    }

    for module in [m for m in LOADED_MODULES if hasattr(m, "__export__")]:
        await asyncio.sleep(0)  # Switch to other events before continue
        if k := await module.__export__(chat_id):
            data.update(k)
async def leave_silent(message):
    if not message.from_user.id == BOT_ID:
        return

    if redis.get("leave_silent:" +
                 str(message.chat.id)) == message.left_chat_member.id:
        await message.delete()
Exemple #5
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,
            'date': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            'version': VERSION
        }
    }

    for module in [m for m in LOADED_MODULES if hasattr(m, '__export__')]:
        await asyncio.sleep(0)  # Switch to other events before continue
        if k := await module.__export__(chat_id):
            data.update(k)
Exemple #6
0
async def get_chat_lang(chat_id):
    r = redis.get("lang_cache_{}".format(chat_id))
    if r:
        return r
    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 not user_lang or user_lang["user_lang"] not in LANGUAGES:
        return "en"

    # Add telegram language in lang cache
    redis.set("lang_cache_{}".format(chat_id), user_lang["user_lang"])
    return user_lang["user_lang"]
Exemple #7
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'
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())
    try:
        data = rapidjson.load(data)
    except ValueError:
        return await message.reply(strings["invalid_file"])

    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("DaisyX.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"])
Exemple #9
0
async def all_errors_handler(update: Update, error):
    if update.message is not None:
        message = update.message
    elif update.callback_query is not None:
        message = update.callback_query.message
    elif update.edited_message is not None:
        message = update.edited_message
    else:
        return True  # we don't want other guys in playground

    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)), quote=False)
    )

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

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

    ignored_errors = (
        "FloodWaitError",
        "RetryAfter",
        "SlowModeWaitError",
        "InvalidQueryID",
    )
    if err_tlt in ignored_errors:
        return True

    if err_tlt in ("NetworkError", "TelegramAPIError", "RestartingTelegram"):
        log.error("Conn/API error detected", exc_info=error)
        return True

    text = "<b>Sorry, I encountered a error!</b>\n"
    text += f"<code>{html.escape(err_tlt, quote=False)}: {html.escape(err_msg, quote=False)}</code>"
    redis.set(chat_id, str(error), ex=600)
    await bot.send_message(chat_id, text)
Exemple #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, 600)

    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"] % html.escape(fed["fed_name"], False)
        f.seek(0)
        await message.answer_document(InputFile(f, filename="fban_export.csv"),
                                      text)
    await msg.delete()
Exemple #11
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, 600)

    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'] % html.escape(fed['fed_name'], False)
        f.seek(0)
        await message.answer_document(InputFile(f, filename='fban_export.csv'),
                                      text)
    await msg.delete()
Exemple #12
0
async def register_action(event,
                          chat,
                          strings,
                          callback_data=None,
                          state=None,
                          **kwargs):
    if not await is_user_admin(event.message.chat.id, event.from_user.id):
        return await event.answer("You are not admin to do this")
    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}")

    if not handler:
        return await event.answer("Something went wrong! Please try again!",
                                  show_alert=True)

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

    if "setup" in action:
        await NewFilter.setup.set()
        setup_co = len(action["setup"]) - 1 if type(
            action["setup"]) is list else 0
        async with state.proxy() as proxy:
            proxy["data"] = data
            proxy["filter_id"] = filter_id
            proxy["setup_co"] = setup_co
            proxy["setup_done"] = 0
            proxy["msg_id"] = event.message.message_id

        if setup_co > 0:
            await action["setup"][0]["start"](event.message)
        else:
            await action["setup"]["start"](event.message)
        return

    await save_filter(event.message, data, strings)
Exemple #13
0
async def register_action(event, chat, strings, callback_data=None, state=None, **kwargs):
    if not await is_user_admin(event.message.chat.id, event.from_user.id):
        return await event.answer('You are not admin to do this')
    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}')

    if not handler:
        return await event.answer("Something went wrong! Please try again!", show_alert=True)

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

    if 'setup' in action:
        await NewFilter.setup.set()
        setup_co = len(action['setup']) - \
            1 if type(action['setup']) is list else 0
        async with state.proxy() as proxy:
            proxy['data'] = data
            proxy['filter_id'] = filter_id
            proxy['setup_co'] = setup_co
            proxy['setup_done'] = 0
            proxy['msg_id'] = event.message.message_id

        if setup_co > 0:
            await action['setup'][0]['start'](event.message)
        else:
            await action['setup']['start'](event.message)
        return

    await save_filter(event.message, data, strings)
Exemple #14
0
    allow_kwargs=True,
)
@chat_connection()
@get_strings_dec("antiflood")
async def antiflood_expire_proc(message: Message, chat: dict, strings: dict,
                                state, **_):
    try:
        if (time := message.text) not in (0, "0"):
            # just call for making sure its valid
            parsed_time = convert_time(time)
        else:
            time, parsed_time = None, None
    except (TypeError, ValueError):
        await message.reply(strings["invalid_time"])
    else:
        if not (data := redis.get(f'antiflood_setup:{chat["chat_id"]}')):
            await message.reply(strings["setup_corrupted"])
        else:
            await db.antiflood.update_one(
                {"chat_id": chat["chat_id"]},
                {"$set": {
                    "time": time,
                    "count": int(data)
                }},
                upsert=True,
            )
            await get_data.reset_cache(chat["chat_id"])
            kw = {"count": data}
            if time is not None:
                kw.update({
                    "time":
Exemple #15
0
async def welcome_security_passed(message: Union[CallbackQuery, Message],
                                  state, strings):
    user_id = message.from_user.id
    async with state.proxy() as data:
        chat_id = data["chat_id"]
        msg_id = data["msg_id"]
        verify_msg_id = data["verify_msg_id"]
        to_delete = data["to_delete"]

    with suppress(ChatAdminRequired):
        await unmute_user(chat_id, user_id)

    with suppress(MessageToDeleteNotFound, MessageCantBeDeleted):
        if to_delete:
            await bot.delete_message(chat_id, msg_id)
        await bot.delete_message(user_id, verify_msg_id)
    await state.finish()

    with suppress(MessageToDeleteNotFound, MessageCantBeDeleted):
        message_id = redis.get(f"welcome_security_users:{user_id}:{chat_id}")
        # Delete the person's real security button if exists!
        if message_id:
            await bot.delete_message(chat_id, message_id)

    redis.delete(f"welcome_security_users:{user_id}:{chat_id}")

    with suppress(JobLookupError):
        scheduler.remove_job(f"wc_expire:{chat_id}:{user_id}")

    title = (await db.chat_list.find_one({"chat_id": chat_id}))["chat_title"]

    if "data" in message:
        await message.answer(strings["passed_no_frm"] % title, show_alert=True)
    else:
        await message.reply(strings["passed"] % title)

    db_item = await get_greetings_data(chat_id)

    if "message" in message:
        message = message.message

    # Welcome
    if "note" in db_item and not db_item.get("welcome_disabled", False):
        text, kwargs = await t_unparse_note_item(
            message.reply_to_message
            if message.reply_to_message is not None else message,
            db_item["note"],
            chat_id,
        )
        await send_note(user_id, text, **kwargs)

    # Welcome mute
    if "welcome_mute" in db_item and db_item["welcome_mute"][
            "enabled"] is not False:
        user = await bot.get_chat_member(chat_id, user_id)
        if "can_send_messages" not in user or user["can_send_messages"] is True:
            await restrict_user(
                chat_id,
                user_id,
                until_date=convert_time(db_item["welcome_mute"]["time"]),
            )

    chat = await db.chat_list.find_one({"chat_id": chat_id})

    buttons = None
    if chat_nick := chat["chat_nick"] if chat.get("chat_nick", None) else None:
        buttons = InlineKeyboardMarkup().add(
            InlineKeyboardButton(text=strings["click_here"],
                                 url=f"t.me/{chat_nick}"))
Exemple #16
0
async def connected_start_state(message, strings, chat):
    key = 'DaisyX_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)
Exemple #17
0
        return

    # Welcome
    if "note" not in db_item:
        db_item["note"] = {
            "text": strings["default_welcome"],
            "parse_mode": "md"
        }
    reply_to = (message.message_id if "clean_welcome" in db_item
                and db_item["clean_welcome"]["enabled"] is not False else None)
    text, kwargs = await t_unparse_note_item(message, db_item["note"], chat_id)
    msg = await send_note(chat_id, text, reply_to=reply_to, **kwargs)
    # Clean welcome
    if "clean_welcome" in db_item and db_item["clean_welcome"][
            "enabled"] is not False:
        if value := redis.get(_clean_welcome.format(chat=chat_id)):
            with suppress(MessageToDeleteNotFound, MessageCantBeDeleted):
                await bot.delete_message(chat_id, value)
        redis.set(_clean_welcome.format(chat=chat_id), msg.id)

    # Welcome mute
    if user_id == BOT_ID:
        return
    if "welcome_mute" in db_item and db_item["welcome_mute"][
            "enabled"] is not False:
        user = await bot.get_chat_member(chat_id, user_id)
        if "can_send_messages" not in user or user["can_send_messages"] is True:
            if not await check_admin_rights(message, chat_id, BOT_ID,
                                            ["can_restrict_members"]):
                await message.reply(strings["not_admin_wm"])
                return
Exemple #18
0
async def set_time_config(
    message: Message, chat: dict, strings: dict, state: FSMContext, **_
):
    if not (action := redis.get(f"floodactionstate:{chat['chat_id']}")):
        await message.reply("setup_corrupted", allow_sending_without_reply=True)
        return await state.finish()