Exemplo n.º 1
0
def send_debug(client: Client,
               message: Message,
               action: str,
               uid: int,
               aid: int,
               em: Message = None,
               reason: str = None) -> bool:
    # Send the debug message
    try:
        text = get_debug_text(client, message.chat)
        text += (f"{lang('user_id')}{lang('colon')}{code(uid)}\n"
                 f"{lang('action')}{lang('colon')}{code(action)}\n"
                 f"{lang('admin_group')}{lang('colon')}{code(aid)}\n")

        if em:
            text += f"{lang('stored_message')}{lang('colon')}{general_link(em.message_id, message_link(em))}\n"

        # If the message is a report callback message
        if reason:
            text += f"{lang('reason')}{lang('colon')}{code(reason)}\n"
        elif message.from_user.is_self and action not in {
                lang("action_unban"),
                lang("action_unwarns")
        }:
            text += f"{lang('reason')}{lang('colon')}{code(lang('by_button'))}\n"
        else:
            reason = get_command_type(message)
            if reason:
                text += f"{lang('reason')}{lang('colon')}{code(reason)}\n"

        thread(send_message, (client, glovar.debug_channel_id, text))
    except Exception as e:
        logger.warning(f"Send debug error: {e}", exc_info=True)

    return False
Exemplo n.º 2
0
def get_config_text(config: dict) -> str:
    # Get config text
    result = ""
    try:
        # Basic
        default_text = (lambda x: lang("default") if x else lang("custom"))(config.get("default"))
        delete_text = (lambda x: lang("enabled") if x else lang("disabled"))(config.get("delete"))
        result += (f"{lang('config')}{lang('colon')}{code(default_text)}\n"
                   f"{lang('delete')}{lang('colon')}{code(delete_text)}\n")

        # Limit
        limit_text = config.get("limit")
        result += f"{lang('limit')}{lang('colon')}{code(limit_text)}\n"

        # Mention
        mention_text = (lambda x: lang("enabled") if x else lang("disabled"))(config.get("mention"))
        result += f"{lang('mention')}{lang('colon')}{code(mention_text)}\n"

        # Report
        for the_type in ["auto", "manual"]:
            the_bool = config.get("report") and config["report"].get(the_type)
            the_text = (lambda x: lang("enabled") if x else lang("disabled"))(the_bool)
            result += f"{lang(f'report_{the_type}')}{lang('colon')}{code(the_text)}\n"
    except Exception as e:
        logger.warning(f"Get config text error: {e}", exc_info=True)

    return result
Exemplo n.º 3
0
def undo_user(client: Client, message: Message, aid: int, uid: int,
              action_type: str) -> str:
    try:
        # Basic
        gid = message.chat.id
        mid = message.message_id

        # Init user data
        if not init_user_id(uid):
            return ""

        # Check the user's lock
        if gid in glovar.user_ids[uid]["lock"]:
            return lang("answer_proceeded")

        # Proceed
        glovar.user_ids[uid]["lock"].add(gid)
        try:
            if action_type == "ban":
                text = unban_user(client, message, uid, aid)
            else:
                text = unwarn_user(client, message, uid, aid)

            thread(edit_message_text, (client, gid, mid, text))
        finally:
            glovar.user_ids[uid]["lock"].discard(gid)

        # Save data
        save("user_ids")
    except Exception as e:
        logger.warning(f"Undo user error: {e}", exc_info=True)

    return ""
Exemplo n.º 4
0
def unban_user(client: Client, message: Message, uid: int, aid: int) -> str:
    # Unban a user
    text = ""
    try:
        # Basic data
        gid = message.chat.id

        # Check ban status
        if gid not in glovar.user_ids[uid]["ban"]:
            text = (
                f"{lang('user_id')}{lang('colon')}{mention_id(uid)}\n"
                f"{lang('action')}{lang('colon')}{code(lang('action_unban'))}\n"
                f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n"
                f"{lang('reason')}{lang('colon')}{code(lang('reason_none'))}\n"
                f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n"
            )
            return text

        # Proceed
        unban_chat_member(client, gid, uid)
        glovar.user_ids[uid]["ban"].discard(gid)
        update_score(client, uid)
        text = (
            f"{lang('user_unbanned')}{lang('colon')}{code(uid)}\n"
            f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n"
        )
        send_debug(client=client,
                   message=message,
                   action=lang("action_unban"),
                   uid=uid,
                   aid=aid)
    except Exception as e:
        logger.warning(f"Unban user error: {e}", exc_info=True)

    return text
