♻️ Reformat All Plugins

This commit is contained in:
xtaodada 2023-07-01 20:18:58 +08:00
parent 4aa94e7db1
commit a7a34202fd
Signed by: xtaodada
GPG Key ID: 4CBB3F4FA8C85659
108 changed files with 5043 additions and 2225 deletions

View File

@ -49,10 +49,12 @@ class Game:
return a, b return a, b
@listener(command="1A2B", @listener(
command="1A2B",
groups_only=True, groups_only=True,
description="Play a game of 1A2B", description="Play a game of 1A2B",
parameters="[start/stop/answer]") parameters="[start/stop/answer]",
)
async def play_game_1a2b(message: Message): async def play_game_1a2b(message: Message):
if not message.arguments: if not message.arguments:
return await message.edit("Please specify a command.") return await message.edit("Please specify a command.")
@ -76,7 +78,9 @@ async def play_game_1a2b(message: Message):
try: try:
a, b = game.check_answer(message.arguments) a, b = game.check_answer(message.arguments)
except ValueError: except ValueError:
return await message.edit("You need to guess 4 numbers between 0 ~ 9.\nFor example: 1234") return await message.edit(
"You need to guess 4 numbers between 0 ~ 9.\nFor example: 1234"
)
if a == 4: if a == 4:
return await message.edit("You Win!\n\nGame over.") return await message.edit("You Win!\n\nGame over.")
return await message.edit("%d: %dA%dB" % (game.times, a, b)) return await message.edit("%d: %dA%dB" % (game.times, a, b))

File diff suppressed because it is too large Load Diff

View File

@ -23,9 +23,11 @@ def del_aff() -> None:
del sqlite["aff.web_page"] del sqlite["aff.web_page"]
@listener(command="aff", @listener(
command="aff",
description="在别人要打算买机场的时候光速发出自己的aff信息(请尽量配合短链接)", description="在别人要打算买机场的时候光速发出自己的aff信息(请尽量配合短链接)",
parameters="[save|remove] (可选,回复一条消息,用于保存|删除aff信息)") parameters="[save|remove] (可选,回复一条消息,用于保存|删除aff信息)",
)
async def aff(message: Message): async def aff(message: Message):
if not message.parameter: if not message.parameter:
msg, web_page = get_aff() msg, web_page = get_aff()

View File

@ -36,10 +36,12 @@ class Setting:
ai_setting = Setting("aireply") ai_setting = Setting("aireply")
@listener(command="aireply", @listener(
command="aireply",
need_admin=True, need_admin=True,
parameters="{on|off|add|del|list}", parameters="{on|off|add|del|list}",
description="通过预设根据语义分析进行应答,支持设置白名单并全局开关") description="通过预设根据语义分析进行应答,支持设置白名单并全局开关",
)
async def ai_reply(_: Client, message: Message): async def ai_reply(_: Client, message: Message):
input_str = message.arguments input_str = message.arguments
chats = ai_setting.chats() chats = ai_setting.chats()
@ -76,7 +78,7 @@ async def ai_reply(_: Client, message: Message):
text += f"• `{chatid}`\n" text += f"• `{chatid}`\n"
await message.edit(text) await message.edit(text)
else: else:
await edit_delete(message, lang('arg_error')) await edit_delete(message, lang("arg_error"))
@listener(incoming=True, outgoing=True, privates_only=True) @listener(incoming=True, outgoing=True, privates_only=True)
@ -100,4 +102,6 @@ async def replay_listener(_, message: Message):
if reply != 0: if reply != 0:
await asyncio.sleep(random.uniform(0, 1)) await asyncio.sleep(random.uniform(0, 1))
await bot.send_message(message.from_user.id, reply) await bot.send_message(message.from_user.id, reply)
print(f"aireply: AI Reply to '{message.from_user.mention()}' by '{reply}'") print(
f"aireply: AI Reply to '{message.from_user.mention()}' by '{reply}'"
)

View File

