mirror of
https://github.com/Xtao-Labs/sticker-captcha-bot.git
synced 2024-11-25 09:37:34 +00:00
refa: clean verify user message
This commit is contained in:
parent
4f0607c034
commit
f1f10b454a
@ -1,5 +1,4 @@
|
||||
import contextlib
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from cashews import cache
|
||||
from pyrogram import filters
|
||||
@ -8,17 +7,45 @@ from pyrogram.types import ChatMemberUpdated
|
||||
|
||||
from pyromod.utils.errors import TimeoutConversationError
|
||||
from sticker.languages import MSG_PUBLIC, ADMIN_MSG, MSG, VERIFY_TIME
|
||||
from sticker.scheduler import add_delete_message_job
|
||||
from sticker.scheduler import add_ban_chat_member_job
|
||||
from sticker.service_message import ServiceMessage
|
||||
from sticker.single_utils import Client
|
||||
from sticker import bot, log
|
||||
from sticker.single_utils import Client, Message
|
||||
from sticker import bot, log, LogAction
|
||||
|
||||
|
||||
async def start_verify(client: "Client", chat, user):
|
||||
key = f"wait:{chat.id}:{user.id}"
|
||||
await cache.set(key, "True", expire=VERIFY_TIME + 5)
|
||||
try:
|
||||
msg: "Message" = await client.send_message(
|
||||
chat.id, MSG % (user.mention, user.mention)
|
||||
)
|
||||
except Exception:
|
||||
return
|
||||
await log(chat, user, LogAction.REQUEST)
|
||||
try:
|
||||
msg_: "Message" = await client.listen(
|
||||
chat.id, filters=filters.user(user.id), timeout=VERIFY_TIME
|
||||
)
|
||||
await msg.delay_delete(1)
|
||||
await msg_.delay_delete(1)
|
||||
if not msg_.sticker:
|
||||
add_ban_chat_member_job(chat.id, user.id)
|
||||
await log(chat, user, LogAction.FAIL_ERROR)
|
||||
await ServiceMessage.try_delete(user.id, chat.id)
|
||||
else:
|
||||
await cache.delete(key)
|
||||
await log(chat, user, LogAction.ACCEPT)
|
||||
except TimeoutConversationError:
|
||||
await msg.delay_delete(1)
|
||||
add_ban_chat_member_job(chat.id, user.id)
|
||||
await log(chat, user, LogAction.FAIL_TIMEOUT)
|
||||
await ServiceMessage.try_delete(user.id, chat.id)
|
||||
|
||||
|
||||
@bot.on_chat_member_updated()
|
||||
async def invite(client: Client, chat_member_updated: ChatMemberUpdated):
|
||||
chat = chat_member_updated.chat
|
||||
if await cache.get(f"cid:{chat.id}"):
|
||||
return
|
||||
member = chat_member_updated.new_chat_member
|
||||
old_member = chat_member_updated.old_chat_member
|
||||
if not member:
|
||||
@ -27,6 +54,17 @@ async def invite(client: Client, chat_member_updated: ChatMemberUpdated):
|
||||
return
|
||||
user = member.user
|
||||
old_user = old_member.user if old_member else None
|
||||
if user.is_self:
|
||||
if member.status not in {
|
||||
ChatMemberStatus.ADMINISTRATOR,
|
||||
ChatMemberStatus.MEMBER,
|
||||
}:
|
||||
return
|
||||
await log(chat, chat_member_updated.from_user, LogAction.NEW_GROUP)
|
||||
if chat.username:
|
||||
with contextlib.suppress(Exception):
|
||||
await client.send_message(chat.id, MSG_PUBLIC)
|
||||
return
|
||||
if user.is_verified or user.is_bot or user.is_deleted or user.is_support:
|
||||
return
|
||||
if member.status not in {ChatMemberStatus.MEMBER}:
|
||||
@ -43,13 +81,6 @@ async def invite(client: Client, chat_member_updated: ChatMemberUpdated):
|
||||
}
|
||||
):
|
||||
return
|
||||
if user.is_self:
|
||||
with contextlib.suppress(Exception):
|
||||
await log(chat, chat_member_updated.from_user, "NEW_GROUP")
|
||||
if chat.username:
|
||||
with contextlib.suppress(Exception):
|
||||
await client.send_message(chat.id, MSG_PUBLIC)
|
||||
return
|
||||
from_user = chat_member_updated.from_user
|
||||
if from_user and from_user.id == user.id:
|
||||
from_user = None
|
||||
@ -61,42 +92,8 @@ async def invite(client: Client, chat_member_updated: ChatMemberUpdated):
|
||||
and (await bot.get_chat_member(chat.id, from_user.id)).status
|
||||
in {ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.OWNER}
|
||||
):
|
||||
try:
|
||||
msg = await client.send_message(chat.id, ADMIN_MSG)
|
||||
except Exception:
|
||||
return
|
||||
add_delete_message_job(msg)
|
||||
with contextlib.suppress(Exception):
|
||||
msg: "Message" = await client.send_message(chat.id, ADMIN_MSG)
|
||||
await msg.delay_delete()
|
||||
return
|
||||
try:
|
||||
msg = await client.send_message(chat.id, MSG % (user.mention, user.mention))
|
||||
except Exception:
|
||||
return
|
||||
try:
|
||||
with contextlib.suppress(Exception):
|
||||
await log(chat, user, "REQUEST")
|
||||
msg_ = await client.listen(chat.id, filters=filters.user(user.id), timeout=VERIFY_TIME)
|
||||
with contextlib.suppress(Exception):
|
||||
await msg.delete()
|
||||
if not msg_.sticker:
|
||||
with contextlib.suppress(Exception):
|
||||
await bot.ban_chat_member(
|
||||
chat.id, user.id, datetime.now() + timedelta(minutes=5)
|
||||
)
|
||||
with contextlib.suppress(Exception):
|
||||
await log(chat, user, "FAIL_ERROR")
|
||||
await ServiceMessage.try_delete(user.id, chat.id)
|
||||
else:
|
||||
with contextlib.suppress(Exception):
|
||||
await log(chat, user, "ACCEPT")
|
||||
with contextlib.suppress(Exception):
|
||||
await msg_.delete()
|
||||
except TimeoutConversationError:
|
||||
with contextlib.suppress(Exception):
|
||||
await msg.delete()
|
||||
with contextlib.suppress(Exception):
|
||||
await bot.ban_chat_member(
|
||||
chat.id, user.id, datetime.now() + timedelta(minutes=5)
|
||||
)
|
||||
with contextlib.suppress(Exception):
|
||||
await log(chat, user, "FAIL_TIMEOUT")
|
||||
await ServiceMessage.try_delete(user.id, chat.id)
|
||||
await start_verify(client, chat, user)
|
||||
|
17
plugins/clean_message.py
Normal file
17
plugins/clean_message.py
Normal file
@ -0,0 +1,17 @@
|
||||
from cashews import cache
|
||||
from pyrogram import filters
|
||||
|
||||
from sticker import bot
|
||||
from sticker.single_utils import Message
|
||||
|
||||
|
||||
@bot.on_message(filters=filters.group & ~filters.service, group=1)
|
||||
async def clean_message(_, message: "Message"):
|
||||
if not message.from_user:
|
||||
return
|
||||
cid = message.chat.id
|
||||
uid = message.from_user.id
|
||||
key = f"wait:{cid}:{uid}"
|
||||
result = await cache.get(key)
|
||||
if result:
|
||||
await message.delay_delete(1)
|
@ -1,13 +1,12 @@
|
||||
import contextlib
|
||||
|
||||
from cashews import cache
|
||||
from pyrogram.types import ChatJoinRequest
|
||||
from pyrogram import filters
|
||||
|
||||
from sticker.languages import MSG, MSG_SUCCESS, MSG_FAILURE, VERIFY_TIME
|
||||
from sticker.single_utils import Client
|
||||
from sticker.scheduler import add_decline_request_job, rem_decline_request_job
|
||||
from sticker import bot, log
|
||||
from sticker import bot, log, LogAction
|
||||
|
||||
from pyromod.utils.errors import TimeoutConversationError
|
||||
|
||||
@ -15,24 +14,24 @@ from pyromod.utils.errors import TimeoutConversationError
|
||||
@bot.on_chat_join_request()
|
||||
async def new_member(client: Client, chat_join_request: ChatJoinRequest):
|
||||
chat = chat_join_request.chat
|
||||
await cache.set(f"cid:{chat.id}", "True", expire=3600, exist=True)
|
||||
user = chat_join_request.from_user
|
||||
add_decline_request_job(chat_join_request)
|
||||
try:
|
||||
with contextlib.suppress(Exception):
|
||||
await log(chat, user, "REQUEST")
|
||||
await client.ask(user.id, MSG % (chat.title, chat.title), filters=filters.sticker, timeout=VERIFY_TIME)
|
||||
await log(chat, user, LogAction.REQUEST)
|
||||
await client.ask(
|
||||
user.id,
|
||||
MSG % (chat.title, chat.title),
|
||||
filters=filters.sticker,
|
||||
timeout=VERIFY_TIME,
|
||||
)
|
||||
with contextlib.suppress(Exception):
|
||||
await client.send_message(user.id, MSG_SUCCESS)
|
||||
await chat_join_request.approve()
|
||||
with contextlib.suppress(Exception):
|
||||
await log(chat, user, "ACCEPT")
|
||||
with contextlib.suppress(Exception):
|
||||
rem_decline_request_job(chat_join_request)
|
||||
await log(chat, user, LogAction.ACCEPT)
|
||||
rem_decline_request_job(chat_join_request)
|
||||
except TimeoutConversationError:
|
||||
with contextlib.suppress(Exception):
|
||||
await client.send_message(user.id, MSG_FAILURE)
|
||||
with contextlib.suppress(Exception):
|
||||
await chat_join_request.decline()
|
||||
with contextlib.suppress(Exception):
|
||||
await log(chat, user, "FAIL_TIMEOUT")
|
||||
await log(chat, user, LogAction.FAIL_TIMEOUT)
|
||||
|
@ -1,25 +1,23 @@
|
||||
import contextlib
|
||||
|
||||
from cashews import cache
|
||||
from pyrogram import filters
|
||||
from pyrogram.enums import ChatMemberStatus
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from pyromod.utils.errors import TimeoutConversationError
|
||||
from sticker.languages import RE_MSG, VERIFY_TIME
|
||||
from sticker.scheduler import add_delete_message_job
|
||||
from sticker.scheduler import add_ban_chat_member_job
|
||||
from sticker.single_utils import Message, Client
|
||||
from sticker import bot, log
|
||||
from sticker import bot, log, LogAction
|
||||
|
||||
|
||||
@bot.on_message(filters=filters.group & filters.command("reverify"))
|
||||
async def re_verify(client: Client, message: Message):
|
||||
if not message.from_user or not message.reply_to_message:
|
||||
reply_to: "Message" = message.reply_to_message
|
||||
if not message.from_user or not reply_to:
|
||||
msg: Message = await message.reply("请回复一条消息来使 Ta 重新验证。")
|
||||
add_delete_message_job(message, 10)
|
||||
add_delete_message_job(msg, 10)
|
||||
await message.delay_delete(10)
|
||||
await msg.delay_delete(10)
|
||||
return
|
||||
if not message.reply_to_message.from_user:
|
||||
if not reply_to.from_user:
|
||||
return
|
||||
chat = message.chat
|
||||
user = message.from_user
|
||||
@ -27,7 +25,7 @@ async def re_verify(client: Client, message: Message):
|
||||
if member.status not in [ChatMemberStatus.OWNER, ChatMemberStatus.ADMINISTRATOR]:
|
||||
return
|
||||
|
||||
user = message.reply_to_message.from_user
|
||||
user = reply_to.from_user
|
||||
if (
|
||||
user.is_self
|
||||
or user.is_verified
|
||||
@ -37,46 +35,36 @@ async def re_verify(client: Client, message: Message):
|
||||
):
|
||||
return
|
||||
member = await client.get_chat_member(chat.id, user.id)
|
||||
with contextlib.suppress(Exception):
|
||||
await message.delete()
|
||||
await message.delay_delete(1)
|
||||
key = f"wait:{chat.id}:{user.id}"
|
||||
await cache.set(key, "True", expire=VERIFY_TIME + 5)
|
||||
try:
|
||||
msg = await message.reply_to_message.reply(RE_MSG % (user.mention, user.mention))
|
||||
msg = await reply_to.reply(RE_MSG % (user.mention, user.mention))
|
||||
except Exception as _:
|
||||
return
|
||||
try:
|
||||
msg_ = await client.listen(chat.id, filters=filters.user(user.id), timeout=VERIFY_TIME)
|
||||
with contextlib.suppress(Exception):
|
||||
await msg.delete()
|
||||
msg_ = await client.listen(
|
||||
chat.id, filters=filters.user(user.id), timeout=VERIFY_TIME
|
||||
)
|
||||
await msg.delay_delete(1)
|
||||
await msg_.delay_delete(1)
|
||||
if not msg_.sticker:
|
||||
with contextlib.suppress(Exception):
|
||||
await message.reply_to_message.delete()
|
||||
await reply_to.delay_delete(1)
|
||||
if member.status not in [
|
||||
ChatMemberStatus.OWNER,
|
||||
ChatMemberStatus.ADMINISTRATOR,
|
||||
]:
|
||||
with contextlib.suppress(Exception):
|
||||
await bot.ban_chat_member(
|
||||
chat.id, user.id, datetime.now() + timedelta(minutes=5)
|
||||
)
|
||||
with contextlib.suppress(Exception):
|
||||
await log(chat, user, "FAIL_ERROR")
|
||||
add_ban_chat_member_job(chat.id, user.id)
|
||||
await log(chat, user, LogAction.FAIL_ERROR)
|
||||
else:
|
||||
with contextlib.suppress(Exception):
|
||||
await log(chat, user, "ACCEPT")
|
||||
with contextlib.suppress(Exception):
|
||||
await msg_.delete()
|
||||
await cache.delete(key)
|
||||
await log(chat, user, LogAction.ACCEPT)
|
||||
except TimeoutConversationError:
|
||||
with contextlib.suppress(Exception):
|
||||
await msg.delete()
|
||||
with contextlib.suppress(Exception):
|
||||
await message.reply_to_message.delete()
|
||||
await msg.delay_delete(1)
|
||||
await reply_to.delay_delete(1)
|
||||
if member.status not in [
|
||||
ChatMemberStatus.OWNER,
|
||||
ChatMemberStatus.ADMINISTRATOR,
|
||||
]:
|
||||
with contextlib.suppress(Exception):
|
||||
await bot.ban_chat_member(
|
||||
chat.id, user.id, datetime.now() + timedelta(minutes=5)
|
||||
)
|
||||
with contextlib.suppress(Exception):
|
||||
await log(chat, user, "FAIL_TIMEOUT")
|
||||
add_ban_chat_member_job(chat.id, user.id)
|
||||
await log(chat, user, LogAction.FAIL_TIMEOUT)
|
||||
|
@ -1,21 +0,0 @@
|
||||
"""
|
||||
pyromod - A monkeypatcher add-on for Pyrogram
|
||||
Copyright (C) 2020 Cezar H. <https://github.com/usernein>
|
||||
|
||||
This file is part of pyromod.
|
||||
|
||||
pyromod is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
pyromod is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with pyromod. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
from .filters import dice
|
@ -1,28 +0,0 @@
|
||||
"""
|
||||
pyromod - A monkeypatcher add-on for Pyrogram
|
||||
Copyright (C) 2020 Cezar H. <https://github.com/usernein>
|
||||
|
||||
This file is part of pyromod.
|
||||
|
||||
pyromod is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
pyromod is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with pyromod. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import pyrogram
|
||||
|
||||
|
||||
def dice(ctx, message):
|
||||
return hasattr(message, "dice") and message.dice
|
||||
|
||||
|
||||
pyrogram.filters.dice = dice
|
@ -1,20 +0,0 @@
|
||||
"""
|
||||
pyromod - A monkeypatcher add-on for Pyrogram
|
||||
Copyright (C) 2020 Cezar H. <https://github.com/usernein>
|
||||
|
||||
This file is part of pyromod.
|
||||
|
||||
pyromod is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
pyromod is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with pyromod. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
from .helpers import ikb, bki, ntb, btn, kb, kbtn, array_chunk, force_reply
|
@ -1,86 +0,0 @@
|
||||
from pyrogram.types import (
|
||||
InlineKeyboardButton,
|
||||
InlineKeyboardMarkup,
|
||||
KeyboardButton,
|
||||
ReplyKeyboardMarkup,
|
||||
ForceReply,
|
||||
)
|
||||
|
||||
|
||||
def ikb(rows=None):
|
||||
if rows is None:
|
||||
rows = []
|
||||
lines = []
|
||||
for row in rows:
|
||||
line = []
|
||||
for button in row:
|
||||
button = btn(*button) # InlineKeyboardButton
|
||||
line.append(button)
|
||||
lines.append(line)
|
||||
return InlineKeyboardMarkup(inline_keyboard=lines)
|
||||
# return {'inline_keyboard': lines}
|
||||
|
||||
|
||||
def btn(text, value, type="callback_data"):
|
||||
return InlineKeyboardButton(text, **{type: value})
|
||||
# return {'text': text, type: value}
|
||||
|
||||
|
||||
# The inverse of above
|
||||
def bki(keyboard):
|
||||
lines = []
|
||||
for row in keyboard.inline_keyboard:
|
||||
line = []
|
||||
for button in row:
|
||||
button = ntb(button) # btn() format
|
||||
line.append(button)
|
||||
lines.append(line)
|
||||
return lines
|
||||
# return ikb() format
|
||||
|
||||
|
||||
def ntb(button):
|
||||
for btn_type in [
|
||||
"callback_data",
|
||||
"url",
|
||||
"switch_inline_query",
|
||||
"switch_inline_query_current_chat",
|
||||
"callback_game",
|
||||
]:
|
||||
value = getattr(button, btn_type)
|
||||
if value:
|
||||
break
|
||||
button = [button.text, value]
|
||||
if btn_type != "callback_data":
|
||||
button.append(btn_type)
|
||||
return button
|
||||
# return {'text': text, type: value}
|
||||
|
||||
|
||||
def kb(rows=None, **kwargs):
|
||||
if rows is None:
|
||||
rows = []
|
||||
lines = []
|
||||
for row in rows:
|
||||
line = []
|
||||
for button in row:
|
||||
button_type = type(button)
|
||||
if button_type == str:
|
||||
button = KeyboardButton(button)
|
||||
elif button_type == dict:
|
||||
button = KeyboardButton(**button)
|
||||
|
||||
line.append(button)
|
||||
lines.append(line)
|
||||
return ReplyKeyboardMarkup(keyboard=lines, **kwargs)
|
||||
|
||||
|
||||
kbtn = KeyboardButton
|
||||
|
||||
|
||||
def force_reply(selective=True):
|
||||
return ForceReply(selective=selective)
|
||||
|
||||
|
||||
def array_chunk(input_, size):
|
||||
return [input_[i : i + size] for i in range(0, len(input_), size)]
|
@ -19,16 +19,18 @@ along with pyromod. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import contextlib
|
||||
import functools
|
||||
|
||||
import pyrogram
|
||||
|
||||
from typing import Dict
|
||||
from sticker.scheduler import add_delete_message_job
|
||||
from ..utils import patch, patchable
|
||||
from ..utils.errors import ListenerCanceled, TimeoutConversationError
|
||||
|
||||
pyrogram.errors.ListenerCanceled = ListenerCanceled
|
||||
LOCK = asyncio.Lock()
|
||||
DONE = []
|
||||
|
||||
|
||||
@patch(pyrogram.client.Client)
|
||||
@ -63,8 +65,9 @@ class Client:
|
||||
|
||||
@patchable
|
||||
def clear_listener(self, chat_id, future):
|
||||
if future == self.listening[chat_id]["future"]:
|
||||
self.listening.pop(chat_id, None)
|
||||
with contextlib.suppress(KeyError):
|
||||
if future == self.listening[chat_id]["future"]:
|
||||
self.listening.pop(chat_id, None)
|
||||
|
||||
@patchable
|
||||
def cancel_listener(self, chat_id):
|
||||
@ -90,25 +93,33 @@ class MessageHandler:
|
||||
|
||||
@patchable
|
||||
async def resolve_listener(self, client, message, *args):
|
||||
listener = client.listening.get(message.chat.id)
|
||||
if listener and not listener["future"].done():
|
||||
listener["future"].set_result(message)
|
||||
else:
|
||||
global LOCK, DONE
|
||||
async with LOCK:
|
||||
listener = client.listening.get(message.chat.id)
|
||||
if listener:
|
||||
with contextlib.suppress(ValueError):
|
||||
DONE.remove(listener)
|
||||
if listener and not listener["future"].done():
|
||||
listener["future"].set_result(message)
|
||||
return
|
||||
if listener and listener["future"].done():
|
||||
client.clear_listener(message.chat.id, listener["future"])
|
||||
await self.user_callback(client, message, *args)
|
||||
await self.user_callback(client, message, *args)
|
||||
|
||||
@patchable
|
||||
async def check(self, client, update):
|
||||
listener = client.listening.get(update.chat.id)
|
||||
|
||||
if listener and not listener["future"].done():
|
||||
return (
|
||||
await listener["filters"](client, update)
|
||||
if callable(listener["filters"])
|
||||
else True
|
||||
)
|
||||
|
||||
global LOCK, DONE
|
||||
async with LOCK:
|
||||
listener = client.listening.get(update.chat.id)
|
||||
if listener and (listener not in DONE) and (not listener["future"].done()):
|
||||
if callable(listener["filters"]):
|
||||
result = await listener["filters"](client, update)
|
||||
if result:
|
||||
DONE.append(listener)
|
||||
return result
|
||||
else:
|
||||
DONE.append(listener)
|
||||
return True
|
||||
return await self.filters(client, update) if callable(self.filters) else True
|
||||
|
||||
|
||||
|
@ -1,20 +0,0 @@
|
||||
"""
|
||||
pyromod - A monkeypatcher add-on for Pyrogram
|
||||
Copyright (C) 2020 Cezar H. <https://github.com/usernein>
|
||||
|
||||
This file is part of pyromod.
|
||||
|
||||
pyromod is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
pyromod is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with pyromod. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
from .pagination import Pagination
|
@ -1,93 +0,0 @@
|
||||
"""
|
||||
pyromod - A monkeypatcher add-on for Pyrogram
|
||||
Copyright (C) 2020 Cezar H. <https://github.com/usernein>
|
||||
|
||||
This file is part of pyromod.
|
||||
|
||||
pyromod is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
pyromod is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with pyromod. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
import math
|
||||
from ..helpers import array_chunk
|
||||
|
||||
|
||||
class Pagination:
|
||||
def __init__(self, objects, page_data=None, item_data=None, item_title=None):
|
||||
default_page_callback = lambda x: str(x)
|
||||
default_item_callback = lambda i, pg: f"[{pg}] {i}"
|
||||
self.objects = objects
|
||||
self.page_data = page_data or default_page_callback
|
||||
self.item_data = item_data or default_item_callback
|
||||
self.item_title = item_title or default_item_callback
|
||||
|
||||
def create(self, page, lines=5, columns=1):
|
||||
quant_per_page = lines * columns
|
||||
page = 1 if page <= 0 else page
|
||||
offset = (page - 1) * quant_per_page
|
||||
stop = offset + quant_per_page
|
||||
cutted = self.objects[offset:stop]
|
||||
|
||||
total = len(self.objects)
|
||||
pages_range = [
|
||||
*range(1, math.ceil(total / quant_per_page) + 1)
|
||||
] # each item is a page
|
||||
last_page = len(pages_range)
|
||||
|
||||
nav = []
|
||||
if page <= 3:
|
||||
for n in [1, 2, 3]:
|
||||
if n not in pages_range:
|
||||
continue
|
||||
text = f"· {n} ·" if n == page else n
|
||||
nav.append((text, self.page_data(n)))
|
||||
if last_page >= 4:
|
||||
nav.append(("4 ›" if last_page > 5 else 4, self.page_data(4)))
|
||||
if last_page > 4:
|
||||
nav.append(
|
||||
(
|
||||
f"{last_page} »" if last_page > 5 else last_page,
|
||||
self.page_data(last_page),
|
||||
)
|
||||
)
|
||||
elif page >= last_page - 2:
|
||||
nav.extend(
|
||||
[
|
||||
("« 1" if last_page > 5 else 1, self.page_data(1)),
|
||||
(
|
||||
f"‹ {last_page - 3}" if last_page > 5 else last_page - 3,
|
||||
self.page_data(last_page - 3),
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
for n in range(last_page - 2, last_page + 1):
|
||||
text = f"· {n} ·" if n == page else n
|
||||
nav.append((text, self.page_data(n)))
|
||||
else:
|
||||
nav = [
|
||||
("« 1", self.page_data(1)),
|
||||
(f"‹ {page - 1}", self.page_data(page - 1)),
|
||||
(f"· {page} ·", "noop"),
|
||||
(f"{page + 1} ›", self.page_data(page + 1)),
|
||||
(f"{last_page} »", self.page_data(last_page)),
|
||||
]
|
||||
|
||||
buttons = [
|
||||
(self.item_title(item, page), self.item_data(item, page)) for item in cutted
|
||||
]
|
||||
|
||||
kb_lines = array_chunk(buttons, columns)
|
||||
if last_page > 1:
|
||||
kb_lines.append(nav)
|
||||
|
||||
return kb_lines
|
@ -1,5 +1,7 @@
|
||||
import contextlib
|
||||
import sys
|
||||
from enum import Enum
|
||||
|
||||
from cashews import cache
|
||||
from datetime import datetime, timezone
|
||||
from logging import getLogger, StreamHandler, CRITICAL, INFO, basicConfig, DEBUG
|
||||
@ -54,22 +56,48 @@ bot = Client(
|
||||
)
|
||||
|
||||
|
||||
async def log(chat, user, action):
|
||||
class LogAction(str, Enum):
|
||||
FAIL_ERROR = "FAIL_ERROR"
|
||||
FAIL_TIMEOUT = "FAIL_TIMEOUT"
|
||||
ACCEPT = "ACCEPT"
|
||||
NEW_GROUP = "NEW_GROUP"
|
||||
REQUEST = "REQUEST"
|
||||
|
||||
|
||||
async def log(chat, user, action: LogAction):
|
||||
scheduler.add_job(
|
||||
_log,
|
||||
args=[chat, user, action],
|
||||
replace_existing=False,
|
||||
)
|
||||
|
||||
|
||||
async def _log(chat, user, action: LogAction):
|
||||
if not Config.LOG_CHANNEL:
|
||||
return
|
||||
me = await bot.get_me()
|
||||
event = {
|
||||
"FAIL_ERROR": "回答错误",
|
||||
"FAIL_TIMEOUT": "回答超时",
|
||||
"ACCEPT": "通过验证",
|
||||
"NEW_GROUP": "加入群组",
|
||||
"REQUEST": "发起验证",
|
||||
LogAction.FAIL_ERROR: "回答错误",
|
||||
LogAction.FAIL_TIMEOUT: "回答超时",
|
||||
LogAction.ACCEPT: "通过验证",
|
||||
LogAction.NEW_GROUP: "加入群组",
|
||||
LogAction.REQUEST: "发起验证",
|
||||
}
|
||||
msg = """#%s
|
||||
群组: %s
|
||||
群组id: <code>%s</code>
|
||||
用户: #id%s
|
||||
昵称:<code>%s</code>
|
||||
OPBot: #bot%s
|
||||
事件: %s"""
|
||||
msg %= (action, chat.title, chat.id, user.id if user else "", me.id, event[action])
|
||||
user_name = user.full_name if user else ""
|
||||
msg %= (
|
||||
action.value,
|
||||
chat.title,
|
||||
chat.id,
|
||||
user.id if user else "",
|
||||
user_name,
|
||||
me.id,
|
||||
event[action],
|
||||
)
|
||||
await bot.send_message(Config.LOG_CHANNEL, msg)
|
||||
|
@ -1,4 +1,4 @@
|
||||
VERIFY_TIME = 60
|
||||
VERIFY_TIME = 180
|
||||
MSG_PUBLIC = """您好,我发现此群组为公开群组,您需要联系创建者打开 `管理员批准后才能入群` 功能,我才能更好地工作。"""
|
||||
MSG_SUCCESS = """验证成功,您已经成为群组的一员了!
|
||||
|
||||
|
@ -5,6 +5,7 @@ import pytz
|
||||
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
||||
from pyrogram.types import ChatJoinRequest
|
||||
|
||||
from sticker.languages import VERIFY_TIME
|
||||
from sticker.single_utils import Message
|
||||
|
||||
scheduler = AsyncIOScheduler(timezone="Asia/ShangHai")
|
||||
@ -24,6 +25,17 @@ async def decline_request(chat_join_request: ChatJoinRequest):
|
||||
return False
|
||||
|
||||
|
||||
async def ban_chat_member(chat_id: int, user_id: int):
|
||||
from sticker import bot
|
||||
|
||||
with contextlib.suppress(Exception):
|
||||
await bot.ban_chat_member(
|
||||
chat_id, user_id, datetime.datetime.now() + datetime.timedelta(minutes=5)
|
||||
)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def add_delete_message_job(message: Message, delete_seconds: int = 60):
|
||||
scheduler.add_job(
|
||||
delete_message,
|
||||
@ -45,7 +57,17 @@ def add_decline_request_job(chat_join_request: ChatJoinRequest):
|
||||
name=f"{chat_join_request.chat.id}|{chat_join_request.from_user.id}|decline_request",
|
||||
args=[chat_join_request],
|
||||
run_date=datetime.datetime.now(pytz.timezone("Asia/Shanghai"))
|
||||
+ datetime.timedelta(seconds=60),
|
||||
+ datetime.timedelta(seconds=VERIFY_TIME),
|
||||
replace_existing=True,
|
||||
)
|
||||
|
||||
|
||||
def add_ban_chat_member_job(chat_id: int, user_id: int):
|
||||
scheduler.add_job(
|
||||
ban_chat_member,
|
||||
id=f"{chat_id}|{user_id}|ban_chat_member",
|
||||
name=f"{chat_id}|{user_id}|ban_chat_member",
|
||||
args=[chat_id, user_id],
|
||||
replace_existing=True,
|
||||
)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user