适配nonebot2 beta4,fix bug

This commit is contained in:
CMHopeSunshine 2022-06-21 16:26:13 +08:00
parent 5e227d9647
commit ba21faad20
23 changed files with 556 additions and 271 deletions

View File

@ -1,11 +1,14 @@
import asyncio
from pathlib import Path
from typing import Union
from nonebot import on_command
from nonebot.adapters.onebot.v11 import GroupMessageEvent, MessageSegment, Bot, MessageEvent
from nonebot.adapters.onebot.v11 import GroupMessageEvent, PrivateMessageEvent, MessageSegment, Bot, MessageEvent, \
Message
from nonebot.exception import FinishedException
from nonebot.params import CommandArg
from nonebot.permission import SUPERUSER
from nonebot.plugin import PluginMetadata
from utils.config import config
from . import download_data
@ -16,22 +19,34 @@ setting_time = config.paimon_guess_voice # 游戏持续时间
dir_name = Path() / 'data' / 'LittlePaimon' / 'guess_voice' / 'voice'
__paimon_help__ = {
'type': '娱乐',
'range': ['group']
}
__plugin_meta__ = PluginMetadata(
name="原神猜语音",
description="小派蒙的原神猜语音模块",
usage=(
"原神猜语音[语言]\n"
"原神语音[语言]<角色名>\n"
"更新原神语音资源\n"
),
extra={
'type': '娱乐',
'range': ['private', 'group'],
"author": "惜月 <277073121@qq.com>",
"version": "1.0.0",
},
)
guess_game = on_command('原神猜语音', priority=12, block=True)
guess_game.__paimon_help__ = {
"usage": "原神猜语音[语言]",
"usage": "原神猜语音[语言]",
"introduce": "来一起猜语音吧",
"priority": 5
"priority": 5
}
ys_voice = on_command('原神语音', priority=12, block=True)
ys_voice.__paimon_help__ = {
"usage": "原神语音[语言]<角色名>",
"usage": "原神语音[语言]<角色名>",
"introduce": "随机发一条该角色的语音",
"priority": 6
"priority": 6
}
update_ys_voice = on_command('更新原神语音资源', priority=12, permission=SUPERUSER, block=True)
@ -45,9 +60,9 @@ async def download_voice(bot: Bot, event: MessageEvent):
@guess_game.handle()
async def guess_genshin_voice(bot: Bot, event: GroupMessageEvent, msg=CommandArg()):
async def guess_genshin_voice(bot: Bot, event: GroupMessageEvent, msg: Message = CommandArg()):
await download_voice(bot, event)
keyword = str(msg).strip()
keyword = msg.extract_plain_text().strip()
guess = Guess(event.group_id, time=setting_time)
hard_mode = False
@ -85,13 +100,20 @@ async def guess_genshin_voice(bot: Bot, event: GroupMessageEvent, msg=CommandArg
@ys_voice.handle()
async def get_genshin_voice(bot: Bot, event: GroupMessageEvent, msg=CommandArg()):
name = str(msg).strip()
async def get_genshin_voice(bot: Bot, event: Union[GroupMessageEvent, PrivateMessageEvent], msg: Message = CommandArg()):
name = msg.extract_plain_text().strip()
if name.startswith(''):
language = ''
name = name[1:]
elif name.startswith(''):
language = ''
name = name[1:]
elif name.startswith(''):
language = ''
name = name[1:]
else:
language = ''
name = name.replace('', '')
await download_voice(bot, event)
path = await get_random_voice(name, language)
if not path:
@ -100,7 +122,7 @@ async def get_genshin_voice(bot: Bot, event: GroupMessageEvent, msg=CommandArg()
@update_ys_voice.handle()
async def update_genshin_voice(bot: Bot, event: GroupMessageEvent):
async def update_genshin_voice(bot: Bot, event: Union[GroupMessageEvent, PrivateMessageEvent]):
await update_ys_voice.send('将在后台开始更新原神语音资源,请耐心等待资源下载完成后再使用原神语音')
await download_data.update_voice_data()
await update_ys_voice.finish('原神语音资源更新完成')

View File

@ -1,32 +1,37 @@
from nonebot import require, get_bot, on_command, logger
from nonebot.adapters.onebot.v11 import MessageEvent, Message
from nonebot.params import CommandArg
from nonebot.plugin import PluginMetadata
from utils.file_handler import load_json, save_json
from utils.message_util import MessageBuild, get_message_id
from .generate import *
import re
HELP_STR = '''
原神活动日历
原神日历 : 查看本群订阅服务器日历
原神日历 on/off : 订阅/取消订阅指定服务器的日历推送
原神日历 time : : 设置日历推送时间
原神日历 status : 查看本群日历推送设置
'''.strip()
require('nonebot_plugin_apscheduler')
from nonebot_plugin_apscheduler import scheduler
__paimon_help__ = {
'type': '原神Wiki',
'range': ['private', 'group', 'guild']
}
__plugin_meta__ = PluginMetadata(
name="原神日历",
description="查看原神活动日历",
usage=(
"原神日历 : 查看本群订阅服务器日历\n"
"原神日历 on 时间/off : 订阅/取消订阅指定服务器的日历推送\n"
),
extra={
'type': '原神Wiki',
'range': ['private', 'group', 'guild'],
"author": "nicklly <1134741727@qq.com>",
"version": "1.0.0",
},
)
calendar = on_command('原神日历', aliases={"原神日历", 'ysrl', '原神日程'}, priority=24, block=True)
calendar.__paimon_help__ = {
"usage": "原神日历",
"usage": "原神日历",
"introduce": "查看原神活动日历后加on时间/off可以开启定时推送",
"priority": 99
"priority": 99
}
scheduler = require('nonebot_plugin_apscheduler').scheduler
async def send_calendar(push_id, push_data):

View File

@ -20,12 +20,14 @@ from utils.config import config
message_id_lock = threading.Lock()
message_id_dict = {}
#检测是否开启该群的机器学习
# 检测是否开启该群的机器学习
def checkGroup(event: GroupMessageEvent) -> bool:
if event.group_id in Chat.learningGroup:
return True
return False
async def check_accounts(event: GroupMessageEvent) -> bool:
# 不响应其他nonebot_plugin_gocqhttp机器人账号的信息
if os.path.exists('accounts'):
@ -40,7 +42,7 @@ async def get_answer(event: GroupMessageEvent, state: T_State) -> bool:
# 不响应被屏蔽的人的信息
if event.user_id in config.paimon_chat_ban:
return False
elif not checkGroup(event): # 判断群组
elif not checkGroup(event): # 判断群组
return False
chat: Chat = Chat(event)
to_learn = True
@ -91,7 +93,6 @@ async def is_shutup(self_id: int, group_id: int) -> bool:
@any_msg.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
delay = random.randint(2, 4)
for item in state['answers']:
logger.info(f'repeater派蒙[{event.self_id}]准备向群[{event.group_id}]回复[{item}]')
@ -220,18 +221,21 @@ def update_data():
Chat.clearup_context()
Chat.completely_sober()
#群组开启
# 群组开启
onLearningGroup = on_message(
rule = to_me() & keyword("派蒙学习开启","说怪话"),
priority = 4,
block = True,
rule=to_me() & keyword("派蒙学习开启", "说怪话"),
priority=4,
block=True,
permission=permission.GROUP_ADMIN | permission.GROUP_OWNER | SUPERUSER
)
onLearningGroup.__paimon_help__ = {
"usage": "@派蒙 <说怪话>",
"usage": "@派蒙 <说怪话>",
"introduce": "开启派蒙在该群的机器学习能力",
"priority": 94
"priority": 94
}
@onLearningGroup.handle()
async def _(bot: Bot, event: GroupMessageEvent):
if checkGroup(event):
@ -240,18 +244,21 @@ async def _(bot: Bot, event: GroupMessageEvent):
Chat.learningGroup.append(event.group_id)
await onLearningGroup.finish("派蒙开始学习群友说怪话!")
#群组关闭
# 群组关闭
offLearningGroup = on_message(
rule = to_me() & keyword("派蒙学习关闭","不准说怪话"),
priority = 3,
block = True,
rule=to_me() & keyword("派蒙学习关闭", "不准说怪话"),
priority=3,
block=True,
permission=permission.GROUP_ADMIN | permission.GROUP_OWNER | SUPERUSER
)
offLearningGroup.__paimon_help__ = {
"usage": "@派蒙 <不准说怪话>",
"usage": "@派蒙 <不准说怪话>",
"introduce": "关闭派蒙在该群的机器学习能力",
"priority": 95
"priority": 95
}
@offLearningGroup.handle()
async def _(bot: Bot, event: GroupMessageEvent):
if not checkGroup(event):
@ -260,18 +267,21 @@ async def _(bot: Bot, event: GroupMessageEvent):
Chat.learningGroup.remove(event.group_id)
await offLearningGroup.finish("派蒙不学就是了TAT")
#发癫
# 发癫
fun_msg = on_message(
rule=to_me() & keyword('发癫','派蒙发癫','喝酒') & Rule(checkGroup),
rule=to_me() & keyword('发癫', '派蒙发癫', '喝酒') & Rule(checkGroup),
priority=6,
block=True,
permission=permission.GROUP_ADMIN | permission.GROUP_OWNER | SUPERUSER
)
fun_msg.__paimon_help__ = {
"usage": "@派蒙 <发癫>",
"usage": "@派蒙 <发癫>",
"introduce": "派蒙喝醉了在群里发癫",
"priority": 96
"priority": 96
}
@fun_msg.handle()
async def funmsg(bot: Bot, event: GroupMessageEvent):
logger.info(f'repeater派蒙开始发癫')
@ -281,21 +291,24 @@ async def funmsg(bot: Bot, event: GroupMessageEvent):
Chat.speak_poke_probability = 1
Chat.speak_continuously_max_len = 10
Chat.cross_group_threshold = 1
msg_send = ['呀,旅行者。你今天走起路来,怎么看着摇摇晃晃的?嘿嘿嘿~~~','……&%*&U*……&%']
msg_send = ['呀,旅行者。你今天走起路来,怎么看着摇摇晃晃的?嘿嘿嘿~~~', '……&%*&U*……&%']
await fun_msg.finish(random.choice(msg_send))
#停止发癫
# 停止发癫
stop_fun_msg = on_message(
rule=to_me() & keyword('恢复','不准发癫','停止','stop'),
rule=to_me() & keyword('恢复', '不准发癫', '停止', 'stop'),
priority=5,
block=True,
permission=permission.GROUP_ADMIN | permission.GROUP_OWNER | SUPERUSER
)
stop_fun_msg.__paimon_help__ = {
"usage": "@派蒙 <不准发癫>",
"usage": "@派蒙 <不准发癫>",
"introduce": "让派蒙恢复正常",
"priority": 97
"priority": 97
}
@stop_fun_msg.handle()
async def stopfunmsg(bot: Bot, event: GroupMessageEvent):
logger.info(f'repeater派蒙停止发癫')
@ -308,18 +321,21 @@ async def stopfunmsg(bot: Bot, event: GroupMessageEvent):
msg_send = ['呃...头好疼...恢复了']
await stop_fun_msg.finish(msg_send)
#上调学习能力和主动发言
# 上调学习能力和主动发言
upLearning = on_message(
rule=to_me() & keyword('加强学习能力','派蒙快学','再学快点','多说点话') & Rule(checkGroup),
rule=to_me() & keyword('加强学习能力', '派蒙快学', '再学快点', '多说点话') & Rule(checkGroup),
priority=6,
block=True,
permission=permission.GROUP_ADMIN | permission.GROUP_OWNER | SUPERUSER
)
upLearning.__paimon_help__ = {
"usage": "@派蒙 <派蒙快学>",
"usage": "@派蒙 <派蒙快学>",
"introduce": "增强派蒙的学习能力",
"priority": 98
"priority": 98
}
@upLearning.handle()
async def _(bot: Bot, event: GroupMessageEvent):
if Chat.speak_threshold == 1:
@ -330,18 +346,21 @@ async def _(bot: Bot, event: GroupMessageEvent):
Chat.answer_threshold = Chat.speak_threshold
await upLearning.finish("派蒙会努力学习的")
#降低学习能力和主动发言
# 降低学习能力和主动发言
downLearning = on_message(
rule=to_me() & keyword('降低学习能力','派蒙变笨','笨比派蒙','少说点话') & Rule(checkGroup),
rule=to_me() & keyword('降低学习能力', '派蒙变笨', '笨比派蒙', '少说点话') & Rule(checkGroup),
priority=6,
block=True,
permission=permission.GROUP_ADMIN | permission.GROUP_OWNER | SUPERUSER
)
downLearning.__paimon_help__ = {
"usage": "@派蒙 <派蒙变笨>",
"usage": "@派蒙 <派蒙变笨>",
"introduce": "降低派蒙的学习能力",
"priority": 99
"priority": 99
}
@downLearning.handle()
async def _(bot: Bot, event: GroupMessageEvent):
if Chat.speak_threshold == 6:

View File

@ -1,10 +1,13 @@
import random
from pathlib import Path
from typing import Union
from nonebot import on_regex, on_command, logger
from nonebot.matcher import matchers
from nonebot.plugin import PluginMetadata
from nonebot.rule import Rule
from nonebot import get_driver
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, GroupMessageEvent, MessageSegment
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, GroupMessageEvent, PrivateMessageEvent
from nonebot.exception import FinishedException
from utils.config import config
@ -12,18 +15,28 @@ from utils.auth_util import FreqLimiter2
from utils.message_util import MessageBuild
from utils.file_handler import load_json_from_url
__paimon_help__ = {
'type': '派蒙机器学习',
'range': ['private', 'group', 'guild']
}
__plugin_meta__ = PluginMetadata(
name="派蒙聊天",
description="派蒙会发语音、会学群友们说骚话哦(",
usage=(
"被动技能"
),
extra={
'type': '派蒙聊天',
'range': ['group'],
"author": "惜月 SCUOP",
"version": "1.0.1",
},
)
if config.paimon_mongodb_url:
try:
from .Learning_repeate import main
except ImportError:
logger.info('派蒙机器学习聊天启用失败可能是mongodb连接失败或缺少相关库')
logger.warning('派蒙机器学习聊天启用失败可能是mongodb连接失败或缺少相关库jieba_fast、pymongo、pypinyin')
else:
logger.info('派蒙机器学习聊天启用失败mongodb尚未配置')
logger.warning('派蒙机器学习聊天启用失败尚未配置mongodb连接url')
driver = get_driver()
@ -32,20 +45,17 @@ chat_lmt = FreqLimiter2(60)
update_voice = on_command('更新派蒙语音', priority=2)
# TODO 被动效果
def check_group(event: GroupMessageEvent) -> bool:
if event.group_id in config.paimon_chat_group:
return True
return False
def check_group(event: Union[GroupMessageEvent, PrivateMessageEvent]) -> bool:
return True if isinstance(event, PrivateMessageEvent) else event.group_id in config.paimon_chat_group
@update_voice.handle()
async def update_paimon_voice(event: MessageEvent):
try:
old_len = len([m for m in matchers[10] if m.plugin_name == 'Paimon_Chat'])
voice_list = await load_json_from_url('https://static.cherishmoon.fun/LittlePaimon/voice/voice_list.json')
path = Path() / 'data' / 'LittlePaimon' / 'voice' / 'voice_list.json'
voice_list = await load_json_from_url('https://static.cherishmoon.fun/LittlePaimon/voice/voice_list.json', path, True)
matchers[10] = [m for m in matchers[10] if m.plugin_name != 'Paimon_Chat']
for key, value in voice_list.items():
create_matcher(key, value['pattern'], value['cooldown'], value['pro'], value['files'])
@ -62,21 +72,25 @@ def create_matcher(chat_word: str, pattern: str, cooldown: int, pro: float, resp
def check_pro() -> bool:
return random.random() < pro
def check_cooldown(event: GroupMessageEvent) -> bool:
def check_cooldown(event: Union[GroupMessageEvent, PrivateMessageEvent]) -> bool:
return chat_lmt.check(event.group_id, chat_word)
hammer = on_regex(pattern, priority=10, rule=Rule(check_group, check_pro, check_cooldown))
hammer.plugin_name = 'Paimon_Chat'
@hammer.handle()
async def handler(event: GroupMessageEvent):
async def handler(event: Union[GroupMessageEvent, PrivateMessageEvent]):
try:
chat_lmt.start_cd(event.group_id, chat_word, cooldown)
response = random.choice(responses)
if '.mp3' not in response:
await hammer.finish(response)
else:
response: str = random.choice(responses)
if response.endswith('.mp3'):
await hammer.finish(await MessageBuild.StaticRecord(url=f'LittlePaimon/voice/{response}'))
if response.endswith(('.png', '.jpg', '.jpeg', '.image', '.gif')):
await hammer.finish(await MessageBuild.StaticImage(url=f'LittlePaimon/voice/{response}'))
if response.endswith(('.mp4', '.avi')):
await hammer.finish(await MessageBuild.StaticVideo(url=f'LittlePaimon/voice/{response}'))
else:
await hammer.finish(MessageBuild.Text(response))
except FinishedException:
raise
except Exception as e:
@ -85,6 +99,7 @@ def create_matcher(chat_word: str, pattern: str, cooldown: int, pro: float, resp
@driver.on_startup
async def load_voice():
voice_list = await load_json_from_url('https://static.cherishmoon.fun/LittlePaimon/voice/voice_list.json')
path = Path() / 'data' / 'LittlePaimon' / 'voice' / 'voice_list.json'
voice_list = await load_json_from_url('https://static.cherishmoon.fun/LittlePaimon/voice/voice_list.json', path)
for k, v in voice_list.items():
create_matcher(k, v['pattern'], v['cooldown'], v['pro'], v['files'])

View File

@ -7,27 +7,39 @@ from nonebot.adapters.onebot.v11 import MessageEvent, Message, GroupMessageEvent
from nonebot.internal.matcher import Matcher
from nonebot.internal.params import ArgPlainText
from nonebot.params import CommandArg
from nonebot.plugin import PluginMetadata
from .data_source import get_Info, get_Notification, check_token
from utils.decorator import exception_handler
from utils.file_handler import load_json, save_json
HELP_STR = '''
云原神相关功能
云原神 绑定/bind : 绑定云原神的token
云原神 信息/info: 查询云原神账户信息
'''.strip()
__plugin_meta__ = PluginMetadata(
name="云原神",
description="云原神相关功能模块",
usage=(
"云原神 绑定/bind : 绑定云原神的token\n"
"云原神 信息/info: 查询云原神账户信息\n"
),
extra={
'type': '工具',
'range': ['private', 'group'],
"author": "nicklly <1134741727@qq.com>",
"version": "1.0.0",
},
)
cloud_ys = on_command('云原神', aliases={'云原神', 'yys'}, priority=16, block=True)
rm_cloud_ys = on_command('云原神解绑', aliases={'yys解绑', 'yys解除绑定', 'yysdel'}, priority=16, block=True)
cloud_ys.__paimon_help__ = {
"usage": "云原神",
"introduce": "查询云原神账户信息, 绑定token进行签到",
"priority": 99
"priority": 95
}
rm_cloud_ys.__paimon_help__ = {
"usage": "云原神解绑",
"introduce": "解绑cookie并取消自动签到",
"priority": 99
"priority": 96
}
scheduler = require('nonebot_plugin_apscheduler').scheduler
uuid = str(uuid.uuid4())

View File

@ -2,12 +2,26 @@ import re
from nonebot import on_command
from nonebot.params import CommandArg, T_State, Arg
from nonebot.adapters.onebot.v11 import PrivateMessageEvent, Message
from nonebot.plugin import PluginMetadata
from .data_source import get_address, get_goods, save_exchange_info, get_exchange_info, delete_exchange_info
__paimon_help__ = {
'type': '工具',
'range': ['private']
}
__plugin_meta__ = PluginMetadata(
name="米游币商品抢兑",
description="小派蒙的米游币商品抢兑模块",
usage=(
"myb 跟随派蒙的指引录入兑换计划\n"
"myb_info 查看当前的兑换计划\n"
"myb_delete 删除你的所有兑换计划\n"
),
extra={
'type': '工具',
'range': ['private'],
"author": "惜月 <277073121@qq.com>",
"version": "1.0.0",
},
)
myb_exchange = on_command('myb', aliases={'米游币兑换', '米游币商品兑换', '米游社商品兑换'}, priority=4, block=True)
myb_exchange.__paimon_help__ = {

View File

@ -4,6 +4,7 @@ from typing import Dict
from nonebot import on_command, on_regex
from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent, Message
from nonebot.params import RegexDict, CommandArg
from nonebot.plugin import PluginMetadata
from utils.config import config
from utils import aiorequests
@ -11,22 +12,27 @@ from utils.auth_util import FreqLimiter
from .gacha_info import *
from .gacha_res import more_ten
__usage__ = '''
1.[抽n十连xx池]抽n次xx池的十连最多同时5次
*池子和官方同步有角色1|角色2|武器|常驻默认为角色1
2.[模拟抽卡记录]查看模拟抽卡记录总结
3.[模拟抽卡记录 角色/武器]查看模拟抽卡抽到的五星角色/武器
4.[删除模拟抽卡记录]顾名思义
5.[选择定轨 武器全名]选择武器定轨
6.[查看定轨]查看当前定轨的武器
7.[删除定轨]删除当前定轨的武器
'''
__help_version__ = '1.0.1'
__paimon_help__ = {
'type': '原神模拟抽卡',
'range': ['private', 'group', 'guild']
}
__plugin_meta__ = PluginMetadata(
name="原神模拟抽卡",
description="小派蒙的原神模拟抽卡模块",
usage=(
"1.[抽n十连xx池]抽n次xx池的十连最多同时5次"
"*池子和官方同步有角色1|角色2|武器|常驻默认为角色1"
"2.[模拟抽卡记录]查看模拟抽卡记录总结"
"3.[模拟抽卡记录 角色/武器]查看模拟抽卡抽到的五星角色/武器"
"4.[删除模拟抽卡记录]顾名思义"
"5.[选择定轨 武器全名]选择武器定轨"
"6.[查看定轨]查看当前定轨的武器"
"7.[删除定轨]删除当前定轨的武器"
),
extra={
'type': '原神模拟抽卡',
'range': ['private', 'group', 'guild'],
"author": "惜月 <277073121@qq.com>",
"version": "1.0.3",
},
)
sim_gacha = on_regex(r'^抽((?P<num>\d+)|(?:.*))十连(?P<pool>.*?)$', priority=5, block=True)
sim_gacha.__paimon_help__ = {

View File

@ -6,25 +6,28 @@ from typing import Union
from nonebot import on_command
from nonebot.adapters.onebot.v11 import Bot, Message, MessageEvent, GroupMessageEvent
from nonebot.params import CommandArg
from nonebot.plugin import PluginMetadata
from utils.message_util import get_uid_in_msg
from .api import toApi, checkApi
from .gacha_logs import get_data
from .get_img import get_gacha_log_img
from pathlib import Path
__usage__ = '''
1.[获取抽卡记录 (uid) (url)]提供url获取原神抽卡记录需要一定时间
2.[查看抽卡记录 (uid)]查看抽卡记录分析
3.[导出抽卡记录 (uid) (xlsx/json)]导出抽卡记录文件上传到群文件中
'''
__help_version__ = '0.9.0'
__paimon_help__ = {
'type': '原神抽卡记录',
'range': ['private', 'group', 'guild']
}
__plugin_meta__ = PluginMetadata(
name="Paimon_Gacha_Log",
description="小派蒙的原神抽卡记录模块",
usage=(
"1.[获取抽卡记录 (uid) (url)]提供url获取原神抽卡记录需要一定时间"
"2.[查看抽卡记录 (uid)]查看抽卡记录分析"
"3.[导出抽卡记录 (uid) (xlsx/json)]导出抽卡记录文件,上传到群文件中"
),
extra={
'type': '原神抽卡记录',
'range': ['private', 'group', 'guild'],
"author": "惜月 <277073121@qq.com>",
"version": "0.1.3",
},
)
gacha_log_export = on_command('ckjldc', aliases={'抽卡记录导出', '导出抽卡记录'}, priority=5, block=True)
gacha_log_export.__paimon_help__ = {

View File

@ -6,7 +6,8 @@ from collections import defaultdict
from nonebot import on_command, require, logger, get_bot
from nonebot.adapters.onebot.v11 import MessageEvent, Message, Bot, MessageSegment
from nonebot.params import CommandArg
from nonebot.params import CommandArg, Arg
from nonebot.plugin import PluginMetadata
from nonebot.typing import T_State
from nonebot.permission import SUPERUSER
from nonebot.rule import to_me
@ -34,36 +35,44 @@ from .draw_role_card import draw_role_card
require('nonebot_plugin_apscheduler')
from nonebot_plugin_apscheduler import scheduler
__usage__ = '''
[ys (uid)]查看原神个人卡片(包含宝箱探索度等数据)
[ysa (uid)]查看所有公开的8角色的简略信息
[ysc (uid) 角色名]查看公开的8角色的详细信息
*绑定私人cookie之后就可以查看所有角色啦
--------
[ssbq/实时便签 (uid)]查询当前树脂洞天宝钱派遣状况等
[ssbq (uid) 开启提醒(树脂数)/关闭提醒]开启/关闭树脂提醒达到树脂数时会在群里艾特你
*绑定私人cookie之后才能使用
--------
[sy/深渊查询/深境螺旋查询 (uid) (层数)]查询深渊战绩信息
*绑定私人cookie之后才能查看层数具体阵容哦
--------
[mys签到]手动进行一次米游社原神签到
[mys自动签到开启uid/关闭]开启米游社原神自动签到
--------
[myzj/每月札记/zj (uid) (月份)]查看该月份获得的原石摩拉数
*绑定私人cookie之后才能使用,只能查看最近3个月的记录,默认为本月
--------
[ysb cookie]绑定你的私人cookie以开启高级功能
[删除ck]删除你的私人cookie
[添加公共ck cookie]添加公共cookie以供大众查询*仅管理员
'''
__paimon_help__ = {
'type': '原神信息查询',
'range': ['private', 'group', 'guild']
}
__plugin_meta__ = PluginMetadata(
name="Paimon_Info",
description="小派蒙的原神信息查询模块",
usage=(
"[ys (uid)]查看原神个人卡片(包含宝箱、探索度等数据)\n"
"[ysa (uid)]查看所有公开的8角色的简略信息\n"
"[ysc (uid) 角色名]查看公开的8角色的详细信息\n"
"*绑定私人cookie之后就可以查看所有角色啦\n"
"--------\n"
"[ssbq/实时便签 (uid)]查询当前树脂、洞天宝钱、派遣状况等\n"
"[ssbq (uid) 开启提醒(树脂数)/关闭提醒]开启/关闭树脂提醒,达到树脂数时会在群里艾特你\n"
"*绑定私人cookie之后才能使用\n"
"--------\n"
"[sy/深渊查询/深境螺旋查询 (uid) (层数)]查询深渊战绩信息\n"
"*绑定私人cookie之后才能查看层数具体阵容哦\n"
"--------\n"
"[mys签到]手动进行一次米游社原神签到\n"
"[mys自动签到开启uid/关闭]开启米游社原神自动签到\n"
"--------\n"
"[myzj/每月札记/zj (uid) (月份)]查看该月份获得的原石、摩拉数\n"
"*绑定私人cookie之后才能使用,只能查看最近3个月的记录,默认为本月\n"
"--------\n"
"[ysb cookie]绑定你的私人cookie以开启高级功能\n"
"[删除ck]删除你的私人cookie\n"
"[添加公共ck cookie]添加公共cookie以供大众查询*仅管理员\n"
"--------\n"
"[更新角色信息 uid]更新游戏内展柜8个角色的面板信息\n"
"[ysd 角色名 uid]查看指定角色的详细面板信息\n"
),
extra={
'type': '原神信息查询',
'range': ['private', 'group', 'guild'],
"author": "惜月 <277073121@qq.com>",
"version": "0.1.3",
},
)
__help_version__ = '1.1.0'
sy = on_command('sy', aliases={'深渊信息', '深境螺旋信息'}, priority=7, block=True)
sy.__paimon_help__ = {
@ -483,7 +492,7 @@ async def mys_sign_auto_handler(event: MessageEvent, msg: Message = CommandArg()
ud_lmt = FreqLimiter(300)
ud_p_lmt = FreqLimiter(12)
ud_p_lmt = FreqLimiter(15)
@update_info.handle()
@ -496,33 +505,38 @@ async def _(event: MessageEvent, state: T_State, msg: Message = CommandArg()):
for msg_seg in msg:
if msg_seg.type == "at":
user = msg_seg.data['qq']
break
if user:
state['uid'] = await get_last_query(str(user))
uid = await get_last_query(str(user))
if uid:
state['uid'] = uid
else:
state['uid'] = await get_last_query(str(event.user_id))
if not ud_lmt.check(state['uid']):
uid = await get_last_query(str(event.user_id))
if uid:
state['uid'] = uid
if 'uid' in state and not ud_lmt.check(state['uid']):
await update_info.finish(f'每个uid每5分钟才能更新一次信息请稍等一下吧~(剩余{ud_lmt.left_time(state["uid"])}秒)')
if not ud_p_lmt.check(get_message_id(event)):
await update_info.finish(f'每个会话每12秒才能更新一次信息,请稍等一下吧~(剩余{ud_lmt.left_time(get_message_id(event))}秒)')
await update_info.finish(f'每个会话每15秒才能更新一次信息,请稍等一下吧~(剩余{ud_lmt.left_time(get_message_id(event))}秒)')
@update_info.got('uid', prompt='请把要更新的uid给派蒙哦~')
@exception_handler()
async def _(event: MessageEvent, state: T_State):
uid = transform_uid(state['uid'])
async def _(event: MessageEvent, uid: Message = Arg('uid')):
uid = transform_uid(uid)
if not uid:
await update_info.finish('个uid不正确哦~,请检查一下', at_sender=True)
await update_info.finish('好像不是一正确的uid哦~,请检查一下', at_sender=True)
await update_last_query(str(event.user_id), uid)
await update_info.send('派蒙开始更新信息~请稍等哦~')
enka_data = await get_enka_data(uid)
if not enka_data:
if uid[0] == '5' or uid[0] == '2':
await update_info.finish('暂不支持B服和2开头的账号哦~请等待开发者更新吧~')
await update_info.finish('暂不支持B服账号哦~请等待开发者更新吧~')
else:
await update_info.finish('派蒙没有查到该uid的信息哦~')
ud_lmt.start_cd(uid, 300)
ud_lmt.start_cd(get_message_id(event), 12)
ud_lmt.start_cd(get_message_id(event), 15)
player_info = PlayerInfo(uid)
player_info.set_player(enka_data['playerInfo'])
if 'avatarInfoList' not in enka_data:

View File

@ -1,25 +1,7 @@
# # 点餐功能
# from .order import *
#
# # 新闻功能
# from .news import *
#
# # 随机图片功能
# from .random_img import *
#
# # 处理好友和群请求功能
# from .auto_handle import *
#
# # 对联功能
# from .couplets import *
#
# from .help import help_
# 如果不需要某项功能将其from xx import * 注释掉即可
from nonebot import load_plugins
import os
load_plugins(os.path.dirname(__file__))

View File

@ -2,15 +2,27 @@ from urllib.parse import quote
from nonebot import on_command
from nonebot.params import CommandArg
from nonebot.adapters.onebot.v11 import MessageEvent
from nonebot.plugin import PluginMetadata
from utils.auth_util import FreqLimiter
from utils.message_util import get_message_id
from utils.config import config
from utils import aiorequests
__paimon_help__ = {
'type': '娱乐',
'range': ['private', 'group', 'guild']
}
__plugin_meta__ = PluginMetadata(
name="对对联",
description="人工智能和你对对联",
usage=(
"对对联 <对联内容>"
),
extra={
'type': '娱乐',
'range': ['private', 'group', 'guild'],
"author": "惜月 <277073121@qq.com>",
"version": "1.0.0",
},
)
couplets = on_command('对联', aliases={'对对联'}, priority=13, block=True)
couplets.__paimon_help__ = {
@ -38,7 +50,7 @@ async def couplets_handler(event: MessageEvent, msg=CommandArg()):
num = num if num < 10 else 10
couplets_limit.start_cd(get_message_id(event), config.paimon_couplets_cd)
text = quote(str(word))
url = f'https://ai-backend.binwang.me/v0.2/couplet/{text}'
url = f'https://seq2seq-couplet-model.rssbrain.com/v0.2/couplet/{text}'
res = await aiorequests.get(url=url)
res = res.json()
result = ''

View File

@ -2,14 +2,26 @@ import re
from nonebot import on_command, require, get_bot, logger
from nonebot.params import CommandArg
from nonebot.adapters.onebot.v11 import MessageEvent, MessageSegment, Message
from nonebot.plugin import PluginMetadata
from utils import aiorequests
from utils.file_handler import load_json, save_json
from utils.message_util import get_message_id
__paimon_help__ = {
'type': '娱乐',
'range': ['private', 'group', 'guild']
}
__plugin_meta__ = PluginMetadata(
name="今日早报",
description="60秒读世界早报",
usage=(
"今日早报 后加on时间/off可以开启/关闭推送"
),
extra={
'type': '娱乐',
'range': ['private', 'group', 'guild'],
"author": "惜月 <277073121@qq.com>",
"version": "1.0.0",
},
)
news60s_pic = on_command('早报', aliases={'今日早报', '今日新闻', '60s读世界'}, priority=13, block=True)
news60s_pic.__paimon_help__ = {

View File

@ -2,13 +2,25 @@ import random
from nonebot import on_command
from nonebot.params import CommandArg
from nonebot.adapters.onebot.v11 import Message, MessageEvent, MessageSegment
from nonebot.plugin import PluginMetadata
from utils.auth_util import FreqLimiter
from utils import aiorequests
__paimon_help__ = {
'type': '娱乐',
'range': ['private', 'group', 'guild']
}
__plugin_meta__ = PluginMetadata(
name="点餐",
description="点餐查看食物图片",
usage=(
"点餐 食物名"
),
extra={
'type': '娱乐',
'range': ['private', 'group', 'guild'],
"author": "惜月 <277073121@qq.com>",
"version": "1.0.0",
},
)
order_pic = on_command('点菜', aliases={'点餐', '食谱', '我想吃'}, priority=13, block=True)
order_pic.__paimon_help__ = {

View File

@ -5,17 +5,26 @@ from nonebot import on_command
from nonebot import plugin as nb_plugin
from nonebot.params import Depends
from nonebot.adapters.onebot.v11 import MessageEvent
from nonebot.plugin import PluginMetadata
from utils.message_util import MessageBuild
__version__ = 'v1.0.0'
__paimon_help__ = {
'type': '工具',
'range': ['private', 'group', 'guild']
}
__plugin_meta__ = PluginMetadata(
name="帮助菜单",
description="自动读取插件的信息,生成帮助菜单图片",
usage=(
"help"
),
extra={
'type': '工具',
'range': ['private', 'group', 'guild'],
"author": "惜月 <277073121@qq.com>",
"version": "v1.0.0",
},
)
help_ = on_command('help', aliases={'帮助菜单'}, priority=1, block=True)
help_ = on_command('help', aliases={'帮助菜单', '派蒙帮助'}, priority=1, block=True)
help_.__paimon_help__ = {
"usage": "帮助菜单|help",
"introduce": "查看派蒙的帮助信息",
@ -84,7 +93,7 @@ def draw_help_info(help_info: dict):
img.paste(bg_img, (0, 0), bg_img)
draw = ImageDraw.Draw(img)
draw_shadow_text(draw, (50, 50), '派蒙帮助', get_font(140), (255, 255, 255), (0, 0, 0, 255), (3, 3))
draw_shadow_text(draw, (610, 140), __version__, get_font(50), (255, 255, 255), (0, 0, 0, 255), (3, 3))
draw_shadow_text(draw, (610, 140), __plugin_meta__.extra.get('version', '1.0.0'), get_font(50), (255, 255, 255), (0, 0, 0, 255), (3, 3))
draw_shadow_text(draw, (520, 250), '<>内为必须,[]内为可选,()内只需要第一次', get_font(50), (255, 255, 255), (0, 0, 0, 255), (2, 2))
draw_shadow_text(draw, (620, 300), '描述前带*号说明需要绑定私人cookie', get_font(50), (255, 255, 255), (0, 0, 0, 255), (2, 2))
n = 400
@ -101,20 +110,22 @@ async def get_all_plugin(event: MessageEvent) -> dict:
help_info: Dict[str, List[dict]] = {}
for plugin in plugin_list:
try:
plugin_info = plugin.module.__getattribute__('__paimon_help__')
plugin_type = plugin.metadata.extra.get('type', '其他')
plugin_range = plugin.metadata.extra.get('range', ['private', 'group', 'guild'])
except AttributeError:
plugin_info = {'type': '其他', 'range': ['private', 'group', 'guild']}
if event.message_type not in plugin_info['range']:
plugin_type = '其他'
plugin_range = ['private', 'group', 'guild']
if event.message_type not in plugin_range:
continue
if plugin_info['type'] not in help_info:
help_info[plugin_info['type']] = []
if plugin_type not in help_info:
help_info[plugin_type] = []
matchers = plugin.matcher
for matcher in matchers:
try:
matchers_info = matcher.__paimon_help__
if 'priority' not in matchers_info:
matchers_info['priority'] = 99
help_info[plugin_info['type']].append(matchers_info)
help_info[plugin_type].append(matchers_info)
except AttributeError:
pass
help_info = {k: v for k, v in help_info.items() if v}

View File

@ -2,15 +2,28 @@ import random
from nonebot import on_command, on_regex
from nonebot.params import RegexGroup
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, MessageSegment
from nonebot.plugin import PluginMetadata
from utils.config import config
from utils.auth_util import FreqLimiter
from utils.message_util import get_message_id
from utils.decorator import auto_withdraw
__paimon_help__ = {
'type': '娱乐',
'range': ['private', 'group', 'guild']
}
__plugin_meta__ = PluginMetadata(
name="随机图片",
description="从各随机图片接口获取一张图片",
usage=(
"来点猫片\n"
"来点二次元图\n"
),
extra={
'type': '娱乐',
'range': ['private', 'group', 'guild'],
"author": "惜月 <277073121@qq.com>",
"version": "1.0.0",
},
)
cat_lmt = FreqLimiter(config.paimon_cat_cd)
ecy_lmt = FreqLimiter(config.paimon_ecy_cd)

View File

@ -6,28 +6,42 @@ from nonebot import on_endswith, on_command, on_regex
from nonebot.adapters.onebot.v11 import MessageEvent, Message, MessageSegment
from nonebot.params import RegexDict
from nonebot.typing import T_State
from nonebot.plugin import PluginMetadata
from utils.alias_handler import get_match_alias
from utils.file_handler import load_json_from_url
from utils.message_util import MessageBuild
from .abyss_rate_draw import draw_rate_rank, draw_teams_rate
__usage__ = '''
1.[xx角色攻略]查看西风驿站出品的角色一图流攻略
2.[xx角色材料]查看惜月出品的角色材料统计
3.[xx参考面板]查看blue菌hehe出品的参考面板攻略
4.[xx收益曲线]查看blue菌hehe出品的收益曲线攻略
*感谢来自大佬们的授权角色支持别名查询
5.[今日/明日/周x材料]查看每日角色天赋材料和武器突破材料表
6.[深渊登场率]查看2.6深渊角色登场率
7.[深渊上半/下半阵容出场率]查看2.6深渊阵容出场率
'''
__help_version__ = '1.0.4'
__paimon_help__ = {
'type': '原神Wiki',
'range': ['private', 'group', 'guild']
}
__plugin_meta__ = PluginMetadata(
name="Paimon_Wiki",
description="小派蒙的wiki查询模块",
usage=(
"1.[xx角色攻略]查看西风驿站出品的角色一图流攻略\n"
"2.[xx角色材料]查看惜月出品的角色材料统计\n"
"3.[xx参考面板]查看blue菌hehe出品的参考面板攻略\n"
"4.[xx收益曲线]查看blue菌hehe出品的收益曲线攻略\n"
"5.[今日/明日/周x材料]查看每日角色天赋材料和武器突破材料表\n"
"6.[深渊登场率]查看2.6深渊角色登场率\n"
"7.[深渊上半/下半阵容出场率]查看2.6深渊阵容出场率\n"
"8.[xx武器攻略]查看武器攻略\n"
"9.[xx原魔图鉴]查看原魔图鉴\n"
),
extra={
'type': '原神Wiki',
'range': ['private', 'group', 'guild'],
"author": "惜月 <277073121@qq.com>",
"version": "0.1.3",
},
)
res_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'res')
guide = on_endswith('角色攻略', priority=8)

View File

@ -64,45 +64,21 @@
</details>
## 丨更新日志
+ 5.19
- 米游社签到新增`全部重签`,仅限超级管理员使用,需@机器人
- `原神猜语音`不再需要`我猜`,直接回答角色别名即可参与猜猜看
- 异步请求库从`aiohttp`改用`httpx`,需安装依赖库`pip install httpx`
- 修复`60秒读世界`在频道无法关闭推送的BUG
+ 5.20
- 修复`ysc`缺少资源问题
- 封装部分常用方法,优化导包
- `Paimon_Chat`新增`更新派蒙语音`,实时更新语音
+ 5.21
- 修复可能因ssl证书导致的静态资源下载问题
+ 5.23
- 新增`xx原魔图鉴`
+ 5.25
- `ys、ysc、ysa、sy`等和`wiki`模块指令可以对话式查询
+ 5.27
- 新增`原神日历`[@nicklly](https://github.com/nicklly)
+ 5.28
- `Paimon_Chat`聊天新增`学习群友发言`(魔改自[Pallas-Bot](https://github.com/InvoluteHell/Pallas-Bot/tree/master/src/plugins/repeater)),需安装`jieba_fast、pymongo、pypinyin依赖库``mongodb数据库`且在`.env.*`配置文件中添加mongodb连接参数`paimon_mongodb_url`,例如`paimon_mongodb_url=mongodb://localhost:27017/`
+ 6.3
- 新增游戏内展柜角色面板卡片,使用`更新角色面板`来获取角色,`ysd角色名`来查看角色卡片
- 修复部分不记录上次查询的uid的bug
- 大幅缩短深渊指令`sy`的缓存时间
+ 6.6
- 修复`模拟抽卡定轨``抽卡记录导出`bug
+ 6.7
- 修复`原神猜语音``模拟抽卡``nonebot2.0.0b3`版本Union校验产生的bug`原神猜语音`将暂时无法私聊使用
+ 6.9
- 新增`帮助菜单`指令~~(不太好看,继续美化)~~
+ 6.12
- 新增`云原神签到`等功能[@nicklly](https://github.com/nicklly)
- 修复部分bug新增`好友、群新成员和龙王提醒`[#45](https://github.com/CMHopeSunshine/LittlePaimon/issues/45)
> README只展示最近2条更新全部更新日志详见[这里](https://github.com/CMHopeSunshine/LittlePaimon/blob/nonebot2/UPDATE_LOG.md)
+ 6.19
- 新增`米游币商品兑换`功能,私聊机器人发送`myb`跟着一步步指引来做目前该功能还没有机会做测试出现问题请提issue
- `ysb`绑定cookie的方法增加腾讯文档
+ 6.21
- 适配`nonebot2 beta4`插件元数据请更新nb版本`pip install nonebot2 --upgrade`
- `Paimon_Chat`现在可以发图片、视频等,可自行添加
- 修复`Paimon_Wiki`搜索对象名结果只有一个时仍需要选择的bug
- 对对联功能api更换
- 增加部分注释文档
## 丨功能列表
详见[功能列表](https://blog.cherishmoon.fun/posts/nonebot2funclist.html)
详见我的博客[功能列表](https://blog.cherishmoon.fun/posts/nonebot2funclist.html) <br>
博客内容可能滞后于实际版本 ~~太懒了~~
## 丨部署方法
### 我很熟悉NoneBot2

43
UPDATE_LOG.md Normal file
View File

@ -0,0 +1,43 @@
# LittlePaimon更新日志
+ 5.19
- 米游社签到新增`全部重签`,仅限超级管理员使用,需@机器人
- `原神猜语音`不再需要`我猜`,直接回答角色别名即可参与猜猜看
- 异步请求库从`aiohttp`改用`httpx`,需安装依赖库`pip install httpx`
- 修复`60秒读世界`在频道无法关闭推送的BUG
+ 5.20
- 修复`ysc`缺少资源问题
- 封装部分常用方法,优化导包
- `Paimon_Chat`新增`更新派蒙语音`,实时更新语音
+ 5.21
- 修复可能因ssl证书导致的静态资源下载问题
+ 5.23
- 新增`xx原魔图鉴`
+ 5.25
- `ys、ysc、ysa、sy`等和`wiki`模块指令可以对话式查询
+ 5.27
- 新增`原神日历`[@nicklly](https://github.com/nicklly)
+ 5.28
- `Paimon_Chat`聊天新增`学习群友发言`(魔改自[Pallas-Bot](https://github.com/InvoluteHell/Pallas-Bot/tree/master/src/plugins/repeater)),需安装`jieba_fast、pymongo、pypinyin依赖库``mongodb数据库`且在`.env.*`配置文件中添加mongodb连接参数`paimon_mongodb_url`,例如`paimon_mongodb_url=mongodb://localhost:27017/`
+ 6.3
- 新增游戏内展柜角色面板卡片,使用`更新角色面板`来获取角色,`ysd角色名`来查看角色卡片
- 修复部分不记录上次查询的uid的bug
- 大幅缩短深渊指令`sy`的缓存时间
+ 6.6
- 修复`模拟抽卡定轨``抽卡记录导出`bug
+ 6.7
- 修复`原神猜语音``模拟抽卡``nonebot2.0.0b3`版本Union校验产生的bug`原神猜语音`将暂时无法私聊使用
+ 6.9
- 新增`帮助菜单`指令 ~~(不太好看,继续美化)~~
+ 6.12
- 新增`云原神签到`等功能[@nicklly](https://github.com/nicklly)
- 修复部分bug新增`好友、群新成员和龙王提醒`[#45](https://github.com/CMHopeSunshine/LittlePaimon/issues/45)
+ 6.19
- 新增`米游币商品兑换`功能,私聊机器人发送`myb`跟着一步步指引来做目前该功能还没有机会做测试出现问题请提issue
- `ysb`绑定cookie的方法增加腾讯文档
+ 6.21
- 适配`nonebot2 beta4`插件元数据请更新nb版本`pip install nonebot2 --upgrade`
- `Paimon_Chat`现在可以发图片、视频等,可自行添加
- 修复`Paimon_Wiki`搜索对象名结果只有一个时仍需要选择的bug
- 对对联功能api更换
- 增加部分注释文档

View File

@ -94,7 +94,7 @@ async def get_img(url: str,
timeout=timeout,
**kwargs)
resp = resp.read()
if b'error' in resp:
if 'NoSuchKey' in resp:
return 'No Such File'
img = Image.open(BytesIO(resp))
except SSLCertVerificationError:

View File

@ -5,7 +5,7 @@ import os
def get_short_name(name: str):
short_name = load_json(path=os.path.join(os.path.dirname(__file__),'short_name.json'))
short_name = load_json(path=os.path.join(os.path.dirname(__file__), 'short_name.json'))
return name if name not in short_name.keys() else short_name[name]
@ -26,7 +26,6 @@ def get_name_by_id(role_id: str):
return None
def get_match_alias(msg: str, type: str = 'roles', single_to_dict: bool = False) -> Union[str, list, dict]:
alias_file = load_json(path=os.path.join(os.path.dirname(__file__), 'alias.json'))
alias_list = alias_file[type]
@ -42,6 +41,8 @@ def get_match_alias(msg: str, type: str = 'roles', single_to_dict: bool = False)
else:
return alias[0]
elif match_list:
if len(match_list) == 1:
return alias[0]
possible[alias[0]] = role_id
return possible
elif type == 'weapons':

View File

@ -13,6 +13,16 @@ def load_image(
crop: Optional[Tuple[int, int, int, int]] = None,
mode: Optional[str] = None,
):
"""
说明
读取图像并预处理
参数
:param path: 图片路径
:param size: 预处理尺寸
:param crop: 预处理裁剪大小
:param mode: 预处理图像模式
:return: 图像对象
"""
img = Image.open(path)
if size:
if isinstance(size, float):
@ -26,7 +36,16 @@ def load_image(
return img
def load_json(file: str = None, path: Union[Path, str] = None, encoding: str = 'utf-8'):
def load_json(file: str = None, path: Union[Path, str] = None, encoding: str = 'utf-8') -> dict:
"""
说明
读取本地json文件返回json字典file和path参数2选1即可file需为data/LittlePaimon中的文件path哪的文件都行
参数
:param file: 文件名
:param path: 文件路径
:param encoding: 编码默认为utf-8
:return: json字典
"""
if file and not path:
path = Path() / 'data' / 'LittlePaimon' / file
elif path:
@ -37,12 +56,25 @@ def load_json(file: str = None, path: Union[Path, str] = None, encoding: str = '
return json.load(path.open('r', encoding=encoding))
async def load_json_from_url(url: str):
try:
resp = await aiorequests.get(url)
except SSLCertVerificationError:
resp = await aiorequests.get(url.replace('https', 'http'))
return resp.json()
async def load_json_from_url(url: str, path: Union[Path, str] = None, force_refresh: bool = False) -> dict:
"""
从网络url中读取json当有path参数时如果path文件不存在就会从url下载保存到path如果path文件存在则直接读取path
:param url: url
:param path: 本地json文件路径
:param force_refresh: 是否强制重新下载
:return: json字典
"""
if path and Path(path).exists() and not force_refresh:
return load_json(path=path)
else:
try:
resp = await aiorequests.get(url)
except SSLCertVerificationError:
resp = await aiorequests.get(url.replace('https', 'http'))
data = resp.json()
if path and not Path(path).exists():
save_json(data=data, path=path)
return data
def save_json(data, file: str = None, path: Union[Path, str] = None, encoding: str = 'utf-8'):

4
utils/json/ban_word.txt Normal file
View File

@ -0,0 +1,4 @@
[CQ:
[cq:
[Cq:
[cQ:

View File

@ -13,6 +13,12 @@ from .db_util import get_last_query, update_last_query
from .file_handler import load_image
from . import aiorequests
# 加载敏感违禁词列表
ban_word = []
with open(Path(__file__).parent / 'json' / 'ban_word.txt', 'r', encoding='utf-8') as f:
for line in f:
ban_word.append(line.strip())
class MessageBuild:
@ -25,6 +31,16 @@ class MessageBuild:
quality: Optional[int] = 100,
mode: Optional[str] = 'RGB'
) -> MessageSegment:
"""
说明
图片预处理并构造成MessageSegment
:param img: 图片Image对象或图片路径
:param size: 预处理尺寸
:param crop: 预处理裁剪大小
:param quality: 预处理图片质量
:param mode: 预处理图像模式
:return: MessageSegment.image
"""
if isinstance(img, str) or isinstance(img, Path):
img = load_image(path=img, size=size, mode=mode, crop=crop)
else:
@ -48,11 +64,26 @@ class MessageBuild:
size: Optional[Tuple[int, int]] = None,
crop: Optional[Tuple[int, int, int, int]] = None,
quality: Optional[int] = 100,
mode: Optional[str] = 'RGB',
tips: Optional[str] = None
mode: Optional[str] = None,
tips: Optional[str] = None,
is_check_time: Optional[bool] = True,
check_time_day: Optional[int] = 3
):
"""
从url下载图片并预处理并构造成MessageSegment如果url的图片已存在本地则直接读取本地图片
:param url: 图片url
:param size: 预处理尺寸
:param crop: 预处理裁剪大小
:param quality: 预处理图片质量
:param mode: 预处理图像模式
:param tips: url中不存在该图片时的提示语
:param is_check_time: 是否检查本地图片最后修改时间
:param check_time_day: 检查本地图片最后修改时间的天数超过该天数则重新下载图片
:return: MessageSegment.image
"""
path = Path() / 'data' / url
if path.exists() and not check_time(path.stat().st_mtime, 3):
if path.exists() and (
not is_check_time or (is_check_time and not check_time(path.stat().st_mtime, check_time_day))):
img = Image.open(path)
else:
path.parent.mkdir(parents=True, exist_ok=True)
@ -63,23 +94,35 @@ class MessageBuild:
img = img.resize(size)
if crop:
img = img.crop(crop)
if mode:
img = img.convert(mode)
bio = BytesIO()
img = img.convert(mode)
img.save(bio, format='JPEG' if mode == 'RGB' else 'PNG', quality=quality)
img.save(bio, format=img.format, quality=quality)
return MessageSegment.image(bio)
@classmethod
def Text(cls, text: str) -> MessageSegment:
# TODO 过滤负面文本
"""
过滤文本中的敏感词
:param text: 文本
:return: MessageSegment.text
"""
for word in ban_word:
if word in text:
text = text.replace(word, '*')
return MessageSegment.text(text)
@classmethod
def Record(cls, path: str) -> MessageSegment:
# TODO 网络语音
return MessageSegment.record(path)
@classmethod
async def StaticRecord(cls, url: str) -> MessageSegment:
"""
从url中下载音频文件并构造成MessageSegment如果本地已有该音频文件则直接读取本地文件
:param url: 语音url
:return: MessageSegment.record
"""
path = Path() / 'data' / url
if not path.exists():
path.parent.mkdir(parents=True, exist_ok=True)
@ -88,6 +131,25 @@ class MessageBuild:
path.write_bytes(content)
return MessageSegment.record(file=path)
@classmethod
def Video(cls, path: str) -> MessageSegment:
return MessageSegment.video(path)
@classmethod
async def StaticVideo(cls, url: str) -> MessageSegment:
"""
从url中下载视频文件并构造成MessageSegment如果本地已有该视频文件则直接读取本地文件
:param url: 视频url
:return: MessageSegment.video
"""
path = Path() / 'data' / url
if not path.exists():
path.parent.mkdir(parents=True, exist_ok=True)
resp = await aiorequests.get(url='https://static.cherishmoon.fun/' + url)
content = resp.content
path.write_bytes(content)
return MessageSegment.video(file=path)
async def get_at_target(msg):
for msg_seg in msg:
@ -174,6 +236,8 @@ def replace_all(raw_text: str, text_list: Union[str, list]):
def transform_uid(msg):
if not msg:
return None
if isinstance(msg, Message):
msg = msg.extract_plain_text().strip()
check_uid = msg.split(' ')
@ -193,4 +257,3 @@ def check_time(time_stamp, n=1):
return True
else:
return False