@ -15,7 +15,9 @@ from pagermaid.utils import check_manage_subs, edit_delete
class AliCloud: class AliCloud:
def __init__(self): def __init__(self):
self.url = 'https://api.aliyundrive.com/adrive/v1/timeline/homepage/list_message' self.url = (
"https://api.aliyundrive.com/adrive/v1/timeline/homepage/list_message"
)
self.data = { self.data = {
"user_id": "ec11691148db442aa7aa374ca707543c", # 阿里盘盘酱 "user_id": "ec11691148db442aa7aa374ca707543c", # 阿里盘盘酱
"limit": 50, "limit": 50,
@ -28,7 +30,7 @@ class AliCloud:
@staticmethod @staticmethod
def parse_time(timestamp: int) -> str: def parse_time(timestamp: int) -> str:
"""parse timestamp to date time""" """parse timestamp to date time"""
return datetime.fromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S') return datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d %H:%M:%S")
async def get(self): async def get(self):
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
@ -59,8 +61,14 @@ class AliCloud:
share_time = self.share_time share_time = self.share_time
if not share_id: if not share_id:
share_id = self.share_id share_id = self.share_id
return (f"最近一次阿里云盘掉落福利的时间是 {self.parse_time(share_time)}\n\n" return (
f"https://www.aliyundrive.com/s/{share_id}") if share_id else "未获取到阿里云盘掉落福利信息" (
f"最近一次阿里云盘掉落福利的时间是 {self.parse_time(share_time)}\n\n"
f"https://www.aliyundrive.com/s/{share_id}"
)
if share_id
else "未获取到阿里云盘掉落福利信息"
)
async def send_to_chat(self, cid: int): async def send_to_chat(self, cid: int):
try: try:
@ -94,14 +102,14 @@ async def alicloud_startup() -> None:
await alicloud.push() await alicloud.push()
@listener(command="alicloud", @listener(command="alicloud", description="获取阿里云盘掉落福利信息", parameters="[订阅/退订]")
description="获取阿里云盘掉落福利信息",
parameters="[订阅/退订]")
async def set_alicloud_notice(message: Message): async def set_alicloud_notice(message: Message):
if not message.arguments: if not message.arguments:
try: try:
item = await alicloud.get() item = await alicloud.get()
text = alicloud.get_text(item["created"] / 1000, item["content"]["share_id"]) text = alicloud.get_text(
item["created"] / 1000, item["content"]["share_id"]
)
except Exception as e: # noqa except Exception as e: # noqa
text = f"获取阿里云盘掉落福利信息失败:{e}" text = f"获取阿里云盘掉落福利信息失败:{e}"
return await message.edit(text) return await message.edit(text)

View File

@ -17,16 +17,17 @@ import emoji
# 获取内容中的表情符号,并用|分割 # 获取内容中的表情符号,并用|分割
def get_emoji(text): def get_emoji(text):
if emojiArr := emoji.distinct_emoji_list(text): if emojiArr := emoji.distinct_emoji_list(text):
delimiter = '|' delimiter = "|"
return delimiter.join(emojiArr) return delimiter.join(emojiArr)
else: else:
return False return False
@listener(is_plugin=False, @listener(
is_plugin=False,
outgoing=True, outgoing=True,
command="auto_send_reactions", command="auto_send_reactions",
description='\n自动回复Emoji插件', description="\n自动回复Emoji插件",
parameters="`\n自动回复Emoji插件支持同时设置多个目标生效用户目前仅支持回复用户在群组中发送的消息默认在所有已加入的群组中生效\n" parameters="`\n自动回复Emoji插件支持同时设置多个目标生效用户目前仅支持回复用户在群组中发送的消息默认在所有已加入的群组中生效\n"
"\n**设置插件状态**:" "\n**设置插件状态**:"
"\n启用:`,auto_send_reactions enable`" "\n启用:`,auto_send_reactions enable`"
@ -37,7 +38,8 @@ def get_emoji(text):
"\n支持直接回复消息以进行快速设置,可以省略用户标识参数" "\n支持直接回复消息以进行快速设置,可以省略用户标识参数"
"\n\n**设置生效群组黑名单**:" "\n\n**设置生效群组黑名单**:"
"\n添加:`,auto_send_reactions block <群组id/群组用户名>`" "\n添加:`,auto_send_reactions block <群组id/群组用户名>`"
"\n移除:`,auto_send_reactions unblock <群组id/群组用户名>\n") "\n移除:`,auto_send_reactions unblock <群组id/群组用户名>\n",
)
async def AutoSendReactions(client: Client, message: Message): async def AutoSendReactions(client: Client, message: Message):
reply = message.reply_to_message reply = message.reply_to_message
@ -53,13 +55,12 @@ async def AutoSendReactions(client: Client, message: Message):
# return # return
if not sqlite.get("AutoSendReactions.Enable"): if not sqlite.get("AutoSendReactions.Enable"):
sqlite["AutoSendReactions.Enable"] = 'yes' sqlite["AutoSendReactions.Enable"] = "yes"
# 返回消息 # 返回消息
await edit_delete(message, "✅ **已启用自动回复表情插件**") await edit_delete(message, "✅ **已启用自动回复表情插件**")
elif message.parameter[0] == "disable": elif message.parameter[0] == "disable":
if sqlite.get("AutoSendReactions.Enable"): if sqlite.get("AutoSendReactions.Enable"):
del sqlite["AutoSendReactions.Enable"] del sqlite["AutoSendReactions.Enable"]
@ -67,10 +68,8 @@ async def AutoSendReactions(client: Client, message: Message):
await edit_delete(message, "❌ **已停用自动回复表情插件**") await edit_delete(message, "❌ **已停用自动回复表情插件**")
elif message.parameter[0] in ["set", "unset"]: elif message.parameter[0] in ["set", "unset"]:
## 设置插件 ## 设置插件
if (message.parameter[0] == "set"): if message.parameter[0] == "set":
if not reply and (len(message.parameter) == 3): if not reply and (len(message.parameter) == 3):
target = message.parameter[1] target = message.parameter[1]
content = message.parameter[2] content = message.parameter[2]
@ -83,7 +82,7 @@ async def AutoSendReactions(client: Client, message: Message):
if not content or not get_emoji(content): if not content or not get_emoji(content):
return await message.edit("❌ **Emoji参数不能为空或不合法**") return await message.edit("❌ **Emoji参数不能为空或不合法**")
user_name = ( user_name = (
f'{user_info.first_name} {user_info.last_name}' f"{user_info.first_name} {user_info.last_name}"
if user_info.last_name if user_info.last_name
else user_info.first_name else user_info.first_name
) )
@ -92,7 +91,7 @@ async def AutoSendReactions(client: Client, message: Message):
sqlite[f"AutoSendReactions.{target}"] = content sqlite[f"AutoSendReactions.{target}"] = content
await edit_delete( await edit_delete(
message, message,
f"✅ 已{'更新' if hasSetted else '添加'}对 __{user_name}__ 的自动回复Emoji设置**" f"✅ 已{'更新' if hasSetted else '添加'}对 __{user_name}__ 的自动回复Emoji设置**",
) )
except Exception as e: except Exception as e:
await message.edit(message, f"❌ **在设置中遇到了一些错误** > {e}") await message.edit(message, f"❌ **在设置中遇到了一些错误** > {e}")
@ -107,7 +106,7 @@ async def AutoSendReactions(client: Client, message: Message):
if not content or not get_emoji(content): if not content or not get_emoji(content):
return await message.edit("❌ **Emoji参数不能为空或不合法**") return await message.edit("❌ **Emoji参数不能为空或不合法**")
user_name = ( user_name = (
f'{from_user.first_name} {from_user.last_name}' f"{from_user.first_name} {from_user.last_name}"
if from_user.last_name if from_user.last_name
else from_user.first_name else from_user.first_name
) )
@ -116,17 +115,15 @@ async def AutoSendReactions(client: Client, message: Message):
sqlite[f"AutoSendReactions.{target}"] = content sqlite[f"AutoSendReactions.{target}"] = content
await edit_delete( await edit_delete(
message, message,
f"✅ 已{'更新' if hasSetted else '添加'}对 __{user_name}__ 的自动回复Emoji设置" f"✅ 已{'更新' if hasSetted else '添加'}对 __{user_name}__ 的自动回复Emoji设置",
) )
except Exception as e: except Exception as e:
await message.edit(message, f"❌ **在设置中遇到了一些错误** > {e}") await message.edit(message, f"❌ **在设置中遇到了一些错误** > {e}")
await log(e) # 打印错误日志 await log(e) # 打印错误日志
else: else:
return await message.edit( return await message.edit(f"{lang('error_prefix')}{lang('arg_error')}")
f"{lang('error_prefix')}{lang('arg_error')}")
elif (message.parameter[0] == "unset"):
elif message.parameter[0] == "unset":
if not reply and (len(message.parameter) == 2): if not reply and (len(message.parameter) == 2):
target = message.parameter[1] target = message.parameter[1]
try: try:
@ -137,17 +134,19 @@ async def AutoSendReactions(client: Client, message: Message):
return await message.edit("❌ **目标用户不存在或参数有误**") return await message.edit("❌ **目标用户不存在或参数有误**")
user_id = user_info.id user_id = user_info.id
user_name = ( user_name = (
f'{user_info.first_name} {user_info.last_name}' f"{user_info.first_name} {user_info.last_name}"
if user_info.last_name if user_info.last_name
else user_info.first_name else user_info.first_name
) )
if hasSetted := sqlite.get(f"AutoSendReactions.{user_id}"): if hasSetted := sqlite.get(f"AutoSendReactions.{user_id}"):
del sqlite[f"AutoSendReactions.{user_id}"] del sqlite[f"AutoSendReactions.{user_id}"]
await edit_delete( await edit_delete(
message, f"✅ 对 __{user_name}__ 的自动回复Emoji设置已删除") message, f"✅ 对 __{user_name}__ 的自动回复Emoji设置已删除"
)
else: else:
await edit_delete( await edit_delete(
message, f"❌ 还没有对 __{user_name}__ 设置自动回复Emoji哦~") message, f"❌ 还没有对 __{user_name}__ 设置自动回复Emoji哦~"
)
except Exception as e: except Exception as e:
await message.edit(message, f"❌ **在设置中遇到了一些错误** > {e}") await message.edit(message, f"❌ **在设置中遇到了一些错误** > {e}")
await log(e) # 打印错误日志 await log(e) # 打印错误日志
@ -157,31 +156,33 @@ async def AutoSendReactions(client: Client, message: Message):
target = from_user.id target = from_user.id
try: try:
user_name = ( user_name = (
f'{from_user.first_name} {from_user.last_name}' f"{from_user.first_name} {from_user.last_name}"
if from_user.last_name if from_user.last_name
else from_user.first_name else from_user.first_name
) )
if hasSetted := sqlite.get(f"AutoSendReactions.{target}"): if hasSetted := sqlite.get(f"AutoSendReactions.{target}"):
del sqlite[f"AutoSendReactions.{target}"] del sqlite[f"AutoSendReactions.{target}"]
await edit_delete( await edit_delete(
message, f"✅ 已删除对 __{user_name}__ 的自动回复Emoji设置") message, f"✅ 已删除对 __{user_name}__ 的自动回复Emoji设置"
)
else: else:
await edit_delete( await edit_delete(
message, f"❌ 还没有对 __{user_name}__ 设置自动回复Emoji哦~") message, f"❌ 还没有对 __{user_name}__ 设置自动回复Emoji哦~"
)
except Exception as e: except Exception as e:
await message.edit(message, f"❌ **在设置中遇到了一些错误** > {e}") await message.edit(message, f"❌ **在设置中遇到了一些错误** > {e}")
await log(e) # 打印错误日志 await log(e) # 打印错误日志
else: else:
return await message.edit( return await message.edit(f"{lang('error_prefix')}{lang('arg_error')}")
f"{lang('error_prefix')}{lang('arg_error')}")
else: else:
return await message.edit( return await message.edit(f"{lang('error_prefix')}{lang('arg_error')}")
f"{lang('error_prefix')}{lang('arg_error')}")
elif (message.parameter[0] elif (
== "block") or (message.parameter[0] == "unblock") and (len( (message.parameter[0] == "block")
message.parameter) == 2): or (message.parameter[0] == "unblock")
and (len(message.parameter) == 2)
):
group = message.parameter[1] group = message.parameter[1]
group_info = await bot.get_chat(chat_id=group) group_info = await bot.get_chat(chat_id=group)
if not group_info: if not group_info:
@ -189,36 +190,35 @@ async def AutoSendReactions(client: Client, message: Message):
group_id = group_info.id group_id = group_info.id
group_name = group_info.title group_name = group_info.title
if (message.parameter[0] == "block"): if message.parameter[0] == "block":
if hasBlocked := sqlite.get(f"AutoSendReactionsBlock.{group_id}"): if hasBlocked := sqlite.get(f"AutoSendReactionsBlock.{group_id}"):
await edit_delete( await edit_delete(
message, f"❌ 已经将 __{group_name}__ 加入自动回复Emoji黑名单群组了哦~") message, f"❌ 已经将 __{group_name}__ 加入自动回复Emoji黑名单群组了哦~"
)
else: else:
sqlite[f"AutoSendReactionsBlock.{group_id}"] = 'yes' sqlite[f"AutoSendReactionsBlock.{group_id}"] = "yes"
await edit_delete(message, await edit_delete(message, f"✅ 已将 __{group_name}__ 加入至自动回复Emoji黑名单群组")
f"✅ 已将 __{group_name}__ 加入至自动回复Emoji黑名单群组") elif message.parameter[0] == "unblock":
elif (message.parameter[0] == "unblock"):
if hasBlocked := sqlite.get(f"AutoSendReactionsBlock.{group_id}"): if hasBlocked := sqlite.get(f"AutoSendReactionsBlock.{group_id}"):
del sqlite[f"AutoSendReactionsBlock.{group_id}"] del sqlite[f"AutoSendReactionsBlock.{group_id}"]
await edit_delete(message, await edit_delete(message, f"✅ 已将 __{group_name}__ 从自动回复Emoji黑名单群组中移除")
f"✅ 已将 __{group_name}__ 从自动回复Emoji黑名单群组中移除")
else: else:
await edit_delete( await edit_delete(
message, f"❌ 还没有将 __{group_name}__ 加入进自动回复Emoji群组黑名单哦~") message, f"❌ 还没有将 __{group_name}__ 加入进自动回复Emoji群组黑名单哦~"
)
else: else:
return await message.edit(f"{lang('error_prefix')}{lang('arg_error')}" return await message.edit(f"{lang('error_prefix')}{lang('arg_error')}")
)
@listener(is_plugin=False, incoming=True, ignore_edited=True) @listener(is_plugin=False, incoming=True, ignore_edited=True)
async def AutoSendReactions(message: Message): async def AutoSendReactions(message: Message):
from_user = '' from_user = ""
try: try:
# 判断是否启用了本插件 # 判断是否启用了本插件
if not sqlite.get("AutoSendReactions.Enable"): if not sqlite.get("AutoSendReactions.Enable"):
return return
if 'GROUP' not in str(message.chat.type): if "GROUP" not in str(message.chat.type):
return return
# 判断是否在黑名单中 # 判断是否在黑名单中
if sqlite.get(f"AutoSendReactionsBlock.{message.chat.id}"): if sqlite.get(f"AutoSendReactionsBlock.{message.chat.id}"):
@ -236,9 +236,9 @@ async def AutoSendReactions(message: Message):
return return
# 发送表情 # 发送表情
emoji = sqlite.get(f"AutoSendReactions.{from_user.id}").split('|')[0] emoji = sqlite.get(f"AutoSendReactions.{from_user.id}").split("|")[0]
user_name = ( user_name = (
f'{from_user.first_name} {from_user.last_name}' f"{from_user.first_name} {from_user.last_name}"
if from_user.last_name if from_user.last_name
else from_user.first_name else from_user.first_name
) )

View File

@ -43,7 +43,7 @@ async def get_hitokoto(request: AsyncClient):
htk = (await request.get("https://v1.hitokoto.cn/?charset=utf-8")).json() htk = (await request.get("https://v1.hitokoto.cn/?charset=utf-8")).json()
text = f"\"{htk['hitokoto']}\" —— {htk['from_who']}{htk['from']}" text = f"\"{htk['hitokoto']}\" —— {htk['from_who']}{htk['from']}"
except Exception: except Exception:
text = "\"用代码表达言语的魅力,用代码书写山河的壮丽。\" —— 一言「一言开发者中心」" text = '"用代码表达言语的魅力,用代码书写山河的壮丽。" —— 一言「一言开发者中心」'
return text return text
@ -66,7 +66,9 @@ async def annualreport(client: Client, message: Message, request: AsyncClient):
pmct = "" pmct = ""
if pmc := sqlite.get("pmcaptcha", {}): if pmc := sqlite.get("pmcaptcha", {}):
pmcu = "" if "pmcaptcha" in plg else "不过此插件已经被卸载了,是spam变少了吗?\n" pmcu = "" if "pmcaptcha" in plg else "不过此插件已经被卸载了,是spam变少了吗?\n"
pmct = f'pmcaptcha 已帮助你拦截了 {pmc.get("banned", 0)} 次私聊\n你的清净由 pagermaid 守护\n{pmcu}' pmct = (
f'pmcaptcha 已帮助你拦截了 {pmc.get("banned", 0)} 次私聊\n你的清净由 pagermaid 守护\n{pmcu}'
)
htks = await get_hitokoto(request) htks = await get_hitokoto(request)
msg = f"""{user} 的年度报告 msg = f"""{user} 的年度报告
2022 一路上,你充实而满足 2022 一路上,你充实而满足

View File

@ -4,19 +4,27 @@ from pagermaid.listener import listener
from pagermaid.enums import Client, Message from pagermaid.enums import Client, Message
@listener(command="atadmins", @listener(
command="atadmins",
description="一键 AT 本群管理员(仅在群组中有效)", description="一键 AT 本群管理员(仅在群组中有效)",
groups_only=True, groups_only=True,
parameters="[要说的话]") parameters="[要说的话]",
)
async def at_admins(client: Client, message: Message): async def at_admins(client: Client, message: Message):
admins = [] admins = []
async for m in client.get_chat_members(message.chat.id, filter=ChatMembersFilter.ADMINISTRATORS): async for m in client.get_chat_members(
message.chat.id, filter=ChatMembersFilter.ADMINISTRATORS
):
if not m.user.is_bot and not m.user.is_deleted: if not m.user.is_bot and not m.user.is_deleted:
admins.append(m.user.mention) admins.append(m.user.mention)
if not admins: if not admins:
return await message.edit("❌ 没有管理员") return await message.edit("❌ 没有管理员")
say = message.arguments or "召唤本群所有管理员" say = message.arguments or "召唤本群所有管理员"
send_list = ' , '.join(admins) send_list = " , ".join(admins)
await client.send_message(message.chat.id, "%s\n\n%s" % (say, send_list), await client.send_message(
reply_to_message_id=message.reply_to_message_id or message.reply_to_top_message_id) message.chat.id,
"%s\n\n%s" % (say, send_list),
reply_to_message_id=message.reply_to_message_id
or message.reply_to_top_message_id,
)
await message.safe_delete() await message.safe_delete()

View File

@ -10,8 +10,7 @@ async def get_audio(message: Message):
return message if message.audio else None return message if message.audio else None
@listener(command="audio_to_voice", @listener(command="audio_to_voice", description="将音乐文件转换为语音")
description="将音乐文件转换为语音")
async def audio_to_voice(bot: Client, message: Message): async def audio_to_voice(bot: Client, message: Message):
audio = await get_audio(message) audio = await get_audio(message)
if not audio: if not audio:
@ -22,8 +21,10 @@ async def audio_to_voice(bot: Client, message: Message):
await bot.send_voice( await bot.send_voice(
message.chat.id, message.chat.id,
audio, audio,
reply_to_message_id=message.id if message.audio else (message.reply_to_message_id or reply_to_message_id=message.id
message.reply_to_top_message_id)) if message.audio
else (message.reply_to_message_id or message.reply_to_top_message_id),
)
except Exception as e: except Exception as e:
await message.edit(f"转换为语音消息失败:{e}") await message.edit(f"转换为语音消息失败:{e}")
safe_remove(audio) safe_remove(audio)

View File

@ -11,24 +11,48 @@ from emoji import emojize
from pagermaid import logs, scheduler, bot from pagermaid import logs, scheduler, bot
auto_change_name_init = False auto_change_name_init = False
dizzy = emojize(":dizzy:", language='alias') dizzy = emojize(":dizzy:", language="alias")
cake = emojize(":cake:", language='alias') cake = emojize(":cake:", language="alias")
all_time_emoji_name = ["clock12", "clock1230", "clock1", "clock130", "clock2", "clock230", "clock3", "clock330", all_time_emoji_name = [
"clock4", "clock430", "clock5", "clock530", "clock6", "clock630", "clock7", "clock730", "clock8", "clock12",
"clock830", "clock9", "clock930", "clock10", "clock1030", "clock11", "clock1130"] "clock1230",
time_emoji_symb = [ "clock1",
emojize(f":{s}:", language='alias') for s in all_time_emoji_name "clock130",
"clock2",
"clock230",
"clock3",
"clock330",
"clock4",
"clock430",
"clock5",
"clock530",
"clock6",
"clock630",
"clock7",
"clock730",
"clock8",
"clock830",
"clock9",
"clock930",
"clock10",
"clock1030",
"clock11",
"clock1130",
] ]
time_emoji_symb = [emojize(f":{s}:", language="alias") for s in all_time_emoji_name]
@scheduler.scheduled_job("cron", second=0, id="autochangename") @scheduler.scheduled_job("cron", second=0, id="autochangename")
async def change_name_auto(): async def change_name_auto():
try: try:
time_cur = datetime.utcnow().replace(tzinfo=timezone.utc).astimezone(timezone( time_cur = (
timedelta(hours=8))).strftime('%H:%M:%S:%p:%a') datetime.utcnow()
hour, minu, seco, p, abbwn = time_cur.split(':') .replace(tzinfo=timezone.utc)
.astimezone(timezone(timedelta(hours=8)))
.strftime("%H:%M:%S:%p:%a")
)
hour, minu, seco, p, abbwn = time_cur.split(":")
shift = 1 if int(minu) > 30 else 0 shift = 1 if int(minu) > 30 else 0
hsym = time_emoji_symb[(int(hour) % 12) * 2 + shift] hsym = time_emoji_symb[(int(hour) % 12) * 2 + shift]
_last_name = f"{hour}:{minu} {p} UTC+8 {hsym}" _last_name = f"{hour}:{minu} {p} UTC+8 {hsym}"

View File

@ -33,7 +33,12 @@ class DelTask:
hour = DelTask.check_time(data[i - 1], 0, 24) hour = DelTask.check_time(data[i - 1], 0, 24)
elif data[i] == "days": elif data[i] == "days":
day = DelTask.check_time(data[i - 1], 0, 31) day = DelTask.check_time(data[i - 1], 0, 31)
if second := int(second) + int(minute) * 60 + int(hour) * 3600 + int(day) * 86400: if (
second := int(second)
+ int(minute) * 60
+ int(hour) * 3600
+ int(day) * 86400
):
return second return second
else: else:
raise ValueError("Invalid task format") raise ValueError("Invalid task format")
@ -59,7 +64,9 @@ class DelTask:
@staticmethod @staticmethod
def add_task(message: Message): def add_task(message: Message):
if seconds := DelTask.get_del_seconds(0) or DelTask.get_del_seconds(message.chat.id): if seconds := DelTask.get_del_seconds(0) or DelTask.get_del_seconds(
message.chat.id
):
add_delete_message_job(message, seconds) add_delete_message_job(message, seconds)
@staticmethod @staticmethod
@ -87,9 +94,11 @@ auto_del_help_msg = f"""
""" """
@listener(command="autodel", @listener(
command="autodel",
need_admin=True, need_admin=True,
description=f"定时删除消息\n请使用 ,{alias_command('autodel')} h 查看可用命令") description=f"定时删除消息\n请使用 ,{alias_command('autodel')} h 查看可用命令",
)
async def auto_del(message: Message): async def auto_del(message: Message):
if message.arguments == "h" or len(message.parameter) == 0: if message.arguments == "h" or len(message.parameter) == 0:
return await message.edit(auto_del_help_msg) return await message.edit(auto_del_help_msg)
@ -97,7 +106,9 @@ async def auto_del(message: Message):
return await message.edit(DelTask.get_list(message.chat.id)) return await message.edit(DelTask.get_list(message.chat.id))
try: try:
await DelTask.parse_task(message) await DelTask.parse_task(message)
await message.edit("设置自动删除任务成功。" if message.arguments != "cancel" else "取消自动删除任务成功。") await message.edit(
"设置自动删除任务成功。" if message.arguments != "cancel" else "取消自动删除任务成功。"
)
except ValueError as e: except ValueError as e:
await message.edit(f"开启失败:{str(e)}") await message.edit(f"开启失败:{str(e)}")
except KeyError: except KeyError:

View File

@ -4,9 +4,7 @@ from pagermaid.utils import Message
from base64 import b64decode, b64encode from base64 import b64decode, b64encode
@listener(command="b64e", @listener(command="b64e", description="将文本转为Base64", parameters="[text]")
description="将文本转为Base64",
parameters="[text]")
async def b64e(_: Client, message: Message): async def b64e(_: Client, message: Message):
msg = message.arguments msg = message.arguments
if not msg: if not msg:
@ -16,9 +14,7 @@ async def b64e(_: Client, message: Message):
await message.edit(f"`{result}`") await message.edit(f"`{result}`")
@listener(command="b64d", @listener(command="b64d", description="将Base64转为文本", parameters="[text]")
description="将Base64转为文本",
parameters="[text]")
async def b64d(_: Client, message: Message): async def b64d(_: Client, message: Message):
msg = message.arguments msg = message.arguments
if not msg: if not msg:

View File

@ -24,8 +24,8 @@ import xmltodict
API = "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml" API = "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml"
CURRENCIES = [] CURRENCIES = []
DATA = {} DATA = {}
BINANCE_API_KEY = '8PDfQ2lSIyHPWdNAHNIaIoNy3MiiMuvgwYADbmtsKo867B0xnIhIGjPULsOtvMRk' BINANCE_API_KEY = "8PDfQ2lSIyHPWdNAHNIaIoNy3MiiMuvgwYADbmtsKo867B0xnIhIGjPULsOtvMRk"
BINANCE_API_SECRET = 'tbUiyZ94l0zpYOlKs3eO1dvLNMOSbOb2T1T0eT0I1eogH9Fh8Htvli05eZ1iDvra' BINANCE_API_SECRET = "tbUiyZ94l0zpYOlKs3eO1dvLNMOSbOb2T1T0eT0I1eogH9Fh8Htvli05eZ1iDvra"
def init() -> None: def init() -> None:
@ -35,78 +35,76 @@ def init() -> None:
try: try:
global CURRENCIES, DATA global CURRENCIES, DATA
rate_data = xmltodict.parse(result) rate_data = xmltodict.parse(result)
rate_data = rate_data['gesmes:Envelope']['Cube']['Cube']['Cube'] rate_data = rate_data["gesmes:Envelope"]["Cube"]["Cube"]["Cube"]
for i in rate_data: for i in rate_data:
CURRENCIES.append(i['@currency']) CURRENCIES.append(i["@currency"])
DATA[i['@currency']] = float(i['@rate']) DATA[i["@currency"]] = float(i["@rate"])
CURRENCIES.sort() CURRENCIES.sort()
except Exception as e: except Exception as e:
raise e raise e
@listener(command="bc", @listener(command="bc", description="coins", parameters="[num] [coin1] [coin2]")
description="coins",
parameters="[num] [coin1] [coin2]")
async def coin(_: Client, message: Message) -> None: async def coin(_: Client, message: Message) -> None:
"""coin change""" """coin change"""
init() init()
action = message.arguments.split() action = message.arguments.split()
binanceclient = Client(BINANCE_API_KEY, BINANCE_API_SECRET) binanceclient = Client(BINANCE_API_KEY, BINANCE_API_SECRET)
if len(action) < 3: if len(action) < 3:
await message.edit('输入错误.\n-bc 数量 币种1 币种2') await message.edit("输入错误.\n-bc 数量 币种1 币种2")
return return
else: else:
prices = binanceclient.get_all_tickers() prices = binanceclient.get_all_tickers()
try: try:
number = float(action[0]) number = float(action[0])
except ValueError: except ValueError:
await message.edit('输入错误.\n-bc 数量 币种1 币种2') await message.edit("输入错误.\n-bc 数量 币种1 币种2")
return return
_from = action[1].upper().strip() _from = action[1].upper().strip()
_to = action[2].upper().strip() _to = action[2].upper().strip()
front_text = '' front_text = ""
text = '' text = ""
rear_text = '' rear_text = ""
price = 0.0 price = 0.0
_to_USD_rate = 0.0 _to_USD_rate = 0.0
if (CURRENCIES.count(_from) != 0) and (CURRENCIES.count(_to) != 0): if (CURRENCIES.count(_from) != 0) and (CURRENCIES.count(_to) != 0):
# both are real currency # both are real currency
text = f'{action[0]} {action[1].upper().strip()} = {float(action[0])*DATA[_to]/DATA[_from]:.2f} {action[2].upper().strip()}' text = f"{action[0]} {action[1].upper().strip()} = {float(action[0])*DATA[_to]/DATA[_from]:.2f} {action[2].upper().strip()}"
else: else:
if CURRENCIES.count(_from) != 0: if CURRENCIES.count(_from) != 0:
# from virtual currency to real currency # from virtual currency to real currency
number = number * DATA["USD"] / DATA[_from] number = number * DATA["USD"] / DATA[_from]
_from = 'USDT' _from = "USDT"
front_text = f'{action[0]} {action[1]} = \n' front_text = f"{action[0]} {action[1]} = \n"
if CURRENCIES.count(_to) != 0: if CURRENCIES.count(_to) != 0:
# from real currency to virtual currency # from real currency to virtual currency
_to_USD_rate = DATA[_to] / DATA["USD"] _to_USD_rate = DATA[_to] / DATA["USD"]
_to = 'USDT' _to = "USDT"
for _a in prices: for _a in prices:
if _a['symbol'] == str(f'{_from}{_to}'): if _a["symbol"] == str(f"{_from}{_to}"):
price = _a['price'] price = _a["price"]
if _to == 'USDT': if _to == "USDT":
if action[2].upper().strip() == 'USDT': if action[2].upper().strip() == "USDT":
rear_text = f'\n= {number * float(price) * DATA["CNY"]/DATA["USD"]:.2f} CNY' rear_text = f'\n= {number * float(price) * DATA["CNY"]/DATA["USD"]:.2f} CNY'
else: else:
rear_text = f'\n= {number * float(price) * _to_USD_rate:.2f} {action[2].upper().strip()}' rear_text = f"\n= {number * float(price) * _to_USD_rate:.2f} {action[2].upper().strip()}"
if float(price) < 1: if float(price) < 1:
text = f'{number} {_from} = {number * float(price):.8f} {_to}' text = f"{number} {_from} = {number * float(price):.8f} {_to}"
else: else:
text = f'{number} {_from} = {number * float(price):.2f} {_to}' text = f"{number} {_from} = {number * float(price):.2f} {_to}"
break break
elif _a['symbol'] == str(f'{_to}{_from}'): elif _a["symbol"] == str(f"{_to}{_from}"):
price = 1 / float(_a['price']) price = 1 / float(_a["price"])
text = f'{number} {_from} = {number * float(price):.8f} {_to}' text = f"{number} {_from} = {number * float(price):.8f} {_to}"
break break
else: else:
price = None price = None
if price is None: if price is None:
text = f'Cannot find coinpair {action[1].upper().strip()}{action[2].upper().strip()} or {action[2].upper().strip()}{action[1].upper().strip()}' text = f"Cannot find coinpair {action[1].upper().strip()}{action[2].upper().strip()} or {action[2].upper().strip()}{action[1].upper().strip()}"
await message.edit(f'{front_text}{text}{rear_text}') await message.edit(f"{front_text}{text}{rear_text}")

View File

@ -9,11 +9,9 @@ pip_install("requests")
import requests import requests
@listener(command="bin", @listener(command="bin", description="查询信用卡信息", parameters="[bin4到8位数字]")
description="查询信用卡信息",
parameters="[bin4到8位数字]")
async def card(_: Client, message: Message): async def card(_: Client, message: Message):
await message.edit('正在查询中...') await message.edit("正在查询中...")
try: try:
card_bin = message.arguments card_bin = message.arguments
except ValueError: except ValueError:
@ -39,30 +37,30 @@ async def card(_: Client, message: Message):
msg_out = [f"BIN{card_bin}"] msg_out = [f"BIN{card_bin}"]
try: try:
msg_out.extend(["卡品牌:" + bin_json['scheme']]) msg_out.extend(["卡品牌:" + bin_json["scheme"]])
except (KeyError, TypeError): except (KeyError, TypeError):
pass pass
try: try:
msg_out.extend(["卡类型:" + bin_json['type']]) msg_out.extend(["卡类型:" + bin_json["type"]])
except (KeyError, TypeError): except (KeyError, TypeError):
pass pass
try: try:
msg_out.extend(["卡种类:" + bin_json['brand']]) msg_out.extend(["卡种类:" + bin_json["brand"]])
except (KeyError, TypeError): except (KeyError, TypeError):
pass pass
try: try:
msg_out.extend(["发卡行:" + bin_json['bank']["name"]]) msg_out.extend(["发卡行:" + bin_json["bank"]["name"]])
except (KeyError, TypeError): except (KeyError, TypeError):
pass pass
try: try:
if bin_json['prepaid']: if bin_json["prepaid"]:
msg_out.extend(["是否预付:是"]) msg_out.extend(["是否预付:是"])
else: else:
msg_out.extend(["是否预付:否"]) msg_out.extend(["是否预付:否"])
except (KeyError, TypeError): except (KeyError, TypeError):
pass pass
try: try:
msg_out.extend(["发卡国家:" + bin_json['country']['name']]) msg_out.extend(["发卡国家:" + bin_json["country"]["name"]])
except (KeyError, TypeError): except (KeyError, TypeError):
pass pass
await message.edit("\n".join(msg_out)) await message.edit("\n".join(msg_out))

View File

@ -14,13 +14,12 @@ async def get_wallpaper_url(num):
copy_right = "" copy_right = ""
if req.status_code == 200: if req.status_code == 200:
data = req.json() data = req.json()
url = data['images'][0]['url'] url = data["images"][0]["url"]
copy_right = data['images'][0]['copyright'] copy_right = data["images"][0]["copyright"]
return url, copy_right return url, copy_right
@listener(command="bingwall", @listener(command="bingwall", description="获取Bing每日壁纸带参数发送原图")
description="获取Bing每日壁纸带参数发送原图")
async def bingwall(message: Message): async def bingwall(message: Message):
status = False status = False
filename = f"data{sep}wallpaper.jpg" filename = f"data{sep}wallpaper.jpg"
@ -39,16 +38,14 @@ async def bingwall(message: Message):
if message.arguments: if message.arguments:
await message.reply_document( await message.reply_document(
filename, filename,
caption=f"#bing wallpaper\n" caption=f"#bing wallpaper\n" f"{str(copy_right)}",
f"{str(copy_right)}",
quote=False, quote=False,
reply_to_message_id=message.reply_to_top_message_id, reply_to_message_id=message.reply_to_top_message_id,
) )
else: else:
await message.reply_photo( await message.reply_photo(
filename, filename,
caption=f"#bing wallpaper\n" caption=f"#bing wallpaper\n" f"{str(copy_right)}",
f"{str(copy_right)}",
quote=False, quote=False,
reply_to_message_id=message.reply_to_top_message_id, reply_to_message_id=message.reply_to_top_message_id,
) )

View File

@ -3,9 +3,11 @@ from pagermaid.listener import listener
from pagermaid.utils import Message, execute from pagermaid.utils import Message, execute
@listener(command="cal", @listener(
command="cal",
description="计算\n示例:\n`,cal 1+1`加法\n`,cal 2-1`减法\n`,cal 1*2`乘法\n`,cal 4/2`除法\n`,cal 4^2`幂运算\n`,cal sqrt(4)`开方", description="计算\n示例:\n`,cal 1+1`加法\n`,cal 2-1`减法\n`,cal 1*2`乘法\n`,cal 4/2`除法\n`,cal 4^2`幂运算\n`,cal sqrt(4)`开方",
parameters="[基本运算]") parameters="[基本运算]",
)
async def cal(_: Client, message: Message): async def cal(_: Client, message: Message):
command = message.arguments command = message.arguments
if not command: if not command:
@ -21,9 +23,12 @@ async def cal(_: Client, message: Message):
else: else:
return return
@listener(command="con",
@listener(
command="con",
description="换算\n示例:\n`,con 2 99`将99转换为2进制", description="换算\n示例:\n`,con 2 99`将99转换为2进制",
parameters="[进制(数字)] [数值]") parameters="[进制(数字)] [数值]",
)
async def con(_: Client, message: Message): async def con(_: Client, message: Message):
command = message.arguments.split() command = message.arguments.split()
if not command: if not command:

View File

@ -25,7 +25,9 @@ async def export_chat_to_csv():
writer = csv.writer(f) writer = csv.writer(f)
writer.writerow(["name", "id", "username", "members"]) writer.writerow(["name", "id", "username", "members"])
for chat in chats: for chat in chats:
writer.writerow([chat.title, chat.id, chat.username or "", chat.members_count]) writer.writerow(
[chat.title, chat.id, chat.username or "", chat.members_count]
)
return len(chats) return len(chats)
@ -61,10 +63,12 @@ async def join_chat_from_csv(file_name):
return success, failed, processed return success, failed, processed
@listener(command="chat_transfer", @listener(
command="chat_transfer",
need_admin=True, need_admin=True,
parameters="导出/导入", parameters="导出/导入",
description="导出、导入已加入的群组/频道(仅可导入公开群组/频道)") description="导出、导入已加入的群组/频道(仅可导入公开群组/频道)",
)
async def chat_transfer(message: Message): async def chat_transfer(message: Message):
if message.arguments == "导出": if message.arguments == "导出":
message: Message = await message.edit("导出中...") message: Message = await message.edit("导出中...")
@ -93,6 +97,8 @@ async def chat_transfer(message: Message):
file_name = await reply.download() file_name = await reply.download()
success, failed, processed = await join_chat_from_csv(file_name) success, failed, processed = await join_chat_from_csv(file_name)
safe_remove(file_name) safe_remove(file_name)
await message.edit(f"处理了 {processed} 条记录,导入成功 {success} 个群组/频道,失败 {failed} 个群组/频道") await message.edit(
f"处理了 {processed} 条记录,导入成功 {success} 个群组/频道,失败 {failed} 个群组/频道"
)
else: else:
await message.edit("❌ 参数错误,请选择 `导出` 或 `导入`") await message.edit("❌ 参数错误,请选择 `导出` 或 `导入`")

View File

@ -59,11 +59,13 @@ class AsyncChatbot:
chat_bot = AsyncChatbot() chat_bot = AsyncChatbot()
chat_bot_session = defaultdict(dict) chat_bot_session = defaultdict(dict)
chat_bot_lock = threading.Lock() chat_bot_lock = threading.Lock()
chat_bot_help = "使用 ChatGPT 聊天\n\n" \ chat_bot_help = (
"参数:\n\n- 无参数:进入聊天模式\n" \ "使用 ChatGPT 聊天\n\n"
"- reset重置聊天状态\n" \ "参数:\n\n- 无参数:进入聊天模式\n"
"- set <session_token>:设置 ChatGPT 会话令牌,获取令牌: https://t.me/PagerMaid_Modify/212 \n" \ "- reset重置聊天状态\n"
"- set <session_token>:设置 ChatGPT 会话令牌,获取令牌: https://t.me/PagerMaid_Modify/212 \n"
"- del删除 ChatGPT 会话令牌" "- del删除 ChatGPT 会话令牌"
)
@scheduler.scheduled_job("interval", minutes=30) @scheduler.scheduled_job("interval", minutes=30)
@ -105,7 +107,9 @@ async def chat_bot_func(message: Message):
return await message.edit("请先通过参数 `set [session_token]` 设置 OpenAI API Token。") return await message.edit("请先通过参数 `set [session_token]` 设置 OpenAI API Token。")
with chat_bot_lock: with chat_bot_lock:
try: try:
msg = await chat_bot(**chat_bot_session[from_id]).get_chat_response(message.arguments) msg = await chat_bot(**chat_bot_session[from_id]).get_chat_response(
message.arguments
)
except Exception as e: except Exception as e:
msg = f"可能是 Session Token 过期了,请重新设置。\n{str(e)}" msg = f"可能是 Session Token 过期了,请重新设置。\n{str(e)}"
if not msg: if not msg:

View File

@ -4,7 +4,13 @@ from random import uniform
from pyrogram.enums import ChatMemberStatus from pyrogram.enums import ChatMemberStatus
from pyrogram import filters from pyrogram import filters
from pyrogram.errors import ChatAdminRequired, FloodWait, UserAdminInvalid, PeerIdInvalid, BadRequest from pyrogram.errors import (
ChatAdminRequired,
FloodWait,
UserAdminInvalid,
PeerIdInvalid,
BadRequest,
)
from datetime import datetime, timedelta from datetime import datetime, timedelta
@ -31,32 +37,40 @@ async def kick_chat_member(cid, uid, only_search: bool = False):
return return
try: try:
with contextlib.suppress(UserAdminInvalid, PeerIdInvalid, BadRequest): with contextlib.suppress(UserAdminInvalid, PeerIdInvalid, BadRequest):
await bot.ban_chat_member( await bot.ban_chat_member(cid, uid, datetime.now() + timedelta(minutes=5))
cid,
uid,
datetime.now() + timedelta(minutes=5))
except FloodWait as e: except FloodWait as e:
await sleep(e.value + uniform(0.5, 1.0)) await sleep(e.value + uniform(0.5, 1.0))
await kick_chat_member(cid, uid, only_search) await kick_chat_member(cid, uid, only_search)
async def process_clean_member(message: Message, mode: str, day: int, only_search: bool = False): async def process_clean_member(
message: Message, mode: str, day: int, only_search: bool = False
):
member_count = 0 member_count = 0
try: try:
async for member in bot.get_chat_members(message.chat.id): async for member in bot.get_chat_members(message.chat.id):
if mode == "1" and member.user.last_online_date and \ if (
member.user.last_online_date < datetime.now() - timedelta(days=day): mode == "1"
and member.user.last_online_date
and member.user.last_online_date < datetime.now() - timedelta(days=day)
):
member_count += 1 member_count += 1
await kick_chat_member(message.chat.id, member.user.id, only_search) await kick_chat_member(message.chat.id, member.user.id, only_search)
if mode == "2": if mode == "2":
now = datetime.now() - timedelta(days=day) now = datetime.now() - timedelta(days=day)
async for message in bot.search_messages(message.chat.id, limit=1, from_user=member.user.id): async for message in bot.search_messages(
message.chat.id, limit=1, from_user=member.user.id
):
if message.date < now: if message.date < now:
member_count += 1 member_count += 1
await kick_chat_member(message.chat.id, member.user.id, only_search) await kick_chat_member(
message.chat.id, member.user.id, only_search
)
elif mode == "3": elif mode == "3":
try: try:
count = await bot.search_messages_count(message.chat.id, from_user=member.user.id) count = await bot.search_messages_count(
message.chat.id, from_user=member.user.id
)
except PeerIdInvalid: except PeerIdInvalid:
continue continue
if count < day: if count < day:
@ -69,32 +83,35 @@ async def process_clean_member(message: Message, mode: str, day: int, only_searc
member_count += 1 member_count += 1
await kick_chat_member(message.chat.id, member.user.id, only_search) await kick_chat_member(message.chat.id, member.user.id, only_search)
if not only_search: if not only_search:
await message.edit(f'成功清理了 `{member_count}` 人。') await message.edit(f"成功清理了 `{member_count}` 人。")
else: else:
await message.edit(f'查找到了 `{member_count}` 人。') await message.edit(f"查找到了 `{member_count}` 人。")
except ChatAdminRequired: except ChatAdminRequired:
await message.edit("你好像并不拥有封禁用户权限。") await message.edit("你好像并不拥有封禁用户权限。")
except FloodWait: except FloodWait:
return await message.edit('处理失败,您已受到 TG 服务器限制。') return await message.edit("处理失败,您已受到 TG 服务器限制。")
@listener(command="clean_member", @listener(
need_admin=True, command="clean_member", need_admin=True, groups_only=True, description="多种方式清理群成员"
groups_only=True, )
description="多种方式清理群成员")
async def clean_member(client: Client, message: Message): async def clean_member(client: Client, message: Message):
if not await check_self_and_from(message): if not await check_self_and_from(message):
return await message.edit("您不是群管理员,无法使用此命令") return await message.edit("您不是群管理员,无法使用此命令")
uid = message.from_user.id uid = message.from_user.id
mode, day = "0", 0 mode, day = "0", 0
reply = await message.edit("请选择清理模式:\n\n" reply = await message.edit(
"请选择清理模式:\n\n"
"1. 按未上线时间清理\n" "1. 按未上线时间清理\n"
"2. 按未发言时间清理(大群慎用)\n" "2. 按未发言时间清理(大群慎用)\n"
"3. 按发言数清理\n" "3. 按发言数清理\n"
"4. 清理死号\n" "4. 清理死号\n"
"5. 清理所有人(大群慎用)") "5. 清理所有人(大群慎用)"
)
try: try:
async with client.conversation(message.chat.id, filters=filters.user(uid)) as conv: async with client.conversation(
message.chat.id, filters=filters.user(uid)
) as conv:
await sleep(1) await sleep(1)
res: Message = await conv.get_response() res: Message = await conv.get_response()
mode = res.text mode = res.text

View File

@ -26,7 +26,9 @@ async def clear_blocked_func(client: Client, message: Message):
success += 1 success += 1
except FloodWait as e: except FloodWait as e:
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
await message.edit(f"🧹 Clearing blocked users...\n\nWill run after {e.value} seconds.") await message.edit(
f"🧹 Clearing blocked users...\n\nWill run after {e.value} seconds."
)
await sleep(e.value + 1) await sleep(e.value + 1)
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
await message.edit("🧹 Clearing blocked users...") await message.edit("🧹 Clearing blocked users...")
@ -35,7 +37,9 @@ async def clear_blocked_func(client: Client, message: Message):
except Exception: except Exception:
failed += 1 failed += 1
offset += 100 offset += 100
if (isinstance(blocked, BlockedSlice) and offset > blocked.count) or not isinstance(blocked, BlockedSlice): if (
isinstance(blocked, BlockedSlice) and offset > blocked.count
) or not isinstance(blocked, BlockedSlice):
break break
return success, failed, skipped return success, failed, skipped
@ -49,5 +53,7 @@ async def clear_blocked(client: Client, message: Message):
except Exception as e: except Exception as e:
await message.edit(f"❌ Failed to clear blocked users: {e}") await message.edit(f"❌ Failed to clear blocked users: {e}")
return return
await message.edit(f"🧹 Clear blocked users complete. \n" await message.edit(
f"Success: {success}, Failed: {failed}, Skipped: {skipped}") f"🧹 Clear blocked users complete. \n"
f"Success: {success}, Failed: {failed}, Skipped: {skipped}"
)

View File

@ -11,11 +11,13 @@ from pagermaid.services import bot
async def delete_private_chat(cid: int): async def delete_private_chat(cid: int):
try: try:
await bot.invoke(DeleteHistory( await bot.invoke(
DeleteHistory(
just_clear=False, just_clear=False,
revoke=False, revoke=False,
peer=await bot.resolve_peer(cid), peer=await bot.resolve_peer(cid),
max_id=0, ) max_id=0,
)
) )
except FloodWait as e: except FloodWait as e:
await sleep(e.value) await sleep(e.value)
@ -24,10 +26,12 @@ async def delete_private_chat(cid: int):
pass pass
@listener(command="clear_private_chat", @listener(
command="clear_private_chat",
need_admin=True, need_admin=True,
description="通过指定关键词清除私聊", description="通过指定关键词清除私聊",
parameters="[关键词]") parameters="[关键词]",
)
async def clear_private_chat(message: Message): async def clear_private_chat(message: Message):
"""通过指定关键词清除私聊记录""" """通过指定关键词清除私聊记录"""
if not message.arguments: if not message.arguments:

View File

@ -12,61 +12,54 @@ from pagermaid.listener import listener
from pagermaid.enums import Message, AsyncClient from pagermaid.enums import Message, AsyncClient
codeType = { codeType = {
'py': ['python', 'py'], "py": ["python", "py"],
'cpp': ['cpp', 'cpp'], "cpp": ["cpp", "cpp"],
'java': ['java', 'java'], "java": ["java", "java"],
'php': ['php', 'php'], "php": ["php", "php"],
'js': ['javascript', 'js'], "js": ["javascript", "js"],
'c': ['c', 'c'], "c": ["c", "c"],
'c#': ['csharp', 'cs'], "c#": ["csharp", "cs"],
'go': ['go', 'go'], "go": ["go", "go"],
'asm': ['assembly', 'asm'] "asm": ["assembly", "asm"],
} }
async def run(string: str, client: AsyncClient): async def run(string: str, client: AsyncClient):
string = string.replace('&amp;', '&').replace('&#91;', '[').replace('&#93;', ']') string = string.replace("&amp;", "&").replace("&#91;", "[").replace("&#93;", "]")
try: try:
a = re.findall(r'(py|php|java|cpp|js|c#|c|go|asm)\s?(-i)?\s?(\w*)?(\n|\r)((?:.|\n)+)', string)[0] a = re.findall(
r"(py|php|java|cpp|js|c#|c|go|asm)\s?(-i)?\s?(\w*)?(\n|\r)((?:.|\n)+)",
string,
)[0]
print(a) print(a)
except Exception: except Exception:
return "输入有误汪\n目前仅支持c/cpp/c#/py/php/go/java/js" return "输入有误汪\n目前仅支持c/cpp/c#/py/php/go/java/js"
lang, code_str = a[0], a[4] lang, code_str = a[0], a[4]
if "-i" in string: if "-i" in string:
data_json = { data_json = {
"files": [ "files": [{"name": f"main.{codeType[lang][1]}", "content": code_str}],
{
"name": f"main.{codeType[lang][1]}",
"content": code_str
}
],
"stdin": a[2], "stdin": a[2],
"command": "" "command": "",
} }
else: else:
data_json = { data_json = {
"files": [ "files": [{"name": f"main.{codeType[lang][1]}", "content": code_str}],
{
"name": f"main.{codeType[lang][1]}",
"content": code_str
}
],
"stdin": "", "stdin": "",
"command": "" "command": "",
} }
headers = { headers = {
"Authorization": "Token 0123456-789a-bcde-f012-3456789abcde", "Authorization": "Token 0123456-789a-bcde-f012-3456789abcde",
"content-type": "application/" "content-type": "application/",
} }
res = await client.post( res = await client.post(
url=f'https://glot.io/run/{codeType[lang][0]}?version=latest', url=f"https://glot.io/run/{codeType[lang][0]}?version=latest",
headers=headers, headers=headers,
json=data_json json=data_json,
) )
if res.status_code != 200: if res.status_code != 200:
return "请求失败了呐~~~" return "请求失败了呐~~~"
if res.json()['stdout'] == "": if res.json()["stdout"] == "":
return res.json()['stderr'].strip() return res.json()["stderr"].strip()
return f"<b>>>></b> <code>{code_str}</code> \n{res.json()['stdout']}" return f"<b>>>></b> <code>{code_str}</code> \n{res.json()['stdout']}"

View File

@ -1,6 +1,10 @@
from pyrogram.raw.functions.messages import GetStickerSet from pyrogram.raw.functions.messages import GetStickerSet
from pyrogram.raw.functions.stickers import CreateStickerSet from pyrogram.raw.functions.stickers import CreateStickerSet
from pyrogram.raw.types import InputStickerSetShortName, InputStickerSetItem, InputDocument from pyrogram.raw.types import (
InputStickerSetShortName,
InputStickerSetItem,
InputDocument,
)
from pyrogram.raw.types.messages import StickerSet from pyrogram.raw.types.messages import StickerSet
from pagermaid.listener import listener from pagermaid.listener import listener
@ -14,22 +18,21 @@ class NoStickerSetNameError(Exception):
""" """
def __init__(self, string: str = "贴纸包不存在"): def __init__(self, string: str = "贴纸包不存在"):
super().__init__( super().__init__(string)
string
)
async def get_pack(name: str): async def get_pack(name: str):
try: try:
return await bot.invoke(GetStickerSet( return await bot.invoke(
stickerset=InputStickerSetShortName(short_name=name), GetStickerSet(stickerset=InputStickerSetShortName(short_name=name), hash=0)
hash=0 )
))
except Exception as e: # noqa except Exception as e: # noqa
raise NoStickerSetNameError() from e raise NoStickerSetNameError() from e
async def create_sticker_set(sticker_set: str, title: str, is_animated: bool, is_video: bool, stickers): async def create_sticker_set(
sticker_set: str, title: str, is_animated: bool, is_video: bool, stickers
):
try: try:
await bot.invoke( await bot.invoke(
CreateStickerSet( CreateStickerSet(
@ -61,8 +64,9 @@ async def process_old_sticker_set(sticker_set: str):
access_hash=i.access_hash, access_hash=i.access_hash,
file_reference=i.file_reference, file_reference=i.file_reference,
), ),
emoji=hash_map.get(i.id, "👀") emoji=hash_map.get(i.id, "👀"),
) for i in pack.documents )
for i in pack.documents
] ]
return stickers, is_animated, is_video return stickers, is_animated, is_video
@ -73,12 +77,17 @@ async def process_old_sticker_set(sticker_set: str):
description="复制某个贴纸包", description="复制某个贴纸包",
) )
async def copy_sticker_set(message: Message): async def copy_sticker_set(message: Message):
if (not message.reply_to_message) or (not message.reply_to_message.sticker) or ( if (
not message.reply_to_message.sticker.set_name): (not message.reply_to_message)
or (not message.reply_to_message.sticker)
or (not message.reply_to_message.sticker.set_name)
):
return await message.edit("请先回复一张需要复制的贴纸包的贴纸") return await message.edit("请先回复一张需要复制的贴纸包的贴纸")
sticker_set = message.reply_to_message.sticker.set_name sticker_set = message.reply_to_message.sticker.set_name
if len(message.parameter) < 2: if len(message.parameter) < 2:
return await message.edit("请指定贴纸包链接和贴纸包名称,例如 <code>xxxx_sticker xxxx 的贴纸包</code>") return await message.edit(
"请指定贴纸包链接和贴纸包名称,例如 <code>xxxx_sticker xxxx 的贴纸包</code>"
)
set_name = message.parameter[0] set_name = message.parameter[0]
name = " ".join(message.parameter[1:]) name = " ".join(message.parameter[1:])
try: try:
@ -86,4 +95,6 @@ async def copy_sticker_set(message: Message):
await create_sticker_set(set_name, name, is_animated, is_video, stickers) await create_sticker_set(set_name, name, is_animated, is_video, stickers)
except Exception as e: except Exception as e:
return await message.edit(f"复制贴纸包失败:{e}") return await message.edit(f"复制贴纸包失败:{e}")
await message.edit(f"复制贴纸包成功 <a href=\"https://t.me/addstickers/{set_name}\">{name}</a>") await message.edit(
f'复制贴纸包成功 <a href="https://t.me/addstickers/{set_name}">{name}</a>'
)

View File

@ -13,11 +13,11 @@ POLICY_ID = {}
class Area: class Area:
def __init__(self, data): def __init__(self, data):
self.name = data['name'] self.name = data["name"]
self.today = data['today'] self.today = data["today"]
self.total = data['total'] self.total = data["total"]
self.grade = data['total'].get('grade', '风险未确认') self.grade = data["total"].get("grade", "风险未确认")
self.children = data.get('children', None) self.children = data.get("children", None)
@property @property
async def policy(self): async def policy(self):
@ -25,9 +25,11 @@ class Area:
@property @property
def main_info(self): def main_info(self):
return f"**{self.name} 新冠肺炎疫情情况** ({self.grade})\n\n" \ return (
f"`😔新增确诊:{self.today['confirm']}`\n" \ f"**{self.name} 新冠肺炎疫情情况** ({self.grade})\n\n"
f"`😔新增确诊:{self.today['confirm']}`\n"
f"`☢️现存确诊:{self.total['nowConfirm']}`" f"`☢️现存确诊:{self.total['nowConfirm']}`"
)
class AreaList(Dict): class AreaList(Dict):
@ -38,46 +40,44 @@ class AreaList(Dict):
class NewsData: class NewsData:
def __init__(self): def __init__(self):
self.data = {} self.data = {}
self.time = '' self.time = ""
async def update_data(self): async def update_data(self):
url = "https://api.inews.qq.com/newsqa/v1/query/inner/publish/modules/list?modules=statisGradeCityDetail,diseaseh5Shelf" url = "https://api.inews.qq.com/newsqa/v1/query/inner/publish/modules/list?modules=statisGradeCityDetail,diseaseh5Shelf"
res = await client.get(url) res = await client.get(url)
if res.status_code != 200: if res.status_code != 200:
return return
data = res.json()['data']['diseaseh5Shelf'] data = res.json()["data"]["diseaseh5Shelf"]
if data['lastUpdateTime'] != self.time: if data["lastUpdateTime"] != self.time:
self.time = data["lastUpdateTime"]
self.time = data['lastUpdateTime']
self.data = AreaList() self.data = AreaList()
def get_data(data_): def get_data(data_):
if isinstance(data_, list): if isinstance(data_, list):
for i in data_: for i in data_:
get_data(i) get_data(i)
if isinstance(data_, dict): if isinstance(data_, dict):
if area_ := data_.get('children'): if area_ := data_.get("children"):
get_data(area_) get_data(area_)
self.data.add(Area(data_)) # noqa self.data.add(Area(data_)) # noqa
get_data(data['areaTree'][0]) get_data(data["areaTree"][0])
return return
async def set_pid(): async def set_pid():
url_city_list = 'https://r.inews.qq.com/api/trackmap/citylist?' url_city_list = "https://r.inews.qq.com/api/trackmap/citylist?"
resp = await client.get(url_city_list) resp = await client.get(url_city_list)
res = resp.json() res = resp.json()
for province in res['result']: for province in res["result"]:
if cities := province.get('list'): if cities := province.get("list"):
for city in cities: for city in cities:
cid = city['id'] cid = city["id"]
name = city['name'] name = city["name"]
POLICY_ID[name] = cid POLICY_ID[name] = cid
@ -85,10 +85,10 @@ async def get_policy(uid):
url_get_policy = f"https://r.inews.qq.com/api/trackmap/citypolicy?&city_id={uid}" url_get_policy = f"https://r.inews.qq.com/api/trackmap/citypolicy?&city_id={uid}"
resp = await client.get(url_get_policy) resp = await client.get(url_get_policy)
res_ = resp.json() res_ = resp.json()
if res_['message'] != 'success': if res_["message"] != "success":
return "数据获取失败!" return "数据获取失败!"
try: try:
data = res_['result']['data'][0] data = res_["result"]["data"][0]
except IndexError: except IndexError:
return "暂无政策信息" return "暂无政策信息"
return f"出行({data['leave_policy_date']})\n{data['leave_policy']}\n\ return f"出行({data['leave_policy_date']})\n{data['leave_policy']}\n\
@ -99,9 +99,7 @@ async def get_policy(uid):
NewsBot = NewsData() NewsBot = NewsData()
@listener(command="covid", @listener(command="covid", description="获取新冠疫情信息。", parameters="[地区]")
description="获取新冠疫情信息。",
parameters="[地区]")
async def covid_info(message: Message): async def covid_info(message: Message):
global POLICY_ID, NewsBot global POLICY_ID, NewsBot
if not POLICY_ID: if not POLICY_ID:

View File

@ -160,11 +160,10 @@ crazy4_data = [
"我在研究mond理论突然一个电话让我措手不及女友认为我天天研究虚无缥缈的东西跟我提出了分手。一百年前提出了暗物质现在已经用修正牛顿引力理论可以很大程度上认为暗物质不存在。但是这又有什么用呢一百年足以让人们对暗物质根深蒂固即使它极大可能并不存在。今天星期四的晚上一个伤心人思考着如何证明不存在的东西不存在用这些来告诉她自己不是在研究虚无缥缈的东西怎么样才能发现点新的东西没错就是疯狂星期四怎么可能有这么大魅力去让大家去编段子一定是营销手段v我50我亲自去看看它是不是营销手段。", "我在研究mond理论突然一个电话让我措手不及女友认为我天天研究虚无缥缈的东西跟我提出了分手。一百年前提出了暗物质现在已经用修正牛顿引力理论可以很大程度上认为暗物质不存在。但是这又有什么用呢一百年足以让人们对暗物质根深蒂固即使它极大可能并不存在。今天星期四的晚上一个伤心人思考着如何证明不存在的东西不存在用这些来告诉她自己不是在研究虚无缥缈的东西怎么样才能发现点新的东西没错就是疯狂星期四怎么可能有这么大魅力去让大家去编段子一定是营销手段v我50我亲自去看看它是不是营销手段。",
"其实,我对你们是有一些失望的。当初给你们进这个群,是高于你面试时的水平的。我是希望进来后,你能够拼一把,快速成长起来的。我们这个群,不是把事情做好就可以的。你需要有体系化思考的能力。你做的事情,他的价值点在哪里?你是否作出了壁垒,形成了核心竞争力?你做的事情,和其他群的差异化在哪里?你的事情,是否沉淀了一套可复用的物理资料和方法论?为什么是你来做,其他人不能做吗?你需要有自己的判断力,而不是我说什么你就做什么。后续,把你的思考沉淀到日报周报月报里,我希望看到你的思考,而不仅仅是进度。另外,提醒一下,你的产出,和同层级比,是有些单薄的,马上要到年底了,加把劲儿。你看咱们群的那个谁, 人家去年晋升之前,可以一整年都在项目室打地铺的。成长,一定是伴随着痛苦的,当你最痛苦的时候其实才是你成长最快的时候。加油!但是今天疯狂星期四 香辣翅尖9.9十五根+鸡翅十块39.9+葡式蛋挞29.9八个 ,你还有机会挽救。", "其实,我对你们是有一些失望的。当初给你们进这个群,是高于你面试时的水平的。我是希望进来后,你能够拼一把,快速成长起来的。我们这个群,不是把事情做好就可以的。你需要有体系化思考的能力。你做的事情,他的价值点在哪里?你是否作出了壁垒,形成了核心竞争力?你做的事情,和其他群的差异化在哪里?你的事情,是否沉淀了一套可复用的物理资料和方法论?为什么是你来做,其他人不能做吗?你需要有自己的判断力,而不是我说什么你就做什么。后续,把你的思考沉淀到日报周报月报里,我希望看到你的思考,而不仅仅是进度。另外,提醒一下,你的产出,和同层级比,是有些单薄的,马上要到年底了,加把劲儿。你看咱们群的那个谁, 人家去年晋升之前,可以一整年都在项目室打地铺的。成长,一定是伴随着痛苦的,当你最痛苦的时候其实才是你成长最快的时候。加油!但是今天疯狂星期四 香辣翅尖9.9十五根+鸡翅十块39.9+葡式蛋挞29.9八个 ,你还有机会挽救。",
"xdm 破防了!!!\n我的青梅竹马是个蛮横无理的女生,成绩不太好,天天吵着我给她作业抄,上学放学必须等她。\n到高一,她交了个男朋友,就没再烦我了。\n高三上学期,她妈妈一直喊我照顾点她,我就劝她分了,先高考,以后再耍男朋友。\n本来我以为她会当我放屁。但她真的一点不拖泥带水,秒分。\n高三下学期,我们俩个,基本空暇时间都在一起学习。\n她常常问我,想去哪里,说她也想去。我就笑她做梦。\n高考成绩出来,我去了理想的学校。她选择复读。\n大一期间,我们两个联系渐渐淡化。\n我也没多在意,毕竟我有女朋友了。\n大二,接新生的时候,她就那么直直的出现在我眼前,戏谑地笑着说,看我是不是来了。\n我有些欣慰,这傻丫头终于变的没那么傻了。\n我领她去了宿舍。在楼下,我遇到了我女朋友,便给她介绍。\n青梅只是有气无力地一个劲夸我女友。\n我觉得她是在嫉妒我大学交了这么个女友,便安慰她说,大学帅哥多,你也会有一段新的爱恋的。\n她看了看我,没在说什么。\n我觉得有些尴尬,便帮她搬了东西上去,就走了。\n因为是同乡,她大一国庆节和我一起回的家。\n车上她问我,怎么和我女友认识的,我大概讲了讲。\n听完,她好像睡着了,头侧在我的肩膀,我也渐渐睡意上来了,便躺在椅子上准备睡觉,半睡半醒中感觉嘴唇被什么吸着。\n吓得我睁眼,却是青梅哭着在吻我。\n我连忙把她推开小段距离,问她这是在干嘛!\n她却低着头一言不发。尴尬持续着,直到车到了休息站,我准备下车呼吸空气冷静下,她却一把拉住我的手。\n她不再沉默抬起充满泪痕的脸面对着我,用全车人都听得见的声音喊着:今天疯狂星期四!", "xdm 破防了!!!\n我的青梅竹马是个蛮横无理的女生,成绩不太好,天天吵着我给她作业抄,上学放学必须等她。\n到高一,她交了个男朋友,就没再烦我了。\n高三上学期,她妈妈一直喊我照顾点她,我就劝她分了,先高考,以后再耍男朋友。\n本来我以为她会当我放屁。但她真的一点不拖泥带水,秒分。\n高三下学期,我们俩个,基本空暇时间都在一起学习。\n她常常问我,想去哪里,说她也想去。我就笑她做梦。\n高考成绩出来,我去了理想的学校。她选择复读。\n大一期间,我们两个联系渐渐淡化。\n我也没多在意,毕竟我有女朋友了。\n大二,接新生的时候,她就那么直直的出现在我眼前,戏谑地笑着说,看我是不是来了。\n我有些欣慰,这傻丫头终于变的没那么傻了。\n我领她去了宿舍。在楼下,我遇到了我女朋友,便给她介绍。\n青梅只是有气无力地一个劲夸我女友。\n我觉得她是在嫉妒我大学交了这么个女友,便安慰她说,大学帅哥多,你也会有一段新的爱恋的。\n她看了看我,没在说什么。\n我觉得有些尴尬,便帮她搬了东西上去,就走了。\n因为是同乡,她大一国庆节和我一起回的家。\n车上她问我,怎么和我女友认识的,我大概讲了讲。\n听完,她好像睡着了,头侧在我的肩膀,我也渐渐睡意上来了,便躺在椅子上准备睡觉,半睡半醒中感觉嘴唇被什么吸着。\n吓得我睁眼,却是青梅哭着在吻我。\n我连忙把她推开小段距离,问她这是在干嘛!\n她却低着头一言不发。尴尬持续着,直到车到了休息站,我准备下车呼吸空气冷静下,她却一把拉住我的手。\n她不再沉默抬起充满泪痕的脸面对着我,用全车人都听得见的声音喊着:今天疯狂星期四!",
"混一天和努力一天看不出任何差别\n三天看不到任何变化\n七天也看不到任何距离\n但是一个月后会看到话题不同\n三个月后会看到气场不同\n你继续堕落下去的话\n你的天赋就会被全部收走\n你身边比你差的人\n也会努力一个个超越你\n你继续差的话没人会等你\n所以 请不要在该吃苦的年纪选择安逸\n走自己的路为自己的梦想去奋斗\n即使有人亏待你 我不会亏待你\n今天肯德基疯狂星期四V我99带你吃两份" "混一天和努力一天看不出任何差别\n三天看不到任何变化\n七天也看不到任何距离\n但是一个月后会看到话题不同\n三个月后会看到气场不同\n你继续堕落下去的话\n你的天赋就会被全部收走\n你身边比你差的人\n也会努力一个个超越你\n你继续差的话没人会等你\n所以 请不要在该吃苦的年纪选择安逸\n走自己的路为自己的梦想去奋斗\n即使有人亏待你 我不会亏待你\n今天肯德基疯狂星期四V我99带你吃两份",
] ]
@listener(command="crazy4", @listener(command="crazy4", description="天天疯狂随机输出KFC疯狂星期四文案。")
description="天天疯狂随机输出KFC疯狂星期四文案。")
async def crazy4(message: Message): async def crazy4(message: Message):
await message.edit(choice(crazy4_data)) await message.edit(choice(crazy4_data))

View File

@ -7,15 +7,19 @@ from pagermaid.scheduler import add_delete_message_job
from pagermaid.utils import alias_command from pagermaid.utils import alias_command
@listener(command="da", @listener(
command="da",
groups_only=True, groups_only=True,
need_admin=True, need_admin=True,
description="删除群内所有消息。(非群组管理员只删除自己的消息)", description="删除群内所有消息。(非群组管理员只删除自己的消息)",
parameters="[true]") parameters="[true]",
)
async def da(bot: Client, message: Message): async def da(bot: Client, message: Message):
if message.arguments != "true": if message.arguments != "true":
return await message.edit(f"[da] 呜呜呜,请执行 `,{alias_command('da')} true` 来删除所有消息。") return await message.edit(
await message.edit('[da] 正在删除所有消息 . . .') f"[da] 呜呜呜,请执行 `,{alias_command('da')} true` 来删除所有消息。"
)
await message.edit("[da] 正在删除所有消息 . . .")
messages = [] messages = []
count = 0 count = 0
async for message in bot.get_chat_history(message.chat.id): async for message in bot.get_chat_history(message.chat.id):

View File

@ -1,23 +1,22 @@
# -*- coding: UTF-8 -*- # -*- coding: UTF-8 -*-
''' """
@File main.py @File main.py
@Author 汐洛 @guimc233 @Author 汐洛 @guimc233
@Date 2022/6/23 2:49 @Date 2022/6/23 2:49
''' """
from pyrogram import Client from pyrogram import Client
from pagermaid.listener import listener from pagermaid.listener import listener
from pagermaid.utils import Message from pagermaid.utils import Message
from pyrogram.enums import ParseMode from pyrogram.enums import ParseMode
@listener(command="dc",
description="查看本群dc分布, 查看你回复的人在哪个dc") @listener(command="dc", description="查看本群dc分布, 查看你回复的人在哪个dc")
async def dc(bot: Client, context: Message): async def dc(bot: Client, context: Message):
context = await context.edit("Please wait...") context = await context.edit("Please wait...")
if context.reply_to_message: if context.reply_to_message:
user = ( user = (
context.reply_to_message.from_user context.reply_to_message.from_user or context.reply_to_message.sender_chat
or context.reply_to_message.sender_chat
) )
if not user: if not user:
return await context.edit("出错啦!") return await context.edit("出错啦!")
@ -33,7 +32,9 @@ async def dc(bot: Client, context: Message):
return await context.edit("无法查询! 您是否设置了头像呢?我是否可以看到你的头像呢?") return await context.edit("无法查询! 您是否设置了头像呢?我是否可以看到你的头像呢?")
count = await bot.get_chat_members_count(context.chat.id) count = await bot.get_chat_members_count(context.chat.id)
if count >= 10000 and context.arguments != "force": if count >= 10000 and context.arguments != "force":
return await context.edit("太...太多人了... 我会...会...会坏掉的...\n\n如果您执意要运行的的话,您可以使用指令 ,dc force") return await context.edit(
"太...太多人了... 我会...会...会坏掉的...\n\n如果您执意要运行的的话,您可以使用指令 ,dc force"
)
users = bots = deleted = 0 users = bots = deleted = 0
dc_ids = {"1": 0, "2": 0, "3": 0, "4": 0, "5": 0, "failed": 0} dc_ids = {"1": 0, "2": 0, "3": 0, "4": 0, "5": 0, "failed": 0}
async for m in bot.get_chat_members(context.chat.id, limit=9999): async for m in bot.get_chat_members(context.chat.id, limit=9999):
@ -47,7 +48,8 @@ async def dc(bot: Client, context: Message):
bots += 1 bots += 1
else: else:
deleted += 1 deleted += 1
await context.edit(f"""DC: await context.edit(
f"""DC:
> DC1用户: **{dc_ids["1"]}** 分遗产占比: **{round((dc_ids["1"]/users)*100, 2)}%** > DC1用户: **{dc_ids["1"]}** 分遗产占比: **{round((dc_ids["1"]/users)*100, 2)}%**
> DC2用户: **{dc_ids["2"]}** 分遗产占比: **{round((dc_ids["2"]/users)*100, 2)}%** > DC2用户: **{dc_ids["2"]}** 分遗产占比: **{round((dc_ids["2"]/users)*100, 2)}%**
> DC3用户: **{dc_ids["3"]}** 分遗产占比: **{round((dc_ids["3"]/users)*100, 2)}%** > DC3用户: **{dc_ids["3"]}** 分遗产占比: **{round((dc_ids["3"]/users)*100, 2)}%**
@ -56,4 +58,6 @@ async def dc(bot: Client, context: Message):
> 无法获取在哪个DC的用户: **{dc_ids["failed"]}** > 无法获取在哪个DC的用户: **{dc_ids["failed"]}**
> 已自动过滤掉 **{bots}** Bot, **{deleted}** 死号 > 已自动过滤掉 **{bots}** Bot, **{deleted}** 死号
{'***请注意: 由于tg限制 我们只能遍历前10k人 此次获得到的数据并不完整***' if count >= 10000 else ''}""", parse_mode = ParseMode.MARKDOWN) {'***请注意: 由于tg限制 我们只能遍历前10k人 此次获得到的数据并不完整***' if count >= 10000 else ''}""",
parse_mode=ParseMode.MARKDOWN,
)

View File

@ -11,14 +11,14 @@ from PyDictionary import PyDictionary
dictionary_data = PyDictionary() dictionary_data = PyDictionary()
@listener(command="dictionary", @listener(command="dictionary", parameters="[单词]", description="查询英语单词的意思")
parameters="[单词]",
description="查询英语单词的意思")
async def get_word_mean(message: Message): async def get_word_mean(message: Message):
"""Look up a word in the dictionary.""" """Look up a word in the dictionary."""
word = message.arguments word = message.arguments
if not word: if not word:
return await message.edit(f"[dictionary] 使用方法:`,{alias_command('dictionary')} <单词>`") return await message.edit(
f"[dictionary] 使用方法:`,{alias_command('dictionary')} <单词>`"
)
result = dictionary_data.meaning(word) result = dictionary_data.meaning(word)
output = f"<b>Word :</b> <i>{word}</i>\n\n" output = f"<b>Word :</b> <i>{word}</i>\n\n"

View File

@ -9,10 +9,13 @@ from pagermaid.modules.prune import self_prune
from pagermaid.utils import lang from pagermaid.utils import lang
@listener(is_plugin=False, command="dme", @listener(
is_plugin=False,
command="dme",
need_admin=True, need_admin=True,
description=lang('sp_des'), description=lang("sp_des"),
parameters=lang('sp_parameters')) parameters=lang("sp_parameters"),
)
async def dme(bot: Client, message: Message): async def dme(bot: Client, message: Message):
"""Deletes specific amount of messages you sent.""" """Deletes specific amount of messages you sent."""
async with _lock: async with _lock:

View File

@ -40,9 +40,11 @@ async def eat_it(context, user, base, mask, photo, number, layer=0):
photo_size = photo.size photo_size = photo.size
if mask_size[0] < photo_size[0] and mask_size[1] < photo_size[1]: if mask_size[0] < photo_size[0] and mask_size[1] < photo_size[1]:
scale = photo_size[1] / mask_size[1] scale = photo_size[1] / mask_size[1]
photo = photo.resize((int(photo_size[0] / scale), int(photo_size[1] / scale)), Image.LANCZOS) photo = photo.resize(
(int(photo_size[0] / scale), int(photo_size[1] / scale)), Image.LANCZOS
)
photo = photo.crop((0, 0, mask_size[0], mask_size[1])) photo = photo.crop((0, 0, mask_size[0], mask_size[1]))
mask1 = Image.new('RGBA', mask_size) mask1 = Image.new("RGBA", mask_size)
mask1.paste(photo, mask=mask) mask1.paste(photo, mask=mask)
numberPosition = positions[str(number)] numberPosition = positions[str(number)]
isSwap = False isSwap = False
@ -52,7 +54,7 @@ async def eat_it(context, user, base, mask, photo, number, layer=0):
except: except:
pass pass
if isSwap: if isSwap:
photoBg = Image.new('RGBA', base.size) photoBg = Image.new("RGBA", base.size)
photoBg.paste(mask1, (numberPosition[0], numberPosition[1]), mask1) photoBg.paste(mask1, (numberPosition[0], numberPosition[1]), mask1)
photoBg.paste(base, (0, 0), base) photoBg.paste(base, (0, 0), base)
base = photoBg base = photoBg
@ -68,16 +70,22 @@ async def eat_it(context, user, base, mask, photo, number, layer=0):
try: try:
markImg = Image.open(f"plugins{sep}eat{sep}{str(user.id)}.jpg") markImg = Image.open(f"plugins{sep}eat{sep}{str(user.id)}.jpg")
maskImg = Image.open(f"plugins{sep}eat{sep}mask{str(numberPosition[2])}.png").convert("RGBA") maskImg = Image.open(
f"plugins{sep}eat{sep}mask{str(numberPosition[2])}.png"
).convert("RGBA")
except: except:
await context.edit(f"图片模版加载出错请检查并更新配置mask{str(numberPosition[2])}.png") await context.edit(f"图片模版加载出错请检查并更新配置mask{str(numberPosition[2])}.png")
return base return base
base = await eat_it(context, user, base, maskImg, markImg, numberPosition[2], layer + 1) base = await eat_it(
context, user, base, maskImg, markImg, numberPosition[2], layer + 1
)
temp = base.size[0] if base.size[0] > base.size[1] else base.size[1] temp = base.size[0] if base.size[0] > base.size[1] else base.size[1]
if temp != 512: if temp != 512:
scale = 512 / temp scale = 512 / temp
base = base.resize((int(base.size[0] * scale), int(base.size[1] * scale)), Image.LANCZOS) base = base.resize(
(int(base.size[0] * scale), int(base.size[1] * scale)), Image.LANCZOS
)
return base return base
@ -94,7 +102,7 @@ async def updateConfig(context):
async def downloadFileFromUrl(url, filepath): async def downloadFileFromUrl(url, filepath):
try: try:
re = await client.get(url) re = await client.get(url)
with open(filepath, 'wb') as ms: with open(filepath, "wb") as ms:
ms.write(re.content) ms.write(re.content)
except: except:
return -1 return -1
@ -104,7 +112,7 @@ async def downloadFileFromUrl(url, filepath):
async def loadConfigFile(context, forceDownload=False): async def loadConfigFile(context, forceDownload=False):
global positions, notifyStrArr, extensionConfig global positions, notifyStrArr, extensionConfig
try: try:
with open(configFilePath, 'r', encoding='utf8') as cf: with open(configFilePath, "r", encoding="utf8") as cf:
# 读取已下载的配置文件 # 读取已下载的配置文件
remoteConfigJson = json.load(cf) remoteConfigJson = json.load(cf)
# positionsStr = json.dumps(positions) # positionsStr = json.dumps(positions)
@ -160,7 +168,7 @@ def mergeDict(d1, d2):
async def downloadFileByIds(ids, context): async def downloadFileByIds(ids, context):
idsStr = f',{",".join(ids)},' idsStr = f',{",".join(ids)},'
try: try:
with open(configFilePath, 'r', encoding='utf8') as cf: with open(configFilePath, "r", encoding="utf8") as cf:
# 读取已下载的配置文件 # 读取已下载的配置文件
remoteConfigJson = json.load(cf) remoteConfigJson = json.load(cf)
data = json.loads(json.dumps(remoteConfigJson["needDownloadFileList"])) data = json.loads(json.dumps(remoteConfigJson["needDownloadFileList"]))
@ -171,8 +179,12 @@ async def downloadFileByIds(ids, context):
try: try:
fsplit = file_url.split("/") fsplit = file_url.split("/")
fileFullName = fsplit[len(fsplit) - 1] fileFullName = fsplit[len(fsplit) - 1]
fileName = fileFullName.split(".")[0].replace("eat", "").replace("mask", "") fileName = (
if f',{fileName},' in idsStr: fileFullName.split(".")[0]
.replace("eat", "")
.replace("mask", "")
)
if f",{fileName}," in idsStr:
filePath = f"plugins{sep}eat{sep}{fileFullName}" filePath = f"plugins{sep}eat{sep}{fileFullName}"
if (await downloadFileFromUrl(file_url, filePath)) == 0: if (await downloadFileFromUrl(file_url, filePath)) == 0:
sucSet.add(fileName) sucSet.add(fileName)
@ -191,14 +203,18 @@ async def downloadFileByIds(ids, context):
await context.edit("更新下载模版图片失败,请确认配置文件是否正确") await context.edit("更新下载模版图片失败,请确认配置文件是否正确")
@listener(is_plugin=True, outgoing=True, command="eat", @listener(
is_plugin=True,
outgoing=True,
command="eat",
description="生成一张 吃头像 图片\n" description="生成一张 吃头像 图片\n"
"可选:当第二个参数是数字时,读取预存的配置;\n\n" "可选:当第二个参数是数字时,读取预存的配置;\n\n"
"当第二个参数是.开头时头像旋转180°并且判断r后面是数字则读取对应的配置生成\n\n" "当第二个参数是.开头时头像旋转180°并且判断r后面是数字则读取对应的配置生成\n\n"
"当第二个参数是/开头时,在/后面加url则从url下载配置文件保存到本地如果就一个/,则直接更新配置文件,删除则是/delete或者/后面加模版id可以手动更新指定模版配置\n\n" "当第二个参数是/开头时,在/后面加url则从url下载配置文件保存到本地如果就一个/,则直接更新配置文件,删除则是/delete或者/后面加模版id可以手动更新指定模版配置\n\n"
"当第二个参数是-开头时,在-后面加上模版id即可设置默认模版-eat直接使用该模版删除默认模版是-eat -\n\n" "当第二个参数是-开头时,在-后面加上模版id即可设置默认模版-eat直接使用该模版删除默认模版是-eat -\n\n"
"当第二个参数是!或者!开头时,列出当前可用模版", "当第二个参数是!或者!开头时,列出当前可用模版",
parameters="[username/uid] [随意内容]") parameters="[username/uid] [随意内容]",
)
async def eat(client_: Client, context: Message): async def eat(client_: Client, context: Message):
if len(context.parameter) > 2: if len(context.parameter) > 2:
await context.edit("出错了呜呜呜 ~ 无效的参数。") await context.edit("出错了呜呜呜 ~ 无效的参数。")
@ -250,17 +266,24 @@ async def eat(client_: Client, context: Message):
except IndexError: except IndexError:
user = await client_.get_chat(user) # noqa user = await client_.get_chat(user) # noqa
except (UsernameNotOccupied, UsernameInvalid): except (UsernameNotOccupied, UsernameInvalid):
return await context.edit(f"{lang('error_prefix')}{lang('profile_e_nou')}") return await context.edit(
f"{lang('error_prefix')}{lang('profile_e_nou')}"
)
except OverflowError: except OverflowError:
return await context.edit(f"{lang('error_prefix')}{lang('profile_e_long')}") return await context.edit(
f"{lang('error_prefix')}{lang('profile_e_long')}"
)
except Exception as exception: except Exception as exception:
return await context.edit(f"{lang('error_prefix')}{lang('profile_e_nof')}") return await context.edit(
f"{lang('error_prefix')}{lang('profile_e_nof')}"
)
target_user_id = user.id target_user_id = user.id
if not user.photo: if not user.photo:
return await context.edit("出错了呜呜呜 ~ 此用户无头像。") return await context.edit("出错了呜呜呜 ~ 此用户无头像。")
photo = await client_.download_media( photo = await client_.download_media(
user.photo.big_file_id, user.photo.big_file_id,
f"plugins{sep}eat{sep}" + str(target_user_id) + ".jpg",) f"plugins{sep}eat{sep}" + str(target_user_id) + ".jpg",
)
reply_to = context.reply_to_message.id if context.reply_to_message else None reply_to = context.reply_to_message.id if context.reply_to_message else None
if exists(f"plugins{sep}eat{sep}" + str(target_user_id) + ".jpg"): if exists(f"plugins{sep}eat{sep}" + str(target_user_id) + ".jpg"):
@ -333,15 +356,23 @@ async def eat(client_: Client, context: Message):
ids = p2.split(splitStr) ids = p2.split(splitStr)
if len(ids) > 0: if len(ids) > 0:
# 下载文件 # 下载文件
configFileRemoteUrl = sqlite.get(configFileRemoteUrlKey, "") configFileRemoteUrl = sqlite.get(
configFileRemoteUrlKey, ""
)
if configFileRemoteUrl: if configFileRemoteUrl:
if (await downloadFileFromUrl(configFileRemoteUrl, configFilePath)) != 0: if (
await downloadFileFromUrl(
configFileRemoteUrl, configFilePath
)
) != 0:
await context.edit(f"下载配置文件异常请确认url是否正确") await context.edit(f"下载配置文件异常请确认url是否正确")
return return
else: else:
# 下载成功,更新对应配置 # 下载成功,更新对应配置
if await loadConfigFile(context) != 0: if await loadConfigFile(context) != 0:
await context.edit(f"加载配置文件异常,请确认从远程下载的配置文件格式是否正确") await context.edit(
f"加载配置文件异常,请确认从远程下载的配置文件格式是否正确"
)
return return
else: else:
await downloadFileByIds(ids, context) await downloadFileByIds(ids, context)
@ -350,7 +381,9 @@ async def eat(client_: Client, context: Message):
else: else:
# 没传url直接更新 # 没传url直接更新
if await updateConfig(context) != 0: if await updateConfig(context) != 0:
await context.edit(f"更新配置文件异常,请确认是否订阅远程配置文件,或从远程下载的配置文件格式是否正确") await context.edit(
f"更新配置文件异常,请确认是否订阅远程配置文件,或从远程下载的配置文件格式是否正确"
)
return return
else: else:
await context.edit(f"从远程更新配置文件成功") await context.edit(f"从远程更新配置文件成功")
@ -379,7 +412,9 @@ async def eat(client_: Client, context: Message):
number = p2 number = p2
elif isinstance(p2, int) and p2 > 0: elif isinstance(p2, int) and p2 > 0:
number = int(p2) number = int(p2)
elif not diu_round and ((isinstance(p1, int) and int(p1) > 0) or isinstance(p1, str)): elif not diu_round and (
(isinstance(p1, int) and int(p1) > 0) or isinstance(p1, str)
):
try: try:
number = int(p1) number = int(p1)
except: except:
@ -412,7 +447,9 @@ async def eat(client_: Client, context: Message):
markImg = Image.open(f"plugins{sep}eat{sep}" + str(target_user_id) + ".jpg") markImg = Image.open(f"plugins{sep}eat{sep}" + str(target_user_id) + ".jpg")
try: try:
eatImg = Image.open(f"plugins{sep}eat{sep}eat" + str(number) + ".png") eatImg = Image.open(f"plugins{sep}eat{sep}eat" + str(number) + ".png")
maskImg = Image.open(f"plugins{sep}eat{sep}mask" + str(number) + ".png").convert("RGBA") maskImg = Image.open(
f"plugins{sep}eat{sep}mask" + str(number) + ".png"
).convert("RGBA")
except: except:
await context.edit(f"图片模版加载出错,请检查并更新配置:{str(number)}") await context.edit(f"图片模版加载出错,请检查并更新配置:{str(number)}")
return return
@ -423,7 +460,9 @@ async def eat(client_: Client, context: Message):
number = str(number) number = str(number)
except: except:
pass pass
result = await eat_it(context, context.from_user, eatImg, maskImg, markImg, number) result = await eat_it(
context, context.from_user, eatImg, maskImg, markImg, number
)
result.save(f"plugins{sep}eat{sep}eat.webp") result.save(f"plugins{sep}eat{sep}eat.webp")
safe_remove(f"plugins{sep}eat{sep}" + str(target_user_id) + ".jpg") safe_remove(f"plugins{sep}eat{sep}" + str(target_user_id) + ".jpg")
safe_remove(f"plugins{sep}eat{sep}" + str(target_user_id) + ".png") safe_remove(f"plugins{sep}eat{sep}" + str(target_user_id) + ".png")
@ -436,7 +475,7 @@ async def eat(client_: Client, context: Message):
await client_.send_document( await client_.send_document(
context.chat.id, context.chat.id,
f"plugins{sep}eat{sep}eat.webp", f"plugins{sep}eat{sep}eat.webp",
reply_to_message_id=reply_to reply_to_message_id=reply_to,
) )
await final_msg.safe_delete() await final_msg.safe_delete()
except TypeError: except TypeError:
@ -448,7 +487,7 @@ async def eat(client_: Client, context: Message):
await client_.send_document( await client_.send_document(
context.chat.id, context.chat.id,
f"plugins{sep}eat{sep}eat.webp", f"plugins{sep}eat{sep}eat.webp",
reply_to_message_id=context.reply_to_top_message_id reply_to_message_id=context.reply_to_top_message_id,
) )
await final_msg.safe_delete() await final_msg.safe_delete()
except TypeError: except TypeError:

View File

@ -15,8 +15,7 @@ async def get_epic_games():
"Content-Type": "application/json; charset=utf-8", "Content-Type": "application/json; charset=utf-8",
} }
data = { data = {
"query": "query": "query searchStoreQuery($allowCountries: String, $category: String, $count: Int, $country: String!, "
"query searchStoreQuery($allowCountries: String, $category: String, $count: Int, $country: String!, "
"$keywords: String, $locale: String, $namespace: String, $sortBy: String, $sortDir: String, $start: Int, " "$keywords: String, $locale: String, $namespace: String, $sortBy: String, $sortDir: String, $start: Int, "
"$tag: String, $withPrice: Boolean = false, $withPromotions: Boolean = false) {\n Catalog {\n " "$tag: String, $withPrice: Boolean = false, $withPromotions: Boolean = false) {\n Catalog {\n "
"searchStore(allowCountries: $allowCountries, category: $category, count: $count, country: $country, " "searchStore(allowCountries: $allowCountries, category: $category, count: $count, country: $country, "
@ -41,8 +40,8 @@ async def get_epic_games():
"sortBy": "effectiveDate", "sortBy": "effectiveDate",
"sortDir": "asc", "sortDir": "asc",
"withPrice": True, "withPrice": True,
"withPromotions": True "withPromotions": True,
} },
} }
res = await client.post(epic_url, headers=headers, json=data, timeout=10.0) res = await client.post(epic_url, headers=headers, json=data, timeout=10.0)
res_json = res.json() res_json = res.json()
@ -57,8 +56,14 @@ def parse_game(game):
upcoming_promotions = game["promotions"]["upcomingPromotionalOffers"] upcoming_promotions = game["promotions"]["upcomingPromotionalOffers"]
if not game_promotions and upcoming_promotions: if not game_promotions and upcoming_promotions:
raise FileNotFoundError # 促销即将上线,跳过 raise FileNotFoundError # 促销即将上线,跳过
if game_promotions[0]['promotionalOffers'][0]['discountSetting']['discountType'] == 'PERCENTAGE' and \ if (
game_promotions[0]['promotionalOffers'][0]['discountSetting']['discountPercentage'] != 0: game_promotions[0]["promotionalOffers"][0]["discountSetting"]["discountType"]
== "PERCENTAGE"
and game_promotions[0]["promotionalOffers"][0]["discountSetting"][
"discountPercentage"
]
!= 0
):
raise FileNotFoundError # 不免费,跳过 raise FileNotFoundError # 不免费,跳过
game_thumbnail, game_dev, game_pub = None, None, None game_thumbnail, game_dev, game_pub = None, None, None
for image in game["keyImages"]: for image in game["keyImages"]:
@ -67,26 +72,40 @@ def parse_game(game):
game_dev = pair["value"] if pair["key"] == "developerName" else game_corp game_dev = pair["value"] if pair["key"] == "developerName" else game_corp
game_pub = pair["value"] if pair["key"] == "publisherName" else game_corp game_pub = pair["value"] if pair["key"] == "publisherName" else game_corp
game_desp = game["description"] game_desp = game["description"]
end_date_iso = game["promotions"]["promotionalOffers"][0]["promotionalOffers"][0]["endDate"][:-1] end_date_iso = game["promotions"]["promotionalOffers"][0]["promotionalOffers"][0][
end_date = datetime.fromisoformat(end_date_iso).replace( "endDate"
tzinfo=timezone('UTC')).astimezone(timezone('Asia/Chongqing')).strftime("%Y-%m-%d %H:%M:%S") ][:-1]
end_date = (
datetime.fromisoformat(end_date_iso)
.replace(tzinfo=timezone("UTC"))
.astimezone(timezone("Asia/Chongqing"))
.strftime("%Y-%m-%d %H:%M:%S")
)
# API 返回不包含游戏商店 URL此处自行拼接可能出现少数游戏 404 # API 返回不包含游戏商店 URL此处自行拼接可能出现少数游戏 404
game_url = f"https://www.epicgames.com/store/zh-CN/p/{game['productSlug'].replace('/home', '')}" if \ game_url = (
game['productSlug'] else "暂无链接" f"https://www.epicgames.com/store/zh-CN/p/{game['productSlug'].replace('/home', '')}"
if game["productSlug"]
else "暂无链接"
)
msg = f"**FREE now :: {game_name} ({game_price})**\n\n{game_desp}\n\n" msg = f"**FREE now :: {game_name} ({game_price})**\n\n{game_desp}\n\n"
msg += f"游戏由 {game_pub} 发售," if game_dev == game_pub else f"游戏由 {game_dev} 开发、{game_pub} 出版," msg += (
f"游戏由 {game_pub} 发售,"
if game_dev == game_pub
else f"游戏由 {game_dev} 开发、{game_pub} 出版,"
)
msg += f"将在 **{end_date}** 结束免费游玩,戳下面的链接领取吧~\n{game_url}" msg += f"将在 **{end_date}** 结束免费游玩,戳下面的链接领取吧~\n{game_url}"
return msg, game_thumbnail return msg, game_thumbnail
@listener(command="epic", @listener(command="epic", description="获取 Epic 喜加一限免")
description="获取 Epic 喜加一限免")
async def epic(message: Message): async def epic(message: Message):
try: try:
games = await get_epic_games() games = await get_epic_games()
except Exception as e: except Exception as e:
return await message.edit(f"请求 Epic Store API 错误:{str(sys.exc_info()[0])}" + "\n" + str(e)) return await message.edit(
f"请求 Epic Store API 错误:{str(sys.exc_info()[0])}" + "\n" + str(e)
)
if not games: if not games:
return await message.edit("Epic 可能又抽风啦,请稍后再试(") return await message.edit("Epic 可能又抽风啦,请稍后再试(")
for game in games: for game in games:
@ -97,10 +116,18 @@ async def epic(message: Message):
with open("epic.jpg", "wb") as code: with open("epic.jpg", "wb") as code:
code.write(r.content) code.write(r.content)
try: try:
await message.reply_photo("epic.jpg", caption=msg, quote=False, await message.reply_photo(
reply_to_message_id=message.reply_to_top_message_id) "epic.jpg",
caption=msg,
quote=False,
reply_to_message_id=message.reply_to_top_message_id,
)
except Exception: except Exception:
await message.reply(msg, quote=False, reply_to_message_id=message.reply_to_top_message_id) await message.reply(
msg,
quote=False,
reply_to_message_id=message.reply_to_top_message_id,
)
safe_remove("epic.jpg") safe_remove("epic.jpg")
else: else:
await message.reply(msg, quote=False) await message.reply(msg, quote=False)
@ -109,5 +136,7 @@ async def epic(message: Message):
except FileNotFoundError: except FileNotFoundError:
continue continue
except Exception as e: except Exception as e:
return await message.edit(f"获取 Epic 信息错误:{str(sys.exc_info()[0])}" + "\n" + str(e)) return await message.edit(
f"获取 Epic 信息错误:{str(sys.exc_info()[0])}" + "\n" + str(e)
)
await message.delete() await message.delete()

View File

@ -23,8 +23,12 @@ everyday_en_cache_time: Optional[date] = None
async def get_everyday_en() -> None: async def get_everyday_en() -> None:
global everyday_en_data_cache, everyday_en_cache_time global everyday_en_data_cache, everyday_en_cache_time
if everyday_en_cache_time == date.today() and everyday_en_data_cache and \ if (
isfile(f"data{sep}everyday_en.jpg") and isfile(f"data{sep}everyday_en.mp3"): everyday_en_cache_time == date.today()
and everyday_en_data_cache
and isfile(f"data{sep}everyday_en.jpg")
and isfile(f"data{sep}everyday_en.mp3")
):
return return
resp = await client.get("https://open.iciba.com/dsapi/") resp = await client.get("https://open.iciba.com/dsapi/")
if resp.is_error: if resp.is_error:
@ -51,7 +55,7 @@ async def push_everyday_en(gid: int) -> None:
f"data{sep}everyday_en.jpg", f"data{sep}everyday_en.jpg",
caption=f"{everyday_en_data_cache['dateline']}\n" caption=f"{everyday_en_data_cache['dateline']}\n"
f"{everyday_en_data_cache['content']}\n" f"{everyday_en_data_cache['content']}\n"
f"释义:{everyday_en_data_cache['note']}" f"释义:{everyday_en_data_cache['note']}",
) )
if isfile(f"data{sep}everyday_en.mp3"): if isfile(f"data{sep}everyday_en.mp3"):
await bot.send_voice( await bot.send_voice(
@ -71,9 +75,9 @@ async def everyday_en_subscribe() -> None:
everyday_en_sub.del_id(gid) everyday_en_sub.del_id(gid)
@listener(command="everyday_en", @listener(
parameters="订阅/退订", command="everyday_en", parameters="订阅/退订", description="查看今日每日英语,支持订阅/退订每天上午八点定时发送"
description="查看今日每日英语,支持订阅/退订每天上午八点定时发送") )
async def everyday_en(_: Client, message: Message): async def everyday_en(_: Client, message: Message):
"""每日英语""" """每日英语"""
if not message.arguments: if not message.arguments:
@ -84,17 +88,25 @@ async def everyday_en(_: Client, message: Message):
await message.safe_delete() await message.safe_delete()
await push_everyday_en(message.chat.id) await push_everyday_en(message.chat.id)
elif message.arguments == "订阅": elif message.arguments == "订阅":
if from_self(message) or enforce_permission(from_msg_get_sudo_uid(message), "modules.manage_subs"): if from_self(message) or enforce_permission(
from_msg_get_sudo_uid(message), "modules.manage_subs"
):
if everyday_en_sub.check_id(message.chat.id): if everyday_en_sub.check_id(message.chat.id):
return await edit_delete(message, "❌ 你已经订阅了每日英语", parse_mode=ParseMode.HTML) return await edit_delete(
message, "❌ 你已经订阅了每日英语", parse_mode=ParseMode.HTML
)
everyday_en_sub.add_id(message.chat.id) everyday_en_sub.add_id(message.chat.id)
await message.edit("你已经成功订阅了每日英语") await message.edit("你已经成功订阅了每日英语")
else: else:
await edit_delete(message, "❌ 权限不足,无法订阅每日英语", parse_mode=ParseMode.HTML) await edit_delete(message, "❌ 权限不足,无法订阅每日英语", parse_mode=ParseMode.HTML)
elif message.arguments == "退订": elif message.arguments == "退订":
if from_self(message) or enforce_permission(from_msg_get_sudo_uid(message), "modules.manage_subs"): if from_self(message) or enforce_permission(
from_msg_get_sudo_uid(message), "modules.manage_subs"
):
if not everyday_en_sub.check_id(message.chat.id): if not everyday_en_sub.check_id(message.chat.id):
return await edit_delete(message, "❌ 你还没有订阅每日英语", parse_mode=ParseMode.HTML) return await edit_delete(
message, "❌ 你还没有订阅每日英语", parse_mode=ParseMode.HTML
)
everyday_en_sub.del_id(message.chat.id) everyday_en_sub.del_id(message.chat.id)
await message.edit("你已经成功退订了每日英语") await message.edit("你已经成功退订了每日英语")
else: else:

View File

@ -12,28 +12,12 @@ everyday_greet_data = {
"起床啦起床啦!现在还没起床的都是懒狗!", "起床啦起床啦!现在还没起床的都是懒狗!",
"哦哈哟米娜桑!今日も元気でね!🥳", "哦哈哟米娜桑!今日も元気でね!🥳",
"新的一天又是全气满满哦!", "新的一天又是全气满满哦!",
"一日之计在于晨,懒狗还不起床?" "一日之计在于晨,懒狗还不起床?",
],
"lunch": [
"中午12点啦吃午餐啦",
"恰饭啦恰饭啦!再不去食堂就没吃的啦!",
"中午还不恰点好的?整点碳水大餐嗯造吧!"
],
"snack": [
"下午三点了,饮茶了先!",
"摸鱼时刻,整点恰滴先~",
"做咩啊做,真给老板打工啊!快来摸鱼!"
],
"dinner": [
"下午6点了不会真有人晚上加班恰外卖吧",
"下班咯,这不开造?",
"当务之急是下班!"
],
"midnight": [
"晚上10点啦整个夜宵犒劳自己吧",
"夜宵这不来个外卖?",
"夜宵这不整点好的?"
], ],
"lunch": ["中午12点啦吃午餐啦", "恰饭啦恰饭啦!再不去食堂就没吃的啦!", "中午还不恰点好的?整点碳水大餐嗯造吧!"],
"snack": ["下午三点了,饮茶了先!", "摸鱼时刻,整点恰滴先~", "做咩啊做,真给老板打工啊!快来摸鱼!"],
"dinner": ["下午6点了不会真有人晚上加班恰外卖吧", "下班咯,这不开造?", "当务之急是下班!"],
"midnight": ["晚上10点啦整个夜宵犒劳自己吧", "夜宵这不来个外卖?", "夜宵这不整点好的?"],
} }
@ -71,10 +55,12 @@ async def everyday_greet_midnight() -> None:
await everyday_do_greet("midnight") await everyday_do_greet("midnight")
@listener(command="everyday_greet", @listener(
command="everyday_greet",
parameters="订阅/退订", parameters="订阅/退订",
groups_only=True, groups_only=True,
description="订阅/退订每日问候,仅支持群组") description="订阅/退订每日问候,仅支持群组",
)
async def everyday_greet(message: Message): async def everyday_greet(message: Message):
if not message.arguments: if not message.arguments:
return await message.edit("请输入 `订阅/退订` 参数") return await message.edit("请输入 `订阅/退订` 参数")

View File

@ -56,9 +56,9 @@ class FaDian:
"-我英语不好一次英语课老师问我wife是什么意思我向隔壁的{name}求助,她指了指自己,我愣了许久,轻轻的说:主人", "-我英语不好一次英语课老师问我wife是什么意思我向隔壁的{name}求助,她指了指自己,我愣了许久,轻轻的说:主人",
"-{name}姐姐的声音就像一瓶汽水。”“你指{name}的声音就是天籁之音?”“不,我的意思是,听了姐姐的声音就像夏天里的饮料机," "-{name}姐姐的声音就像一瓶汽水。”“你指{name}的声音就是天籁之音?”“不,我的意思是,听了姐姐的声音就像夏天里的饮料机,"
"脸贴在玻璃上许久才选到心怡的汽水,想把仔仔细细选中的汽水打开时盖子却不小心松掉了。”“然后汽水喷涌而出?”“" "脸贴在玻璃上许久才选到心怡的汽水,想把仔仔细细选中的汽水打开时盖子却不小心松掉了。”“然后汽水喷涌而出?”“"
"然后我的心就扑通扑通的涌了出去,我想把我的心送给她。”" "然后我的心就扑通扑通的涌了出去,我想把我的心送给她。”",
], ],
"date": 0 "date": 0,
} }
self.api = f"{Config.GIT_SOURCE}fadian/fadian.json" self.api = f"{Config.GIT_SOURCE}fadian/fadian.json"
@ -84,9 +84,7 @@ async def fa_dian_refresher_data():
await fa_dian.fetch() await fa_dian.fetch()
@listener(command="fadian", @listener(command="fadian", description="快速对着指定人物发电", parameters="[query]")
description="快速对着指定人物发电",
parameters="[query]")
async def fa_dian_process(message: Message): async def fa_dian_process(message: Message):
if fa_dian.data.get("date") == 0: if fa_dian.data.get("date") == 0:
await fa_dian.fetch() await fa_dian.fetch()

View File

@ -12,11 +12,15 @@ from pagermaid.enums import Client, Message
async def get_status_emoji(bot: Client, message: Message = None) -> str: async def get_status_emoji(bot: Client, message: Message = None) -> str:
try: try:
peer = InputUserFromMessage( peer = (
InputUserFromMessage(
peer=(await bot.resolve_peer(message.chat.id)), peer=(await bot.resolve_peer(message.chat.id)),
msg_id=message.id, msg_id=message.id,
user_id=message.from_user.id, user_id=message.from_user.id,
) if message else InputUserSelf() )
if message
else InputUserSelf()
)
req = await bot.invoke(GetUsers(id=[peer])) req = await bot.invoke(GetUsers(id=[peer]))
emoji_status = req[0].emoji_status emoji_status = req[0].emoji_status
if not emoji_status or isinstance(emoji_status, EmojiStatusEmpty): if not emoji_status or isinstance(emoji_status, EmojiStatusEmpty):
@ -25,10 +29,8 @@ async def get_status_emoji(bot: Client, message: Message = None) -> str:
return f"你的自定义 emoji 状态是 <emoji id='{emoji_status.document_id}'>🔥</emoji>" return f"你的自定义 emoji 状态是 <emoji id='{emoji_status.document_id}'>🔥</emoji>"
if isinstance(emoji_status, EmojiStatusUntil): if isinstance(emoji_status, EmojiStatusUntil):
time = datetime.strftime( time = datetime.strftime(
datetime.fromtimestamp( datetime.fromtimestamp(emoji_status.until, timezone("Asia/Shanghai")),
emoji_status.until, timezone("Asia/Shanghai") "%Y-%m-%d %H:%M:%S",
),
"%Y-%m-%d %H:%M:%S"
) )
return f"你的自定义 emoji 状态是 <emoji id='{emoji_status.document_id}'>🔥</emoji> (有效期至:{time}" return f"你的自定义 emoji 状态是 <emoji id='{emoji_status.document_id}'>🔥</emoji> (有效期至:{time}"
except DocumentInvalid: except DocumentInvalid:
@ -37,9 +39,7 @@ async def get_status_emoji(bot: Client, message: Message = None) -> str:
raise FileNotFoundError from e raise FileNotFoundError from e
@listener(command="get_status", @listener(command="get_status", need_admin=True, description="获取自己或者他人的大会员自定义 emoji 状态")
need_admin=True,
description="获取自己或者他人的大会员自定义 emoji 状态")
async def get_emoji_status(bot: Client, message: Message): async def get_emoji_status(bot: Client, message: Message):
"""获取自己或者他人的大会员自定义 emoji 状态""" """获取自己或者他人的大会员自定义 emoji 状态"""
if not message.reply_to_message_id: if not message.reply_to_message_id:

View File

@ -6,19 +6,23 @@ from pagermaid.listener import listener
from pagermaid.enums import Client, Message from pagermaid.enums import Client, Message
@listener(command="getdel", @listener(
command="getdel",
groups_only=True, groups_only=True,
need_admin=True, need_admin=True,
parameters="清理", parameters="清理",
description="获取当前群组的死号数。") description="获取当前群组的死号数。",
)
async def get_del(client: Client, message: Message): async def get_del(client: Client, message: Message):
"""PagerMaid get_del.""" """PagerMaid get_del."""
need_kick = message.arguments need_kick = message.arguments
member_count = 0 member_count = 0
try: try:
await message.edit('遍历成员中。。。') await message.edit("遍历成员中。。。")
if need_kick: if need_kick:
user = await client.get_chat_member(message.chat.id, (await client.get_me()).id) user = await client.get_chat_member(
message.chat.id, (await client.get_me()).id
)
need_kick = bool(user.privileges and user.privileges.can_restrict_members) need_kick = bool(user.privileges and user.privileges.can_restrict_members)
async for member in client.get_chat_members(message.chat.id): async for member in client.get_chat_members(message.chat.id):
if member.user.is_deleted: if member.user.is_deleted:
@ -28,14 +32,15 @@ async def get_del(client: Client, message: Message):
await client.ban_chat_member( await client.ban_chat_member(
message.chat.id, message.chat.id,
member.user.id, member.user.id,
datetime.now() + timedelta(minutes=5)) datetime.now() + timedelta(minutes=5),
)
except FloodWait: except FloodWait:
return await message.edit('处理失败,您已受到 TG 服务器限制。') return await message.edit("处理失败,您已受到 TG 服务器限制。")
except UserAdminInvalid: except UserAdminInvalid:
pass pass
if need_kick: if need_kick:
await message.edit(f'此群组的死号数:`{member_count}`,并且已经清理完毕。') await message.edit(f"此群组的死号数:`{member_count}`,并且已经清理完毕。")
else: else:
await message.edit(f'此群组的死号数:`{member_count}`。') await message.edit(f"此群组的死号数:`{member_count}`。")
except ChatAdminRequired: except ChatAdminRequired:
await message.edit("你好像并不拥有封禁用户权限。") await message.edit("你好像并不拥有封禁用户权限。")

View File

@ -19,11 +19,14 @@ from pagermaid.single_utils import safe_remove
async def download_stickers(bot: Client, message: Message, sticker: Sticker): async def download_stickers(bot: Client, message: Message, sticker: Sticker):
try: try:
sticker_set: StickerSet = await bot.invoke( sticker_set: StickerSet = await bot.invoke(
GetStickerSet(stickerset=InputStickerSetShortName(short_name=sticker.set_name), hash=0)) GetStickerSet(
stickerset=InputStickerSetShortName(short_name=sticker.set_name), hash=0
)
)
except Exception: # noqa except Exception: # noqa
return await message.edit('回复的贴纸不存在于任何贴纸包中。') return await message.edit("回复的贴纸不存在于任何贴纸包中。")
pack_file = os.path.join('data/sticker/', sticker_set.set.short_name, "pack.txt") pack_file = os.path.join("data/sticker/", sticker_set.set.short_name, "pack.txt")
if os.path.isfile(pack_file): if os.path.isfile(pack_file):
os.remove(pack_file) os.remove(pack_file)
@ -39,20 +42,33 @@ async def download_stickers(bot: Client, message: Message, sticker: Sticker):
async def download(sticker_, emojis_, path, file): async def download(sticker_, emojis_, path, file):
sticker_file = Document._parse(bot, sticker_, "sticker.webp") # noqa sticker_file = Document._parse(bot, sticker_, "sticker.webp") # noqa
await bot.download_media(sticker_file.file_id, file_name=os.path.join(path, file)) await bot.download_media(
sticker_file.file_id, file_name=os.path.join(path, file)
)
with open(pack_file, "a") as f: with open(pack_file, "a") as f:
f.write(f"{{'image_file': '{file}','emojis':{emojis_[sticker_.id]}}},") f.write(f"{{'image_file': '{file}','emojis':{emojis_[sticker_.id]}}},")
pending_tasks = [asyncio.ensure_future( pending_tasks = [
download(document, emojis, f"data/sticker/{sticker_set.set.short_name}", f"{i:03d}.{file_ext_ns_ion}") asyncio.ensure_future(
) for i, document in enumerate(sticker_set.documents)] download(
document,
emojis,
f"data/sticker/{sticker_set.set.short_name}",
f"{i:03d}.{file_ext_ns_ion}",
)
)
for i, document in enumerate(sticker_set.documents)
]
message: Message = await message.edit( message: Message = await message.edit(
f"正在下载 {sticker_set.set.short_name} 中的 {sticker_set.set.count} 张贴纸。。。") f"正在下载 {sticker_set.set.short_name} 中的 {sticker_set.set.count} 张贴纸。。。"
)
while 1: while 1:
done, pending_tasks = await asyncio.wait(pending_tasks, timeout=2.5, return_when=asyncio.FIRST_COMPLETED) done, pending_tasks = await asyncio.wait(
pending_tasks, timeout=2.5, return_when=asyncio.FIRST_COMPLETED
)
if not pending_tasks: if not pending_tasks:
break break
await upload_sticker(bot, message, sticker_set) await upload_sticker(bot, message, sticker_set)
@ -69,7 +85,8 @@ async def upload_sticker(bot: Client, message: Message, sticker_set: StickerSet)
message.chat.id, message.chat.id,
f"{directory_name}.zip", f"{directory_name}.zip",
caption=sticker_set.set.short_name, caption=sticker_set.set.short_name,
reply_to_message_id=message.reply_to_message_id or message.reply_to_top_message_id, reply_to_message_id=message.reply_to_message_id
or message.reply_to_top_message_id,
) )
safe_remove(f"{directory_name}.zip") safe_remove(f"{directory_name}.zip")
shutil.rmtree(directory_name) shutil.rmtree(directory_name)
@ -82,19 +99,22 @@ async def get_custom_emojis(bot: Client, message: Message):
for entity in message.entities: for entity in message.entities:
if entity.type == MessageEntityType.CUSTOM_EMOJI: if entity.type == MessageEntityType.CUSTOM_EMOJI:
try: try:
sticker = await bot.get_custom_emoji_stickers([entity.custom_emoji_id]) sticker = await bot.get_custom_emoji_stickers(
[entity.custom_emoji_id]
)
except Exception: except Exception:
return None return None
return sticker[0] if sticker else None return sticker[0] if sticker else None
@listener(command="getstickers", @listener(command="getstickers", description="获取整个贴纸包的贴纸")
description="获取整个贴纸包的贴纸")
async def get_stickers(bot: Client, message: Message): async def get_stickers(bot: Client, message: Message):
if not os.path.isdir('data/sticker/'): if not os.path.isdir("data/sticker/"):
os.makedirs('data/sticker/') os.makedirs("data/sticker/")
if message.reply_to_message: if message.reply_to_message:
sticker = message.reply_to_message.sticker or await get_custom_emojis(bot, message.reply_to_message) sticker = message.reply_to_message.sticker or await get_custom_emojis(
bot, message.reply_to_message
)
else: else:
sticker = message.sticker or await get_custom_emojis(bot, message) sticker = message.sticker or await get_custom_emojis(bot, message)
if not sticker: if not sticker:

View File

@ -22,14 +22,12 @@ def get_ip(domain):
async def post(host): async def post(host):
url = 'https://api.potatonet.idc.wiki/network/simple_health_check/scripts/gfw_check' url = "https://api.potatonet.idc.wiki/network/simple_health_check/scripts/gfw_check"
data = {'host': host} data = {"host": host}
return await requests.post(url, data=data) return await requests.post(url, data=data)
@listener(command="gfw", @listener(command="gfw", parameters="[text]", description="查询是否被墙")
parameters="[text]",
description="查询是否被墙")
async def gfw(message: Message): async def gfw(message: Message):
text = None text = None
if message.arguments: if message.arguments:
@ -53,10 +51,15 @@ async def gfw(message: Message):
except Exception as e: except Exception as e:
return await message.edit(f"出错了呜呜呜 ~ 查询失败。{e}") return await message.edit(f"出错了呜呜呜 ~ 查询失败。{e}")
if data['success']: if data["success"]:
if data['data']['tcp']['cn'] == data['data']['tcp']['!cn'] and data['data']['icmp']['cn'] == \ if (
data['data']['icmp']['!cn']: data["data"]["tcp"]["cn"] == data["data"]["tcp"]["!cn"]
if data['data']['tcp']['cn'] == False and data['data']['icmp']['cn'] == False: and data["data"]["icmp"]["cn"] == data["data"]["icmp"]["!cn"]
):
if (
data["data"]["tcp"]["cn"] == False
and data["data"]["icmp"]["cn"] == False
):
reply = f"IP: {text}\n状态: 全球不通,不能判断是否被墙" reply = f"IP: {text}\n状态: 全球不通,不能判断是否被墙"
else: else:
reply = f"IP: {text}\n状态: 未被墙" reply = f"IP: {text}\n状态: 未被墙"

View File

@ -8,27 +8,28 @@ pip_install("magic-google", alias="magic_google")
from magic_google import MagicGoogle from magic_google import MagicGoogle
@listener(command="google", @listener(command="google", description=lang("google_des"), parameters="[query]")
description=lang('google_des'),
parameters="[query]")
async def google(message: Message): async def google(message: Message):
"""Searches Google for a string.""" """Searches Google for a string."""
query = message.arguments query = message.arguments
if not query: if not query:
if not message.reply_to_message: if not message.reply_to_message:
return await message.edit(lang('arg_error')) return await message.edit(lang("arg_error"))
query = message.reply_to_message.text query = message.reply_to_message.text
mg = MagicGoogle() mg = MagicGoogle()
query = query.replace(' ', '+') query = query.replace(" ", "+")
if not Config.SILENT: if not Config.SILENT:
message = await message.edit(lang('google_processing')) message = await message.edit(lang("google_processing"))
results = "" results = ""
for i in mg.search(query=query, num=5): for i in mg.search(query=query, num=5):
try: try:
title = i['text'][:30] + '...' title = i["text"][:30] + "..."
link = i['url'] link = i["url"]
results += f"\n<a href=\"{link}\">{title}</a> \n" results += f'\n<a href="{link}">{title}</a> \n'
except Exception: except Exception:
return await message.edit(lang('google_connection_error')) return await message.edit(lang("google_connection_error"))
await message.edit(f"<b>Google</b> |<code>{query}</code>| 🎙 🔍 \n{results}", disable_web_page_preview=True) await message.edit(
f"<b>Google</b> |<code>{query}</code>| 🎙 🔍 \n{results}",
disable_web_page_preview=True,
)
await log(f"{lang('google_success')} `{query}`") await log(f"{lang('google_success')} `{query}`")

View File

@ -33,14 +33,14 @@ class HisMsg:
"POLL": "[POLL]:", "POLL": "[POLL]:",
"WEB_PAGE": "[WEB_PAGE]:", "WEB_PAGE": "[WEB_PAGE]:",
"DICE": "[DICE]:", "DICE": "[DICE]:",
"GAME": "[GAME]:" "GAME": "[GAME]:",
}, },
"service": { "service": {
"service": "[Service_Message]: ", "service": "[Service_Message]: ",
"PINNED_MESSAGE": "Pinned: ", "PINNED_MESSAGE": "Pinned: ",
"NEW_CHAT_TITLE": "New chat title: ", "NEW_CHAT_TITLE": "New chat title: ",
}, },
"query_success": "Queryed history message. chat_id: {chat_id} user: {user}" "query_success": "Queryed history message. chat_id: {chat_id} user: {user}",
}, },
"zh-cn": { "zh-cn": {
"help": "查询指定用户在群内的发言历史\n" "help": "查询指定用户在群内的发言历史\n"
@ -63,15 +63,15 @@ class HisMsg:
"POLL": "[投票]:", "POLL": "[投票]:",
"WEB_PAGE": "[网页]:", "WEB_PAGE": "[网页]:",
"DICE": "[骰子]:", "DICE": "[骰子]:",
"GAME": "[游戏]:" "GAME": "[游戏]:",
}, },
"service": { "service": {
"service": "[服务消息]: ", "service": "[服务消息]: ",
"PINNED_MESSAGE": "置顶了: ", "PINNED_MESSAGE": "置顶了: ",
"NEW_CHAT_TITLE": "新的群组名字: ", "NEW_CHAT_TITLE": "新的群组名字: ",
}, },
"query_success": "查询历史消息完成. 群组id: {chat_id} 用户: {user}" "query_success": "查询历史消息完成. 群组id: {chat_id} 用户: {user}",
} },
} }
MAX_COUNT = 30 MAX_COUNT = 30
@ -87,14 +87,17 @@ class HisMsg:
res = text res = text
return res return res
his_msg = HisMsg() his_msg = HisMsg()
@listener(command="his", @listener(
command="his",
groups_only=True, groups_only=True,
need_admin=True, need_admin=True,
description=his_msg.lang("help"), description=his_msg.lang("help"),
parameters=his_msg.lang("arg", "&lt;user> [-n &lt;num>]")) parameters=his_msg.lang("arg", "&lt;user> [-n &lt;num>]"),
)
async def his(bot: Client, message: Message): async def his(bot: Client, message: Message):
user = "" user = ""
num = 9999999 num = 9999999
@ -108,23 +111,29 @@ async def his(bot: Client, message: Message):
elif len(message.parameter) == 1: elif len(message.parameter) == 1:
user = message.parameter[0] user = message.parameter[0]
# 回复消息+指定数量 # 回复消息+指定数量
elif len(message.parameter) == 2 and (message.reply_to_message_id is not None) and message.parameter[0] == "-n" : elif (
len(message.parameter) == 2
and (message.reply_to_message_id is not None)
and message.parameter[0] == "-n"
):
user = int(message.reply_to_message.from_user.id) user = int(message.reply_to_message.from_user.id)
num = int(message.parameter[1]) num = int(message.parameter[1])
# 回复消息 # 回复消息
elif (message.reply_to_message_id is not None): elif message.reply_to_message_id is not None:
user = int(message.reply_to_message.from_user.id) user = int(message.reply_to_message.from_user.id)
# 预期外的调用方式 # 预期外的调用方式
else: else:
return await message.edit(his_msg.lang('help')) return await message.edit(his_msg.lang("help"))
except Exception: except Exception:
return await message.edit(his_msg.lang('help')) return await message.edit(his_msg.lang("help"))
await message.edit(his_msg.lang("processing")) await message.edit(his_msg.lang("processing"))
count = 0 count = 0
results = "" results = ""
try: try:
async for msg in bot.search_messages(chat_id, limit=min(num, his_msg.MAX_COUNT), from_user=user): async for msg in bot.search_messages(
chat_id, limit=min(num, his_msg.MAX_COUNT), from_user=user
):
if msg.empty: if msg.empty:
continue continue
count += 1 count += 1
@ -138,10 +147,20 @@ async def his(bot: Client, message: Message):
if msg.service is not None: # 服务消息 if msg.service is not None: # 服务消息
service_text = "" service_text = ""
service_type = str(msg.service).split(".")[1] service_type = str(msg.service).split(".")[1]
if service_type == "PINNED_MESSAGE" and msg.pinned_message.text is not None: if (
service_text = his_msg.lang("service")[service_type] + msg.pinned_message.text[:20] service_type == "PINNED_MESSAGE"
elif service_type == "NEW_CHAT_TITLE" and msg.new_chat_title is not None: and msg.pinned_message.text is not None
service_text = his_msg.lang("service")[service_type] + msg.new_chat_title ):
service_text = (
his_msg.lang("service")[service_type]
+ msg.pinned_message.text[:20]
)
elif (
service_type == "NEW_CHAT_TITLE" and msg.new_chat_title is not None
):
service_text = (
his_msg.lang("service")[service_type] + msg.new_chat_title
)
else: else:
service_text = service_type service_text = service_type
message_text = his_msg.lang("service")["service"] + service_text message_text = his_msg.lang("service")["service"] + service_text
@ -150,10 +169,13 @@ async def his(bot: Client, message: Message):
message_text = f"{count}. {message_text[:20]}..." message_text = f"{count}. {message_text[:20]}..."
else: else:
message_text = f"{count}. {message_text}" message_text = f"{count}. {message_text}"
results += f"\n<a href=\"{message_link}\">{message_text}</a> \n" results += f'\n<a href="{message_link}">{message_text}</a> \n'
await message.edit(f"<b>Message History</b> | <code>{user}</code> | 🔍 \n{results}", disable_web_page_preview=True) await message.edit(
await log(his_msg.lang('query_success').format(chat_id=chat_id, user=user)) f"<b>Message History</b> | <code>{user}</code> | 🔍 \n{results}",
disable_web_page_preview=True,
)
await log(his_msg.lang("query_success").format(chat_id=chat_id, user=user))
except Exception as e: except Exception as e:
await message.edit(f"[HIS_ERROR]: {e}") await message.edit(f"[HIS_ERROR]: {e}")
await log(f"[HIS_ERROR]: {e}") await log(f"[HIS_ERROR]: {e}")

View File

@ -3,29 +3,40 @@ from pagermaid.enums import Message, AsyncClient
from pagermaid.utils import lang from pagermaid.utils import lang
@listener(command="hitokoto", @listener(command="hitokoto", description=lang("hitokoto_des"))
description=lang('hitokoto_des'))
async def hitokoto(request: AsyncClient, message: Message): async def hitokoto(request: AsyncClient, message: Message):
hitokoto_while = 1 hitokoto_while = 1
hitokoto_json = None hitokoto_json = None
try: try:
hitokoto_json = (await request.get("https://v1.hitokoto.cn/?charset=utf-8")).json() hitokoto_json = (
await request.get("https://v1.hitokoto.cn/?charset=utf-8")
).json()
except ValueError: except ValueError:
while hitokoto_while < 10: while hitokoto_while < 10:
hitokoto_while += 1 hitokoto_while += 1
try: try:
hitokoto_json = (await request.get("https://v1.hitokoto.cn/?charset=utf-8")).json() hitokoto_json = (
await request.get("https://v1.hitokoto.cn/?charset=utf-8")
).json()
break break
except Exception: except Exception:
continue continue
if not hitokoto_json: if not hitokoto_json:
return return
hitokoto_type = {'a': lang('hitokoto_type_anime'), 'b': lang('hitokoto_type_manga'), hitokoto_type = {
'c': lang('hitokoto_type_game'), 'd': lang('hitokoto_type_article'), "a": lang("hitokoto_type_anime"),
'e': lang('hitokoto_type_original'), 'f': lang('hitokoto_type_web'), "b": lang("hitokoto_type_manga"),
'g': lang('hitokoto_type_other'), 'h': lang('hitokoto_type_movie'), "c": lang("hitokoto_type_game"),
'i': lang('hitokoto_type_poem'), 'j': lang('hitokoto_type_netease_music'), "d": lang("hitokoto_type_article"),
'k': lang('hitokoto_type_philosophy'), 'l': lang('hitokoto_type_meme')} "e": lang("hitokoto_type_original"),
"f": lang("hitokoto_type_web"),
"g": lang("hitokoto_type_other"),
"h": lang("hitokoto_type_movie"),
"i": lang("hitokoto_type_poem"),
"j": lang("hitokoto_type_netease_music"),
"k": lang("hitokoto_type_philosophy"),
"l": lang("hitokoto_type_meme"),
}
add = "" add = ""
if works := hitokoto_json["from"]: if works := hitokoto_json["from"]:
add += f"{works}" add += f"{works}"

View File

@ -22,5 +22,8 @@ async def httpcat(client: Client, message: Message, request: AsyncClient):
io, io,
reply_to_message_id=( reply_to_message_id=(
message.reply_to_message_id or message.reply_to_top_message_id message.reply_to_message_id or message.reply_to_top_message_id
) if message.outgoing else message.id) )
if message.outgoing
else message.id,
)
await message.safe_delete() await message.safe_delete()

View File

@ -13,15 +13,15 @@ from tld import get_fld
async def post_data(path, data, content, token): async def post_data(path, data, content, token):
url = 'https://hlwicpfwc.miit.gov.cn/icpproject_query/api/' url = "https://hlwicpfwc.miit.gov.cn/icpproject_query/api/"
client_ip = f'{str(randint(1, 254))}.{str(randint(1, 254))}.{str(randint(1, 254))}.{str(randint(1, 254))}' client_ip = f"{str(randint(1, 254))}.{str(randint(1, 254))}.{str(randint(1, 254))}.{str(randint(1, 254))}"
headers = { headers = {
'Content-Type': content, "Content-Type": content,
'Origin': 'https://beian.miit.gov.cn/', "Origin": "https://beian.miit.gov.cn/",
'Referer': 'https://beian.miit.gov.cn/', "Referer": "https://beian.miit.gov.cn/",
'token': token, "token": token,
'Client-IP': client_ip, "Client-IP": client_ip,
'X-Forwarded-For': client_ip "X-Forwarded-For": client_ip,
} }
return await requests.post(url + path, data=data, headers=headers) return await requests.post(url + path, data=data, headers=headers)
@ -29,35 +29,37 @@ async def post_data(path, data, content, token):
async def icp_search(domain): async def icp_search(domain):
md5 = hashlib.md5() md5 = hashlib.md5()
timestamp = int(time.time()) timestamp = int(time.time())
auth_key = f'testtest{timestamp}' auth_key = f"testtest{timestamp}"
md5.update(auth_key.encode('utf-8')) md5.update(auth_key.encode("utf-8"))
auth_key = md5.hexdigest() auth_key = md5.hexdigest()
token = await post_data( token = await post_data(
'auth', "auth",
f'authKey={auth_key}&timeStamp={timestamp}', f"authKey={auth_key}&timeStamp={timestamp}",
'application/x-www-form-urlencoded;charset=UTF-8', "application/x-www-form-urlencoded;charset=UTF-8",
'0', "0",
) )
token = token.json() token = token.json()
if token.get("code", None) == 200: if token.get("code", None) == 200:
token = token['params']['bussiness'] token = token["params"]["bussiness"]
else: else:
return {'isBeian': False, 'msg': '获取token失败'} return {"isBeian": False, "msg": "获取token失败"}
query = await post_data('icpAbbreviateInfo/queryByCondition', '{"pageNum":"","pageSize":"","unitName":"%s"}' % ( query = await post_data(
domain), 'application/json;charset=UTF-8', token) "icpAbbreviateInfo/queryByCondition",
'{"pageNum":"","pageSize":"","unitName":"%s"}' % (domain),
"application/json;charset=UTF-8",
token,
)
query = query.json() query = query.json()
if query.get("code", None) != 200: if query.get("code", None) != 200:
return {'isBeian': False, 'msg': '查询失败'} return {"isBeian": False, "msg": "查询失败"}
icp_list = query['params']['list'] icp_list = query["params"]["list"]
if len(icp_list) <= 0: if len(icp_list) <= 0:
return {'isBeian': False, 'msg': '成功'} return {"isBeian": False, "msg": "成功"}
return {'isBeian': True, 'msg': '成功', 'data': icp_list[0]} return {"isBeian": True, "msg": "成功", "data": icp_list[0]}
@listener(command="icp", @listener(command="icp", parameters="[域名]", description="查询域名是否已备案")
parameters="[域名]",
description="查询域名是否已备案")
async def icp_bei_an(message: Message): async def icp_bei_an(message: Message):
url = None url = None
if message.arguments: if message.arguments:
@ -84,7 +86,8 @@ async def icp_bei_an(message: Message):
f"备案时间: {data.get('updateRecordTime', '')}\n" f"备案时间: {data.get('updateRecordTime', '')}\n"
f"备案类型: {data.get('natureName', '')}\n" f"备案类型: {data.get('natureName', '')}\n"
f"备案号: {data.get('serviceLicence', '')}\n" f"备案号: {data.get('serviceLicence', '')}\n"
f"是否限制访问: {data.get('limitAccess', '')}") f"是否限制访问: {data.get('limitAccess', '')}"
)
elif data.get("msg", "") == "成功": elif data.get("msg", "") == "成功":
await message.edit(f"域名 {url} 未备案!") await message.edit(f"域名 {url} 未备案!")
else: else:

View File

@ -5,7 +5,9 @@ from pagermaid.enums import Message
from pagermaid.listener import listener from pagermaid.listener import listener
@listener(command="punyencode", description="编码至 Punycode", parameters="[待编码内容] (支持回复消息)") @listener(
command="punyencode", description="编码至 Punycode", parameters="[待编码内容] (支持回复消息)"
)
async def punyencode(message: Message): async def punyencode(message: Message):
if not (text := message.obtain_message()): if not (text := message.obtain_message()):
return await message.edit("请输入参数") return await message.edit("请输入参数")
@ -16,7 +18,9 @@ async def punyencode(message: Message):
await message.edit(f"`{encoded}`") await message.edit(f"`{encoded}`")
@listener(command="punydecode", description="从 Punycode 解码", parameters="[待解码内容] (支持回复消息)") @listener(
command="punydecode", description="从 Punycode 解码", parameters="[待解码内容] (支持回复消息)"
)
async def punydecode(message: Message): async def punydecode(message: Message):
if not (text := message.obtain_message()): if not (text := message.obtain_message()):
return await message.edit("请输入参数") return await message.edit("请输入参数")

View File

@ -9,41 +9,68 @@ from pagermaid.services import client as requests
async def get_ip_info(url: str) -> str: async def get_ip_info(url: str) -> str:
data = await requests.get( data = await requests.get(
f"http://ip-api.com/json/{url}?fields=status,message,country,regionName," f"http://ip-api.com/json/{url}?fields=status,message,country,regionName,"
f"city,lat,lon,isp,org,as,mobile,proxy,hosting,query") f"city,lat,lon,isp,org,as,mobile,proxy,hosting,query"
)
ipinfo_json = data.json() ipinfo_json = data.json()
if ipinfo_json['status'] == 'fail': if ipinfo_json["status"] == "fail":
return "" return ""
elif ipinfo_json['status'] == 'success': elif ipinfo_json["status"] == "success":
ipinfo_list = [f"查询目标: `{url}`"] ipinfo_list = [f"查询目标: `{url}`"]
if ipinfo_json['query'] != url: if ipinfo_json["query"] != url:
ipinfo_list.extend(["解析地址: `" + ipinfo_json['query'] + "`"]) ipinfo_list.extend(["解析地址: `" + ipinfo_json["query"] + "`"])
ipinfo_list.extend( ipinfo_list.extend(
[(("地区: `" + ipinfo_json['country'] + ' - ' + ipinfo_json['regionName'] + ' - ' + ipinfo_json['city']) + "`"), [
"经纬度: `" + str(ipinfo_json['lat']) + ',' + str(ipinfo_json['lon']) + "`", (
"ISP `" + ipinfo_json['isp'] + "`"]) (
if ipinfo_json['org'] != '': "地区: `"
ipinfo_list.extend(["组织: `" + ipinfo_json['org'] + "`"]) + ipinfo_json["country"]
+ " - "
+ ipinfo_json["regionName"]
+ " - "
+ ipinfo_json["city"]
)
+ "`"
),
"经纬度: `"
+ str(ipinfo_json["lat"])
+ ","
+ str(ipinfo_json["lon"])
+ "`",
"ISP `" + ipinfo_json["isp"] + "`",
]
)
if ipinfo_json["org"] != "":
ipinfo_list.extend(["组织: `" + ipinfo_json["org"] + "`"])
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
ipinfo_list.extend(['[' + ipinfo_json['as'] + '](https://bgp.he.net/' + ipinfo_json['as'].split()[0] + ')']) ipinfo_list.extend(
if ipinfo_json['mobile']: [
ipinfo_list.extend(['此 IP 可能为**蜂窝移动数据 IP**']) "["
if ipinfo_json['proxy']: + ipinfo_json["as"]
ipinfo_list.extend(['此 IP 可能为**代理 IP**']) + "](https://bgp.he.net/"
if ipinfo_json['hosting']: + ipinfo_json["as"].split()[0]
ipinfo_list.extend(['此 IP 可能为**数据中心 IP**']) + ")"
]
)
if ipinfo_json["mobile"]:
ipinfo_list.extend(["此 IP 可能为**蜂窝移动数据 IP**"])
if ipinfo_json["proxy"]:
ipinfo_list.extend(["此 IP 可能为**代理 IP**"])
if ipinfo_json["hosting"]:
ipinfo_list.extend(["此 IP 可能为**数据中心 IP**"])
return "\n".join(ipinfo_list) return "\n".join(ipinfo_list)
@listener(command="ip", @listener(command="ip", description="IPINFO (或者回复一句话)", parameters="[ip/域名]")
description="IPINFO (或者回复一句话)",
parameters="[ip/域名]")
async def ipinfo(message: Message): async def ipinfo(message: Message):
reply = message.reply_to_message reply = message.reply_to_message
message: Message = await message.edit('正在查询中...') message: Message = await message.edit("正在查询中...")
try: try:
if reply: if reply:
for num in range(len(reply.entities)): for num in range(len(reply.entities)):
url = reply.text[reply.entities[num].offset:reply.entities[num].offset + reply.entities[num].length] url = reply.text[
reply.entities[num].offset : reply.entities[num].offset
+ reply.entities[num].length
]
url = urlparse(url) url = urlparse(url)
url = url.hostname or url.path url = url.hostname or url.path
await message.edit(await get_ip_info(url)) await message.edit(await get_ip_info(url))
@ -55,6 +82,6 @@ async def ipinfo(message: Message):
url = message.arguments url = message.arguments
await message.edit(await get_ip_info(url)) await message.edit(await get_ip_info(url))
return return
await message.edit('没有找到要查询的 ip/域名 ...') await message.edit("没有找到要查询的 ip/域名 ...")
except Exception: except Exception:
await message.edit('没有找到要查询的 ip/域名 ...') await message.edit("没有找到要查询的 ip/域名 ...")

View File

@ -12,7 +12,14 @@ class JIKIPediaDefinition:
item_id: int item_id: int
image: Optional[str] image: Optional[str]
def __init__(self, plaintext: str, tags: List[Dict], title: str, item_id: int, image: Optional[str]): def __init__(
self,
plaintext: str,
tags: List[Dict],
title: str,
item_id: int,
image: Optional[str],
):
self.plaintext = plaintext self.plaintext = plaintext
self.tags = [] self.tags = []
for i in tags: for i in tags:
@ -24,7 +31,9 @@ class JIKIPediaDefinition:
def format(self): def format(self):
plaintext = self.plaintext.replace("\u200b", "").replace("\u200c", "") plaintext = self.plaintext.replace("\u200b", "").replace("\u200c", "")
tags = " ".join([f"#{x}" for x in list(self.tags)]) if self.tags else "该词条还没有Tag哦" tags = (
" ".join([f"#{x}" for x in list(self.tags)]) if self.tags else "该词条还没有Tag哦"
)
text = f"词条:【{self.title}\n\n" text = f"词条:【{self.title}\n\n"
text += f"{plaintext}\n\n" text += f"{plaintext}\n\n"
@ -63,7 +72,11 @@ class JIKIPedia:
self.key = key self.key = key
async def search(self): async def search(self):
req = await httpx.post(url=self.url, headers=self.headers, json={"phrase": self.key, "page": 1, "size": 60}) req = await httpx.post(
url=self.url,
headers=self.headers,
json={"phrase": self.key, "page": 1, "size": 60},
)
return self.parse(**req.json()) return self.parse(**req.json())
def parse(self, **kwargs): def parse(self, **kwargs):
@ -83,15 +96,15 @@ class JIKIPedia:
image = "" image = ""
if len(images) > 0: if len(images) > 0:
image = images[0].get("full", {}).get("path", "") image = images[0].get("full", {}).get("path", "")
self.definitions.append(JIKIPediaDefinition(plaintext, tags, title, item_id, image)) self.definitions.append(
JIKIPediaDefinition(plaintext, tags, title, item_id, image)
)
self.message = kwargs.get("message") self.message = kwargs.get("message")
if issubclass(type(self.message), dict): if issubclass(type(self.message), dict):
self.message = self.message.get("title", None) self.message = self.message.get("title", None)
@listener(command="jikipedia", @listener(command="jikipedia", parameters="[关键词]", description="梗查询")
parameters="[关键词]",
description="梗查询")
async def jikipedia(message: Message): async def jikipedia(message: Message):
if not message.arguments: if not message.arguments:
return await message.edit("请输入关键词") return await message.edit("请输入关键词")

View File

@ -7,21 +7,18 @@ from pagermaid.utils import lang
ju_pai_api = "https://api.txqq.pro/api/zt.php" ju_pai_api = "https://api.txqq.pro/api/zt.php"
@listener( @listener(command="jupai", description="生成举牌小人", parameters="[text/reply]")
command="jupai",
description="生成举牌小人",
parameters="[text/reply]"
)
async def ju_pai(message: Message): async def ju_pai(message: Message):
text = message.obtain_message() text = message.obtain_message()
if not text: if not text:
return await message.edit(lang('arg_error')) return await message.edit(lang("arg_error"))
try: try:
image_url = f"{ju_pai_api}?msg={urllib.parse.quote(text)}" image_url = f"{ju_pai_api}?msg={urllib.parse.quote(text)}"
await message.reply_photo( await message.reply_photo(
image_url, image_url,
quote=False, quote=False,
reply_to_message_id=message.reply_to_message_id or message.reply_to_top_message_id, reply_to_message_id=message.reply_to_message_id
or message.reply_to_top_message_id,
) )
await message.safe_delete() await message.safe_delete()
except Exception as e: except Exception as e:

View File

@ -31,9 +31,23 @@ class KeywordTask:
restrict: int restrict: int
delay_delete: int delay_delete: int
def __init__(self, task_id: Optional[int] = None, cid: int = 0, key: str = "", msg: str = "", include: bool = True, regexp: bool = False, def __init__(
exact: bool = False, case: bool = False, ignore_forward: bool = False, self,
reply: bool = True, delete: bool = False, ban: int = 0, restrict: int = 0, delay_delete: int = 0): task_id: Optional[int] = None,
cid: int = 0,
key: str = "",
msg: str = "",
include: bool = True,
regexp: bool = False,
exact: bool = False,
case: bool = False,
ignore_forward: bool = False,
reply: bool = True,
delete: bool = False,
ban: int = 0,
restrict: int = 0,
delay_delete: int = 0,
):
self.task_id = task_id self.task_id = task_id
self.cid = cid self.cid = cid
self.key = key self.key = key
@ -50,9 +64,22 @@ class KeywordTask:
self.delay_delete = delay_delete self.delay_delete = delay_delete
def export(self): def export(self):
return {"task_id": self.task_id, "cid": self.cid, "key": self.key, "msg": self.msg, "include": self.include, "regexp": self.regexp, return {
"exact": self.exact, "case": self.case, "ignore_forward": self.ignore_forward, "reply": self.reply, "task_id": self.task_id,
"delete": self.delete, "ban": self.ban, "restrict": self.restrict, "delay_delete": self.delay_delete} "cid": self.cid,
"key": self.key,
"msg": self.msg,
"include": self.include,
"regexp": self.regexp,
"exact": self.exact,
"case": self.case,
"ignore_forward": self.ignore_forward,
"reply": self.reply,
"delete": self.delete,
"ban": self.ban,
"restrict": self.restrict,
"delay_delete": self.delay_delete,
}
def export_str(self, show_all: bool = False): def export_str(self, show_all: bool = False):
text = f"<code>{self.task_id}</code> - " text = f"<code>{self.task_id}</code> - "
@ -89,19 +116,29 @@ class KeywordTask:
@staticmethod @staticmethod
def mention_chat(chat: Chat): def mention_chat(chat: Chat):
return f'<a href="https://t.me/{chat.username}">{chat.title}</a>' if chat.username \ return (
else f'<code>{chat.title}</code>' f'<a href="https://t.me/{chat.username}">{chat.title}</a>'
if chat.username
else f"<code>{chat.title}</code>"
)
def replace_reply(self, message: Message): def replace_reply(self, message: Message):
text = self.msg text = self.msg
if message.from_user: if message.from_user:
text = text.replace("$mention", str(Link( text = text.replace(
"$mention",
str(
Link(
f"tg://user?id={message.from_user.id}", f"tg://user?id={message.from_user.id}",
message.from_user.first_name or "Deleted Account", message.from_user.first_name or "Deleted Account",
ParseMode.HTML ParseMode.HTML,
))) )
),
)
text = text.replace("$code_id", str(message.from_user.id)) text = text.replace("$code_id", str(message.from_user.id))
text = text.replace("$code_name", message.from_user.first_name or "Deleted Account") text = text.replace(
"$code_name", message.from_user.first_name or "Deleted Account"
)
elif message.sender_chat: elif message.sender_chat:
text = text.replace("$mention", self.mention_chat(message.sender_chat)) text = text.replace("$mention", self.mention_chat(message.sender_chat))
text = text.replace("$code_id", str(message.sender_chat.id)) text = text.replace("$code_id", str(message.sender_chat.id))
@ -121,19 +158,27 @@ class KeywordTask:
text = self.replace_reply(message) text = self.replace_reply(message)
reply_id = message.id if self.reply else message.reply_to_top_message_id reply_id = message.id if self.reply else message.reply_to_top_message_id
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
msg = await message.reply(text, parse_mode=ParseMode.HTML, reply_to_message_id=reply_id) msg = await message.reply(
text, parse_mode=ParseMode.HTML, reply_to_message_id=reply_id
)
if self.delete: if self.delete:
await message.safe_delete() await message.safe_delete()
uid = message.from_user.id if message.from_user else message.sender_chat.id uid = message.from_user.id if message.from_user else message.sender_chat.id
if self.ban > 0: if self.ban > 0:
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
await bot.ban_chat_member( await bot.ban_chat_member(
message.chat.id, uid, until_date=datetime.now() + timedelta(seconds=self.ban)) message.chat.id,
uid,
until_date=datetime.now() + timedelta(seconds=self.ban),
)
if self.restrict > 0: if self.restrict > 0:
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
await bot.restrict_chat_member( await bot.restrict_chat_member(
message.chat.id, uid, ChatPermissions(), message.chat.id,
until_date=datetime.now() + timedelta(seconds=self.restrict)) uid,
ChatPermissions(),
until_date=datetime.now() + timedelta(seconds=self.restrict),
)
if self.delay_delete > 0 and msg: if self.delay_delete > 0 and msg:
add_delete_message_job(msg, self.delay_delete) add_delete_message_job(msg, self.delay_delete)
@ -246,7 +291,11 @@ class KeywordTasks:
return [task.task_id for task in self.tasks] return [task.task_id for task in self.tasks]
def print_all_tasks(self, show_all: bool = False, cid: int = 0) -> str: def print_all_tasks(self, show_all: bool = False, cid: int = 0) -> str:
return "\n".join(task.export_str(show_all) for task in self.tasks if task.cid == cid or show_all) return "\n".join(
task.export_str(show_all)
for task in self.tasks
if task.cid == cid or show_all
)
def save_to_file(self): def save_to_file(self):
data = [task.export() for task in self.tasks] data = [task.export() for task in self.tasks]
@ -290,10 +339,12 @@ async def from_msg_get_task_ids(message: Message) -> List[int]:
return id_list return id_list
@listener(command="keyword", @listener(
command="keyword",
parameters="指定参数", parameters="指定参数",
need_admin=True, need_admin=True,
description="关键词回复\n\nhttps://telegra.ph/PagerMaid-keyword-07-12") description="关键词回复\n\nhttps://telegra.ph/PagerMaid-keyword-07-12",
)
async def keyword_set(message: Message): async def keyword_set(message: Message):
if message.arguments == "h" or len(message.parameter) == 0: if message.arguments == "h" or len(message.parameter) == 0:
return await message.edit("关键词回复\n\nhttps://telegra.ph/PagerMaid-keyword-07-12") return await message.edit("关键词回复\n\nhttps://telegra.ph/PagerMaid-keyword-07-12")
@ -301,12 +352,15 @@ async def keyword_set(message: Message):
if message.parameter[0] == "list": if message.parameter[0] == "list":
if keyword_tasks.get_all_ids(): if keyword_tasks.get_all_ids():
return await message.edit( return await message.edit(
f"关键词任务:\n\n{keyword_tasks.print_all_tasks(show_all=False, cid=message.chat.id)}") f"关键词任务:\n\n{keyword_tasks.print_all_tasks(show_all=False, cid=message.chat.id)}"
)
else: else:
return await message.edit("没有关键词任务。") return await message.edit("没有关键词任务。")
elif message.parameter[0] == "alias": elif message.parameter[0] == "alias":
if keyword_alias.get(message.chat.id): if keyword_alias.get(message.chat.id):
return await message.edit(f"当前群组的关键字将继承:{keyword_alias.get(message.chat.id)}") return await message.edit(
f"当前群组的关键字将继承:{keyword_alias.get(message.chat.id)}"
)
else: else:
return await message.edit("当前群组没有继承。") return await message.edit("当前群组没有继承。")
elif len(message.parameter) == 2: elif len(message.parameter) == 2:
@ -319,7 +373,8 @@ async def keyword_set(message: Message):
elif message.parameter[0] == "list": elif message.parameter[0] == "list":
if keyword_tasks.get_all_ids(): if keyword_tasks.get_all_ids():
return await message.edit( return await message.edit(
f"关键词任务:\n\n{keyword_tasks.print_all_tasks(show_all=True)}") f"关键词任务:\n\n{keyword_tasks.print_all_tasks(show_all=True)}"
)
else: else:
return await message.edit("没有关键词任务。") return await message.edit("没有关键词任务。")
elif message.parameter[0] == "alias": elif message.parameter[0] == "alias":

View File

@ -4,9 +4,7 @@ from pagermaid.listener import listener
from pyrogram.raw.functions.channels import GetAdminedPublicChannels from pyrogram.raw.functions.channels import GetAdminedPublicChannels
@listener(command="listusernames", @listener(command="listusernames", admins_only=True, description="列出所有属于自己的公开群组/频道。")
admins_only=True,
description="列出所有属于自己的公开群组/频道。")
async def list_usernames(bot: Client, message: Message): async def list_usernames(bot: Client, message: Message):
"""Get a list of your reserved usernames.""" """Get a list of your reserved usernames."""
result = await bot.invoke(GetAdminedPublicChannels()) result = await bot.invoke(GetAdminedPublicChannels())

View File

@ -9,7 +9,14 @@ from pagermaid.sub_utils import Sub
from pagermaid.scheduler import add_delete_message_job from pagermaid.scheduler import add_delete_message_job
lottery_bot = Sub("lottery_bot") lottery_bot = Sub("lottery_bot")
lottery_json = {"start": False, "chat_id": 0, "num": 0, "win": 0, "title": "", "keyword": ""} lottery_json = {
"start": False,
"chat_id": 0,
"num": 0,
"win": 0,
"title": "",
"keyword": "",
}
create_text = """抽奖活动 <b>{}</b> 已经创建 create_text = """抽奖活动 <b>{}</b> 已经创建
奖品数量<b>{}</b> 奖品数量<b>{}</b>
参与人数达到 <b>{}</b> 即可开奖 参与人数达到 <b>{}</b> 即可开奖
@ -40,10 +47,14 @@ async def lottery_end():
win_user.append(temp) win_user.append(temp)
if len(win_user) >= win_user_num: if len(win_user) >= win_user_num:
break break
win_text = end_text.format( win_text = (
end_text.format(
lottery_json["title"], lottery_json["title"],
"\n".join(f"<a href=\"tg://user?id={uid}\">@{uid}</a>" for uid in win_user "\n".join(f'<a href="tg://user?id={uid}">@{uid}</a>' for uid in win_user),
)) if win_user else end_empty_text.format(lottery_json["title"]) )
if win_user
else end_empty_text.format(lottery_json["title"])
)
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
await bot.send_message(lottery_json["chat_id"], win_text) await bot.send_message(lottery_json["chat_id"], win_text)
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
@ -78,7 +89,9 @@ async def handle_lottery(_, message: Message):
lottery_json["title"], lottery_json["title"],
lottery_json["win"], lottery_json["win"],
lottery_json["num"], lottery_json["num"],
all_join)) all_join,
)
)
add_delete_message_job(reply, 15) add_delete_message_job(reply, 15)
if all_join >= lottery_json["num"]: if all_join >= lottery_json["num"]:
lottery_json["start"] = False lottery_json["start"] = False
@ -99,15 +112,18 @@ async def create_lottery(chat_id: int, num: int, win: int, title: str, keyword:
await bot.send_message(chat_id, create_text.format(title, win, num, keyword)) await bot.send_message(chat_id, create_text.format(title, win, num, keyword))
@listener(command="lottery", @listener(
command="lottery",
groups_only=True, groups_only=True,
need_admin=True, need_admin=True,
parameters="[奖品数/人数] [关键词] [标题] / 强制开奖", parameters="[奖品数/人数] [关键词] [标题] / 强制开奖",
description=f"举行抽奖活动\n\n例如:,{alias_command('lottery')} 1/10 测试 测试") description=f"举行抽奖活动\n\n例如:,{alias_command('lottery')} 1/10 测试 测试",
)
async def lottery(message: Message): async def lottery(message: Message):
if not message.arguments: if not message.arguments:
return await message.edit( return await message.edit(
f"请输入 奖品数、人数等参数 或者 强制开奖\n\n例如 `,{alias_command('lottery')} 1/10 测试 测试`") f"请输入 奖品数、人数等参数 或者 强制开奖\n\n例如 `,{alias_command('lottery')} 1/10 测试 测试`"
)
if message.arguments == "强制开奖": if message.arguments == "强制开奖":
await message.edit("强制开奖成功。") await message.edit("强制开奖成功。")
return await lottery_end() return await lottery_end()

View File

@ -26,10 +26,11 @@ lu_xiao_xun_sticker: Optional[StickerSet] = None
async def load_bs_sticker(): async def load_bs_sticker():
global lu_xiao_xun_sticker global lu_xiao_xun_sticker
try: try:
lu_xiao_xun_sticker = await bot.invoke(GetStickerSet( lu_xiao_xun_sticker = await bot.invoke(
stickerset=InputStickerSetShortName(short_name="luxiaoxunbs"), GetStickerSet(
hash=0 stickerset=InputStickerSetShortName(short_name="luxiaoxunbs"), hash=0
)) )
)
except Exception: except Exception:
lu_xiao_xun_sticker = None lu_xiao_xun_sticker = None
@ -46,7 +47,9 @@ async def get_bs_sticker():
hour %= 12 hour %= 12
if hour == -1: if hour == -1:
hour = 11 hour = 11
return Document._parse(bot, lu_xiao_xun_sticker.documents[hour % 12], "sticker.webp") # noqa return Document._parse(
bot, lu_xiao_xun_sticker.documents[hour % 12], "sticker.webp"
) # noqa
@scheduler.scheduled_job("cron", minute="0", id="lu_xiao_xun_bs.push") @scheduler.scheduled_job("cron", minute="0", id="lu_xiao_xun_bs.push")
@ -62,9 +65,9 @@ async def lu_xiao_xun_bs_subscribe() -> None:
lu_xiao_xun_bs_sub.del_id(gid) lu_xiao_xun_bs_sub.del_id(gid)
@listener(command="luxiaoxunbs", @listener(
parameters="订阅/退订", command="luxiaoxunbs", parameters="订阅/退订", description="整点报时,每小时定时发送,自动删除上一条消息"
description="整点报时,每小时定时发送,自动删除上一条消息") )
async def lu_xiao_xun_bs(_: Client, message: Message): async def lu_xiao_xun_bs(_: Client, message: Message):
if not message.arguments: if not message.arguments:
return await message.edit("请输入订阅/退订") return await message.edit("请输入订阅/退订")

View File

@ -47,9 +47,7 @@ async def calendar_subscribe() -> None:
moyu_sub.del_id(gid) moyu_sub.del_id(gid)
@listener(command="moyu", @listener(command="moyu", parameters="订阅/退订", description="查看今日摸鱼日历,支持订阅/退订每天上午八点定时发送")
parameters="订阅/退订",
description="查看今日摸鱼日历,支持订阅/退订每天上午八点定时发送")
async def moyu(_: Client, message: Message): async def moyu(_: Client, message: Message):
"""摸鱼日历""" """摸鱼日历"""
if not message.arguments: if not message.arguments:
@ -60,17 +58,25 @@ async def moyu(_: Client, message: Message):
await message.safe_delete() await message.safe_delete()
await push_moyu(message.chat.id, delete=True) await push_moyu(message.chat.id, delete=True)
elif message.arguments == "订阅": elif message.arguments == "订阅":
if from_self(message) or enforce_permission(from_msg_get_sudo_uid(message), "modules.manage_subs"): if from_self(message) or enforce_permission(
from_msg_get_sudo_uid(message), "modules.manage_subs"
):
if moyu_sub.check_id(message.chat.id): if moyu_sub.check_id(message.chat.id):
return await edit_delete(message, "❌ 你已经订阅了摸鱼日历", parse_mode=ParseMode.HTML) return await edit_delete(
message, "❌ 你已经订阅了摸鱼日历", parse_mode=ParseMode.HTML
)
moyu_sub.add_id(message.chat.id) moyu_sub.add_id(message.chat.id)
await message.edit("你已经成功订阅了摸鱼日历") await message.edit("你已经成功订阅了摸鱼日历")
else: else:
await edit_delete(message, "❌ 权限不足,无法订阅摸鱼日历", parse_mode=ParseMode.HTML) await edit_delete(message, "❌ 权限不足,无法订阅摸鱼日历", parse_mode=ParseMode.HTML)
elif message.arguments == "退订": elif message.arguments == "退订":
if from_self(message) or enforce_permission(from_msg_get_sudo_uid(message), "modules.manage_subs"): if from_self(message) or enforce_permission(
from_msg_get_sudo_uid(message), "modules.manage_subs"
):
if not moyu_sub.check_id(message.chat.id): if not moyu_sub.check_id(message.chat.id):
return await edit_delete(message, "❌ 你还没有订阅摸鱼日历", parse_mode=ParseMode.HTML) return await edit_delete(
message, "❌ 你还没有订阅摸鱼日历", parse_mode=ParseMode.HTML
)
moyu_sub.del_id(message.chat.id) moyu_sub.del_id(message.chat.id)
await message.edit("你已经成功退订了摸鱼日历") await message.edit("你已经成功退订了摸鱼日历")
else: else:

View File

@ -34,14 +34,17 @@ async def netease_search(keyword: str, message: Message):
if not answer.reply_markup: if not answer.reply_markup:
return await message.edit(answer.text.html) return await message.edit(answer.text.html)
await bot.request_callback_answer( await bot.request_callback_answer(
answer.chat.id, answer.id, answer.chat.id,
callback_data=answer.reply_markup.inline_keyboard[0][0].callback_data) answer.id,
callback_data=answer.reply_markup.inline_keyboard[0][0].callback_data,
)
await conv.mark_as_read() await conv.mark_as_read()
answer: Message = await conv.get_response(filters=filters.audio) answer: Message = await conv.get_response(filters=filters.audio)
await conv.mark_as_read() await conv.mark_as_read()
await answer.copy( await answer.copy(
message.chat.id, message.chat.id,
reply_to_message_id=message.reply_to_message_id or message.reply_to_top_message_id reply_to_message_id=message.reply_to_message_id
or message.reply_to_top_message_id,
) )
await message.safe_delete() await message.safe_delete()
@ -54,7 +57,8 @@ async def netease_url(url: str, message: Message):
await conv.mark_as_read() await conv.mark_as_read()
await answer.copy( await answer.copy(
message.chat.id, message.chat.id,
reply_to_message_id=message.reply_to_message_id or message.reply_to_top_message_id reply_to_message_id=message.reply_to_message_id
or message.reply_to_top_message_id,
) )
await message.safe_delete() await message.safe_delete()
@ -67,14 +71,17 @@ async def netease_id(music_id: str, message: Message):
await conv.mark_as_read() await conv.mark_as_read()
await answer.copy( await answer.copy(
message.chat.id, message.chat.id,
reply_to_message_id=message.reply_to_message_id or message.reply_to_top_message_id reply_to_message_id=message.reply_to_message_id
or message.reply_to_top_message_id,
) )
await message.safe_delete() await message.safe_delete()
@listener(command="netease", @listener(
command="netease",
description="Netease Music", description="Netease Music",
parameters="[query]",) parameters="[query]",
)
async def netease_music(message: Message): async def netease_music(message: Message):
if not message.arguments: if not message.arguments:
return await message.edit(Netease_Help_Msg) return await message.edit(Netease_Help_Msg)

View File

@ -2,17 +2,28 @@ from pagermaid.listener import listener
from pagermaid.enums import Message, AsyncClient from pagermaid.enums import Message, AsyncClient
@listener(command="netease_comment", @listener(command="netease_comment", description="随机一条网易云音乐评论。")
description="随机一条网易云音乐评论。")
async def netease(request: AsyncClient, message: Message): async def netease(request: AsyncClient, message: Message):
for _ in range(5): for _ in range(5):
try: try:
req = await request.get("https://api.66mz8.com/api/music.163.php?format=json") req = await request.get(
"https://api.66mz8.com/api/music.163.php?format=json"
)
assert req.status_code == 200 assert req.status_code == 200
data = req.json() data = req.json()
res = data['comments'] + '\n\n来自 @' + data[ res = (
'nickname'] + ' 在鸽曲 <a href="' + str(data['music_url']) + '">' + \ data["comments"]
data['name'] + ' --by' + data['artists_name'] + '</a>' + ' 下方的评论。' + "\n\n来自 @"
+ data["nickname"]
+ ' 在鸽曲 <a href="'
+ str(data["music_url"])
+ '">'
+ data["name"]
+ " --by"
+ data["artists_name"]
+ "</a>"
+ " 下方的评论。"
)
return await message.edit(res, disable_web_page_preview=False) return await message.edit(res, disable_web_page_preview=False)
except Exception: except Exception:
continue continue

View File

@ -3,8 +3,7 @@ from pagermaid.listener import listener
from pagermaid.utils import Message, client from pagermaid.utils import Message, client
@listener(command="news", @listener(command="news", description="每日新闻、历史上的今天、天天成语、慧语香风、诗歌天地")
description="每日新闻、历史上的今天、天天成语、慧语香风、诗歌天地")
async def news(_: Client, context: Message): async def news(_: Client, context: Message):
msg = context.arguments msg = context.arguments
if not msg: if not msg:
@ -13,7 +12,7 @@ async def news(_: Client, context: Message):
data = await client.get("https://news.topurl.cn/api") data = await client.get("https://news.topurl.cn/api")
data = data.json()["data"] data = data.json()["data"]
text = "📮 每日新闻 📮\n" text = "📮 每日新闻 📮\n"
for idx, i in enumerate(data['newsList']): for idx, i in enumerate(data["newsList"]):
text += f"{idx + 1}. [{i['title']}]({i['url']})\n" text += f"{idx + 1}. [{i['title']}]({i['url']})\n"
text += "\n🎬 历史上的今天 🎬\n" text += "\n🎬 历史上的今天 🎬\n"
@ -27,8 +26,10 @@ async def news(_: Client, context: Message):
text += f"{data['sentence']['sentence']} ----{data['sentence']['author']}\n" text += f"{data['sentence']['sentence']} ----{data['sentence']['author']}\n"
text += "\n🎑 诗歌天地 🎑\n" text += "\n🎑 诗歌天地 🎑\n"
text += f"{''.join(data['poem']['content'])} " \ text += (
f"{''.join(data['poem']['content'])} "
f"----《{data['poem']['title']}{data['poem']['author']}" f"----《{data['poem']['title']}{data['poem']['author']}"
)
await context.edit(text) await context.edit(text)
except Exception as e: except Exception as e:
await context.edit(f"获取失败\n{e}") await context.edit(f"获取失败\n{e}")

View File

@ -68,16 +68,24 @@ async def news60s(message: Message):
elif message.arguments == "订阅": elif message.arguments == "订阅":
if check_manage_subs(message): if check_manage_subs(message):
if news60s_sub.check_id(message.chat.id): if news60s_sub.check_id(message.chat.id):
return await edit_delete(message, "❌ 你已经订阅了 60s 看世界新闻", parse_mode=ParseMode.HTML) return await edit_delete(
message, "❌ 你已经订阅了 60s 看世界新闻", parse_mode=ParseMode.HTML
)
news60s_sub.add_id(message.chat.id) news60s_sub.add_id(message.chat.id)
await message.edit("你已经成功订阅了 60s 看世界新闻") await message.edit("你已经成功订阅了 60s 看世界新闻")
else: else:
await edit_delete(message, "❌ 权限不足,无法订阅 60s 看世界新闻", parse_mode=ParseMode.HTML) await edit_delete(
message, "❌ 权限不足,无法订阅 60s 看世界新闻", parse_mode=ParseMode.HTML
)
elif message.arguments == "退订": elif message.arguments == "退订":
if check_manage_subs(message): if check_manage_subs(message):
if not news60s_sub.check_id(message.chat.id): if not news60s_sub.check_id(message.chat.id):
return await edit_delete(message, "❌ 你还没有订阅 60s 看世界新闻", parse_mode=ParseMode.HTML) return await edit_delete(
message, "❌ 你还没有订阅 60s 看世界新闻", parse_mode=ParseMode.HTML
)
news60s_sub.del_id(message.chat.id) news60s_sub.del_id(message.chat.id)
await message.edit("你已经成功退订了 60s 看世界新闻") await message.edit("你已经成功退订了 60s 看世界新闻")
else: else:
await edit_delete(message, "❌ 权限不足,无法退订 60s 看世界新闻", parse_mode=ParseMode.HTML) await edit_delete(
message, "❌ 权限不足,无法退订 60s 看世界新闻", parse_mode=ParseMode.HTML
)

View File

@ -10,9 +10,11 @@ from pyromod import require_mod_version
no_mentions_sub = Sub("no_mentions") no_mentions_sub = Sub("no_mentions")
@listener(command="no_mentions", @listener(
command="no_mentions",
description="自动消除某个对话的 @ 提醒", description="自动消除某个对话的 @ 提醒",
parameters="[true|false|status]") parameters="[true|false|status]",
)
async def no_mentions(_: Client, message: Message): async def no_mentions(_: Client, message: Message):
if len(message.parameter) != 1: if len(message.parameter) != 1:
await message.edit(f"[no_mentions] {lang('error_prefix')}{lang('arg_error')}") await message.edit(f"[no_mentions] {lang('error_prefix')}{lang('arg_error')}")
@ -49,6 +51,8 @@ async def set_read_mentions(client: Client, message: Message):
await client.invoke( await client.invoke(
ReadMentions( ReadMentions(
peer=await client.resolve_peer(message.chat.id), peer=await client.resolve_peer(message.chat.id),
top_msg_id=message.reply_to_top_message_id if message.chat.is_forum else None, top_msg_id=message.reply_to_top_message_id
if message.chat.is_forum
else None,
) )
) )

View File

@ -17,9 +17,11 @@ from pagermaid.utils import lang
no_reactions_sub = Sub("no_reactions") no_reactions_sub = Sub("no_reactions")
@listener(command="no_reactions", @listener(
command="no_reactions",
description="自动已读某个对话的消息表态", description="自动已读某个对话的消息表态",
parameters="[true|false|status]") parameters="[true|false|status]",
)
async def no_reactions(_: Client, message: Message): async def no_reactions(_: Client, message: Message):
if len(message.parameter) != 1: if len(message.parameter) != 1:
await message.edit(f"[no_reactions] {lang('error_prefix')}{lang('arg_error')}") await message.edit(f"[no_reactions] {lang('error_prefix')}{lang('arg_error')}")

View File

@ -15,7 +15,8 @@ import openai
async def get_chat_response(prompt: str) -> str: async def get_chat_response(prompt: str) -> str:
return openai.Completion.create( return (
openai.Completion.create(
model="text-davinci-003", model="text-davinci-003",
prompt=prompt, prompt=prompt,
temperature=0.9, temperature=0.9,
@ -23,8 +24,11 @@ async def get_chat_response(prompt: str) -> str:
top_p=1, top_p=1,
frequency_penalty=0.0, frequency_penalty=0.0,
presence_penalty=0.6, presence_penalty=0.6,
stop=["Human: ", "AI: "] stop=["Human: ", "AI: "],
).choices[0].text )
.choices[0]
.text
)
chat_bot_session = defaultdict(dict) chat_bot_session = defaultdict(dict)
@ -55,7 +59,7 @@ def get_template() -> str:
def formatted_response(prompt: str, message: str) -> str: def formatted_response(prompt: str, message: str) -> str:
if not get_template(): if not get_template():
set_template(default_template) set_template(default_template)
message = re.sub(r'^\s+', r'', message) message = re.sub(r"^\s+", r"", message)
try: try:
return get_template().format(prompt, message) return get_template().format(prompt, message)
except Exception: except Exception:
@ -64,15 +68,17 @@ def formatted_response(prompt: str, message: str) -> str:
default_template = "{0}\n====\n{1}\nPowered by OpenAI Chat (text-davinci-003)" default_template = "{0}\n====\n{1}\nPowered by OpenAI Chat (text-davinci-003)"
openai.api_key = get_api_key() openai.api_key = get_api_key()
chat_bot_help = "使用 OpenAI Chat 聊天\n" \ chat_bot_help = (
"基于 text-davinci-003 模型,与 ChatGPT 的效果有些许不同\n" \ "使用 OpenAI Chat 聊天\n"
"代码参考了原先的 ChatGPT 插件\n\n" \ "基于 text-davinci-003 模型,与 ChatGPT 的效果有些许不同\n"
"参数:\n\n- 问题:询问 ai\n" \ "代码参考了原先的 ChatGPT 插件\n\n"
"- reset重置聊天话题\n" \ "参数:\n\n- 问题:询问 ai\n"
"- thread获取已记录的聊天话题\n" \ "- reset重置聊天话题\n"
"- set <api_key>:设置 OpenAI API Key获取 API Key https://beta.openai.com/account/api-keys \n" \ "- thread获取已记录的聊天话题\n"
"- del删除 OpenAI API Key\n" \ "- set <api_key>:设置 OpenAI API Key获取 API Key https://beta.openai.com/account/api-keys \n"
"- del删除 OpenAI API Key\n"
"- template {set|get|reset} <template>: 设置/获取/重置回应模板。回应模板中的 {0} 将替换为问题,{1} 将替换为回答" "- template {set|get|reset} <template>: 设置/获取/重置回应模板。回应模板中的 {0} 将替换为问题,{1} 将替换为回答"
)
@listener( @listener(
@ -112,7 +118,9 @@ async def chat_bot_func(message: Message):
del chat_bot_session[from_id] del chat_bot_session[from_id]
return await message.edit("已重置聊天话题。") return await message.edit("已重置聊天话题。")
elif message.arguments == "thread": elif message.arguments == "thread":
return await message.edit(chat_bot_session.get(from_id, {}).get("chat_thread", "没有已记录的聊天话题。")) return await message.edit(
chat_bot_session.get(from_id, {}).get("chat_thread", "没有已记录的聊天话题。")
)
elif message.arguments == "del": elif message.arguments == "del":
if not get_api_key(): if not get_api_key():
return await message.edit("没有设置 API Key。") return await message.edit("没有设置 API Key。")
@ -122,10 +130,14 @@ async def chat_bot_func(message: Message):
return await message.edit("请先通过参数 `set [api_key]` 设置 OpenAI API Key。") return await message.edit("请先通过参数 `set [api_key]` 设置 OpenAI API Key。")
with chat_bot_lock: with chat_bot_lock:
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
message: Message = await message.edit(formatted_response(message.arguments, "处理中...")) message: Message = await message.edit(
formatted_response(message.arguments, "处理中...")
)
try: try:
chat_thread = chat_bot_session.get(from_id, {}).get("chat_thread", "") chat_thread = chat_bot_session.get(from_id, {}).get("chat_thread", "")
prompt = f"{chat_thread}\nHuman: {message.arguments}\nAI: "[-3946:] # 4096 - 150(max_tokens) prompt = f"{chat_thread}\nHuman: {message.arguments}\nAI: "[
-3946:
] # 4096 - 150(max_tokens)
msg = await get_chat_response(prompt) msg = await get_chat_response(prompt)
chat_bot_session[from_id]["chat_thread"] = prompt + msg chat_bot_session[from_id]["chat_thread"] = prompt + msg
except Exception as e: except Exception as e:

View File

@ -9,10 +9,9 @@ from pagermaid.enums import Client, Message
from pagermaid.scheduler import add_delete_message_job from pagermaid.scheduler import add_delete_message_job
@listener(command="paolu", @listener(
groups_only=True, command="paolu", groups_only=True, need_admin=True, description="⚠一键跑路 删除群内消息并禁言⚠"
need_admin=True, )
description="⚠一键跑路 删除群内消息并禁言⚠")
async def pao_lu(bot: Client, message: Message): async def pao_lu(bot: Client, message: Message):
"""一键跑路 删除群内消息并禁言""" """一键跑路 删除群内消息并禁言"""
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
@ -20,7 +19,8 @@ async def pao_lu(bot: Client, message: Message):
message.chat.id, message.chat.id,
permissions=ChatPermissions( permissions=ChatPermissions(
can_send_messages=False, can_send_messages=False,
)) ),
)
reply = await message.edit("[paolu] 处理中...") reply = await message.edit("[paolu] 处理中...")
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
await bot.delete_messages(message.chat.id, list(range(1, message.id))) await bot.delete_messages(message.chat.id, list(range(1, message.id)))

View File

@ -17,11 +17,19 @@ async def get_photo(message: Message) -> Optional[str]:
if reply := message.reply_to_message: if reply := message.reply_to_message:
if reply.photo: if reply.photo:
return await reply.download() return await reply.download()
elif reply.document and reply.document.mime_type and reply.document.mime_type.startswith("image"): elif (
reply.document
and reply.document.mime_type
and reply.document.mime_type.startswith("image")
):
return await reply.download() return await reply.download()
elif message.photo: elif message.photo:
return await message.download() return await message.download()
elif message.document and message.document.mime_type and message.document.mime_type.startswith("image"): elif (
message.document
and message.document.mime_type
and message.document.mime_type.startswith("image")
):
return await message.download() return await message.download()
return None return None
@ -44,10 +52,7 @@ async def set_photo(client: Client, user: InputUser, photo: str, me: bool) -> No
safe_remove(photo) safe_remove(photo)
@listener( @listener(command="pfp", description=lang("pfp_des"))
command="pfp",
description=lang("pfp_des")
)
async def pfp(client: Client, message: Message): async def pfp(client: Client, message: Message):
"""Sets your profile picture.""" """Sets your profile picture."""
me = await client.get_me() me = await client.get_me()
@ -59,7 +64,7 @@ async def pfp(client: Client, message: Message):
if not photo: if not photo:
return await message.edit(f"{lang('error_prefix')}{lang('pfp_e_notp')}") return await message.edit(f"{lang('error_prefix')}{lang('pfp_e_notp')}")
if not Config.SILENT: if not Config.SILENT:
message = await message.edit(lang('pfp_process')) message = await message.edit(lang("pfp_process"))
try: try:
await set_photo(client, peer, photo, peer.user_id == me.id) await set_photo(client, peer, photo, peer.user_id == me.id)
await message.edit("头像修改成功啦 ~") await message.edit("头像修改成功啦 ~")

View File

@ -31,8 +31,7 @@ async def resize_image(photo):
return image return image
@listener(command="pic_to_sticker", @listener(command="pic_to_sticker", description="将你回复的图片转换为贴纸")
description="将你回复的图片转换为贴纸")
async def pic_to_sticker(bot: Client, message: Message): async def pic_to_sticker(bot: Client, message: Message):
reply = message.reply_to_message reply = message.reply_to_message
photo = None photo = None

View File

@ -5,8 +5,7 @@ import copy
import os import os
import random import random
from dataclasses import dataclass from dataclasses import dataclass
from typing import (Any, Awaitable, Callable, Dict, List, NamedTuple, Optional, from typing import Any, Awaitable, Callable, Dict, List, NamedTuple, Optional, Tuple
Tuple)
import yaml import yaml
from pagermaid import logs from pagermaid import logs
@ -358,9 +357,7 @@ async def help_cmd(_: Client, message: Message) -> None:
) )
@cmdman.subcommand( @cmdman.subcommand("id", "根据 ID 获取 Pixiv 相关插图", "<ID>")
"id", "根据 ID 获取 Pixiv 相关插图", "<ID>"
)
async def id_cmd(_: Client, message: Message) -> None: async def id_cmd(_: Client, message: Message) -> None:
try: try:
id_ = int(message.arguments) id_ = int(message.arguments)

File diff suppressed because it is too large Load Diff

View File

@ -8,9 +8,14 @@ from pagermaid.listener import listener
from pagermaid.enums import Client, Message from pagermaid.enums import Client, Message
@listener(command="portball", is_plugin=True, outgoing=True, need_admin=True, @listener(
command="portball",
is_plugin=True,
outgoing=True,
need_admin=True,
description="回复你要临时禁言的人的消息来实现XX秒的禁言", description="回复你要临时禁言的人的消息来实现XX秒的禁言",
parameters="[理由]|<时间/秒>") parameters="[理由]|<时间/秒>",
)
async def portball(bot: Client, message: Message): async def portball(bot: Client, message: Message):
if message.chat.type in (ChatType.GROUP, ChatType.SUPERGROUP): if message.chat.type in (ChatType.GROUP, ChatType.SUPERGROUP):
reply_to_message = message.reply_to_message reply_to_message = message.reply_to_message
@ -20,7 +25,7 @@ async def portball(bot: Client, message: Message):
if from_user is None: if from_user is None:
return return
if from_user.is_self: if from_user.is_self:
edit_message: Message = await message.edit_text('无法禁言自己。') edit_message: Message = await message.edit_text("无法禁言自己。")
await edit_message.delay_delete() await edit_message.delay_delete()
return return
seconds: int = -1 seconds: int = -1
@ -49,8 +54,12 @@ async def portball(bot: Client, message: Message):
await edit_message.delay_delete() await edit_message.delay_delete()
return return
try: try:
await bot.restrict_chat_member(chat.id, from_user.id, ChatPermissions(), await bot.restrict_chat_member(
datetime.now() + timedelta(seconds=seconds)) chat.id,
from_user.id,
ChatPermissions(),
datetime.now() + timedelta(seconds=seconds),
)
except (UserAdminInvalid, ChatAdminRequired): except (UserAdminInvalid, ChatAdminRequired):
await bot.send_message(chat.id, "错误:该操作需要管理员权限") await bot.send_message(chat.id, "错误:该操作需要管理员权限")
await message.delay_delete() await message.delay_delete()

View File

@ -1,9 +1,9 @@
# -*- coding: UTF-8 -*- # -*- coding: UTF-8 -*-
''' """
@File main.py @File main.py
@Author 汐洛 @guimc233 @Author 汐洛 @guimc233
@Date 2022/6/23 21:57 @Date 2022/6/23 21:57
''' """
from pyrogram import Client from pyrogram import Client
from pagermaid.listener import listener from pagermaid.listener import listener
@ -11,16 +11,16 @@ from pagermaid.utils import Message, client
from pyrogram.enums import ChatMemberStatus, ParseMode from pyrogram.enums import ChatMemberStatus, ParseMode
@listener(command="premium", @listener(command="premium", groups_only=True, description="分遗产咯")
groups_only=True,
description="分遗产咯")
async def premium(bot: Client, context: Message): async def premium(bot: Client, context: Message):
context = await context.edit("Please wait...") context = await context.edit("Please wait...")
premium_users = users = admins = premium_admins = bots = deleted = 0 premium_users = users = admins = premium_admins = bots = deleted = 0
dc_ids = {"1": 0, "2": 0, "3": 0, "4": 0, "5": 0, "failed": 0} dc_ids = {"1": 0, "2": 0, "3": 0, "4": 0, "5": 0, "failed": 0}
count = await bot.get_chat_members_count(context.chat.id) count = await bot.get_chat_members_count(context.chat.id)
if count >= 10000 and context.arguments != "force": if count >= 10000 and context.arguments != "force":
return await context.edit("太...太多人了... 我会...会...会坏掉的...\n\n如果您执意要运行的的话,您可以使用指令 ,premium force") return await context.edit(
"太...太多人了... 我会...会...会坏掉的...\n\n如果您执意要运行的的话,您可以使用指令 ,premium force"
)
async for m in bot.get_chat_members(context.chat.id): async for m in bot.get_chat_members(context.chat.id):
if not m.user.is_bot and not m.user.is_deleted: if not m.user.is_bot and not m.user.is_deleted:
users += 1 users += 1
@ -38,7 +38,8 @@ async def premium(bot: Client, context: Message):
bots += 1 bots += 1
else: else:
deleted += 1 deleted += 1
await context.edit(f"""**分遗产咯** await context.edit(
f"""**分遗产咯**
管理员: 管理员:
> 大会员: **{premium_admins}** / 总管理数: **{admins}** 分遗产占比: **{round((premium_admins/admins)*100, 2) if admins != 0 else '你群管理员全死号?'}%** > 大会员: **{premium_admins}** / 总管理数: **{admins}** 分遗产占比: **{round((premium_admins/admins)*100, 2) if admins != 0 else '你群管理员全死号?'}%**
@ -48,4 +49,6 @@ async def premium(bot: Client, context: Message):
> 已自动过滤掉 **{bots}** Bot, **{deleted}** 死号 > 已自动过滤掉 **{bots}** Bot, **{deleted}** 死号
{'***请注意: 由于tg限制 我们只能遍历前10k人 此次获得到的数据并不完整***' if count >= 10000 else ''}""", parse_mode = ParseMode.MARKDOWN) {'***请注意: 由于tg限制 我们只能遍历前10k人 此次获得到的数据并不完整***' if count >= 10000 else ''}""",
parse_mode=ParseMode.MARKDOWN,
)

View File

@ -7,4 +7,6 @@ from pagermaid.listener import listener
async def print_official_notifications(message: Message): async def print_official_notifications(message: Message):
if not message.from_user.is_verified: if not message.from_user.is_verified:
return return
logs.info(f"Official notification from {message.from_user.first_name}: {message.text}") logs.info(
f"Official notification from {message.from_user.first_name}: {message.text}"
)

View File

@ -18,13 +18,15 @@ def escape_definition(definition):
return definition return definition
@listener(command="pypi", @listener(
description="Search PyPI packages", command="pypi", description="Search PyPI packages", parameters="The query string"
parameters="The query string") )
async def pypi(message: Message, httpx: AsyncClient): async def pypi(message: Message, httpx: AsyncClient):
if not message.arguments: if not message.arguments:
return await message.edit("Please provide a query string") return await message.edit("Please provide a query string")
r = await httpx.get(f"https://pypi.org/pypi/{message.arguments}/json", follow_redirects=True) r = await httpx.get(
f"https://pypi.org/pypi/{message.arguments}/json", follow_redirects=True
)
if r.status_code != 200: if r.status_code != 200:
return await message.edit("Could not find the package") return await message.edit("Could not find the package")
json = r.json() json = r.json()

View File

@ -17,12 +17,12 @@ async def qq_music(message: Message, client: AsyncClient):
msg: Message = await message.edit("正在查询,请稍候...") msg: Message = await message.edit("正在查询,请稍候...")
try: try:
res = await client.get( res = await client.get(
f'https://zj.v.api.aa1.cn/api/qqmusic/?songName={key}&pageNum=1&pageSize=1&type=qq', f"https://zj.v.api.aa1.cn/api/qqmusic/?songName={key}&pageNum=1&pageSize=1&type=qq",
timeout=10.0, timeout=10.0,
) )
if res.status_code == 200: if res.status_code == 200:
resp = res.json() resp = res.json()
data = resp['list'] data = resp["list"]
if len(data) == 0: if len(data) == 0:
return await msg.edit("没有找到相关音乐") return await msg.edit("没有找到相关音乐")
uri = data[0].get("url") uri = data[0].get("url")
@ -35,7 +35,8 @@ async def qq_music(message: Message, client: AsyncClient):
uri, uri,
thumb=cover or None, thumb=cover or None,
caption=f"{text}", caption=f"{text}",
reply_to_message_id=message.reply_to_message_id or message.reply_to_top_message_id, reply_to_message_id=message.reply_to_message_id
or message.reply_to_top_message_id,
) )
await msg.safe_delete() await msg.safe_delete()
except Exception as e: except Exception as e:

View File

@ -14,23 +14,28 @@ pip_install("pyzbar")
from pyqrcode import create from pyqrcode import create
@listener(is_plugin=False, outgoing=True, command="genqr", @listener(
description=lang('genqr_des'), is_plugin=False,
parameters="[string]") outgoing=True,
command="genqr",
description=lang("genqr_des"),
parameters="[string]",
)
async def gen_qr(client: Client, message: Message): async def gen_qr(client: Client, message: Message):
"""Generate QR codes.""" """Generate QR codes."""
text = message.obtain_message() text = message.obtain_message()
if not text: if not text:
await message.edit(lang('error_prefix')) await message.edit(lang("error_prefix"))
return return
if not Config.SILENT: if not Config.SILENT:
await message.edit(lang('genqr_process')) await message.edit(lang("genqr_process"))
try: try:
create(text, error="L", encoding="utf-8", mode="binary").png("qr.webp", scale=6) create(text, error="L", encoding="utf-8", mode="binary").png("qr.webp", scale=6)
await client.send_document( await client.send_document(
message.chat.id, message.chat.id,
document="qr.webp", document="qr.webp",
reply_to_message_id=message.reply_to_message_id or message.reply_to_top_message_id, reply_to_message_id=message.reply_to_message_id
or message.reply_to_top_message_id,
) )
except UnicodeEncodeError: except UnicodeEncodeError:
await message.edit(f"{lang('error_prefix')}{lang('genqr_e_encode')}") await message.edit(f"{lang('error_prefix')}{lang('genqr_e_encode')}")
@ -44,8 +49,9 @@ async def gen_qr(client: Client, message: Message):
await log(f"`{text}` {lang('genqr_ok')}") await log(f"`{text}` {lang('genqr_ok')}")
@listener(is_plugin=False, outgoing=True, command="parseqr", @listener(
description=lang('parseqr_des')) is_plugin=False, outgoing=True, command="parseqr", description=lang("parseqr_des")
)
async def parse_qr(message: Message): async def parse_qr(message: Message):
"""Parse attachment of replied message as a QR Code and output results.""" """Parse attachment of replied message as a QR Code and output results."""
try: try:
@ -64,8 +70,7 @@ async def parse_qr(message: Message):
try: try:
text = str(pyzbar_decode(Image.open(target_file_path))[0].data)[2:][:-1] text = str(pyzbar_decode(Image.open(target_file_path))[0].data)[2:][:-1]
success = True success = True
await message.edit(f"**{lang('parseqr_content')}: **\n" await message.edit(f"**{lang('parseqr_content')}: **\n" f"`{text}`")
f"`{text}`")
except Exception: except Exception:
await message.edit(f"{lang('error_prefix')}{lang('parseqr_e_noqr')}") await message.edit(f"{lang('error_prefix')}{lang('parseqr_e_noqr')}")
text = None text = None