Exemplo n.º 5
0
def mention_answer(client: Client, message: Message, aid: int, uid: int,
                   action_type: str) -> str:
    # Mention abuse
    try:
        # Basic data
        gid = message.chat.id
        mid = message.message_id

        # Abuse
        if action_type == "abuse":
            message.reply_to_message = message
            message.reply_to_message.from_user.id = uid
            message.reply_to_message.from_user.is_self = lang("abuse_mention")
            text, markup = warn_user(client, message, uid, aid)
            text += f"{lang('reason')}{lang('colon')}{code(lang('reason_abuse'))}\n"

            # Edit the report message
            thread(edit_message_text, (client, gid, mid, text, markup))
            delay(180, delete_message, [client, gid, mid])

        # Delete
        elif action_type == "delete":
            glovar.message_ids[gid] = (0, 0)
            save("message_ids")
            delete_message(client, gid, mid)
    except Exception as e:
        logger.warning(f"Mention answer error: {e}", exc_info=True)

    return ""
Exemplo n.º 6
0
def receive_leave_approve(client: Client, data: dict) -> bool:
    # Receive leave approve
    result = False

    try:
        # Basic data
        admin_id = data["admin_id"]
        the_id = data["group_id"]
        force = data["force"]
        reason = data["reason"]

        if reason in {"permissions", "user"}:
            reason = lang(f"reason_{reason}")

        if not glovar.admin_ids.get(the_id) and not force:
            return True

        text = get_debug_text(client, the_id)
        text += (
            f"{lang('admin_project')}{lang('colon')}{mention_id(admin_id)}\n"
            f"{lang('status')}{lang('colon')}{code(lang('leave_approve'))}\n")

        if reason:
            text += f"{lang('reason')}{lang('colon')}{code(reason)}\n"

        leave_group(client, the_id)
        thread(send_message, (client, glovar.debug_channel_id, text))

        result = True
    except Exception as e:
        logger.warning(f"Receive leave approve error: {e}", exc_info=True)

    return result
Exemplo n.º 7
0
def unwarn_user(client: Client, message: Message, uid: int, aid: int) -> str:
    # Unwarn a user
    text = ""
    try:
        # Basic data
        gid = message.chat.id

        # Check ban status
        if gid in glovar.user_ids[uid]["ban"]:
            text = (
                f"{lang('user_id')}{lang('colon')}{mention_id(uid)}\n"
                f"{lang('action')}{lang('colon')}{code(lang('action_unwarn'))}\n"
                f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n"
                f"{lang('reason')}{lang('colon')}{code(lang('reason_banned'))}\n"
                f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n"
            )
            return text

        # Check warnings count
        if not glovar.user_ids[uid]["warn"].get(gid, 0):
            text = (
                f"{lang('user_id')}{lang('colon')}{mention_id(uid)}\n"
                f"{lang('action')}{lang('colon')}{lang('action_unwarn')}\n"
                f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n"
                f"{lang('reason')}{lang('colon')}{code(lang('reason_none'))}\n"
                f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n"
            )
            return text

        # Proceed
        glovar.user_ids[uid]["warn"][gid] -= 1
        warn_count = glovar.user_ids[uid]["warn"][gid]

        if warn_count == 0:
            glovar.user_ids[uid]["warn"].pop(gid, 0)
            update_score(client, uid)
            text = (
                f"{lang('user_unwarned')}{lang('colon')}{mention_id(uid)}\n"
                f"{lang('user_warns')}{lang('colon')}{code(lang('reason_none'))}\n"
            )
            send_debug(client=client,
                       message=message,
                       action=lang("action_unwarns"),
                       uid=uid,
                       aid=aid)
        else:
            limit = glovar.configs[gid]["limit"]
            text = (
                f"{lang('user_unwarned')}{lang('colon')}{mention_id(uid)}\n"
                f"{lang('user_warns')}{lang('colon')}{code(f'{warn_count}/{limit}')}\n"
            )

        text += f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n"
    except Exception as e:
        logger.warning(f"Unwarn user error: {e}", exc_info=True)

    return text
Exemplo n.º 8
0
def receive_config_reply(client: Client, data: dict) -> bool:
    # Receive config reply
    try:
        # Basic data
        gid = data["group_id"]
        uid = data["user_id"]
        link = data["config_link"]

        text = (
            f"{lang('admin')}{lang('colon')}{code(uid)}\n"
            f"{lang('action')}{lang('colon')}{code(lang('config_change'))}\n"
            f"{lang('description')}{lang('colon')}{code(lang('config_button'))}\n"
        )
        markup = InlineKeyboardMarkup(
            [[InlineKeyboardButton(text=lang("config_go"), url=link)]])
        thread(send_report_message, (180, client, gid, text, None, markup))

        return True
    except Exception as e:
        logger.warning(f"Receive config reply error: {e}", exc_info=True)

    return False
