diff --git a/.gitignore b/.gitignore index 96f66cd..0907678 100644 --- a/.gitignore +++ b/.gitignore @@ -132,4 +132,4 @@ dmypy.json # Pyre type checker .pyre/ config.ini -bot.session +bot.session* diff --git a/defs/anti_channel.py b/defs/anti_channel.py index ad09a60..86f6f1e 100644 --- a/defs/anti_channel.py +++ b/defs/anti_channel.py @@ -4,10 +4,10 @@ from os.path import exists def init() -> None: - data = {} if not exists("data"): mkdir("data") if not exists(f"data{sep}anti_channel.pkl"): + data = {} with open(f"data{sep}anti_channel.pkl", "wb") as f: pickle.dump(data, f, pickle.HIGHEST_PROTOCOL) @@ -46,14 +46,8 @@ def get(gid: int) -> list: def get_status(gid: int) -> bool: - if len(get(gid)) == 0: - return False - else: - return True + return len(get(gid)) != 0 def check_status(gid: int, cid: int) -> bool: - if cid in get(gid): - return True - else: - return False + return cid in get(gid) diff --git a/defs/ask.py b/defs/ask.py index faeccb4..985aaa2 100644 --- a/defs/ask.py +++ b/defs/ask.py @@ -6,8 +6,8 @@ from init import bot async def how_many(message: str) -> str: while re.findall("几|多少", message): - message = message.replace("几", str(secrets.choice(range(0, 99))), 1) - message = message.replace("多少", str(secrets.choice(range(0, 99))), 1) + message = message.replace("几", str(secrets.choice(range(99))), 1) + message = message.replace("多少", str(secrets.choice(range(99))), 1) return message @@ -22,12 +22,8 @@ async def what_time(message: str) -> str: async def how_long(message: str) -> str: unit = ["秒", "小时", "天", "周", "月", "年", "世纪"] while re.findall("多久|多长时间", message): - message = message.replace( - "多久", str(secrets.choice(range(0, 99))) + secrets.choice(unit), 1 - ) - message = message.replace( - "多长时间", str(secrets.choice(range(0, 99))) + secrets.choice(unit), 1 - ) + message = message.replace("多久", str(secrets.choice(range(99))) + secrets.choice(unit), 1) + message = message.replace("多长时间", str(secrets.choice(range(99))) + secrets.choice(unit), 1) return message @@ -44,18 +40,16 @@ async def hif(message: str) -> str: async def who(message: str, group_id: int) -> str: group_member_list = await bot.get_chat_member(group_id) - member_list: List[str] = [] - for n in group_member_list: - member_list += [n.first_name] + member_list: List[str] = [n.first_name for n in group_member_list] while "谁" in message: - member_name = member_list[secrets.choice(range(0, len(member_list) - 1))] + member_name = member_list[secrets.choice(range(len(member_list) - 1))] message = message.replace("谁", member_name, 1) return message async def handle_pers(message: str) -> str: message_list = list(message) - for i in range(0, len(message_list)): + for i in range(len(message_list)): if message_list[i] == "我": message_list[i] = "你" continue diff --git a/init.py b/init.py index 84b39c7..fa4b4a3 100644 --- a/init.py +++ b/init.py @@ -19,8 +19,12 @@ basicConfig(level=INFO) logs.setLevel(INFO) logger = logging.getLogger("iShotaBot") # Init client -bot = Client("bot", ipv6=ipv6, plugins=dict(root="plugins")) -bot.start() -user_me = bot.get_me() -bot.stop() -bot = Client("bot", ipv6=ipv6) + + +class UserMe: + username = "iShotaBot" + id = 2144128213 + + +user_me = UserMe() +bot = Client("bot", ipv6=ipv6, plugins=dict(root="modules")) diff --git a/modules/anti_channel.py b/modules/anti_channel.py index 45e42bc..1122133 100644 --- a/modules/anti_channel.py +++ b/modules/anti_channel.py @@ -1,3 +1,4 @@ +import contextlib from pyrogram import Client, filters, ContinuePropagation, errors from pyrogram.types import Message from pyrogram.raw import types, functions @@ -12,7 +13,7 @@ init() @Client.on_raw_update(filters.incoming & filters.group) -async def anti_channel_msg(client: Client, update: Update, _, chats: dict): +async def anti_channel_msg(client: Client, update: Update, _, __: dict): while True: try: # Check for message that are from channel @@ -41,7 +42,7 @@ async def anti_channel_msg(client: Client, update: Update, _, chats: dict): raise ContinuePropagation # Delete the message sent by channel and ban it. - await client.send( + await client.invoke( functions.channels.EditBanned( channel=await client.resolve_peer(chat_id), participant=await client.resolve_peer(channel_id), @@ -61,22 +62,17 @@ async def anti_channel_msg(client: Client, update: Update, _, chats: dict): add(chat_id, channel_id) raise ContinuePropagation except errors.FloodWait as e: - logs.debug(f"{e}, retry after {e.x} seconds...") - await sleep(e.x) - except errors.ChatAdminRequired: - try: + logs.debug(f"{e}, retry after {e.value} seconds...") + await sleep(e.value) + except errors.ChatAdminRequired as e: + with contextlib.suppress(NameError): clean(chat_id) # noqa - except NameError: - pass - raise ContinuePropagation - except ContinuePropagation: - raise ContinuePropagation - except: # noqa - logs.exception("An exception occurred in message_handler") - raise ContinuePropagation + raise ContinuePropagation from e + except ContinuePropagation as e: + raise ContinuePropagation from e -@Client.on_message(filters.incoming & ~filters.edited & filters.group & +@Client.on_message(filters.incoming & filters.group & filters.command(["anti_channel_msg", f"anti_channel_msg@{user_me.username}"])) async def switch_anti_channel_msg(client: Client, message: Message): # Check user @@ -90,19 +86,8 @@ async def switch_anti_channel_msg(client: Client, message: Message): if data.status not in ["creator", "administrator"]: await message.reply("I'm not an admin of this chat.") raise ContinuePropagation - # Check if switch - switch = False - if len(message.text.split(" ")) > 1: - switch = True - if not get_status(message.chat.id): - if switch: - add(message.chat.id, message.chat.id) - await message.reply("Anti-channel is now enabled.") - else: - await message.reply("Anti-channel is already disabled.\n" - "\n" - "Tips: Use `/anti_channel_msg true` to enable or disable it.") - else: + switch = len(message.text.split(" ")) > 1 + if get_status(message.chat.id): if switch: clean(message.chat.id) await message.reply("Anti-channel is now disabled.") @@ -110,4 +95,11 @@ async def switch_anti_channel_msg(client: Client, message: Message): await message.reply("Anti-channel is already enabled.\n" "\n" "Tips: Use `/anti_channel_msg true` to enable or disable it.") + elif switch: + add(message.chat.id, message.chat.id) + await message.reply("Anti-channel is now enabled.") + else: + await message.reply("Anti-channel is already disabled.\n" + "\n" + "Tips: Use `/anti_channel_msg true` to enable or disable it.") raise ContinuePropagation diff --git a/modules/ask.py b/modules/ask.py index 8abacaf..4b58faa 100644 --- a/modules/ask.py +++ b/modules/ask.py @@ -6,9 +6,9 @@ from pyrogram.types import Message from defs.ask import how_many, what_time, how_long, hif, handle_pers, who -@Client.on_message(filters.incoming & ~filters.edited & +@Client.on_message(filters.incoming & filters.regex(r"^问")) -async def ask(client: Client, message: Message): +async def ask(_: Client, message: Message): msg = message if not message.text: raise ContinuePropagation diff --git a/modules/banme.py b/modules/banme.py index 3a3a163..7839d03 100644 --- a/modules/banme.py +++ b/modules/banme.py @@ -1,13 +1,14 @@ import re import random -from time import time +from datetime import datetime, timedelta from pyrogram import Client, filters +from pyrogram.enums import ChatMemberStatus from pyrogram.types import Message, ChatPermissions from init import user_me -@Client.on_message(filters.incoming & ~filters.edited & filters.group & +@Client.on_message(filters.incoming & filters.group & filters.command(["banme", f"banme@{user_me.username}"])) async def ban_me_command(client: Client, message: Message): args = str(message.text).strip() @@ -18,22 +19,24 @@ async def ban_me_command(client: Client, message: Message): multiple = 1 # 检查bot和用户身份 - if not (await client.get_chat_member(message.chat.id, "self")).status == "administrator": + if (await client.get_chat_member(message.chat.id, "self")).status != ChatMemberStatus.ADMINISTRATOR: await message.reply('Bot非群管理员, 无法执行禁言操作QAQ') return if not message.from_user: # 频道 - await message.reply('你也是个管理, 别来凑热闹OvO') + await message.reply('你是个频道, 别来凑热闹OvO') return + member = (await client.get_chat_member(message.chat.id, message.from_user.id)).status - if member in ["creator", "administrator"]: + if member in [ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.OWNER]: await message.reply('你也是个管理, 别来凑热闹OvO') return # 随机禁言时间 random_time = 2 * int(random.gauss(128 * multiple, 640 * multiple // 10)) - act_time = 60 if random_time < 60 else (random_time if random_time < 2591940 else 2591940) + act_time = 60 if random_time < 60 else min(random_time, 2591940) msg = f'既然你那么想被口球的话, 那我就成全你吧!\n送你一份{act_time // 60}分{act_time % 60}秒禁言套餐哦, 谢谢惠顾~' - await client.restrict_chat_member(message.chat.id, message.from_user.id, ChatPermissions(), int(time() + act_time)) + await client.restrict_chat_member(message.chat.id, message.from_user.id, ChatPermissions(), + datetime.now() + timedelta(seconds=act_time)) await message.reply(msg) diff --git a/modules/bilibili.py b/modules/bilibili.py index b0c846b..60454c1 100644 --- a/modules/bilibili.py +++ b/modules/bilibili.py @@ -7,26 +7,23 @@ from defs.bilibili import b23_extract, video_info_get, binfo_image_create from defs.button import gen_button, Button -@Client.on_message(filters.incoming & ~filters.edited & +@Client.on_message(filters.incoming & filters.regex(r"av(\d{1,12})|BV(1[A-Za-z0-9]{2}4.1.7[A-Za-z0-9]{2})|b23.tv")) -async def bili_resolve(client: Client, message: Message): +async def bili_resolve(_: Client, message: Message): """ 解析 bilibili 链接 """ - video_info = None if "b23.tv" in message.text: message.text = await b23_extract(message.text) p = re.compile(r"av(\d{1,12})|BV(1[A-Za-z0-9]{2}4.1.7[A-Za-z0-9]{2})") video_number = p.search(message.text) if video_number: - video_number = video_number.group(0) - if video_number: - video_info = await video_info_get(video_number) - if video_info: - if video_info["code"] == 0: - image = binfo_image_create(video_info) - await message.reply_photo(image, - quote=True, - reply_markup=gen_button( - [Button(0, "Link", "https://b23.tv/" + video_info["data"]["bvid"])])) + video_number = video_number[0] + video_info = await video_info_get(video_number) if video_number else None + if video_info and video_info["code"] == 0: + image = binfo_image_create(video_info) + await message.reply_photo(image, + quote=True, + reply_markup=gen_button( + [Button(0, "Link", "https://b23.tv/" + video_info["data"]["bvid"])])) raise ContinuePropagation diff --git a/modules/book_of_answers.py b/modules/book_of_answers.py index ea632a1..98133a5 100644 --- a/modules/book_of_answers.py +++ b/modules/book_of_answers.py @@ -1,21 +1,22 @@ import json from secrets import choice from os import sep +from typing import List from pyrogram import Client, filters, ContinuePropagation from pyrogram.types import Message -book_of_answers: list[str] +book_of_answers: List[str] with open(f"resources{sep}text{sep}book_of_answers.json", "r", encoding="utf-8") as file: book_of_answers = json.load(file) -@Client.on_message(filters.incoming & ~filters.edited & +@Client.on_message(filters.incoming & filters.regex(r"^答案之书$")) -async def book_of_answer(client: Client, message: Message): +async def book_of_answer(_: Client, message: Message): await message.reply_text( f"{choice(book_of_answers)}", quote=True diff --git a/modules/friend_say.py b/modules/friend_say.py index c40c363..fb9204f 100644 --- a/modules/friend_say.py +++ b/modules/friend_say.py @@ -8,7 +8,7 @@ from pyrogram.types import Message from defs.friend_say import ImageUtil -@Client.on_message(filters.incoming & ~filters.edited & filters.group & +@Client.on_message(filters.incoming & filters.group & filters.regex(r"^我有个朋友")) async def friend_say(client: Client, message: Message): if not message.reply_to_message: diff --git a/modules/luxun.py b/modules/luxun.py index 139d034..8d80b06 100644 --- a/modules/luxun.py +++ b/modules/luxun.py @@ -1,14 +1,12 @@ -from os import sep - from pyrogram import Client, filters, ContinuePropagation from pyrogram.types import Message from defs.luxun import process_pic -@Client.on_message(filters.incoming & ~filters.edited & +@Client.on_message(filters.incoming & filters.regex(r"^鲁迅说过")) -async def luxun_say(client: Client, message: Message): +async def luxun_say(_: Client, message: Message): args = message.text[4:] if not args: await message.reply("烦了,不说了", quote=True) diff --git a/modules/repeater.py b/modules/repeater.py index 5ab8ba7..bb03957 100644 --- a/modules/repeater.py +++ b/modules/repeater.py @@ -8,7 +8,7 @@ last_repeat_msg = {} repeat_count = {} -@Client.on_message(filters.incoming & ~filters.edited & filters.group) +@Client.on_message(filters.incoming & filters.group) async def repeater_handler(client: Client, message: Message): global last_msg, last_repeat_msg, repeat_count diff --git a/modules/start.py b/modules/start.py index d4b8110..bbca543 100644 --- a/modules/start.py +++ b/modules/start.py @@ -13,13 +13,14 @@ des = """本机器人特性: """ -@Client.on_message(filters.incoming & filters.private & ~filters.edited & +@Client.on_message(filters.incoming & filters.private & filters.command(["start"])) -async def start_command(client: Client, message: Message): +async def start_command(_: Client, message: Message): """ 回应机器人信息 """ await message.reply(des, quote=True, reply_markup=gen_button( - [Button(0, "Gitlab", "https://gitlab.com/Xtao-Labs/iShotaBot")])) + [Button(0, "Gitlab", "https://gitlab.com/Xtao-Labs/iShotaBot"), + Button(0, "Github", "https://github.com/Xtao-Labs/iShotaBot")])) diff --git a/requirements.txt b/requirements.txt index 7fa5a09..6afe140 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -pyrogram +pyrogram==2.0.35 tgcrypto httpx pillow