View File

@ -15,22 +15,26 @@ class Rate:
def __init__(self): def __init__(self):
if Config.LANGUAGE == "en": if Config.LANGUAGE == "en":
self.lang_rate = { self.lang_rate = {
"des": "Currency exchange rate plugin", "arg": "[from_] [to_] [NUM]", "des": "Currency exchange rate plugin",
"arg": "[from_] [to_] [NUM]",
"help": "Currency exchange rate plugin\n\n" "help": "Currency exchange rate plugin\n\n"
f"Usage: `,{alias_command('rate')} [from_] [to_] [NUM] where [NUM] is " f"Usage: `,{alias_command('rate')} [from_] [to_] [NUM] where [NUM] is "
"optional`\n\nAvailable currencies: \n", "optional`\n\nAvailable currencies: \n",
"nc": "is not available.\n\nAvailable currencies: \n", "nc": "is not available.\n\nAvailable currencies: \n",
"notice": "Data are updated daily.", "notice": "Data are updated daily.",
"warning": "Data are updated daily."} "warning": "Data are updated daily.",
}
else: else:
self.lang_rate = { self.lang_rate = {
"des": "货币汇率插件", "arg": "[from_] [to_] [NUM]", "des": "货币汇率插件",
"arg": "[from_] [to_] [NUM]",
"help": "这是货币汇率插件\n\n" "help": "这是货币汇率插件\n\n"
f"使用方法: `,{alias_command('rate')} [from_] [to_] [NUM],其中 [NUM] 是可省略的`\n\n" f"使用方法: `,{alias_command('rate')} [from_] [to_] [NUM],其中 [NUM] 是可省略的`\n\n"
"支持货币: \n", "支持货币: \n",
"nc": "不是支持的货币. \n\n支持货币: \n", "nc": "不是支持的货币. \n\n支持货币: \n",
"notice": "数据每日八点更新", "notice": "数据每日八点更新",
"warning": "数据每日八点更新"} "warning": "数据每日八点更新",
}
self.host = "https://cdn.jsdelivr.net/gh/fawazahmed0/currency-api@1/latest" self.host = "https://cdn.jsdelivr.net/gh/fawazahmed0/currency-api@1/latest"
self.api = f"{self.host}/currencies.json" self.api = f"{self.host}/currencies.json"
self.currencies = [] self.currencies = []
@ -52,9 +56,11 @@ class Rate:
try: try:
req = await client.get(endpoint, follow_redirects=True) req = await client.get(endpoint, follow_redirects=True)
rate__data = req.json() rate__data = req.json()
return f'`{from_} : {to_} = {nb} : {round(nb * rate__data[to_.lower()], 4)}`' \ return (
f'\n\n' \ f"`{from_} : {to_} = {nb} : {round(nb * rate__data[to_.lower()], 4)}`"
f"\n\n"
f'{self.lang_rate["warning"]}' f'{self.lang_rate["warning"]}'
)
except Exception as e: except Exception as e:
return str(e) return str(e)
@ -72,9 +78,11 @@ async def refresher_rate():
await rate_data.get_data() await rate_data.get_data()
@listener(command="rate", @listener(
command="rate",
description=rate_data.lang_rate["des"], description=rate_data.lang_rate["des"],
parameters=rate_data.lang_rate["arg"]) parameters=rate_data.lang_rate["arg"],
)
async def rate(message: Message): async def rate(message: Message):
global rate_data global rate_data
if not rate_data.data: if not rate_data.data:
@ -82,13 +90,17 @@ async def rate(message: Message):
if not rate_data.data: if not rate_data.data:
return return
if not message.arguments: if not message.arguments:
await message.edit(f"{rate_data.lang_rate['help']}`{', '.join(rate_data.currencies)}`\n\n" await message.edit(
f"{rate_data.lang_rate['notice']}") f"{rate_data.lang_rate['help']}`{', '.join(rate_data.currencies)}`\n\n"
f"{rate_data.lang_rate['notice']}"
)
return return
nb = 1.0 nb = 1.0
if len(message.parameter) not in [3, 2]: if len(message.parameter) not in [3, 2]:
await message.edit(f"{rate_data.lang_rate['help']}`{', '.join(rate_data.currencies)}`" await message.edit(
f"\n\n{rate_data.lang_rate['notice']}") f"{rate_data.lang_rate['help']}`{', '.join(rate_data.currencies)}`"
f"\n\n{rate_data.lang_rate['notice']}"
)
return return
from_ = message.parameter[0].upper().strip() from_ = message.parameter[0].upper().strip()
to_ = message.parameter[1].upper().strip() to_ = message.parameter[1].upper().strip()
@ -97,10 +109,14 @@ async def rate(message: Message):
except Exception: except Exception:
nb = 1.0 nb = 1.0
if rate_data.currencies.count(from_) == 0: if rate_data.currencies.count(from_) == 0:
await message.edit(f"{from_}{rate_data.lang_rate['nc']}`{', '.join(rate_data.currencies)}`") await message.edit(
f"{from_}{rate_data.lang_rate['nc']}`{', '.join(rate_data.currencies)}`"
)
return return
if rate_data.currencies.count(to_) == 0: if rate_data.currencies.count(to_) == 0:
await message.edit(f"{to_}{rate_data.lang_rate['nc']}{', '.join(rate_data.currencies)}`") await message.edit(
f"{to_}{rate_data.lang_rate['nc']}{', '.join(rate_data.currencies)}`"
)
return return
try: try:
text = await rate_data.get_rate(from_, to_, nb) text = await rate_data.get_rate(from_, to_, nb)