Exemplo n.º 9
0
def get_class_d_id(message: Message) -> (int, int):
    # Get Class D personnel's id
    uid = 0
    mid = 0

    try:
        r_message = message.reply_to_message

        if not r_message or not is_from_user(None, None, r_message):
            return 0, 0

        if not is_class_c(None, None, r_message):
            uid = r_message.from_user.id
            mid = r_message.message_id
        elif r_message.from_user.is_self:
            uid = get_int(
                r_message.text.split("\n")[0].split(lang("colon"))[1])

            if uid in glovar.admin_ids[message.chat.id]:
                uid = 0
    except Exception as e:
        logger.warning(f"Get class d id error: {e}", exc_info=True)

    return uid, mid
Exemplo n.º 10
0
def warn_user(client: Client,
              message: Message,
              uid: int,
              aid: int,
              reason: str = None) -> (str, InlineKeyboardMarkup):
    # Warn a user
    text = ""
    markup = None
    try:
        # Basic data
        gid = message.chat.id

        # Init user data
        if not init_user_id(uid):
            return "", None

        # Check users' locks
        if gid in glovar.user_ids[uid]["lock"]:
            return "", None

        # Proceed
        glovar.user_ids[uid]["lock"].add(gid)
        try:
            # Check ban status
            if gid in glovar.user_ids[uid]["ban"]:
                text += (
                    f"{lang('user_id')}{lang('colon')}{mention_id(uid)}\n"
                    f"{lang('action')}{lang('colon')}{code(lang('action_warn'))}\n"
                    f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n"
                    f"{lang('reason')}{lang('colon')}{code(lang('reason_banned'))}\n"
                    f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n"
                )
                return text, None

            # Forward evidence
            result = forward_evidence(client=client,
                                      message=message.reply_to_message,
                                      level=lang("action_warn"))

            # Check message
            if not result:
                text += (
                    f"{lang('user_id')}{lang('colon')}{mention_id(uid)}\n"
                    f"{lang('action')}{lang('colon')}{code(lang('action_warn'))}\n"
                    f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n"
                    f"{lang('reason')}{lang('colon')}{code(lang('reason_deleted'))}\n"
                    f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n"
                )
                return text, None

            # Add warn count
            if not glovar.user_ids[uid]["warn"].get(gid, 0):
                glovar.user_ids[uid]["warn"][gid] = 1
                update_score(client, uid)
            else:
                glovar.user_ids[uid]["warn"][gid] += 1

            # Read count and group config
            warn_count = glovar.user_ids[uid]["warn"][gid]
            limit = glovar.configs[gid]["limit"]

            # Warn or ban
            if warn_count >= limit:
                glovar.user_ids[uid]["lock"].discard(gid)
                text = (
                    f"{lang('user_banned')}{lang('colon')}{mention_id(uid)}\n"
                    f"{lang('ban_reason')}{lang('colon')}{code(lang('reason_limit'))}\n"
                )
                _, markup = ban_user(client, message, uid, aid, result, reason)
            else:
                text = (
                    f"{lang('user_warned')}{lang('colon')}{mention_id(uid)}\n"
                    f"{lang('user_warns')}{lang('colon')}{code(f'{warn_count}/{limit}')}\n"
                )

                data = button_data("undo", "warn", uid)
                markup = InlineKeyboardMarkup([[
                    InlineKeyboardButton(text=lang("undo"), callback_data=data)
                ]])

                send_debug(client=client,
                           message=message,
                           action=lang("action_warn"),
                           uid=uid,
                           aid=aid,
                           em=result,
                           reason=reason)

            stored_link = general_link(result.message_id, message_link(result))
            text += (
                f"{lang('stored_message')}{lang('colon')}{stored_link}\n"
                f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n"
            )

            if markup and reason:
                text += f"{lang('reason')}{lang('colon')}{code(reason)}\n"
        finally:
            glovar.user_ids[uid]["lock"].discard(gid)
    except Exception as e:
        logger.warning(f"Warn user error: {e}", exc_info=True)

    return text, markup
