示例#1
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)
示例#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)
示例#3
0
async def join_expired(chat_id, user_id, message_id, wlkm_msg_id):
    user = await bot.get_chat_member(chat_id, user_id)
    if user.status != "restricted":
        return

    bot_user = await bot.get_chat_member(chat_id, BOT_ID)
    if ("can_restrict_members" not in bot_user
            or bot_user["can_restrict_members"] is False):
        return

    key = "leave_silent:" + str(chat_id)
    redis.set(key, user_id)

    await unmute_user(chat_id, user_id)
    await kick_user(chat_id, user_id)
    await tbot.delete_messages(chat_id, [message_id, wlkm_msg_id])
示例#4
0
async def kick_user_cmd(message, chat, user, args, strings):
    chat_id = chat["chat_id"]
    user_id = user["user_id"]

    if user_id == BOT_ID:
        await message.reply(strings["kick_RaVaN"])
        return

    elif user_id == message.from_user.id:
        await message.reply(strings["kick_self"])
        return

    elif await is_user_admin(chat_id, user_id):
        await message.reply(strings["kick_admin"])
        return

    text = strings["user_kicked"].format(
        user=await get_user_link(user_id),
        admin=await get_user_link(message.from_user.id),
        chat_name=chat["chat_title"],
    )

    # Add reason
    if args:
        text += strings["reason"] % args

    # Check if silent
    silent = False
    if get_cmd(message) == "skick":
        silent = True
        key = "leave_silent:" + str(chat_id)
        redis.set(key, user_id)
        redis.expire(key, 30)
        text += strings["purge"]

    await kick_user(chat_id, user_id)

    msg = await message.reply(text)

    # Del msgs if silent
    if silent:
        to_del = [msg.message_id, message.message_id]
        if ("reply_to_message" in message
                and message.reply_to_message.from_user.id == user_id):
            to_del.append(message.reply_to_message.message_id)
        await asyncio.sleep(5)
        await tbot.delete_messages(chat_id, to_del)
示例#5
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"
示例#6
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())
    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("RaVaN.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"])
示例#7
0
async def setflood_command(message: Message, chat: dict, strings: dict):
    try:
        args = int(get_args(message)[0])
    except ValueError:
        return await message.reply(strings["invalid_args:setflood"])
    if args > 200:
        return await message.reply(strings["overflowed_count"])

    await AntiFloodConfigState.expiration_proc.set()
    redis.set(f"antiflood_setup:{chat['chat_id']}", args)
    await message.reply(
        strings["config_proc_1"],
        reply_markup=InlineKeyboardMarkup().add(
            InlineKeyboardButton(
                text=strings["cancel"],
                callback_data=cancel_state.new(user_id=message.from_user.id),
            )),
    )
示例#8
0
async def add_handler(message, chat, strings):
    # filters doesn't support anon admins
    if message.from_user.id == 1087968824:
        return await message.reply(strings["anon_detected"])
    # if not await check_admin_rights(message, chat_id, message.from_user.id, ["can_change_info"]):
    # return await message.reply("You can't change info of this group")

    handler = get_args_str(message)

    if handler.startswith("re:"):
        pattern = handler
        random_text_str = "".join(random.choice(printable) for i in range(50))
        try:
            regex.match(pattern, random_text_str, timeout=0.2)
        except TimeoutError:
            await message.reply(strings["regex_too_slow"])
            return
    else:
        handler = handler.lower()

    text = strings["adding_filter"].format(handler=handler,
                                           chat_name=chat["chat_title"])

    buttons = InlineKeyboardMarkup(row_width=2)
    for action in FILTERS_ACTIONS.items():
        filter_id = action[0]
        data = action[1]

        buttons.insert(
            InlineKeyboardButton(
                await get_string(chat["chat_id"], data["title"]["module"],
                                 data["title"]["string"]),
                callback_data=filter_action_cp.new(filter_id=filter_id),
            ))
    buttons.add(
        InlineKeyboardButton(strings["cancel_btn"], callback_data="cancel"))

    user_id = message.from_user.id
    chat_id = chat["chat_id"]
    redis.set(f"add_filter:{user_id}:{chat_id}", handler)
    if handler is not None:
        await message.reply(text, reply_markup=buttons)
示例#9
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()
示例#10
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)
示例#11
0
async def connect_to_chat_direct(message, strings):
    user_id = message.from_user.id
    chat_id = message.chat.id

    if user_id == 1087968824:
        # just warn the user that connections with admin rights doesn't work
        return await message.reply(
            strings["anon_admin_conn"],
            reply_markup=InlineKeyboardMarkup().add(
                InlineKeyboardButton(strings["click_here"],
                                     callback_data="anon_conn_cb")),
        )

    chat = await db.chat_list.find_one({"chat_id": chat_id})
    chat_title = chat["chat_title"] if chat is not None else message.chat.title
    text = strings["pm_connected"].format(chat_name=chat_title)

    try:
        await bot.send_message(user_id, text)
        await def_connect_chat(message, user_id, chat_id, chat_title)
    except (BotBlocked, CantInitiateConversation):
        await message.reply(
            strings["connected_pm_to_me"].format(chat_name=chat_title))
        redis.set("RaVaN_connected_start_state:" + str(user_id), 1)
示例#12
0
    ]

    # FIXME: Better workaround
    if not (msg := await send_note(chat_id, text, **kwargs)):
        # Wasn't able to sent message
        return

    # Mute user
    try:
        await mute_user(chat_id, user_id)
    except BadRequest as error:
        # TODO: Delete the "sent" message ^
        return await message.reply(
            f"welcome security failed due to {error.args[0]}")

    redis.set(f"welcome_security_users:{user_id}:{chat_id}", msg.id)

    if raw_time := db_item["welcome_security"].get("expire", None):
        time = convert_time(raw_time)
    else:
        time = convert_time(get_str_key("JOIN_CONFIRM_DURATION"))

    scheduler.add_job(
        join_expired,
        "date",
        id=f"wc_expire:{chat_id}:{user_id}",
        run_date=datetime.utcnow() + time,
        kwargs={
            "chat_id": chat_id,
            "user_id": user_id,
            "message_id": msg.id,
示例#13
0
        user=await get_user_link(user_id),
        user_id=user_id,
        by=await get_user_link(message.from_user.id),
        chat_count=len(banned_chats),
        all_chats=num,
    )

    if reason:
        channel_text += strings["fban_reason_fed_log"].format(reason=reason)

    # Check if silent
    silent = False
    if get_cmd(message) == "sfban":
        silent = True
        key = "leave_silent:" + str(message.chat.id)
        redis.set(key, user_id)
        redis.expire(key, 30)
        text += strings["fbanned_silence"]

    # SubsFeds process
    if len(sfeds_list := await get_all_subs_feds_r(fed["fed_id"], [])) > 1:
        sfeds_list.remove(fed["fed_id"])
        this_fed_banned_count = len(banned_chats)

        await msg.edit_text(
            text + strings["fbanned_subs_process"].format(feds=len(sfeds_list))
        )

        all_banned_chats_count = 0
        for s_fed_id in sfeds_list:
            if (
示例#14
0
async def change_chat_lang(chat_id, lang):
    redis.set("lang_cache_{}".format(chat_id), lang)
    await db.lang.update_one(
        {"chat_id": chat_id}, {"$set": {"chat_id": chat_id, "lang": lang}}, upsert=True
    )