View File

@ -4,8 +4,7 @@ from pagermaid.listener import listener
from pagermaid.utils import Message, client from pagermaid.utils import Message, client
@listener(command="zhrs", @listener(command="zhrs", description="知乎热搜。")
description="知乎热搜。")
async def zhrs(_: Client, message: Message): async def zhrs(_: Client, message: Message):
req = await client.get("https://tenapi.cn/zhihuresou/") req = await client.get("https://tenapi.cn/zhihuresou/")
if req.status_code == 200: if req.status_code == 200:
@ -14,7 +13,7 @@ async def zhrs(_: Client, message: Message):
except JSONDecodeError: except JSONDecodeError:
await message.edit("出错了呜呜呜 ~ API 数据解析失败。") await message.edit("出错了呜呜呜 ~ API 数据解析失败。")
return return
res = '知乎实时热搜榜:\n' res = "知乎实时热搜榜:\n"
for i in range(10): for i in range(10):
res += f'\n{i + 1}.「<a href={data["list"][i]["url"]}>{data["list"][i]["query"]}</a>」' res += f'\n{i + 1}.「<a href={data["list"][i]["url"]}>{data["list"][i]["query"]}</a>」'
await message.edit(res) await message.edit(res)
@ -22,8 +21,7 @@ async def zhrs(_: Client, message: Message):
await message.edit("出错了呜呜呜 ~ 无法访问到 API 服务器 。") await message.edit("出错了呜呜呜 ~ 无法访问到 API 服务器 。")
@listener(command="wbrs", @listener(command="wbrs", description="微博热搜。")
description="微博热搜。")
async def wbrs(_: Client, message: Message): async def wbrs(_: Client, message: Message):
req = await client.get("https://tenapi.cn/resou/") req = await client.get("https://tenapi.cn/resou/")
if req.status_code == 200: if req.status_code == 200:
@ -32,17 +30,18 @@ async def wbrs(_: Client, message: Message):
except JSONDecodeError: except JSONDecodeError:
await message.edit("出错了呜呜呜 ~ API 数据解析失败。") await message.edit("出错了呜呜呜 ~ API 数据解析失败。")
return return
res = '微博实时热搜榜:\n' res = "微博实时热搜榜:\n"
for i in range(10): for i in range(10):
res += f'\n{i + 1}.「<a href={data["list"][i]["url"]}>{data["list"][i]["name"]}</a>」 ' \ res += (
f'\n{i + 1}.「<a href={data["list"][i]["url"]}>{data["list"][i]["name"]}</a>」 '
f'热度:{data["list"][i]["hot"]}' f'热度:{data["list"][i]["hot"]}'
)
await message.edit(res) await message.edit(res)
else: else:
await message.edit("出错了呜呜呜 ~ 无法访问到 API 服务器 。") await message.edit("出错了呜呜呜 ~ 无法访问到 API 服务器 。")
@listener(command="dyrs", @listener(command="dyrs", description="抖音热搜。")
description="抖音热搜。")
async def dyrs(_: Client, message: Message): async def dyrs(_: Client, message: Message):
req = await client.get("https://tenapi.cn/douyinresou/") req = await client.get("https://tenapi.cn/douyinresou/")
if req.status_code == 200: if req.status_code == 200:
@ -51,7 +50,7 @@ async def dyrs(_: Client, message: Message):
except JSONDecodeError: except JSONDecodeError:
await message.edit("出错了呜呜呜 ~ API 数据解析失败。") await message.edit("出错了呜呜呜 ~ API 数据解析失败。")
return return
res = '抖音实时热搜榜:\n' res = "抖音实时热搜榜:\n"
for i in range(10): for i in range(10):
res += f'\n{i + 1}.「{data["list"][i]["name"]}」 热度:{data["list"][i]["hot"]}' res += f'\n{i + 1}.「{data["list"][i]["name"]}」 热度:{data["list"][i]["hot"]}'
await message.edit(res) await message.edit(res)