Exemplo n.º 11
0
def report_user(gid: int,
                user: User,
                rid: int,
                mid: int,
                name: str = None,
                reason: str = None) -> (str, InlineKeyboardMarkup, str):
    # Report a user
    text = ""
    markup = None
    key = ""

    try:
        if user:
            uid = user.id
        else:
            return "", None

        glovar.user_ids[uid]["waiting"].add(gid)
        glovar.user_ids[rid]["waiting"].add(gid)
        save("user_ids")

        key = random_str(8)

        while glovar.reports.get(key):
            key = random_str(8)

        glovar.reports[key] = {
            "time": get_now(),
            "group_id": gid,
            "reporter_id": rid,
            "user_id": uid,
            "message_id": mid,
            "report_id": 0,
            "reason": reason
        }

        if rid:
            reporter_text = code("██████")
        else:
            reporter_text = code(lang("auto_triggered"))

        text = f"{lang('reported_user')}{lang('colon')}{mention_id(uid)}\n"

        if name:
            text += f"{lang('reported_name')}{lang('colon')}{code(name)}\n"

        text += (
            f"{lang('reported_message')}{lang('colon')}{general_link(mid, f'{get_channel_link(gid)}/{mid}')}\n"
            f"{lang('reporter')}{lang('colon')}{reporter_text}\n"
            f"{lang('mention_admins')}{lang('colon')}{get_admin_text(gid)}\n"
            f"{lang('description')}{lang('colon')}{code(lang('description_wait_admin'))}\n"
        )

        if reason:
            text += f"{lang('reason')}{lang('colon')}{code(reason)}\n"

        warn_data = button_data("report", "warn", key)
        ban_data = button_data("report", "ban", key)
        cancel_data = button_data("report", "cancel", key)
        markup_list = [[
            InlineKeyboardButton(text=lang("warn"), callback_data=warn_data),
            InlineKeyboardButton(text=lang("ban"), callback_data=ban_data)
        ],
                       [
                           InlineKeyboardButton(text=lang("cancel"),
                                                callback_data=cancel_data)
                       ]]

        if rid:
            abuse_data = button_data("report", "abuse", key)
            markup_list[1].append(
                InlineKeyboardButton(text=lang("abuse"),
                                     callback_data=abuse_data))

        markup = InlineKeyboardMarkup(markup_list)
    except Exception as e:
        logger.warning(f"Report user error: {e}", exc_info=True)

    return text, markup, key
Exemplo n.º 12
0
def remove_user(client: Client,
                message: Message,
                uid: int,
                aid: int,
                reason: str = None) -> (str, bool):
    # Kick a user
    text = ""
    success = False
    try:
        # Basic data
        gid = message.chat.id

        # Check admin
        if is_limited_admin(gid, aid):
            return "", False

        # Init user data
        if not init_user_id(uid):
            return "", False

        # Check users' locks
        if gid in glovar.user_ids[uid]["lock"]:
            return "", False

        # Proceed
        glovar.user_ids[uid]["lock"].add(gid)
        try:
            # Check ban status
            if gid in glovar.user_ids[uid]["ban"]:
                text += (
                    f"{lang('user_id')}{lang('colon')}{mention_id(uid)}\n"
                    f"{lang('action')}{lang('colon')}{code(lang('action_kick'))}\n"
                    f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n"
                    f"{lang('reason')}{lang('colon')}{code(lang('reason_banned'))}\n"
                    f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n"
                )
                return text, False

            # Forward evidence
            result = forward_evidence(client=client,
                                      message=message.reply_to_message,
                                      level=lang("action_kick"))

            # Check message
            if not result:
                text += (
                    f"{lang('user_id')}{lang('colon')}{mention_id(uid)}\n"
                    f"{lang('action')}{lang('colon')}{code(lang('action_kick'))}\n"
                    f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n"
                    f"{lang('reason')}{lang('colon')}{code(lang('reason_deleted'))}\n"
                    f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n"
                )
                return text, False

            # Count admin operation
            glovar.counts[gid][aid] += 1

            # Kick the user
            kick_user(client, gid, uid)
            glovar.user_ids[uid]["kick"].add(gid)
            update_score(client, uid)

            # Generate report text
            stored_link = general_link(result.message_id, message_link(result))
            text += (
                f"{lang('user_kicked')}{lang('colon')}{mention_id(uid)}\n"
                f"{lang('stored_message')}{lang('colon')}{stored_link}\n"
                f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n"
            )

            if reason:
                text += f"{lang('reason')}{lang('colon')}{code(reason)}\n"

            # Update success status
            success = True

            # Share
            ask_for_help(client, "delete", gid, uid)
            send_debug(client=client,
                       message=message,
                       action=lang("action_kick"),
                       uid=uid,
                       aid=aid,
                       em=result,
                       reason=reason)
        finally:
            glovar.user_ids[uid]["lock"].discard(gid)
    except Exception as e:
        logger.warning(f"Remove user error: {e}", exc_info=True)

    return text, success
Exemplo n.º 13
0
def forgive_user(client: Client,
                 message: Message,
                 uid: int,
                 reason: str = None) -> (str, bool):
    # Forgive user
    text = ""
    success = False
    try:
        # Basic data
        gid = message.chat.id
        aid = message.from_user.id

        # Init user data
        if not init_user_id(uid):
            return "", False

        # Check users' locks
        if gid in glovar.user_ids[uid]["lock"]:
            return "", False

        # Proceed
        glovar.user_ids[uid]["lock"].add(gid)
        try:
            # Text prefix
            text += f"{lang('user_id')}{lang('colon')}{mention_id(uid)}\n"

            if gid in glovar.user_ids[uid]["ban"]:
                glovar.user_ids[uid]["ban"].discard(gid)
                thread(unban_chat_member, (client, gid, uid))
                text += (
                    f"{lang('action')}{lang('colon')}{code(lang('action_unban'))}\n"
                    f"{lang('status')}{lang('colon')}{code(lang('status_succeeded'))}\n"
                )
                success = True
            elif glovar.user_ids[uid]["warn"].get(gid, 0):
                glovar.user_ids[uid]["warn"].pop(gid, 0)
                text += (
                    f"{lang('action')}{lang('colon')}{code(lang('action_unwarns'))}\n"
                    f"{lang('status')}{lang('colon')}{code(lang('status_succeeded'))}\n"
                )
                success = True
            elif gid in glovar.user_ids[uid]["waiting"]:
                glovar.user_ids[uid]["waiting"].discard(gid)
                text += (
                    f"{lang('action')}{lang('colon')}{code(lang('action_unwait'))}\n"
                    f"{lang('status')}{lang('colon')}{code(lang('status_succeeded'))}\n"
                )
                success = True
            else:
                text += (
                    f"{lang('action')}{lang('colon')}{code(lang('action_forgive'))}\n"
                    f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n"
                    f"{lang('reason')}{lang('colon')}{code(lang('reason_none'))}\n"
                )
                success = False

            text += f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n"

            if not success:
                return text, success

            save("user_ids")

            if reason:
                text += f"{lang('reason')}{lang('colon')}{code(reason)}\n"

            update_score(client, uid)
            send_debug(client=client,
                       message=message,
                       action=lang("action_forgive"),
                       uid=uid,
                       aid=aid,
                       reason=reason)
        finally:
            glovar.user_ids[uid]["lock"].discard(gid)
    except Exception as e:
        logger.warning(f"Forgive user error: {e}")

    return text, success
Exemplo n.º 14
0
def forward_evidence(client: Client,
                     message: Message,
                     level: str,
                     more: str = None) -> Optional[Union[bool, Message]]:
    # Forward the message to logging channel as evidence
    result = None
    try:
        if not message or not message.from_user:
            return result

        # Basic information
        uid = message.from_user.id
        text = (f"{lang('project')}{lang('colon')}{code(glovar.sender)}\n"
                f"{lang('user_id')}{lang('colon')}{code(uid)}\n"
                f"{lang('level')}{lang('colon')}{code(level)}\n"
                f"{lang('rule')}{lang('colon')}{code(lang('rule_admin'))}\n")

        # Additional information
        if message.game:
            text += f"{lang('message_type')}{lang('colon')}{code(lang('gam'))}\n"
        elif message.service:
            text += f"{lang('message_type')}{lang('colon')}{code(lang('ser'))}\n"

        if message.game:
            text += f"{lang('message_game')}{lang('colon')}{code(message.game.short_name)}\n"

        if message.from_user.is_self:
            if message.from_user.is_self is True:
                if message.entities:
                    for en in message.entities:
                        if not en.user:
                            continue

                        name = get_full_name(en.user)
                        if not name:
                            continue

                        text += f"{lang('user_name')}{lang('colon')}{code(name)}\n"
                        break

                text += f"{lang('more')}{lang('colon')}{code(lang('from_self'))}\n"
            # User didn't use report function wisely, should not forward evidence
            else:
                text += f"{lang('more')}{lang('colon')}{code(message.from_user.is_self)}"

            result = send_message(client, glovar.warn_channel_id, text)
            return result

        name = get_full_name(message.from_user)
        if name:
            text += f"{lang('user_name')}{lang('colon')}{code(name)}\n"

        if message.service and level == lang("action_ban"):
            bio = get_user_bio(client, uid)
            if bio:
                text += f"{lang('user_bio')}{lang('colon')}{code(bio)}\n"

        # Extra information
        if message.contact or message.location or message.venue or message.video_note or message.voice:
            text += f"{lang('more')}{lang('colon')}{code(lang('privacy'))}\n"
        elif message.game or message.service:
            text += f"{lang('more')}{lang('colon')}{code(lang('cannot_forward'))}\n"
        elif more:
            text += f"{lang('more')}{lang('colon')}{code(more)}\n"

        # DO NOT try to forward these types of message
        if (message.contact or message.location or message.venue
                or message.video_note or message.voice or message.game
                or message.service):
            result = send_message(client, glovar.warn_channel_id, text)
            return result

        flood_wait = True
        while flood_wait:
            flood_wait = False
            try:
                result = message.forward(chat_id=glovar.warn_channel_id,
                                         disable_notification=True)
            except FloodWait as e:
                flood_wait = True
                wait_flood(e)
            except Exception as e:
                logger.info(f"Forward evidence message error: {e}",
                            exc_info=True)
                return False

        result = result.message_id
        result = send_message(client, glovar.warn_channel_id, text, result)
    except Exception as e:
        logger.warning(f"Forward evidence error: {e}", exc_info=True)

    return result