View File

@ -1,7 +1,13 @@
from asyncio import sleep from asyncio import sleep
from pyrogram.enums import ChatType from pyrogram.enums import ChatType
from pyrogram.errors import ChatAdminRequired, FloodWait, PeerIdInvalid, UserAdminInvalid, UsernameInvalid from pyrogram.errors import (
ChatAdminRequired,
FloodWait,
PeerIdInvalid,
UserAdminInvalid,
UsernameInvalid,
)
from pyrogram.types import Chat from pyrogram.types import Chat
from pagermaid import log from pagermaid import log
@ -13,7 +19,11 @@ from pagermaid.utils import lang
def mention_group(chat: Chat): def mention_group(chat: Chat):
return f'<a href="https://t.me/{chat.username}">{chat.title}</a>' if chat.username else f'<code>{chat.title}</code>' return (
f'<a href="https://t.me/{chat.username}">{chat.title}</a>'
if chat.username
else f"<code>{chat.title}</code>"
)
async def ban_one(chat: Chat, uid): async def ban_one(chat: Chat, uid):
@ -64,11 +74,13 @@ async def get_uid(chat: Chat, message: Message):
return uid, channel, delete_all, sender return uid, channel, delete_all, sender
@listener(command="sb", @listener(
description=lang('sb_des'), command="sb",
description=lang("sb_des"),
need_admin=True, need_admin=True,
groups_only=True, groups_only=True,
parameters="[reply|id|username> <do_not_del_all]") parameters="[reply|id|username> <do_not_del_all]",
)
async def super_ban(message: Message): async def super_ban(message: Message):
chat = message.chat chat = message.chat
try: try:
@ -126,6 +138,6 @@ async def super_ban(message: Message):
else: else:
text = f'{lang("sb_per")} {count} {lang("sb_in")} {sender.mention}' text = f'{lang("sb_per")} {count} {lang("sb_in")} {sender.mention}'
await message.edit(text) await message.edit(text)
groups = f'\n{lang("sb_pro")}\n' + "\n".join(groups) if groups else '' groups = f'\n{lang("sb_pro")}\n' + "\n".join(groups) if groups else ""
await log(f'{text}\nuid: `{uid}` {groups}') await log(f"{text}\nuid: `{uid}` {groups}")
add_delete_message_job(message, 10) add_delete_message_job(message, 10)

View File

@ -17,7 +17,14 @@ class SendTask:
cron: str cron: str
pause: bool pause: bool
def __init__(self, task_id: int, cid: int = 0, msg: str = "", cron: str = "", pause: bool = False): def __init__(
self,
task_id: int,
cid: int = 0,
msg: str = "",
cron: str = "",
pause: bool = False,
):
self.task_id = task_id self.task_id = task_id
self.cid = cid self.cid = cid
self.msg = msg self.msg = msg
@ -25,7 +32,13 @@ class SendTask:
self.pause = pause self.pause = pause
def export(self): def export(self):
return {"task_id": self.task_id, "cid": self.cid, "msg": self.msg, "cron": self.cron, "pause": self.pause} return {
"task_id": self.task_id,
"cid": self.cid,
"msg": self.msg,
"cron": self.cron,
"pause": self.pause,
}
def get_job(self): def get_job(self):
return scheduler.get_job(f"send_cron|{self.cid}|{self.task_id}") return scheduler.get_job(f"send_cron|{self.cid}|{self.task_id}")
@ -35,8 +48,7 @@ class SendTask:
scheduler.remove_job(f"send_cron|{self.cid}|{self.task_id}") scheduler.remove_job(f"send_cron|{self.cid}|{self.task_id}")
def export_str(self, show_all: bool = False): def export_str(self, show_all: bool = False):
text = f"<code>{self.task_id}</code> - " \ text = f"<code>{self.task_id}</code> - " f"<code>{self.cron}</code> -"
f"<code>{self.cron}</code> -"
if job := self.get_job(): if job := self.get_job():
time: datetime.datetime = job.next_run_time time: datetime.datetime = job.next_run_time
text += f"<code>{time.strftime('%Y-%m-%d %H:%M:%S')}</code> - " text += f"<code>{time.strftime('%Y-%m-%d %H:%M:%S')}</code> - "
@ -108,7 +120,11 @@ class SendTasks:
return [task.task_id for task in self.tasks] return [task.task_id for task in self.tasks]
def print_all_tasks(self, show_all: bool = False, cid: int = 0) -> str: def print_all_tasks(self, show_all: bool = False, cid: int = 0) -> str:
return "\n".join(task.export_str(show_all) for task in self.tasks if task.cid == cid or show_all) return "\n".join(
task.export_str(show_all)
for task in self.tasks
if task.cid == cid or show_all
)
def save_to_file(self): def save_to_file(self):
data = [task.export() for task in self.tasks] data = [task.export() for task in self.tasks]
@ -210,7 +226,8 @@ async def send_cron(message: Message):
return await message.edit("请输入正确的参数") return await message.edit("请输入正确的参数")
if send_cron_tasks.get_all_ids(): if send_cron_tasks.get_all_ids():
return await message.edit( return await message.edit(
f"已注册的任务:\n\n{send_cron_tasks.print_all_tasks(show_all=False, cid=message.chat.id)}") f"已注册的任务:\n\n{send_cron_tasks.print_all_tasks(show_all=False, cid=message.chat.id)}"
)
else: else:
return await message.edit("没有已注册的任务。") return await message.edit("没有已注册的任务。")
if len(message.parameter) == 2: if len(message.parameter) == 2:
@ -231,7 +248,8 @@ async def send_cron(message: Message):
elif message.parameter[0] == "list": elif message.parameter[0] == "list":
if send_cron_tasks.get_all_ids(): if send_cron_tasks.get_all_ids():
return await message.edit( return await message.edit(
f"已注册的任务:\n\n{send_cron_tasks.print_all_tasks(show_all=True)}") f"已注册的任务:\n\n{send_cron_tasks.print_all_tasks(show_all=True)}"
)
else: else:
return await message.edit("没有已注册的任务。") return await message.edit("没有已注册的任务。")
# add task # add task

View File

@ -24,9 +24,19 @@ class SendTask:
minute: str = "0" minute: str = "0"
second: str = "0" second: str = "0"
def __init__(self, task_id: Optional[int] = None, cid: int = 0, msg: str = "", interval: bool = False, def __init__(
cron: bool = False, pause: bool = False, time_limit: int = -1, self,
hour: str = "0", minute: str = "0", second: str = "0"): task_id: Optional[int] = None,
cid: int = 0,
msg: str = "",
interval: bool = False,
cron: bool = False,
pause: bool = False,
time_limit: int = -1,
hour: str = "0",
minute: str = "0",
second: str = "0",
):
self.task_id = task_id self.task_id = task_id
self.cid = cid self.cid = cid
self.msg = msg self.msg = msg
@ -44,9 +54,18 @@ class SendTask:
self.save_to_file() self.save_to_file()
def export(self): def export(self):
return {"task_id": self.task_id, "cid": self.cid, "msg": self.msg, "interval": self.interval, return {
"cron": self.cron, "pause": self.pause, "time_limit": self.time_limit, "hour": self.hour, "task_id": self.task_id,
"minute": self.minute, "second": self.second} "cid": self.cid,
"msg": self.msg,
"interval": self.interval,
"cron": self.cron,
"pause": self.pause,
"time_limit": self.time_limit,
"hour": self.hour,
"minute": self.minute,
"second": self.second,
}
def get_job(self): def get_job(self):
return scheduler.get_job(f"sendat|{self.cid}|{self.task_id}") return scheduler.get_job(f"sendat|{self.cid}|{self.task_id}")
@ -56,8 +75,10 @@ class SendTask:
scheduler.remove_job(f"sendat|{self.cid}|{self.task_id}") scheduler.remove_job(f"sendat|{self.cid}|{self.task_id}")
def export_str(self, show_all: bool = False): def export_str(self, show_all: bool = False):
text = f"<code>{self.task_id}</code> - " \ text = (
f"<code>{self.task_id}</code> - "
f"<code>{'循环任务' if self.interval else '单次任务'}</code> - " f"<code>{'循环任务' if self.interval else '单次任务'}</code> - "
)
if job := self.get_job(): if job := self.get_job():
time: datetime.datetime = job.next_run_time time: datetime.datetime = job.next_run_time
text += f"<code>{time.strftime('%Y-%m-%d %H:%M:%S')}</code> - " text += f"<code>{time.strftime('%Y-%m-%d %H:%M:%S')}</code> - "
@ -162,7 +183,11 @@ class SendTasks:
return [task.task_id for task in self.tasks] return [task.task_id for task in self.tasks]
def print_all_tasks(self, show_all: bool = False, cid: int = 0) -> str: def print_all_tasks(self, show_all: bool = False, cid: int = 0) -> str:
return "\n".join(task.export_str(show_all) for task in self.tasks if task.cid == cid or show_all) return "\n".join(
task.export_str(show_all)
for task in self.tasks
if task.cid == cid or show_all
)
def save_to_file(self): def save_to_file(self):
data = [task.export() for task in self.tasks] data = [task.export() for task in self.tasks]
@ -193,36 +218,44 @@ class SendTasks:
task.remove_job() task.remove_job()
def register_interval_task(self, task: SendTask): def register_interval_task(self, task: SendTask):
scheduler.add_job(self.send_message, scheduler.add_job(
self.send_message,
"interval", "interval",
id=f"sendat|{task.cid}|{task.task_id}", id=f"sendat|{task.cid}|{task.task_id}",
name=f"sendat|{task.cid}|{task.task_id}", name=f"sendat|{task.cid}|{task.task_id}",
hours=int(task.hour), hours=int(task.hour),
minutes=int(task.minute), minutes=int(task.minute),
seconds=int(task.second), seconds=int(task.second),
args=[task, self]) args=[task, self],
)
def register_cron_task(self, task: SendTask): def register_cron_task(self, task: SendTask):
scheduler.add_job(self.send_message, scheduler.add_job(
self.send_message,
"cron", "cron",
id=f"sendat|{task.cid}|{task.task_id}", id=f"sendat|{task.cid}|{task.task_id}",
name=f"sendat|{task.cid}|{task.task_id}", name=f"sendat|{task.cid}|{task.task_id}",
hour=int(task.hour), hour=int(task.hour),
minute=int(task.minute), minute=int(task.minute),
second=int(task.second), second=int(task.second),
args=[task, self]) args=[task, self],
)
def register_date_task(self, task: SendTask): def register_date_task(self, task: SendTask):
date_now = datetime.datetime.now(pytz.timezone(Config.TIME_ZONE)) date_now = datetime.datetime.now(pytz.timezone(Config.TIME_ZONE))
date_will = date_now.replace(hour=int(task.hour), minute=int(task.minute), second=int(task.second)) date_will = date_now.replace(
hour=int(task.hour), minute=int(task.minute), second=int(task.second)
)
if date_will < date_now: if date_will < date_now:
date_will += datetime.timedelta(days=1) date_will += datetime.timedelta(days=1)
scheduler.add_job(self.send_message, scheduler.add_job(
self.send_message,
"date", "date",
id=f"sendat|{task.cid}|{task.task_id}", id=f"sendat|{task.cid}|{task.task_id}",
name=f"sendat|{task.cid}|{task.task_id}", name=f"sendat|{task.cid}|{task.task_id}",
run_date=date_will, run_date=date_will,
args=[task, self]) args=[task, self],
)
def register_single_task(self, task: SendTask): def register_single_task(self, task: SendTask):
if task.pause or task.time_limit == 0: if task.pause or task.time_limit == 0:
@ -286,10 +319,12 @@ async def from_msg_get_task_id(message: Message):
return uid return uid
@listener(command="sendat", @listener(
command="sendat",
parameters="时间 | 消息内容", parameters="时间 | 消息内容",
need_admin=True, need_admin=True,
description=f"定时发送消息\n请使用 ,{alias_command('sendat')} h 查看可用命令") description=f"定时发送消息\n请使用 ,{alias_command('sendat')} h 查看可用命令",
)
async def send_at(message: Message): async def send_at(message: Message):
if message.arguments == "h" or len(message.parameter) == 0: if message.arguments == "h" or len(message.parameter) == 0:
return await message.edit(send_help_msg) return await message.edit(send_help_msg)
@ -298,7 +333,8 @@ async def send_at(message: Message):
return await message.edit("请输入正确的参数") return await message.edit("请输入正确的参数")
if send_tasks.get_all_ids(): if send_tasks.get_all_ids():
return await message.edit( return await message.edit(
f"已注册的任务:\n\n{send_tasks.print_all_tasks(show_all=False, cid=message.chat.id)}") f"已注册的任务:\n\n{send_tasks.print_all_tasks(show_all=False, cid=message.chat.id)}"
)
else: else:
return await message.edit("没有已注册的任务。") return await message.edit("没有已注册的任务。")
if len(message.parameter) == 2: if len(message.parameter) == 2:
@ -319,7 +355,8 @@ async def send_at(message: Message):
elif message.parameter[0] == "list": elif message.parameter[0] == "list":
if send_tasks.get_all_ids(): if send_tasks.get_all_ids():
return await message.edit( return await message.edit(
f"已注册的任务:\n\n{send_tasks.print_all_tasks(show_all=True)}") f"已注册的任务:\n\n{send_tasks.print_all_tasks(show_all=True)}"
)
else: else:
return await message.edit("没有已注册的任务。") return await message.edit("没有已注册的任务。")
# add task # add task

View File

@ -26,7 +26,14 @@ async def filter_session(hash_start: str) -> Optional[Authorization]:
return None return None
except ValueError: except ValueError:
return None return None
return next((session for session in await get_all_session() if str(session.hash).startswith(str(hash_start))), None) return next(
(
session
for session in await get_all_session()
if str(session.hash).startswith(str(hash_start))
),
None,
)
async def kick_session(session: Authorization) -> bool: async def kick_session(session: Authorization) -> bool:
@ -42,18 +49,21 @@ def format_timestamp(timestamp: int) -> str:
def format_session(session: Authorization, private: bool = True) -> str: def format_session(session: Authorization, private: bool = True) -> str:
text = f"标识符:<code>{str(session.hash)[:6]}</code>\n" \ text = (
f"设备型号:<code>{session.device_model}</code>\n" \ f"标识符:<code>{str(session.hash)[:6]}</code>\n"
f"设备平台:<code>{session.platform}</code>\n" \ f"设备型号:<code>{session.device_model}</code>\n"
f"系统版本:<code>{session.system_version}</code>\n" \ f"设备平台:<code>{session.platform}</code>\n"
f"应用名称:<code>{session.app_name}</code>\n" \ f"系统版本:<code>{session.system_version}</code>\n"
f"应用版本:<code>{session.app_version}</code>\n" \ f"应用名称:<code>{session.app_name}</code>\n"
f"官方应用:<code>{'' if session.official_app else ''}</code>\n" \ f"应用版本:<code>{session.app_version}</code>\n"
f"登录时间:<code>{format_timestamp(session.date_created)}</code>\n" \ f"官方应用:<code>{'' if session.official_app else ''}</code>\n"
f"登录时间:<code>{format_timestamp(session.date_created)}</code>\n"
f"在线时间:<code>{format_timestamp(session.date_active)}</code>" f"在线时间:<code>{format_timestamp(session.date_active)}</code>"
)
if private: if private:
text += f"\nIP<code>{session.ip}</code>\n" \ text += (
f"地理位置:<code>{session.country}</code>" f"\nIP<code>{session.ip}</code>\n" f"地理位置:<code>{session.country}</code>"
)
if session.hash != 0: if session.hash != 0:
text += f"\n\n使用命令 <code>,{alias_command('session')} 注销 {str(session.hash)[:6]}</code> 可以注销此会话。" text += f"\n\n使用命令 <code>,{alias_command('session')} 注销 {str(session.hash)[:6]}</code> 可以注销此会话。"
return text return text
@ -75,25 +85,33 @@ async def count_platform(private: bool = True) -> str:
text += f" - <code>{session.app_name}</code>" text += f" - <code>{session.app_name}</code>"
text += f"\n" text += f"\n"
text += "\n" text += "\n"
text += "\n".join(f"{platform}{count}" for platform, count in platform_count.items()) text += "\n".join(
f"{platform}{count}" for platform, count in platform_count.items()
)
return text return text
@listener(command="session", @listener(
need_admin=True, command="session", need_admin=True, parameters="注销/查询", description="注销/查询已登录的会话"
parameters="注销/查询", )
description="注销/查询已登录的会话")
async def session_manage(message: Message): async def session_manage(message: Message):
if not message.arguments: if not message.arguments:
return await message.edit(await count_platform(private=message.chat.type in [ChatType.PRIVATE, ChatType.BOT])) return await message.edit(
await count_platform(
private=message.chat.type in [ChatType.PRIVATE, ChatType.BOT]
)
)
if len(message.parameter) != 2: if len(message.parameter) != 2:
return await message.edit_text("请输入 `注销/查询 标识符` 来查询或注销会话") return await message.edit_text("请输入 `注销/查询 标识符` 来查询或注销会话")
if message.parameter[0] == "查询": if message.parameter[0] == "查询":
session = await filter_session(message.parameter[1]) session = await filter_session(message.parameter[1])
if session: if session:
return await message.edit(format_session( return await message.edit(
format_session(
session, session,
private=message.chat.type in [ChatType.PRIVATE, ChatType.BOT])) private=message.chat.type in [ChatType.PRIVATE, ChatType.BOT],
)
)
return await message.edit_text("请输入正确的标识符!") return await message.edit_text("请输入正确的标识符!")
if message.parameter[0] == "注销": if message.parameter[0] == "注销":
session = await filter_session(message.parameter[1]) session = await filter_session(message.parameter[1])

View File

@ -26,10 +26,12 @@ async def set_custom_emoji(bot: Client, custom_emoji_id: int):
raise FileNotFoundError from e raise FileNotFoundError from e
@listener(command="set_status", @listener(
command="set_status",
parameters="[大会员自定义 emoji]", parameters="[大会员自定义 emoji]",
need_admin=True, need_admin=True,
description="快速设置大会员自定义 emoji 状态") description="快速设置大会员自定义 emoji 状态",
)
async def set_emoji_status(bot: Client, message: Message): async def set_emoji_status(bot: Client, message: Message):
"""快速设置大会员自定义 emoji 状态""" """快速设置大会员自定义 emoji 状态"""
me = bot.me or await bot.get_me() me = bot.me or await bot.get_me()

View File

@ -171,8 +171,6 @@ async def loosely_forward(
delay = min + uniform(0.5, 1.0) delay = min + uniform(0.5, 1.0)
await notifier.edit(f"触发 Flood ,暂停 {delay} 秒。") await notifier.edit(f"触发 Flood ,暂停 {delay} 秒。")
await sleep(delay) await sleep(delay)
await loosely_forward( await loosely_forward(notifier, message, chat_id, disable_notification)
notifier, message, chat_id, disable_notification
)
except Exception: except Exception:
pass # drop other errors pass # drop other errors

View File

@ -1,9 +1,9 @@
from asyncio import sleep from asyncio import sleep
from pagermaid.listener import listener from pagermaid.listener import listener
from pagermaid.enums import Message from pagermaid.enums import Message
from pagermaid.single_utils import sqlite from pagermaid.single_utils import sqlite
from pagermaid.utils import client, edit_delete from pagermaid.utils import client, edit_delete
# from pagermaid import bot # from pagermaid import bot
from pyrogram.enums.chat_type import ChatType from pyrogram.enums.chat_type import ChatType
from pagermaid.hook import Hook from pagermaid.hook import Hook
@ -13,6 +13,7 @@ from pyrogram.types import ChatPermissions
import json import json
class SillyGirl: class SillyGirl:
address = "" address = ""
token = "" token = ""
@ -27,7 +28,7 @@ class SillyGirl:
sqlite["silly_girl_address"] = address sqlite["silly_girl_address"] = address
else: else:
address = sqlite.get("silly_girl_address") address = sqlite.get("silly_girl_address")
if '@' in address: if "@" in address:
s1 = address.split("//", 1) s1 = address.split("//", 1)
s2 = s1[1].split("@", 1) s2 = s1[1].split("@", 1)
sillyGirl.token = s2[0] sillyGirl.token = s2[0]
@ -40,7 +41,7 @@ class SillyGirl:
async def poll(self, data): async def poll(self, data):
try: try:
init = '' init = ""
if sillyGirl.init == False: if sillyGirl.init == False:
init = "&init=true" init = "&init=true"
sillyGirl.init = True sillyGirl.init = True
@ -67,14 +68,28 @@ class SillyGirl:
uid = reply["sender_id"] uid = reply["sender_id"]
if reply["command"] == "ban": if reply["command"] == "ban":
if id != 0: if id != 0:
await bot.restrict_chat_member(cid, uid, ChatPermissions(),datetime.now() + timedelta(seconds=id)) await bot.restrict_chat_member(
cid,
uid,
ChatPermissions(),
datetime.now() + timedelta(seconds=id),
)
else: else:
await bot.restrict_chat_member(cid, uid, ChatPermissions()) await bot.restrict_chat_member(
cid, uid, ChatPermissions()
)
elif reply["command"] == "unban": elif reply["command"] == "unban":
await bot.restrict_chat_member(cid, uid, ChatPermissions(),datetime.now() + timedelta(seconds=60)) await bot.restrict_chat_member(
cid,
uid,
ChatPermissions(),
datetime.now() + timedelta(seconds=60),
)
elif reply["command"] == "kick": elif reply["command"] == "kick":
if id != 0: if id != 0:
await bot.ban_chat_member(cid,uid,datetime.now() + timedelta(seconds=60)) await bot.ban_chat_member(
cid, uid, datetime.now() + timedelta(seconds=60)
)
else: else:
await bot.ban_chat_member(cid, uid) await bot.ban_chat_member(cid, uid)
except Exception as e: except Exception as e:
@ -82,7 +97,9 @@ class SillyGirl:
continue continue
if reply["delete"]: if reply["delete"]:
try: try:
await bot.edit_message(reply["chat_id"], reply["id"], "打错字了,呱呱~") await bot.edit_message(
reply["chat_id"], reply["id"], "打错字了,呱呱~"
)
except Exception as e: except Exception as e:
pass pass
try: try:
@ -91,7 +108,9 @@ class SillyGirl:
pass pass
if reply["id"] != 0: if reply["id"] != 0:
try: try:
await bot.edit_message(reply["chat_id"], reply["id"], reply["text"]) await bot.edit_message(
reply["chat_id"], reply["id"], reply["text"]
)
continue continue
except Exception as e: except Exception as e:
continue continue
@ -110,13 +129,19 @@ class SillyGirl:
caption=reply["text"], caption=reply["text"],
reply_to_message_id=reply["reply_to"], reply_to_message_id=reply["reply_to"],
) )
elif reply["text"] != '': elif reply["text"] != "":
message = await bot.send_message(reply["chat_id"], reply["text"], reply_to_message_id=reply["reply_to"]) message = await bot.send_message(
reply["chat_id"],
reply["text"],
reply_to_message_id=reply["reply_to"],
)
if message: if message:
results.append({ results.append(
'id': message.id, {
'uuid': reply["uuid"], "id": message.id,
}) "uuid": reply["uuid"],
}
)
if len(results): if len(results):
await sillyGirl.poll(results) await sillyGirl.poll(results)
except Exception as e: except Exception as e:
@ -124,8 +149,10 @@ class SillyGirl:
await sleep(0.1) await sleep(0.1)
return return
sillyGirl = SillyGirl() sillyGirl = SillyGirl()
@Hook.on_startup() @Hook.on_startup()
async def connect_sillyGirl(): async def connect_sillyGirl():
sillyGirl.init_connect_info("") sillyGirl.init_connect_info("")
@ -133,8 +160,14 @@ async def connect_sillyGirl():
bot.loop.create_task(sillyGirl.polls()) bot.loop.create_task(sillyGirl.polls())
@listener(
@listener(is_plugin=True,outgoing=True, ignore_edited=True, command="sillyGirl",description="连接到傻妞服务器", parameters="[auth]") is_plugin=True,
outgoing=True,
ignore_edited=True,
command="sillyGirl",
description="连接到傻妞服务器",
parameters="[auth]",
)
async def Connect(message: Message): async def Connect(message: Message):
try: try:
await edit_delete(message, "连接中,建议重启...") await edit_delete(message, "连接中,建议重启...")
@ -143,6 +176,7 @@ async def Connect(message: Message):
print(e, "+++") print(e, "+++")
print(e) print(e)
@listener(outgoing=True, ignore_edited=True, incoming=True) @listener(outgoing=True, ignore_edited=True, incoming=True)
async def handle_receive(message: Message): async def handle_receive(message: Message):
try: try:
@ -174,17 +208,17 @@ async def handle_receive(message: Message):
await sillyGirl.poll( await sillyGirl.poll(
[ [
{ {
'id': message.id, "id": message.id,
'chat_id': chat_id, "chat_id": chat_id,
'text': message.text, "text": message.text,
'sender_id': sender_id, "sender_id": sender_id,
'reply_to': reply_to, "reply_to": reply_to,
'reply_to_sender_id': reply_to_sender_id, "reply_to_sender_id": reply_to_sender_id,
'bot_id': sillyGirl.self_user_id, "bot_id": sillyGirl.self_user_id,
'is_group': message.chat.type "is_group": message.chat.type
in [ChatType.SUPERGROUP, ChatType.CHANNEL], in [ChatType.SUPERGROUP, ChatType.CHANNEL],
'user_name': user_name, "user_name": user_name,
'chat_name': chat_name, "chat_name": chat_name,
} }
] ]
) )
@ -193,5 +227,3 @@ async def handle_receive(message: Message):
print(e) print(e)
print(e, "---") print(e, "---")
return return