Exemplo n.º 15
0
def config_directly(client: Client, message: Message) -> bool:
    # Config the bot directly

    if not message or not message.chat:
        return True

    # Basic data
    gid = message.chat.id
    mid = message.message_id

    try:
        # Check permission
        if not is_class_c(None, None, message):
            return True

        aid = message.from_user.id
        success = True
        reason = lang("config_updated")
        new_config = deepcopy(glovar.configs[gid])
        text = f"{lang('admin_group')}{lang('colon')}{code(aid)}\n"

        # Check command format
        command_type, command_context = get_command_context(message)
        if command_type:
            if command_type == "show":
                text += f"{lang('action')}{lang('colon')}{code(lang('config_show'))}\n"
                text += get_config_text(new_config)
                thread(send_report_message, (30, client, gid, text))
                return True

            now = get_now()
            if now - new_config["lock"] > 310:
                if command_type == "default":
                    new_config = deepcopy(glovar.default_config)
                else:
                    if command_context:
                        if command_type in {"delete", "mention"}:
                            if command_context == "off":
                                new_config[command_type] = False
                            elif command_context == "on":
                                new_config[command_type] = True
                            else:
                                success = False
                                reason = lang("command_para")
                        elif command_type == "limit":
                            limit = get_int(command_context)
                            if 2 <= limit <= 5:
                                new_config["limit"] = limit
                            else:
                                success = False
                                reason = lang("command_para")
                        elif command_type == "report":
                            if not new_config.get("report"):
                                new_config["report"] = {}

                            if command_context == "off":
                                new_config["report"]["auto"] = False
                                new_config["report"]["manual"] = False
                            elif command_context == "auto":
                                new_config["report"]["auto"] = True
                                new_config["report"]["manual"] = False
                            elif command_context == "manual":
                                new_config["report"]["auto"] = False
                                new_config["report"]["manual"] = True
                            elif command_context == "both":
                                new_config["report"]["auto"] = True
                                new_config["report"]["manual"] = True
                            else:
                                success = False
                                reason = lang("command_para")
                        else:
                            success = False
                            reason = lang("command_type")
                    else:
                        success = False
                        reason = lang("command_lack")

                    if success:
                        new_config["default"] = False
            else:
                success = False
                reason = lang("config_locked")
        else:
            success = False
            reason = lang("command_usage")

        if success and new_config != glovar.configs[gid]:
            # Save new config
            glovar.configs[gid] = new_config
            save("configs")

            # Send debug message
            debug_text = get_debug_text(client, message.chat)
            debug_text += (
                f"{lang('admin_group')}{lang('colon')}{code(message.from_user.id)}\n"
                f"{lang('action')}{lang('colon')}{code(lang('config_change'))}\n"
                f"{lang('more')}{lang('colon')}{code(f'{command_type} {command_context}')}\n"
            )
            thread(send_message, (client, glovar.debug_channel_id, debug_text))

        text += (
            f"{lang('action')}{lang('colon')}{code(lang('config_change'))}\n"
            f"{lang('status')}{lang('colon')}{code(reason)}\n")
        thread(send_report_message,
               ((lambda x: 10 if x else 5)(success), client, gid, text))

        return True
    except Exception as e:
        logger.warning(f"Config directly error: {e}", exc_info=True)
    finally:
        delete_message(client, gid, mid)

    return False
Exemplo n.º 16
0
def admin(client: Client, message: Message) -> bool:
    # Mention admins

    if not message or not message.chat:
        return True

    # Basic data
    gid = message.chat.id
    mid = message.message_id

    try:
        # Check permission
        if is_class_c(None, None, message):
            return True

        # Check config
        if not glovar.configs[gid].get("mention"):
            return True

        uid = message.from_user.id

        # Init user data
        if not init_user_id(uid):
            return True

        # Warned user and the user having report status can't mention admins
        if (gid in glovar.user_ids[uid]["waiting"]
                or gid in glovar.user_ids[uid]["ban"]
                or glovar.user_ids[uid]["warn"].get(gid)):
            return True

        # Generate report text
        text = (
            f"{lang('from_user')}{lang('colon')}{mention_id(uid)}\n"
            f"{lang('mention_admins')}{lang('colon')}{get_admin_text(gid)}\n")
        reason = get_command_type(message)

        if reason:
            text += f"{lang('reason')}{lang('colon')}{code(reason)}\n"

        # Generate report markup
        button_abuse = button_data("mention", "abuse", uid)
        button_delete = button_data("mention", "delete", uid)
        markup = InlineKeyboardMarkup([[
            InlineKeyboardButton(text=lang("abuse"),
                                 callback_data=button_abuse),
            InlineKeyboardButton(text=lang("del"), callback_data=button_delete)
        ]])

        # Send the report message
        if message.reply_to_message:
            rid = message.reply_to_message.message_id
        else:
            rid = None

        result = send_message(client, gid, text, rid, markup)

        if not result:
            return True

        old_mid, _ = glovar.message_ids.get(gid, (0, 0))
        old_mid and thread(delete_message, (client, gid, old_mid))
        sent_mid = result.message_id
        glovar.message_ids[gid] = (sent_mid, get_now())
        save("message_ids")

        return True
    except Exception as e:
        logger.warning(f"Admin error: {e}", exc_info=True)
    finally:
        delete_message(client, gid, mid)

    return False