View File

@ -11,20 +11,21 @@ from pagermaid.utils import lang, pip_install
pip_install("speedtest-cli", alias="speedtest") pip_install("speedtest-cli", alias="speedtest")
from speedtest import Speedtest, ShareResultsConnectFailure, ShareResultsSubmitFailure, NoMatchedServers, \ from speedtest import (
SpeedtestBestServerFailure, SpeedtestHTTPError Speedtest,
ShareResultsConnectFailure,
ShareResultsSubmitFailure,
NoMatchedServers,
SpeedtestBestServerFailure,
SpeedtestHTTPError,
)
def unit_convert(byte): def unit_convert(byte):
"""Converts byte into readable formats.""" """Converts byte into readable formats."""
power = 1000 power = 1000
zero = 0 zero = 0
units = { units = {0: "", 1: "Kb/s", 2: "Mb/s", 3: "Gb/s", 4: "Tb/s"}
0: '',
1: 'Kb/s',
2: 'Mb/s',
3: 'Gb/s',
4: 'Tb/s'}
while byte > power: while byte > power:
byte /= power byte /= power
zero += 1 zero += 1
@ -57,7 +58,9 @@ async def run_speedtest(request: AsyncClient, message: Message):
f"Timestamp: `{result['timestamp']}`" f"Timestamp: `{result['timestamp']}`"
) )
if result["share"]: if result["share"]:
data = await request.get(result["share"].replace("http:", "https:"), follow_redirects=True) data = await request.get(
result["share"].replace("http:", "https:"), follow_redirects=True
)
with open("speedtest.png", mode="wb") as f: with open("speedtest.png", mode="wb") as f:
f.write(data.content) f.write(data.content)
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
@ -84,28 +87,30 @@ async def get_all_ids():
) )
@listener(command="speedtest", @listener(
description=lang('speedtest_des'), command="speedtest",
parameters="(Server ID/测速点列表)") description=lang("speedtest_des"),
parameters="(Server ID/测速点列表)",
)
async def speedtest(client: Client, message: Message, request: AsyncClient): async def speedtest(client: Client, message: Message, request: AsyncClient):
"""Tests internet speed using speedtest.""" """Tests internet speed using speedtest."""
if message.arguments == "测速点列表": if message.arguments == "测速点列表":
msg = message msg = message
else: else:
msg: Message = await message.edit(lang('speedtest_processing')) msg: Message = await message.edit(lang("speedtest_processing"))
try: try:
if message.arguments == "测速点列表": if message.arguments == "测速点列表":
des, photo = await get_all_ids() des, photo = await get_all_ids()
else: else:
des, photo = await run_speedtest(request, message) des, photo = await run_speedtest(request, message)
except SpeedtestHTTPError: except SpeedtestHTTPError:
return await msg.edit(lang('speedtest_ConnectFailure')) return await msg.edit(lang("speedtest_ConnectFailure"))
except (ValueError, TypeError): except (ValueError, TypeError):
return await msg.edit(lang('arg_error')) return await msg.edit(lang("arg_error"))
except (SpeedtestBestServerFailure, NoMatchedServers): except (SpeedtestBestServerFailure, NoMatchedServers):
return await msg.edit(lang('speedtest_ServerFailure')) return await msg.edit(lang("speedtest_ServerFailure"))
except (ShareResultsSubmitFailure, RuntimeError, ReadTimeout): except (ShareResultsSubmitFailure, RuntimeError, ReadTimeout):
return await msg.edit(lang('speedtest_ConnectFailure')) return await msg.edit(lang("speedtest_ConnectFailure"))
if not photo: if not photo:
return await msg.edit(des) return await msg.edit(des)
try: try:
@ -113,7 +118,8 @@ async def speedtest(client: Client, message: Message, request: AsyncClient):
message.chat.id, message.chat.id,
photo, photo,
caption=des, caption=des,
reply_to_message_id=message.reply_to_top_message_id or message.reply_to_message_id, reply_to_message_id=message.reply_to_top_message_id
or message.reply_to_message_id,
) )
except Exception: except Exception:
return await msg.edit(des) return await msg.edit(des)

View File