Exemplo n.º 17
0
def ban_user(client: Client,
             message: Message,
             uid: int,
             aid: int,
             result: int = 0,
             reason: str = None) -> (str, InlineKeyboardMarkup):
    # Ban a user
    text = ""
    markup = None
    try:
        # Basic data
        gid = message.chat.id

        # Check admin
        if is_limited_admin(gid, aid):
            return "", None

        # Init user data
        if not init_user_id(uid):
            return "", None

        # Check users' locks
        if gid in glovar.user_ids[uid]["lock"]:
            return "", None

        # Proceed
        glovar.user_ids[uid]["lock"].add(gid)
        try:
            if gid in glovar.user_ids[uid]["ban"]:
                text += (
                    f"{lang('user_id')}{lang('colon')}{mention_id(uid)}\n"
                    f"{lang('action')}{lang('colon')}{code(lang('action_ban'))}\n"
                    f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n"
                    f"{lang('reason')}{lang('colon')}{code(lang('reason_banned'))}\n"
                    f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n"
                )
                return text, None

            if not result:
                result = forward_evidence(client=client,
                                          message=message.reply_to_message,
                                          level=lang("action_ban"))

            if not result:
                text += (
                    f"{lang('user_id')}{lang('colon')}{mention_id(uid)}\n"
                    f"{lang('action')}{lang('colon')}{code(lang('action_ban'))}\n"
                    f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n"
                    f"{lang('reason')}{lang('colon')}{code(lang('reason_deleted'))}\n"
                    f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n"
                )
                return text, None

            # Count admin operation
            glovar.counts[gid][aid] += 1

            # Ban the user
            thread(kick_chat_member, (client, gid, uid))
            glovar.user_ids[uid]["ban"].add(gid)
            glovar.user_ids[uid]["warn"].pop(gid, 0)
            update_score(client, uid)

            # Generate report text
            stored_link = general_link(result.message_id, message_link(result))
            text += (
                f"{lang('user_banned')}{lang('colon')}{mention_id(uid)}\n"
                f"{lang('stored_message')}{lang('colon')}{stored_link}\n"
                f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n"
            )

            if reason:
                text += f"{lang('reason')}{lang('colon')}{code(reason)}\n"

            # Generate report markup
            data = button_data("undo", "ban", uid)
            markup = InlineKeyboardMarkup([[
                InlineKeyboardButton(text=lang("unban"), callback_data=data)
            ]])

            # Share
            ask_for_help(client, "delete", gid, uid)
            send_debug(client=client,
                       message=message,
                       action=lang("action_ban"),
                       uid=uid,
                       aid=aid,
                       em=result,
                       reason=reason)
        finally:
            glovar.user_ids[uid]["lock"].discard(gid)
    except Exception as e:
        logger.warning(f"Ban user error: {e}", exc_info=True)

    return text, markup