@ -6,7 +6,11 @@ from typing import Optional
from pyrogram.errors import PeerIdInvalid from pyrogram.errors import PeerIdInvalid
from pyrogram.raw.functions.messages import GetStickerSet from pyrogram.raw.functions.messages import GetStickerSet
from pyrogram.raw.functions.stickers import CreateStickerSet from pyrogram.raw.functions.stickers import CreateStickerSet
from pyrogram.raw.types import InputStickerSetShortName, InputDocument, InputStickerSetItem from pyrogram.raw.types import (
InputStickerSetShortName,
InputDocument,
InputStickerSetItem,
)
from pyrogram.raw.types.messages import StickerSet from pyrogram.raw.types.messages import StickerSet
from pyrogram.file_id import FileId from pyrogram.file_id import FileId
@ -23,9 +27,7 @@ class CannotToStickerSetError(Exception):
""" """
def __init__(self): def __init__(self):
super().__init__( super().__init__("无法将此消息转换为贴纸")
"无法将此消息转换为贴纸"
)
class NoStickerSetNameError(Exception): class NoStickerSetNameError(Exception):
@ -34,9 +36,7 @@ class NoStickerSetNameError(Exception):
""" """
def __init__(self, string: str = "请先设置用户名"): def __init__(self, string: str = "请先设置用户名"):
super().__init__( super().__init__(string)
string
)
class StickerSetFullError(Exception): class StickerSetFullError(Exception):
@ -45,17 +45,14 @@ class StickerSetFullError(Exception):
""" """
def __init__(self): def __init__(self):
super().__init__( super().__init__("贴纸包已满")
"贴纸包已满"
)
async def get_pack(name: str): async def get_pack(name: str):
try: try:
return await bot.invoke(GetStickerSet( return await bot.invoke(
stickerset=InputStickerSetShortName(short_name=name), GetStickerSet(stickerset=InputStickerSetShortName(short_name=name), hash=0)
hash=0 )
))
except Exception as e: # noqa except Exception as e: # noqa
raise NoStickerSetNameError("贴纸名名称错误或者不存在") from e raise NoStickerSetNameError("贴纸名名称错误或者不存在") from e
@ -73,8 +70,13 @@ class Sticker:
document_path: Optional[str] document_path: Optional[str]
software: str = "PagerMaid-Pyro" software: str = "PagerMaid-Pyro"
def __init__(self, message: Message, sticker_set: str = "", emoji: str = "😀", def __init__(
should_forward: Message = None): self,
message: Message,
sticker_set: str = "",
emoji: str = "😀",
should_forward: Message = None,
):
self.message = message self.message = message
self.sticker_set = sticker_set self.sticker_set = sticker_set
self.custom_sticker_set = False self.custom_sticker_set = False
@ -151,7 +153,9 @@ class Sticker:
if not self.document_path: if not self.document_path:
return return
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
msg = await bot.send_document(429000, document=self.document_path, force_document=True) msg = await bot.send_document(
429000, document=self.document_path, force_document=True
)
file = FileId.decode(msg.document.file_id) file = FileId.decode(msg.document.file_id)
self.document = InputDocument( self.document = InputDocument(
id=file.media_id, id=file.media_id,
@ -174,10 +178,7 @@ class Sticker:
title=title, title=title,
short_name=self.sticker_set, short_name=self.sticker_set,
stickers=[ stickers=[
InputStickerSetItem( InputStickerSetItem(document=self.document, emoji=self.emoji)
document=self.document,
emoji=self.emoji
)
], ],
animated=self.is_animated, animated=self.is_animated,
videos=self.is_video, videos=self.is_video,
@ -189,16 +190,16 @@ class Sticker:
async def add_to_sticker_set(self): async def add_to_sticker_set(self):
async with bot.conversation(429000) as conv: async with bot.conversation(429000) as conv:
await conv.ask("/start") await conv.ask("/start")
await sleep(.3) await sleep(0.3)
await conv.mark_as_read() await conv.mark_as_read()
await conv.ask("/cancel") await conv.ask("/cancel")
await sleep(.3) await sleep(0.3)
await conv.mark_as_read() await conv.mark_as_read()
await conv.ask("/addsticker") await conv.ask("/addsticker")
await sleep(.3) await sleep(0.3)
await conv.mark_as_read() await conv.mark_as_read()
resp: Message = await conv.ask(self.sticker_set) resp: Message = await conv.ask(self.sticker_set)
await sleep(.3) await sleep(0.3)
if resp.text == "Invalid set selected.": if resp.text == "Invalid set selected.":
raise NoStickerSetNameError("这个贴纸包好像不属于你~") raise NoStickerSetNameError("这个贴纸包好像不属于你~")
await conv.mark_as_read() await conv.mark_as_read()
@ -207,18 +208,18 @@ class Sticker:
else: else:
await self.should_forward.forward("Stickers") await self.should_forward.forward("Stickers")
resp: Message = await conv.get_response() resp: Message = await conv.get_response()
await sleep(.3) await sleep(0.3)
if not resp.text.startswith("Thanks!"): if not resp.text.startswith("Thanks!"):
raise NoStickerSetNameError("这个贴纸包类型好像不匹配~") raise NoStickerSetNameError("这个贴纸包类型好像不匹配~")
await conv.mark_as_read() await conv.mark_as_read()
await conv.ask(self.emoji) await conv.ask(self.emoji)
await sleep(.3) await sleep(0.3)
await conv.mark_as_read() await conv.mark_as_read()
await conv.ask("/done") await conv.ask("/done")
await sleep(.3) await sleep(0.3)
await conv.mark_as_read() await conv.mark_as_read()
await conv.ask("/done") await conv.ask("/done")
await sleep(.3) await sleep(0.3)
await conv.mark_as_read() await conv.mark_as_read()
async def to_sticker_set(self): async def to_sticker_set(self):
@ -236,10 +237,12 @@ class Sticker:
def get_config(self) -> str: def get_config(self) -> str:
pack = self.mention() if self.sticker_set else "无法保存,请设置用户名" pack = self.mention() if self.sticker_set else "无法保存,请设置用户名"
return f"欢迎使用 sticker 插件\n\n" \ return (
f"将自动保存到贴纸包:{pack}\n\n" \ f"欢迎使用 sticker 插件\n\n"
f"使用命令 <code>,{alias_command('s')} 贴纸包名</code> 自定义保存贴纸包\n" \ f"将自动保存到贴纸包:{pack}\n\n"
f"使用命令 <code>,{alias_command('s')} 贴纸包名</code> 自定义保存贴纸包\n"
f"使用命令 <code>,{alias_command('s')} cancel</code> 取消自定义保存贴纸包" f"使用命令 <code>,{alias_command('s')} cancel</code> 取消自定义保存贴纸包"
)
@listener( @listener(

View File

@ -5,9 +5,9 @@ from pagermaid.enums import Message, Client
from pagermaid.single_utils import safe_remove from pagermaid.single_utils import safe_remove
@listener(command="sticker_to_pic", @listener(
description="将你回复的静态贴纸转换为图片", command="sticker_to_pic", description="将你回复的静态贴纸转换为图片", parameters="(是否发送原图,默认为否)"
parameters="(是否发送原图,默认为否)") )
async def sticker_to_pic(bot: Client, message: Message): async def sticker_to_pic(bot: Client, message: Message):
origin = bool(message.arguments) origin = bool(message.arguments)
reply = message.reply_to_message reply = message.reply_to_message

View File

@ -27,25 +27,33 @@ async def export_sticker_to_csv():
writer = csv.writer(f) writer = csv.writer(f)
writer.writerow(["name", "short_name", "is_masks", "is_animated", "is_video"]) writer.writerow(["name", "short_name", "is_masks", "is_animated", "is_video"])
for sticker_set in stickers.sets: for sticker_set in stickers.sets:
writer.writerow([sticker_set.title, writer.writerow(
[
sticker_set.title,
sticker_set.short_name, sticker_set.short_name,
sticker_set.archived if hasattr(sticker_set, "archived") else False, sticker_set.archived if hasattr(sticker_set, "archived") else False,
sticker_set.animated if hasattr(sticker_set, "animated") else False, sticker_set.animated if hasattr(sticker_set, "animated") else False,
sticker_set.videos if hasattr(sticker_set, "videos") else False, ]) sticker_set.videos if hasattr(sticker_set, "videos") else False,
]
)
return len(stickers.sets) return len(stickers.sets)
async def import_sticker(short_name): async def import_sticker(short_name):
await bot.invoke(InstallStickerSet( await bot.invoke(
InstallStickerSet(
stickerset=InputStickerSetShortName(short_name=short_name), stickerset=InputStickerSetShortName(short_name=short_name),
archived=False, archived=False,
)) )
)
async def remove_sticker(short_name): async def remove_sticker(short_name):
await bot.invoke(UninstallStickerSet( await bot.invoke(
UninstallStickerSet(
stickerset=InputStickerSetShortName(short_name=short_name), stickerset=InputStickerSetShortName(short_name=short_name),
)) )
)
async def import_sticker_from_csv(file_name): async def import_sticker_from_csv(file_name):
@ -92,10 +100,12 @@ async def clear_sets():
return success, failed return success, failed
@listener(command="sticker_transfer", @listener(
command="sticker_transfer",
need_admin=True, need_admin=True,
parameters="导出/导入/清空", parameters="导出/导入/清空",
description="导出、导入、清空已安装的贴纸包") description="导出、导入、清空已安装的贴纸包",
)
async def sticker_transfer(message: Message): async def sticker_transfer(message: Message):
if message.arguments == "导出": if message.arguments == "导出":
try: try:
@ -108,7 +118,7 @@ async def sticker_transfer(message: Message):
"stickers.csv", "stickers.csv",
caption=f"贴纸包导出文件,成功导出了 {num} 个贴纸包", caption=f"贴纸包导出文件,成功导出了 {num} 个贴纸包",
thumb=f"pagermaid{sep}assets{sep}logo.jpg", thumb=f"pagermaid{sep}assets{sep}logo.jpg",
reply_to_message_id=message.reply_to_top_message_id reply_to_message_id=message.reply_to_top_message_id,
) )
safe_remove("stickers.csv") safe_remove("stickers.csv")
await message.safe_delete() await message.safe_delete()

View File

@ -4,29 +4,36 @@ import contextlib
from httpx import get, post from httpx import get, post
token = str(sys.argv[1]) token = str(sys.argv[1])
main = get("https://api.github.com/repos/TeamPGM/PagerMaid_Plugins_Pyro/commits/v2").json() main = get(
"https://api.github.com/repos/TeamPGM/PagerMaid_Plugins_Pyro/commits/v2"
).json()
text = ( text = (
( (
( (
( (
"#更新日志 #pyro #" "#更新日志 #pyro #"
+ main['commit']['author']['name'].replace('_', '') + main["commit"]["author"]["name"].replace("_", "")
+ ' \n\n🔨 [' + " \n\n🔨 ["
+ main['sha'][:7] + main["sha"][:7]
) )
+ '](https://github.com/TeamPGM/PagerMaid_Plugins_Pyro/commit/' + "](https://github.com/TeamPGM/PagerMaid_Plugins_Pyro/commit/"
) )
+ main['sha'] + main["sha"]
) )
+ '): ' + "): "
) + main['commit']['message'] ) + main["commit"]["message"]
url = f'https://api.telegram.org/bot{token}/sendMessage' url = f"https://api.telegram.org/bot{token}/sendMessage"
for cid in ['-1001441461877', '-1001319957857']: for cid in ["-1001441461877", "-1001319957857"]:
push_content = {'chat_id': cid, 'disable_web_page_preview': 'True', 'parse_mode': 'markdown', 'text': text} push_content = {
if cid == '-1001441461877': "chat_id": cid,
push_content['message_thread_id'] = 1027828 "disable_web_page_preview": "True",
"parse_mode": "markdown",
"text": text,
}
if cid == "-1001441461877":
push_content["message_thread_id"] = 1027828
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
main_req = post(url, data=push_content) main_req = post(url, data=push_content)
time.sleep(1) time.sleep(1)
print(main['sha'] + " ok") print(main["sha"] + " ok")

View File

@ -11,6 +11,7 @@ url = "https://t.me/PagerMaid_Modify"
temp = """<h3 id="{0}">{0}</h3><p>{1}</p><blockquote>,apt install {0}</blockquote>""" temp = """<h3 id="{0}">{0}</h3><p>{1}</p><blockquote>,apt install {0}</blockquote>"""
telegraph = Telegraph(token) telegraph = Telegraph(token)
def gen(): def gen():
with open("list.json", "r", encoding="utf-8") as f: with open("list.json", "r", encoding="utf-8") as f:
data = json.load(f) data = json.load(f)
@ -25,4 +26,7 @@ def gen():
k.append(temp.format(i["name"], des)) k.append(temp.format(i["name"], des))
return "<hr>".join(k) return "<hr>".join(k)
telegraph.edit_page(path=path, title=title, html_content=gen(), author_name=name, author_url=url)
telegraph.edit_page(
path=path, title=title, html_content=gen(), author_name=name, author_url=url
)

View File

@ -6,9 +6,12 @@ from pagermaid.listener import listener
from pagermaid.utils import lang, Message from pagermaid.utils import lang, Message
@listener(is_plugin=False, command="teletype", @listener(
description=lang('teletype_des'), is_plugin=False,
parameters="[message]") command="teletype",
description=lang("teletype_des"),
parameters="[message]",
)
async def teletype(message: Message): async def teletype(message: Message):
if not message.arguments: if not message.arguments:
return await message.edit("出错了呜呜呜 ~ 空白的参数。") return await message.edit("出错了呜呜呜 ~ 空白的参数。")
@ -19,7 +22,7 @@ async def teletype(message: Message):
return return
interval = 0.05 interval = 0.05
cursor = "" cursor = ""
buffer = '' buffer = ""
msg = await message.edit(cursor) msg = await message.edit(cursor)
await sleep(interval) await sleep(interval)
for character in text: for character in text:

View File

@ -8,8 +8,7 @@ from pagermaid.listener import listener
from pagermaid.enums import Client, Message from pagermaid.enums import Client, Message
@listener(command="tgbg", description="解析 Telegram 聊天窗口背景图", @listener(command="tgbg", description="解析 Telegram 聊天窗口背景图", parameters="t.me/bg/xxx")
parameters="t.me/bg/xxx")
async def tg_bg(client: Client, message: Message): async def tg_bg(client: Client, message: Message):
argument = message.obtain_message() argument = message.obtain_message()
if url := urlparse(argument): if url := urlparse(argument):
@ -17,11 +16,15 @@ async def tg_bg(client: Client, message: Message):
if url.hostname == "t.me" and path.startswith("/bg/"): if url.hostname == "t.me" and path.startswith("/bg/"):
slug = path[4:] slug = path[4:]
try: try:
bg: WallPaper = await client.invoke(GetWallPaper(wallpaper=InputWallPaperSlug(slug=slug))) bg: WallPaper = await client.invoke(
GetWallPaper(wallpaper=InputWallPaperSlug(slug=slug))
)
except Exception as e: except Exception as e:
return await message.edit(f"获取失败: {str(e)}") return await message.edit(f"获取失败: {str(e)}")
if bg.document: if bg.document:
bg_doc = Document._parse(client, document=bg.document, file_name="bg.jpg") # noqa bg_doc = Document._parse(
client, document=bg.document, file_name="bg.jpg"
) # noqa
await client.send_document( await client.send_document(
message.chat.id, message.chat.id,
bg_doc.file_id, bg_doc.file_id,

View File

@ -26,17 +26,16 @@ async def today_in_history_subscribe() -> None:
text = await get_history() text = await get_history()
for gid in today_in_history_sub.get_subs(): for gid in today_in_history_sub.get_subs():
try: try:
await bot.send_message( await bot.send_message(gid, text)
gid,
text
)
except Exception as e: # noqa except Exception as e: # noqa
today_in_history_sub.del_id(gid) today_in_history_sub.del_id(gid)
@listener(command="today_in_history", @listener(
command="today_in_history",
parameters="订阅/退订", parameters="订阅/退订",
description="查看历史上的今天,支持订阅/退订每天上午八点定时发送") description="查看历史上的今天,支持订阅/退订每天上午八点定时发送",
)
async def today_in_history(message: Message): async def today_in_history(message: Message):
if not message.arguments: if not message.arguments:
try: try:
@ -47,7 +46,9 @@ async def today_in_history(message: Message):
elif message.arguments == "订阅": elif message.arguments == "订阅":
if check_manage_subs(message): if check_manage_subs(message):
if today_in_history_sub.check_id(message.chat.id): if today_in_history_sub.check_id(message.chat.id):
return await edit_delete(message, "❌ 你已经订阅了历史上的今天", parse_mode=ParseMode.HTML) return await edit_delete(
message, "❌ 你已经订阅了历史上的今天", parse_mode=ParseMode.HTML
)
today_in_history_sub.add_id(message.chat.id) today_in_history_sub.add_id(message.chat.id)
await message.edit("你已经成功订阅了历史上的今天") await message.edit("你已经成功订阅了历史上的今天")
else: else:
@ -55,7 +56,9 @@ async def today_in_history(message: Message):
elif message.arguments == "退订": elif message.arguments == "退订":
if check_manage_subs(message): if check_manage_subs(message):
if not today_in_history_sub.check_id(message.chat.id): if not today_in_history_sub.check_id(message.chat.id):
return await edit_delete(message, "❌ 你还没有订阅摸历史上的今天", parse_mode=ParseMode.HTML) return await edit_delete(
message, "❌ 你还没有订阅摸历史上的今天", parse_mode=ParseMode.HTML
)
today_in_history_sub.del_id(message.chat.id) today_in_history_sub.del_id(message.chat.id)
await message.edit("你已经成功退订了历史上的今天") await message.edit("你已经成功退订了历史上的今天")
else: else:

View File

@ -16,7 +16,7 @@ from pagermaid.single_utils import sqlite
pip_install("emoji") pip_install("emoji")
import emoji import emoji
NATIVE_EMOJI = b'\xf0\x9f\x91\x8d\xf0\x9f\x91\x8e\xe2\x9d\xa4\xef\xb8\x8f\xf0\x9f\x94\xa5\xf0\x9f\xa5\xb0\xf0\x9f\x91\x8f\xf0\x9f\x98\x81\xf0\x9f\xa4\x94\xf0\x9f\xa4\xaf\xf0\x9f\x98\xb1\xf0\x9f\xa4\xac\xf0\x9f\x98\xa2\xf0\x9f\x8e\x89\xf0\x9f\xa4\xa9\xf0\x9f\xa4\xae\xf0\x9f\x92\xa9\xf0\x9f\x99\x8f\xf0\x9f\x91\x8c\xf0\x9f\x95\x8a\xf0\x9f\xa4\xa1\xf0\x9f\xa5\xb1\xf0\x9f\xa5\xb4\xf0\x9f\x98\x8d\xf0\x9f\x90\xb3\xe2\x9d\xa4\xef\xb8\x8f\xe2\x80\x8d\xf0\x9f\x94\xa5\xf0\x9f\x8c\x9a\xf0\x9f\x8c\xad\xf0\x9f\x92\xaf\xf0\x9f\xa4\xa3\xe2\x9a\xa1\xef\xb8\x8f\xf0\x9f\x8d\x8c\xf0\x9f\x8f\x86\xf0\x9f\x92\x94\xf0\x9f\xa4\xa8\xf0\x9f\x98\x90\xf0\x9f\x8d\x93\xf0\x9f\x8d\xbe\xf0\x9f\x92\x8b\xf0\x9f\x96\x95\xf0\x9f\x98\x88\xf0\x9f\x98\x82\xf0\x9f\x98\xad'.decode() NATIVE_EMOJI = b"\xf0\x9f\x91\x8d\xf0\x9f\x91\x8e\xe2\x9d\xa4\xef\xb8\x8f\xf0\x9f\x94\xa5\xf0\x9f\xa5\xb0\xf0\x9f\x91\x8f\xf0\x9f\x98\x81\xf0\x9f\xa4\x94\xf0\x9f\xa4\xaf\xf0\x9f\x98\xb1\xf0\x9f\xa4\xac\xf0\x9f\x98\xa2\xf0\x9f\x8e\x89\xf0\x9f\xa4\xa9\xf0\x9f\xa4\xae\xf0\x9f\x92\xa9\xf0\x9f\x99\x8f\xf0\x9f\x91\x8c\xf0\x9f\x95\x8a\xf0\x9f\xa4\xa1\xf0\x9f\xa5\xb1\xf0\x9f\xa5\xb4\xf0\x9f\x98\x8d\xf0\x9f\x90\xb3\xe2\x9d\xa4\xef\xb8\x8f\xe2\x80\x8d\xf0\x9f\x94\xa5\xf0\x9f\x8c\x9a\xf0\x9f\x8c\xad\xf0\x9f\x92\xaf\xf0\x9f\xa4\xa3\xe2\x9a\xa1\xef\xb8\x8f\xf0\x9f\x8d\x8c\xf0\x9f\x8f\x86\xf0\x9f\x92\x94\xf0\x9f\xa4\xa8\xf0\x9f\x98\x90\xf0\x9f\x8d\x93\xf0\x9f\x8d\xbe\xf0\x9f\x92\x8b\xf0\x9f\x96\x95\xf0\x9f\x98\x88\xf0\x9f\x98\x82\xf0\x9f\x98\xad".decode()
SPECIAL_EMOJI = "❤⬅↔➡⬆↕⬇" # TO BE ADDED SPECIAL_EMOJI = "❤⬅↔➡⬆↕⬇" # TO BE ADDED
USAGE = f"""```Usage: USAGE = f"""```Usage:
Reply to a message: Reply to a message:
@ -50,8 +50,13 @@ if cached_sqlite.get("trace.config.big", None) is None:
cached_sqlite["trace.config.big"] = True cached_sqlite["trace.config.big"] = True
async def edit_and_delete(message: Message, text: str, entities: List[MessageEntity] = None, async def edit_and_delete(
seconds=5, parse_mode: ParseMode = ParseMode.DEFAULT): message: Message,
text: str,
entities: List[MessageEntity] = None,
seconds=5,
parse_mode: ParseMode = ParseMode.DEFAULT,
):
if entities is None: if entities is None:
entities = [] entities = []
await message.edit(text, entities=entities, parse_mode=parse_mode) await message.edit(text, entities=entities, parse_mode=parse_mode)
@ -84,12 +89,18 @@ async def get_all_traced(client: Client) -> Dict:
def count_offset(text: str) -> int: def count_offset(text: str) -> int:
return sum( return sum(
1 if c in SPECIAL_EMOJI or c not in SPECIAL_EMOJI and not emoji.is_emoji(c) else 2 for c in text 1
if c in SPECIAL_EMOJI or c not in SPECIAL_EMOJI and not emoji.is_emoji(c)
else 2
for c in text
) )
def append_emoji_to_text(text: str, reaction_list: List[Union[ReactionEmoji, ReactionCustomEmoji]], def append_emoji_to_text(
entities: List[MessageEntity]): text: str,
reaction_list: List[Union[ReactionEmoji, ReactionCustomEmoji]],
entities: List[MessageEntity],
):
if reaction_list is None: if reaction_list is None:
return text, entities return text, entities
text += "[" text += "["
@ -97,12 +108,14 @@ def append_emoji_to_text(text: str, reaction_list: List[Union[ReactionEmoji, Rea
if type(reaction) is ReactionEmoji: if type(reaction) is ReactionEmoji:
text += f"{reaction.emoticon}, " text += f"{reaction.emoticon}, "
elif type(reaction) is ReactionCustomEmoji: elif type(reaction) is ReactionCustomEmoji:
entities.append(MessageEntity( entities.append(
MessageEntity(
type=MessageEntityType.CUSTOM_EMOJI, type=MessageEntityType.CUSTOM_EMOJI,
offset=count_offset(text), offset=count_offset(text),
length=2, length=2,
custom_emoji_id=reaction.document_id custom_emoji_id=reaction.document_id,
)) )
)
text += "👋, " text += "👋, "
else: # Would it reach here? else: # Would it reach here?
text += str(reaction) text += str(reaction)
@ -111,11 +124,7 @@ def append_emoji_to_text(text: str, reaction_list: List[Union[ReactionEmoji, Rea
def get_keyword_emojis_from_message(message) -> Tuple[str, List[Union[str, int]]]: def get_keyword_emojis_from_message(message) -> Tuple[str, List[Union[str, int]]]:
return ( return (message.parameter[0], get_emojis_from_message(message)) if message else None
(message.parameter[0], get_emojis_from_message(message))
if message
else None
)
def get_emojis_from_message(message: Message) -> Optional[List[Union[str, int]]]: def get_emojis_from_message(message: Message) -> Optional[List[Union[str, int]]]:
@ -131,10 +140,12 @@ def get_emojis_from_message(message: Message) -> Optional[List[Union[str, int]]]
if len(emoji_list) == 3: if len(emoji_list) == 3:
break break
if emoji.is_emoji(c): if emoji.is_emoji(c):
if message.entities \ if (
and len(message.entities) - 1 >= entity_i \ message.entities
and message.entities[entity_i].type == MessageEntityType.CUSTOM_EMOJI \ and len(message.entities) - 1 >= entity_i
and message.entities[entity_i].offset == index: and message.entities[entity_i].type == MessageEntityType.CUSTOM_EMOJI
and message.entities[entity_i].offset == index
):
emoji_list.append(message.entities[entity_i].custom_emoji_id) emoji_list.append(message.entities[entity_i].custom_emoji_id)
entity_i += 1 entity_i += 1
else: else:
@ -157,30 +168,42 @@ def get_name_and_username_from_message(message: Message):
return other_name, other_username return other_name, other_username
def append_username_to_text(text: str, other_name: str, other_username: str, entities: List[MessageEntity], def append_username_to_text(
message: Message, user: Optional[User] = None): text: str,
other_name: str,
other_username: str,
entities: List[MessageEntity],
message: Message,
user: Optional[User] = None,
):
if other_username: if other_username:
entities.append(MessageEntity( entities.append(
MessageEntity(
type=MessageEntityType.MENTION, type=MessageEntityType.MENTION,
offset=count_offset(text) + 2, offset=count_offset(text) + 2,
length=count_offset(other_username), length=count_offset(other_username),
)) )
)
text += f" @{other_username}" text += f" @{other_username}"
elif other_name: elif other_name:
if user: if user:
entities.append(MessageEntity( entities.append(
MessageEntity(
type=MessageEntityType.TEXT_MENTION, type=MessageEntityType.TEXT_MENTION,
offset=count_offset(text) + 2, offset=count_offset(text) + 2,
length=count_offset(other_name), length=count_offset(other_name),
user=user user=user,
)) )
)
else: else:
entities.append(MessageEntity( entities.append(
MessageEntity(
type=MessageEntityType.TEXT_MENTION, type=MessageEntityType.TEXT_MENTION,
offset=count_offset(text) + 2, offset=count_offset(text) + 2,
length=count_offset(other_name), length=count_offset(other_name),
user=message.reply_to_message.from_user user=message.reply_to_message.from_user,
)) )
)
text += f" {other_name}" text += f" {other_name}"
else: else:
text += "Some unknown ghost" text += "Some unknown ghost"
@ -192,12 +215,16 @@ def new_bold_string_entities(text: str) -> Tuple[str, List[MessageEntity]]:
return append_bold_string("", text, []) return append_bold_string("", text, [])
def append_bold_string(text: str, append_text: str, entities: List[MessageEntity]) -> Tuple[str, List[MessageEntity]]: def append_bold_string(
entities.append(MessageEntity( text: str, append_text: str, entities: List[MessageEntity]
) -> Tuple[str, List[MessageEntity]]:
entities.append(
MessageEntity(
type=MessageEntityType.BOLD, type=MessageEntityType.BOLD,
offset=count_offset(text), offset=count_offset(text),
length=count_offset(append_text) length=count_offset(append_text),
)) )
)
text += append_text text += append_text
return text, entities return text, entities
@ -207,7 +234,13 @@ async def gen_reaction_list(emojis, bot: Client):
reaction_list = [] reaction_list = []
if not me.is_premium: # Remove custom emojis if not premium (will it happen?) if not me.is_premium: # Remove custom emojis if not premium (will it happen?)
emojis = [x for x in emojis if type(x) is not int] emojis = [x for x in emojis if type(x) is not int]
emojis = reduce(lambda x, y: x if y in x else x + [y], [[], ] + emojis) # Remove replicated emojis = reduce(
lambda x, y: x if y in x else x + [y],
[
[],
]
+ emojis,
) # Remove replicated
for emoji in emojis: for emoji in emojis:
if type(emoji) is int: if type(emoji) is int:
reaction_list.append(ReactionCustomEmoji(document_id=emoji)) reaction_list.append(ReactionCustomEmoji(document_id=emoji))
@ -216,12 +249,14 @@ async def gen_reaction_list(emojis, bot: Client):
return reaction_list return reaction_list
def append_config(text: str, entities: List[MessageEntity]) -> Tuple[str, List[MessageEntity]]: def append_config(
text: str, entities: List[MessageEntity]
) -> Tuple[str, List[MessageEntity]]:
entities.append( entities.append(
MessageEntity( MessageEntity(
type=MessageEntityType.BOLD, type=MessageEntityType.BOLD,
offset=count_offset(text), offset=count_offset(text),
length=len(f"\nKeep log: \n {cached_sqlite['trace.config.keep_log']}") length=len(f"\nKeep log: \n {cached_sqlite['trace.config.keep_log']}"),
) )
) )
text += f"\nKeep log: \n {cached_sqlite['trace.config.keep_log']}" text += f"\nKeep log: \n {cached_sqlite['trace.config.keep_log']}"
@ -230,29 +265,31 @@ def append_config(text: str, entities: List[MessageEntity]) -> Tuple[str, List[M
MessageEntity( MessageEntity(
type=MessageEntityType.BOLD, type=MessageEntityType.BOLD,
offset=count_offset(text), offset=count_offset(text),
length=len(f"\nUse big : \n {cached_sqlite['trace.config.keep_log']}") length=len(f"\nUse big : \n {cached_sqlite['trace.config.keep_log']}"),
) )
) )
text += f"\nUse big : \n {cached_sqlite['trace.config.keep_log']}" text += f"\nUse big : \n {cached_sqlite['trace.config.keep_log']}"
return text, entities return text, entities
@listener(command="trace", @listener(command="trace", need_admin=True, diagnostics=False, description=USAGE)
need_admin=True,
diagnostics=False,
description=USAGE)
async def trace(bot: Client, message: Message): async def trace(bot: Client, message: Message):
''' """
# For debug use # For debug use
if len(message.parameter) and message.parameter[0] == "magicword": if len(message.parameter) and message.parameter[0] == "magicword":
return await message.edit(str(message)) return await message.edit(str(message))
''' """
if len(message.parameter) == 0: # Either untrace someone or throw error if len(message.parameter) == 0: # Either untrace someone or throw error
if message.reply_to_message is None or message.reply_to_message.from_user is None: if (
message.reply_to_message is None
or message.reply_to_message.from_user is None
):
return await print_usage(message) return await print_usage(message)
other_id = message.reply_to_message.from_user.id other_id = message.reply_to_message.from_user.id
if not cached_sqlite.get(f"trace.user_id.{other_id}", None): if not cached_sqlite.get(f"trace.user_id.{other_id}", None):
return await edit_and_delete(message, "This user is not in the traced list.") return await edit_and_delete(
message, "This user is not in the traced list."
)
prev_emojis = cached_sqlite.get(f"trace.user_id.{other_id}", None) prev_emojis = cached_sqlite.get(f"trace.user_id.{other_id}", None)
del sqlite[f"trace.user_id.{other_id}"] del sqlite[f"trace.user_id.{other_id}"]
@ -260,9 +297,13 @@ async def trace(bot: Client, message: Message):
text, entities = new_bold_string_entities("Successfully untraced: \n") text, entities = new_bold_string_entities("Successfully untraced: \n")
other_name, other_username = get_name_and_username_from_message(message) other_name, other_username = get_name_and_username_from_message(message)
text, entities = append_username_to_text(text, other_name, other_username, entities, message) text, entities = append_username_to_text(
text, other_name, other_username, entities, message
)
text, entities = append_emoji_to_text(text, prev_emojis, entities) text, entities = append_emoji_to_text(text, prev_emojis, entities)
return await edit_and_delete(message, text, entities=entities, seconds=5, parse_mode=ParseMode.MARKDOWN) return await edit_and_delete(
message, text, entities=entities, seconds=5, parse_mode=ParseMode.MARKDOWN
)
elif len(message.parameter) == 1: elif len(message.parameter) == 1:
if message.parameter[0] in ["status", "clean"]: # Get all traced info if message.parameter[0] in ["status", "clean"]: # Get all traced info
traced_uids = await get_all_traced(bot) traced_uids = await get_all_traced(bot)
@ -280,49 +321,79 @@ async def trace(bot: Client, message: Message):
other_name += traced_uids[traced_uid]["user"].last_name other_name += traced_uids[traced_uid]["user"].last_name
other_username = traced_uids[traced_uid]["user"].username other_username = traced_uids[traced_uid]["user"].username
text, entities = append_username_to_text(text, other_name, other_username, entities, message, text, entities = append_username_to_text(
traced_uids[traced_uid]["user"]) text,
text, entities = append_emoji_to_text(text, traced_uids[traced_uid]["reactions"], entities) other_name,
other_username,
entities,
message,
traced_uids[traced_uid]["user"],
)
text, entities = append_emoji_to_text(
text, traced_uids[traced_uid]["reactions"], entities
)
text, entities = append_bold_string(text, "\nTraced keywords: \n", entities) text, entities = append_bold_string(text, "\nTraced keywords: \n", entities)
if traced_keywords := cached_sqlite.get("trace.keywordlist", None): if traced_keywords := cached_sqlite.get("trace.keywordlist", None):
for keyword in traced_keywords: for keyword in traced_keywords:
reaction_list = cached_sqlite.get(f"trace.keyword.{keyword.encode().hex()}", None) reaction_list = cached_sqlite.get(
f"trace.keyword.{keyword.encode().hex()}", None
)
text += f" {keyword}: " text += f" {keyword}: "
text, entities = append_emoji_to_text(text, reaction_list, entities) text, entities = append_emoji_to_text(text, reaction_list, entities)
if message.parameter[0] == "status": if message.parameter[0] == "status":
text, entities = append_config(text, entities) text, entities = append_config(text, entities)
if message.parameter[0] == "clean": if message.parameter[0] == "clean":
for (k, v) in cached_sqlite: for k, v in cached_sqlite:
if k.startswith("trace."): if k.startswith("trace."):
del cached_sqlite[k] del cached_sqlite[k]
del sqlite[k] del sqlite[k]
return await edit_and_delete(message, text, entities=entities, seconds=5, parse_mode=ParseMode.MARKDOWN) return await edit_and_delete(
message,
text,
entities=entities,
seconds=5,
parse_mode=ParseMode.MARKDOWN,
)
elif message.parameter[0] == "resettrace": elif message.parameter[0] == "resettrace":
for (k, v) in cached_sqlite: for k, v in cached_sqlite:
if k.startswith("trace."): if k.startswith("trace."):
del cached_sqlite[k] del cached_sqlite[k]
del sqlite[k] del sqlite[k]
return await edit_and_delete(message, "**Database has been reset.**", seconds=5, parse_mode=ParseMode.MARKDOWN) return await edit_and_delete(
message,
"**Database has been reset.**",
seconds=5,
parse_mode=ParseMode.MARKDOWN,
)
else: else:
if emojis := get_emojis_from_message(message): if emojis := get_emojis_from_message(message):
reaction_list = await gen_reaction_list(emojis, bot) reaction_list = await gen_reaction_list(emojis, bot)
if reaction_list: if reaction_list:
sqlite[f"trace.user_id.{message.reply_to_message.from_user.id}"] = reaction_list sqlite[
cached_sqlite[f"trace.user_id.{message.reply_to_message.from_user.id}"] = reaction_list f"trace.user_id.{message.reply_to_message.from_user.id}"
] = reaction_list
cached_sqlite[
f"trace.user_id.{message.reply_to_message.from_user.id}"
] = reaction_list
await bot.invoke( await bot.invoke(
SendReaction( SendReaction(
peer=await bot.resolve_peer(int(message.chat.id)), peer=await bot.resolve_peer(int(message.chat.id)),
msg_id=message.reply_to_message_id, msg_id=message.reply_to_message_id,
reaction=reaction_list, reaction=reaction_list,
big=cached_sqlite["trace.config.big"] big=cached_sqlite["trace.config.big"],
) )
) )
text = "Successfully traced: \n" text = "Successfully traced: \n"
# TODO: Add username # TODO: Add username
text, entities = append_emoji_to_text(text, reaction_list, []) text, entities = append_emoji_to_text(text, reaction_list, [])
return await edit_and_delete(message, text, entities=entities, seconds=5, return await edit_and_delete(
parse_mode=ParseMode.MARKDOWN) message,
text,
entities=entities,
seconds=5,
parse_mode=ParseMode.MARKDOWN,
)
return await edit_and_delete(message, "No valid emojis found!") return await edit_and_delete(message, "No valid emojis found!")
return await print_usage(message) return await print_usage(message)
elif len(message.parameter) == 2: # log t|f; kw del elif len(message.parameter) == 2: # log t|f; kw del
@ -335,7 +406,9 @@ async def trace(bot: Client, message: Message):
cached_sqlite["trace.config.keep_log"] = False cached_sqlite["trace.config.keep_log"] = False
else: else:
return await print_usage(message) return await print_usage(message)
return await message.edit(str(f"**Keep log: \n {cached_sqlite['trace.config.keep_log']}**")) return await message.edit(
str(f"**Keep log: \n {cached_sqlite['trace.config.keep_log']}**")
)
if message.parameter[0] == "big": if message.parameter[0] == "big":
if message.parameter[1] == "true": if message.parameter[1] == "true":
sqlite["trace.config.big"] = True sqlite["trace.config.big"] = True
@ -345,15 +418,21 @@ async def trace(bot: Client, message: Message):
cached_sqlite["trace.config.big"] = False cached_sqlite["trace.config.big"] = False
else: else:
return await print_usage(message) return await print_usage(message)
return await message.edit(str(f"**Use big : \n {cached_sqlite['trace.config.big']}**")) return await message.edit(
str(f"**Use big : \n {cached_sqlite['trace.config.big']}**")
)
elif message.parameter[1] == "del": elif message.parameter[1] == "del":
keyword = message.parameter[0] keyword = message.parameter[0]
keyword_encoded_hex = keyword.encode().hex() keyword_encoded_hex = keyword.encode().hex()
keywordlist = cached_sqlite["trace.keywordlist"] keywordlist = cached_sqlite["trace.keywordlist"]
if keyword not in keywordlist: if keyword not in keywordlist:
return await edit_and_delete(message, f"Keyword \"{keyword}\" is not traced.\n{keywordlist}") return await edit_and_delete(
message, f'Keyword "{keyword}" is not traced.\n{keywordlist}'
)
if not cached_sqlite.get(f"trace.keyword.{keyword_encoded_hex}"): if not cached_sqlite.get(f"trace.keyword.{keyword_encoded_hex}"):
return await edit_and_delete(message, f"Keyword \"{keyword}\" is not traced.") return await edit_and_delete(
message, f'Keyword "{keyword}" is not traced.'
)
prev_emojis = cached_sqlite.get(f"trace.keyword.{keyword_encoded_hex}") prev_emojis = cached_sqlite.get(f"trace.keyword.{keyword_encoded_hex}")
keywordlist.remove(keyword) keywordlist.remove(keyword)
@ -362,10 +441,18 @@ async def trace(bot: Client, message: Message):
del sqlite[f"trace.keyword.{keyword_encoded_hex}"] del sqlite[f"trace.keyword.{keyword_encoded_hex}"]
del cached_sqlite[f"trace.keyword.{keyword_encoded_hex}"] del cached_sqlite[f"trace.keyword.{keyword_encoded_hex}"]
text, entities = new_bold_string_entities("Successfully untraced keyword: \n") text, entities = new_bold_string_entities(
"Successfully untraced keyword: \n"
)
text += f" {keyword}: " text += f" {keyword}: "
text, entities = append_emoji_to_text(text, prev_emojis, entities) text, entities = append_emoji_to_text(text, prev_emojis, entities)
return await edit_and_delete(message, text, entities=entities, seconds=5, parse_mode=ParseMode.MARKDOWN) return await edit_and_delete(
message,
text,
entities=entities,
seconds=5,
parse_mode=ParseMode.MARKDOWN,
)
else: else:
return await print_usage(message) return await print_usage(message)
elif len(message.parameter) == 3: elif len(message.parameter) == 3:
@ -384,10 +471,18 @@ async def trace(bot: Client, message: Message):
cached_sqlite["trace.keywordlist"].append(keyword) cached_sqlite["trace.keywordlist"].append(keyword)
sqlite["trace.keywordlist"] = cached_sqlite["trace.keywordlist"] sqlite["trace.keywordlist"] = cached_sqlite["trace.keywordlist"]
text, entities = new_bold_string_entities("Successfully traced keyword: \n") text, entities = new_bold_string_entities(
"Successfully traced keyword: \n"
)
text += f" {keyword}: " text += f" {keyword}: "
text, entities = append_emoji_to_text(text, reaction_list, entities) text, entities = append_emoji_to_text(text, reaction_list, entities)
return await edit_and_delete(message, text, entities=entities, seconds=5, parse_mode=ParseMode.MARKDOWN) return await edit_and_delete(
message,
text,
entities=entities,
seconds=5,
parse_mode=ParseMode.MARKDOWN,
)
return await edit_and_delete(message, "No valid emojis found!") return await edit_and_delete(message, "No valid emojis found!")
else: else:
return await print_usage(message) return await print_usage(message)
@ -406,7 +501,7 @@ async def trace_user(client: Client, message: Message):
peer=await client.resolve_peer(int(message.chat.id)), peer=await client.resolve_peer(int(message.chat.id)),
msg_id=message.id, msg_id=message.id,
reaction=reaction_list, reaction=reaction_list,
big=cached_sqlite["trace.config.big"] big=cached_sqlite["trace.config.big"],
) )
) )
@ -425,9 +520,11 @@ async def trace_keyword(client: Client, message: Message):
): ):
await client.invoke( await client.invoke(
SendReaction( SendReaction(
peer=await client.resolve_peer(int(message.chat.id)), peer=await client.resolve_peer(
int(message.chat.id)
),
msg_id=message.id, msg_id=message.id,
reaction=reaction_list, reaction=reaction_list,
big=cached_sqlite["trace.config.big"] big=cached_sqlite["trace.config.big"],
) )
) )

View File

@ -19,13 +19,17 @@ async def make_zip(source_dir, output_filename):
zipf.close() zipf.close()
@listener(command="transfer", @listener(
command="transfer",
description="上传 / 下载文件", description="上传 / 下载文件",
parameters="upload [filepath]` 或 `download [filepath]") parameters="upload [filepath]` 或 `download [filepath]",
)
async def transfer(bot: Client, message: Message): async def transfer(bot: Client, message: Message):
params = message.parameter params = message.parameter
if len(params) < 2: if len(params) < 2:
message: Message = await message.edit("参数缺失,请使用 `upload [filepath (包括扩展名)]` 或 `download [filepath (包括扩展名)]`") message: Message = await message.edit(
"参数缺失,请使用 `upload [filepath (包括扩展名)]` 或 `download [filepath (包括扩展名)]`"
)
await message.delay_delete(3) await message.delay_delete(3)
return return
params[1] = " ".join(params[1:]) params[1] = " ".join(params[1:])
@ -42,7 +46,9 @@ async def transfer(bot: Client, message: Message):
token = file_path.split("/") token = file_path.split("/")
token = token[len(token) - 1] token = token[len(token) - 1]
await make_zip(file_path, f"/tmp/{token}.zip") await make_zip(file_path, f"/tmp/{token}.zip")
await bot.send_document(chat_id, f"/tmp/{token}.zip", force_document=True) await bot.send_document(
chat_id, f"/tmp/{token}.zip", force_document=True
)
os.remove(f"/tmp/{token}.zip") os.remove(f"/tmp/{token}.zip")
index += 1 index += 1
message: Message = await message.edit("上传完毕") message: Message = await message.edit("上传完毕")
@ -52,15 +58,17 @@ async def transfer(bot: Client, message: Message):
if exists(file_path): if exists(file_path):
message: Message = await message.edit("路径已存在文件") message: Message = await message.edit("路径已存在文件")
else: else:
message: Message = await message.edit('下载中。。。') message: Message = await message.edit("下载中。。。")
try: try:
_file = await reply.download(file_name=file_list[0]) _file = await reply.download(file_name=file_list[0])
except Exception: except Exception:
await message.edit('无法下载此类型的文件。') await message.edit("无法下载此类型的文件。")
return return
message: Message = await message.edit(f"保存成功, 保存路径 `{file_list[0]}`") message: Message = await message.edit(f"保存成功, 保存路径 `{file_list[0]}`")
else: else:
message: Message = await message.edit("未回复消息或回复消息中不包含文件") message: Message = await message.edit("未回复消息或回复消息中不包含文件")
else: else:
message: Message = await message.edit("未知命令,请使用 `upload [filepath]` 或 `download [filepath]`") message: Message = await message.edit(
"未知命令,请使用 `upload [filepath]` 或 `download [filepath]`"
)
await message.delay_delete(3) await message.delay_delete(3)

View File

@ -1,5 +1,11 @@
from pyrogram.enums import ChatMemberStatus from pyrogram.enums import ChatMemberStatus
from pyrogram.errors import ChatAdminRequired, FloodWait, PeerIdInvalid, UsernameInvalid, UserNotParticipant from pyrogram.errors import (
ChatAdminRequired,
FloodWait,
PeerIdInvalid,
UsernameInvalid,
UserNotParticipant,
)
from pyrogram.types import Chat from pyrogram.types import Chat
from pagermaid import bot from pagermaid import bot
@ -39,11 +45,13 @@ async def get_uid(chat: Chat, message: Message):
return uid, member return uid, member
@listener(command="unban", @listener(
command="unban",
description="解除封禁一位用户", description="解除封禁一位用户",
need_admin=True, need_admin=True,
groups_only=True, groups_only=True,
parameters="[reply|id|username]") parameters="[reply|id|username]",
)
async def unban(client: Client, message: Message): async def unban(client: Client, message: Message):
chat = message.chat chat = message.chat
try: try:

View File

@ -35,9 +35,11 @@ def format_time(t):
return f"时间:`{unix_to_time(t)}`\n\n时间戳:`{t}`" return f"时间:`{unix_to_time(t)}`\n\n时间戳:`{t}`"
@listener(command="unixtime", @listener(
command="unixtime",
description="Unix时间戳转换\n参数缺省将当前服务器时间转换为Unix时间戳\n时间格式: `YYYY-MM-DD HH:MM:SS`", description="Unix时间戳转换\n参数缺省将当前服务器时间转换为Unix时间戳\n时间格式: `YYYY-MM-DD HH:MM:SS`",
parameters="[缺省 / 时间 / Unix时间戳]") parameters="[缺省 / 时间 / Unix时间戳]",
)
async def unix_time(message: Message): async def unix_time(message: Message):
try: try:
return await message.edit(format_time(message.arguments)) return await message.edit(format_time(message.arguments))

View File

@ -9,7 +9,9 @@ def update_des():
list_json = json.load(f) list_json = json.load(f)
for plugin in list_json["list"]: for plugin in list_json["list"]:
if os.path.exists(f"{start}{plugin['name']}{os.sep}DES.md"): if os.path.exists(f"{start}{plugin['name']}{os.sep}DES.md"):
with open(f"{start}{plugin['name']}{os.sep}DES.md", "r", encoding="utf8") as f: with open(
f"{start}{plugin['name']}{os.sep}DES.md", "r", encoding="utf8"
) as f:
plugin["des"] = f.read().strip() plugin["des"] = f.read().strip()
with open(f"{start}list.json", "w", encoding="utf8") as f: with open(f"{start}list.json", "w", encoding="utf8") as f:
json.dump(list_json, f, ensure_ascii=False, indent=4) json.dump(list_json, f, ensure_ascii=False, indent=4)

View File

@ -5,20 +5,22 @@ from httpx import get
from update_des import update_des from update_des import update_des
main = get("https://api.github.com/repos/TeamPGM/PagerMaid_Plugins_Pyro/commits/v2").json() main = get(
"https://api.github.com/repos/TeamPGM/PagerMaid_Plugins_Pyro/commits/v2"
).json()
plugins = [] plugins = []
alpha_plugins = [] alpha_plugins = []
list_json_start = ["", "alpha/"] list_json_start = ["", "alpha/"]
for file in main["files"]: for file in main["files"]:
if "list.json" in file["filename"]: if "list.json" in file["filename"]:
print(main['sha'] + " no need") print(main["sha"] + " no need")
exit() exit()
if "/main.py" in file["filename"]: if "/main.py" in file["filename"]:
if file["filename"].startswith("alpha"): if file["filename"].startswith("alpha"):
alpha_plugins.append(file["filename"].split("/")[1]) alpha_plugins.append(file["filename"].split("/")[1])
else: else:
plugins.append(file["filename"].split("/")[0]) plugins.append(file["filename"].split("/")[0])
delete = bool(main['commit']['message'].startswith("Delete")) delete = bool(main["commit"]["message"].startswith("Delete"))
for idx, plugins_ in enumerate([plugins, alpha_plugins]): for idx, plugins_ in enumerate([plugins, alpha_plugins]):
@ -31,18 +33,20 @@ for idx, plugins_ in enumerate([plugins, alpha_plugins]):
exist = True exist = True
old_version = decimal.Decimal(plug_dict["version"]) old_version = decimal.Decimal(plug_dict["version"])
plug_dict["version"] = str(old_version + decimal.Decimal("0.01")) plug_dict["version"] = str(old_version + decimal.Decimal("0.01"))
plug_dict["size"] = f"{os.path.getsize(f'{list_json_start[idx]}{plugin}{os.sep}main.py') / 1000} kb" plug_dict[
"size"
] = f"{os.path.getsize(f'{list_json_start[idx]}{plugin}{os.sep}main.py') / 1000} kb"
if delete: if delete:
list_json["list"].remove(plug_dict) list_json["list"].remove(plug_dict)
break break
if not exist: if not exist:
short_des = main['commit']['message'].split("\nCo-authored-by")[0].strip() short_des = main["commit"]["message"].split("\nCo-authored-by")[0].strip()
list_json["list"].append( list_json["list"].append(
{ {
"name": plugin, "name": plugin,
"version": "1.0", "version": "1.0",
"section": "chat", "section": "chat",
"maintainer": main['commit']['author']['name'], "maintainer": main["commit"]["author"]["name"],
"size": f"{os.path.getsize(f'{list_json_start[idx]}{plugin}{os.sep}main.py') / 1000} kb", "size": f"{os.path.getsize(f'{list_json_start[idx]}{plugin}{os.sep}main.py') / 1000} kb",
"supported": True, "supported": True,
"des_short": short_des, "des_short": short_des,
@ -54,4 +58,4 @@ for idx, plugins_ in enumerate([plugins, alpha_plugins]):
update_des() update_des()
print(main['sha'] + " ok") print(main["sha"] + " ok")

View File

@ -3,17 +3,19 @@ from pagermaid.enums import AsyncClient, Message
from pagermaid.utils import alias_command from pagermaid.utils import alias_command
@listener(command="urbandictionary", @listener(command="urbandictionary", parameters="[单词]", description="解释英语俚语词汇")
parameters="[单词]",
description="解释英语俚语词汇")
async def get_urban_mean(message: Message, httpx: AsyncClient): async def get_urban_mean(message: Message, httpx: AsyncClient):
"""To fetch meaning of the given word from urban dictionary.""" """To fetch meaning of the given word from urban dictionary."""
word = message.arguments word = message.arguments
if not word: if not word:
return await message.edit(f"[urbandictionary] 使用方法:`,{alias_command('urbandictionary')} <单词>`") return await message.edit(
f"[urbandictionary] 使用方法:`,{alias_command('urbandictionary')} <单词>`"
)
try: try:
response = (await httpx.get(f"https://api.urbandictionary.com/v0/define?term={word}")).json() response = (
await httpx.get(f"https://api.urbandictionary.com/v0/define?term={word}")
).json()
except Exception as e: except Exception as e:
return await message.edit(f"[urbandictionary] API 接口无法访问:{e}") return await message.edit(f"[urbandictionary] API 接口无法访问:{e}")
@ -23,9 +25,11 @@ async def get_urban_mean(message: Message, httpx: AsyncClient):
word = response["list"][0]["word"] word = response["list"][0]["word"]
definition = response["list"][0]["definition"] definition = response["list"][0]["definition"]
example = response["list"][0]["example"] example = response["list"][0]["example"]
result = f"**Word :** __{word}__\n\n" \ result = (
f"**Meaning:**\n" \ f"**Word :** __{word}__\n\n"
f"`{definition}`\n\n" \ f"**Meaning:**\n"
f"**Example:**\n" \ f"`{definition}`\n\n"
f"**Example:**\n"
f"`{example}`" f"`{example}`"
)
await message.edit(result) await message.edit(result)

View File

@ -6,11 +6,13 @@ from pagermaid.listener import listener
from pagermaid.enums import Client, Message from pagermaid.enums import Client, Message
@listener(command="vctools", @listener(
command="vctools",
admins_only=True, admins_only=True,
groups_only=True, groups_only=True,
parameters="[开启/关闭]", parameters="[开启/关闭]",
description="开启/关闭群组直播间") description="开启/关闭群组直播间",
)
async def vctools(bot: Client, message: Message): async def vctools(bot: Client, message: Message):
if not message.arguments: if not message.arguments:
return await message.reply("请输入 `开启/关闭`") return await message.reply("请输入 `开启/关闭`")
@ -27,7 +29,11 @@ async def vctools(bot: Client, message: Message):
return await message.reply("需要管理员权限") return await message.reply("需要管理员权限")
elif message.arguments == "关闭": elif message.arguments == "关闭":
try: try:
full_chat = (await bot.invoke(GetFullChannel(channel=await bot.resolve_peer(message.chat.id)))).full_chat full_chat = (
await bot.invoke(
GetFullChannel(channel=await bot.resolve_peer(message.chat.id))
)
).full_chat
if full_chat.call: if full_chat.call:
await bot.invoke(DiscardGroupCall(call=full_chat.call)) await bot.invoke(DiscardGroupCall(call=full_chat.call))
return await message.edit("已关闭群组直播间") return await message.edit("已关闭群组直播间")

View File

@ -4,9 +4,7 @@ from pagermaid.listener import listener
from pagermaid.enums import Client, Message from pagermaid.enums import Client, Message
@listener(command="duckduckgo", @listener(command="duckduckgo", description="Duckduckgo 搜索", parameters="[query]")
description="Duckduckgo 搜索",
parameters="[query]")
async def duckduckgo(client: Client, message: Message): async def duckduckgo(client: Client, message: Message):
text = message.arguments text = message.arguments
if not text: if not text:
@ -17,9 +15,7 @@ async def duckduckgo(client: Client, message: Message):
await message.edit(answer.text.html, parse_mode=ParseMode.HTML) await message.edit(answer.text.html, parse_mode=ParseMode.HTML)
@listener(command="caiyun", @listener(command="caiyun", description="彩云翻译", parameters="[query]")
description="彩云翻译",
parameters="[query]")
async def caiyun_translate(client: Client, message: Message): async def caiyun_translate(client: Client, message: Message):
text = message.arguments text = message.arguments
if not text: if not text:
@ -30,9 +26,7 @@ async def caiyun_translate(client: Client, message: Message):
await message.edit(answer.text) await message.edit(answer.text)
@listener(command="weather", @listener(command="weather", description="使用彩云天气 api 查询国内实时天气。", parameters="[位置]")
description="使用彩云天气 api 查询国内实时天气。",
parameters="[位置]")
async def weather(client: Client, message: Message): async def weather(client: Client, message: Message):
text = message.arguments text = message.arguments
if not text: if not text:
@ -43,9 +37,9 @@ async def weather(client: Client, message: Message):
await message.edit(answer.text) await message.edit(answer.text)
@listener(command="weather_pic", @listener(
description="使用彩云天气 api 查询国内实时天气,但是显示图片。", command="weather_pic", description="使用彩云天气 api 查询国内实时天气,但是显示图片。", parameters="[位置]"
parameters="[位置]") )
async def weather_pic(client: Client, message: Message): async def weather_pic(client: Client, message: Message):
text = message.arguments text = message.arguments
if not text: if not text:
@ -55,14 +49,15 @@ async def weather_pic(client: Client, message: Message):
await conv.mark_as_read() await conv.mark_as_read()
await answer.copy( await answer.copy(
message.chat.id, message.chat.id,
reply_to_message_id=message.reply_to_message_id or message.reply_to_top_message_id reply_to_message_id=message.reply_to_message_id
or message.reply_to_top_message_id,
) )
await message.safe_delete() await message.safe_delete()
@listener(command="weather_he", @listener(
description="使用和风天气 api 查询国内实时天气,但是显示图片。", command="weather_he", description="使用和风天气 api 查询国内实时天气,但是显示图片。", parameters="[位置]"
parameters="[位置]") )
async def weather_he(client: Client, message: Message): async def weather_he(client: Client, message: Message):
text = message.arguments text = message.arguments
if not text: if not text:
@ -72,7 +67,8 @@ async def weather_he(client: Client, message: Message):
await conv.mark_as_read() await conv.mark_as_read()
await answer.copy( await answer.copy(
message.chat.id, message.chat.id,
reply_to_message_id=message.reply_to_message_id or message.reply_to_top_message_id reply_to_message_id=message.reply_to_message_id
or message.reply_to_top_message_id,
) )
await message.safe_delete() await message.safe_delete()
@ -86,51 +82,58 @@ async def az_tts(client: Client, message: Message, mode: str):
await conv.mark_as_read() await conv.mark_as_read()
await answer.copy( await answer.copy(
message.chat.id, message.chat.id,
reply_to_message_id=message.reply_to_message_id or message.reply_to_top_message_id reply_to_message_id=message.reply_to_message_id
or message.reply_to_top_message_id,
) )
await message.safe_delete() await message.safe_delete()
@listener(command="tts_nan", @listener(
command="tts_nan",
description="通过 Azure 文本到语音 基于字符串生成 简体男声 语音消息。", description="通过 Azure 文本到语音 基于字符串生成 简体男声 语音消息。",
parameters="[字符串]") parameters="[字符串]",
)
async def az_tts_nan(client: Client, message: Message): async def az_tts_nan(client: Client, message: Message):
await az_tts(client, message, "") await az_tts(client, message, "")
@listener(command="tts_nv", @listener(
command="tts_nv",
description="通过 Azure 文本到语音 基于字符串生成 简体女声 语音消息。", description="通过 Azure 文本到语音 基于字符串生成 简体女声 语音消息。",
parameters="[字符串]") parameters="[字符串]",
)
async def az_tts_nv(client: Client, message: Message): async def az_tts_nv(client: Client, message: Message):
await az_tts(client, message, "nv") await az_tts(client, message, "nv")
@listener(command="tts_tw", @listener(
command="tts_tw",
description="通过 Azure 文本到语音 基于字符串生成 繁体男声 语音消息。", description="通过 Azure 文本到语音 基于字符串生成 繁体男声 语音消息。",
parameters="[字符串]") parameters="[字符串]",
)
async def az_tts_tw(client: Client, message: Message): async def az_tts_tw(client: Client, message: Message):
await az_tts(client, message, "tw") await az_tts(client, message, "tw")
@listener(command="tts_ne", @listener(
command="tts_ne",
description="通过 Azure 文本到语音 基于字符串生成 简体新闻男声 语音消息。", description="通过 Azure 文本到语音 基于字符串生成 简体新闻男声 语音消息。",
parameters="[字符串]") parameters="[字符串]",
)
async def az_tts_ne(client: Client, message: Message): async def az_tts_ne(client: Client, message: Message):
await az_tts(client, message, "ne") await az_tts(client, message, "ne")
@listener(command="tts_en", @listener(
command="tts_en",
description="通过 Azure 文本到语音 基于字符串生成 英文男声 语音消息。", description="通过 Azure 文本到语音 基于字符串生成 英文男声 语音消息。",
parameters="[字符串]") parameters="[字符串]",
)
async def az_tts_en(client: Client, message: Message): async def az_tts_en(client: Client, message: Message):
await az_tts(client, message, "en") await az_tts(client, message, "en")
@listener( @listener(command="draw", description="使用 AI 进行绘图。", parameters="prompt")
command="draw",
description="使用 AI 进行绘图。",
parameters="prompt"
)
async def draw_photo(client: Client, message: Message): async def draw_photo(client: Client, message: Message):
text = message.obtain_message() text = message.obtain_message()
if not text: if not text:
@ -140,6 +143,7 @@ async def draw_photo(client: Client, message: Message):
await conv.mark_as_read() await conv.mark_as_read()
await answer.copy( await answer.copy(
message.chat.id, message.chat.id,
reply_to_message_id=message.reply_to_message_id or message.reply_to_top_message_id reply_to_message_id=message.reply_to_message_id
or message.reply_to_top_message_id,
) )
await message.safe_delete() await message.safe_delete()

View File

@ -26,26 +26,44 @@ icons = {
def timestamp_to_time(timestamp, timeZoneShift): def timestamp_to_time(timestamp, timeZoneShift):
timeArray = datetime.datetime.utcfromtimestamp(timestamp) + datetime.timedelta(seconds=timeZoneShift) timeArray = datetime.datetime.utcfromtimestamp(timestamp) + datetime.timedelta(
seconds=timeZoneShift
)
return timeArray.strftime("%H:%M") return timeArray.strftime("%H:%M")
def calcWindDirection(windDirection): def calcWindDirection(windDirection):
dirs = ['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW'] dirs = [
ix = round(windDirection / (360. / len(dirs))) "N",
"NNE",
"NE",
"ENE",
"E",
"ESE",
"SE",
"SSE",
"S",
"SSW",
"SW",
"WSW",
"W",
"WNW",
"NW",
"NNW",
]
ix = round(windDirection / (360.0 / len(dirs)))
return dirs[ix % len(dirs)] return dirs[ix % len(dirs)]
@listener(command="weather", @listener(command="weather", description="查询天气", parameters="[城市]")
description="查询天气",
parameters="[城市]")
async def weather(_: Client, message: Message): async def weather(_: Client, message: Message):
if not message.arguments: if not message.arguments:
return await message.edit("出错了呜呜呜 ~ 无效的参数。") return await message.edit("出错了呜呜呜 ~ 无效的参数。")
try: try:
req = await client.get( req = await client.get(
"http://api.openweathermap.org/data/2.5/weather?appid=973e8a21e358ee9d30b47528b43a8746&units=metric&lang" "http://api.openweathermap.org/data/2.5/weather?appid=973e8a21e358ee9d30b47528b43a8746&units=metric&lang"
"=zh_cn&q=" + message.arguments) "=zh_cn&q=" + message.arguments
)
if req.status_code == 200: if req.status_code == 200:
data = req.json() data = req.json()
cityName = f'{data["name"]}, {data["sys"]["country"]}' cityName = f'{data["name"]}, {data["sys"]["country"]}'

View File

@ -3,9 +3,7 @@ from pagermaid.enums import Message, AsyncClient
from pagermaid.single_utils import safe_remove from pagermaid.single_utils import safe_remove
@listener(command="weather_lite", @listener(command="weather_lite", description="查询天气", parameters="[城市]")
description="查询天气",
parameters="[城市]")
async def weather_lite(request: AsyncClient, message: Message): async def weather_lite(request: AsyncClient, message: Message):
if not message.arguments: if not message.arguments:
return await message.edit("请输入城市名称") return await message.edit("请输入城市名称")
@ -19,8 +17,9 @@ async def weather_lite(request: AsyncClient, message: Message):
f.write(data.content) f.write(data.content)
await message.reply_photo( await message.reply_photo(
"weather.png", "weather.png",
reply_to_message_id=message.reply_to_message_id or message.reply_to_top_message_id, reply_to_message_id=message.reply_to_message_id
quote=False or message.reply_to_top_message_id,
quote=False,
) )
await message.safe_delete() await message.safe_delete()
safe_remove("weather.png") safe_remove("weather.png")

View File

@ -44,7 +44,9 @@ class WebSocket:
if self.is_connected(): if self.is_connected():
await self.disconnect() await self.disconnect()
if self.uri: if self.uri:
self.ws = self.client.ws_connect(self.uri, autoclose=False, autoping=False, timeout=5) self.ws = self.client.ws_connect(
self.uri, autoclose=False, autoping=False, timeout=5
)
self.connection = await self.ws._coro self.connection = await self.ws._coro
async def disconnect(self): async def disconnect(self):
@ -105,8 +107,8 @@ class WebSocket:
data = json.loads(text) data = json.loads(text)
except Exception: except Exception:
return return
action = data.get('action', None) action = data.get("action", None)
action_data = data.get('data', None) action_data = data.get("data", None)
bot_action = getattr(bot, action) bot_action = getattr(bot, action)
if bot_action and action_data: if bot_action and action_data:
@ -136,8 +138,10 @@ async def websocket_to_connect(message: Message):
if message.arguments: if message.arguments:
uri = message.arguments uri = message.arguments
if not uri.startswith("ws://"): if not uri.startswith("ws://"):
return await message.edit("[ws] 请输入正确的 uri 例如ws://127.0.0.1:1080/ws\n\n" return await message.edit(
"**请一定使用强路径并且连接到可信 ws ws 发送方能够对您的账户执行任意操作!!!**") "[ws] 请输入正确的 uri 例如ws://127.0.0.1:1080/ws\n\n"
"**请一定使用强路径并且连接到可信 ws ws 发送方能够对您的账户执行任意操作!!!**"
)
msg: Message = await message.edit("[ws] Websocket 尝试连接中...") msg: Message = await message.edit("[ws] Websocket 尝试连接中...")
try: try:
if ws.is_connected(): if ws.is_connected():
@ -151,8 +155,10 @@ async def websocket_to_connect(message: Message):
bot.loop.create_task(ws.keep_alive()) bot.loop.create_task(ws.keep_alive())
elif not ws.is_connected(): elif not ws.is_connected():
if not ws.database_have_uri(): if not ws.database_have_uri():
return await message.edit("[ws] ws 未链接,请输入正确的 uri 例如ws://127.0.0.1:1080/ws\n\n" return await message.edit(
"**请一定使用强路径并且连接到可信 ws ws 发送方能够对您的账户执行任意操作!!!**") "[ws] ws 未链接,请输入正确的 uri 例如ws://127.0.0.1:1080/ws\n\n"
"**请一定使用强路径并且连接到可信 ws ws 发送方能够对您的账户执行任意操作!!!**"
)
ws.restore_uri() ws.restore_uri()
msg: Message = await message.edit("[ws] Websocket 尝试连接中...") msg: Message = await message.edit("[ws] Websocket 尝试连接中...")
try: try:

Some files were not shown because too many files have changed in this diff Show More