Exemplo n.º 18
0
def report_answer(client: Client,
                  message: Message,
                  gid: int,
                  aid: int,
                  mid: int,
                  action_type: str,
                  key: str,
                  reason: str = None) -> str:
    # Answer the user's report
    try:
        report_record = glovar.reports.get(key)

        if not report_record:
            message_text = get_text(message)
            uid = get_int(message_text.split("\n")[0].split(lang("colon"))[1])
            text = (
                f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n"
                f"{lang('status')}{lang('colon')}{code(lang('status_failed'))}\n"
                f"{lang('reason')}{lang('colon')}{code(lang('expired'))}\n")
            thread(edit_message_text, (client, gid, mid, text))
            delay(15, delete_message, [client, gid, mid])
            glovar.user_ids[uid]["waiting"].discard(gid)
            save("user_ids")
            return ""

        if not report_record["time"]:
            return ""

        rid = report_record["reporter_id"]
        uid = report_record["user_id"]
        r_mid = report_record["message_id"]
        record_reason = report_record["reason"]

        if not reason:
            reason = record_reason

        if not (init_user_id(rid) and init_user_id(uid)):
            return ""

        # Check users' locks
        if gid in glovar.user_ids[uid]["lock"] or gid in glovar.user_ids[rid][
                "lock"]:
            return lang("answer_proceeded")

        # Lock the report status
        glovar.reports[key]["time"] = 0
        try:
            if action_type == "ban":
                text, markup = ban_user(client, message, uid, aid, 0, reason)
                thread(delete_message, (client, gid, r_mid))
            elif action_type == "warn":
                text, markup = warn_user(client, message, uid, aid, reason)
                thread(delete_message, (client, gid, r_mid))
            elif action_type == "abuse":
                if not rid:
                    return ""

                message.reply_to_message.from_user.id = rid
                message.reply_to_message.from_user.is_self = lang(
                    "abuse_report")
                text, markup = warn_user(client, message, rid, aid)
                text += f"{lang('reason')}{lang('colon')}{code(lang('reason_abuse'))}\n"
            else:
                reported_link = general_link(
                    r_mid, f'{get_channel_link(message)}/{r_mid}')

                if rid:
                    reporter_text = code(rid)
                else:
                    reporter_text = code(lang("auto_triggered"))

                text = (
                    f"{lang('reported_user')}{lang('colon')}{mention_id(uid)}\n"
                    f"{lang('reported_message')}{lang('colon')}{reported_link}\n"
                    f"{lang('reporter')}{lang('colon')}{reporter_text}\n"
                    f"{lang('action')}{lang('colon')}{code(lang('action_cancel'))}\n"
                    f"{lang('status')}{lang('colon')}{code(lang('status_succeeded'))}\n"
                    f"{lang('description')}{lang('colon')}{code(lang('description_by_admin'))}\n"
                )
                markup = None

            if markup:
                secs = 180
            else:
                secs = 15

            thread(edit_message_text, (client, gid, mid, text, markup))
            delay(secs, delete_message, [client, gid, mid])
        finally:
            glovar.user_ids[uid]["lock"].discard(gid)
            glovar.user_ids[rid]["lock"].discard(gid)
            glovar.user_ids[uid]["waiting"].discard(gid)
            glovar.user_ids[rid]["waiting"].discard(gid)
            save("user_ids")
    except Exception as e:
        logger.warning(f"Report answer error: {e}", exc_info=True)

    return ""
Exemplo n.º 19
0
def update_admins(client: Client) -> bool:
    # Update admin list every day
    result = False

    glovar.locks["admin"].acquire()

    try:
        # Basic data
        group_list = list(glovar.admin_ids)

        # Check groups
        for gid in group_list:
            group_name, group_link = get_group_info(client, gid)
            admin_members = get_admins(client, gid)

            # Bot is not in the chat, leave automatically without approve
            if admin_members is False or any(
                    admin.user.is_self for admin in admin_members) is False:
                leave_group(client, gid)
                share_data(client=client,
                           receivers=["MANAGE"],
                           action="leave",
                           action_type="info",
                           data={
                               "group_id": gid,
                               "group_name": group_name,
                               "group_link": group_link
                           })
                project_text = general_link(glovar.project_name,
                                            glovar.project_link)
                debug_text = (
                    f"{lang('project')}{lang('colon')}{project_text}\n"
                    f"{lang('group_name')}{lang('colon')}{general_link(group_name, group_link)}\n"
                    f"{lang('group_id')}{lang('colon')}{code(gid)}\n"
                    f"{lang('status')}{lang('colon')}{code(lang('leave_auto'))}\n"
                    f"{lang('reason')}{lang('colon')}{code(lang('reason_leave'))}\n"
                )
                thread(send_message,
                       (client, glovar.debug_channel_id, debug_text))
                continue

            # Check the admin list
            if not (admin_members
                    and any([admin.user.is_self for admin in admin_members])):
                continue

            # Save the admin list
            save_admins(gid, admin_members)

            # Ignore the group
            if gid in glovar.lack_group_ids:
                continue

            # Check the permissions
            if glovar.user_id not in glovar.admin_ids[gid]:
                reason = "user"
            elif any(admin.user.is_self and admin.can_delete_messages
                     and admin.can_restrict_members
                     for admin in admin_members):
                glovar.lack_group_ids.discard(gid)
                save("lack_group_ids")
                continue
            else:
                reason = "permissions"
                glovar.lack_group_ids.add(gid)
                save("lack_group_ids")

            # Send the leave request
            share_data(client=client,
                       receivers=["MANAGE"],
                       action="leave",
                       action_type="request",
                       data={
                           "group_id": gid,
                           "group_name": group_name,
                           "group_link": group_link,
                           "reason": reason
                       })
            reason = lang(f"reason_{reason}")
            project_link = general_link(glovar.project_name,
                                        glovar.project_link)
            debug_text = (
                f"{lang('project')}{lang('colon')}{project_link}\n"
                f"{lang('group_name')}{lang('colon')}{general_link(group_name, group_link)}\n"
                f"{lang('group_id')}{lang('colon')}{code(gid)}\n"
                f"{lang('status')}{lang('colon')}{code(reason)}\n")
            thread(send_message, (client, glovar.debug_channel_id, debug_text))

        result = True
    except Exception as e:
        logger.warning(f"Update admin error: {e}", exc_info=True)
    finally:
        glovar.locks["admin"].release()

    return result