mirror of
https://github.com/xuthus83/LittlePaimon.git
synced 2024-10-21 16:27:15 +08:00
✨ 添加原神语音合成
冷却配置项,优化代码
This commit is contained in:
parent
93e6097de5
commit
23a953190e
@ -1 +0,0 @@
|
|||||||
from .plugin import *
|
|
@ -1,37 +0,0 @@
|
|||||||
from typing import Literal, DefaultDict
|
|
||||||
from collections import defaultdict
|
|
||||||
from pydantic import BaseModel
|
|
||||||
|
|
||||||
|
|
||||||
class Statistics(BaseModel):
|
|
||||||
"""
|
|
||||||
插件调用统计
|
|
||||||
"""
|
|
||||||
month: DefaultDict[int, int] = defaultdict(lambda: 0)
|
|
||||||
"""月统计"""
|
|
||||||
week: DefaultDict[int, int] = defaultdict(lambda: 0)
|
|
||||||
"""周统计"""
|
|
||||||
day: DefaultDict[int, int] = defaultdict(lambda: 0)
|
|
||||||
"""日统计"""
|
|
||||||
|
|
||||||
def add(self, user_id: int):
|
|
||||||
"""
|
|
||||||
增加统计数据
|
|
||||||
:param user_id: 用户id
|
|
||||||
"""
|
|
||||||
self.day[user_id] += 1
|
|
||||||
self.week[user_id] += 1
|
|
||||||
self.month[user_id] += 1
|
|
||||||
|
|
||||||
def clear(self, type: Literal['month', 'week', 'day']):
|
|
||||||
"""
|
|
||||||
清除统计数据
|
|
||||||
:param type: 统计类型
|
|
||||||
"""
|
|
||||||
if type == 'month':
|
|
||||||
self.month.clear()
|
|
||||||
elif type == 'week':
|
|
||||||
self.week.clear()
|
|
||||||
elif type == 'day':
|
|
||||||
self.day.clear()
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
|||||||
|
import datetime
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from tortoise import fields
|
from tortoise import fields
|
||||||
from tortoise.models import Model
|
from tortoise.models import Model
|
||||||
|
|
||||||
from LittlePaimon.config.models import Statistics
|
|
||||||
|
|
||||||
|
|
||||||
class PluginPermission(Model):
|
class PluginPermission(Model):
|
||||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||||
@ -18,9 +17,29 @@ class PluginPermission(Model):
|
|||||||
"""插件总开关"""
|
"""插件总开关"""
|
||||||
ban: List[int] = fields.JSONField(default=[])
|
ban: List[int] = fields.JSONField(default=[])
|
||||||
"""插件屏蔽列表"""
|
"""插件屏蔽列表"""
|
||||||
statistics: Statistics = fields.JSONField(encoder=Statistics.json, decoder=Statistics.parse_raw, default=Statistics())
|
statistics: dict = fields.JSONField(default=dict)
|
||||||
"""插件调用统计"""
|
"""插件调用统计,废弃选项,不再使用"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
table = 'plugin_permission'
|
table = 'plugin_permission'
|
||||||
|
|
||||||
|
|
||||||
|
class PluginStatistics(Model):
|
||||||
|
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||||
|
plugin_name: str = fields.CharField(max_length=255)
|
||||||
|
"""插件名称"""
|
||||||
|
matcher_name: str = fields.CharField(max_length=255)
|
||||||
|
"""命令名称"""
|
||||||
|
matcher_usage: str = fields.CharField(max_length=255, null=True)
|
||||||
|
"""命令用法"""
|
||||||
|
group_id: int = fields.IntField(null=True)
|
||||||
|
"""群id"""
|
||||||
|
user_id: int = fields.IntField()
|
||||||
|
"""用户id"""
|
||||||
|
message_type: str = fields.CharField(max_length=10)
|
||||||
|
"""消息类型,group/user"""
|
||||||
|
time: datetime.datetime = fields.DatetimeField()
|
||||||
|
"""调用时间"""
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
table = 'plugin_statistics'
|
||||||
|
22
LittlePaimon/manager/database_manager/__init__.py
Normal file
22
LittlePaimon/manager/database_manager/__init__.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import datetime
|
||||||
|
from LittlePaimon.utils import scheduler, logger
|
||||||
|
from LittlePaimon.database.models import GuessVoiceRank, PluginStatistics, DailyNoteSub, CookieCache, PublicCookie
|
||||||
|
|
||||||
|
|
||||||
|
@scheduler.scheduled_job('cron', hour=0, minute=0, misfire_grace_time=10)
|
||||||
|
async def _():
|
||||||
|
now = datetime.datetime.now()
|
||||||
|
|
||||||
|
logger.info('原神实时便签', '重置每日提醒次数限制')
|
||||||
|
await DailyNoteSub.all().update(today_remind_num=0)
|
||||||
|
|
||||||
|
logger.info('原神Cookie', '清空每日Cookie缓存和限制')
|
||||||
|
await CookieCache.all().delete()
|
||||||
|
await PublicCookie.filter(status=2).update(status=1)
|
||||||
|
|
||||||
|
logger.info('功能调用统计', '清除超过一个月的统计数据')
|
||||||
|
await PluginStatistics.filter(time__lt=now - datetime.timedelta(days=30)).delete()
|
||||||
|
|
||||||
|
if now.weekday() == 0:
|
||||||
|
logger.info('原神猜语音', '清空每周排行榜')
|
||||||
|
await GuessVoiceRank.all().delete()
|
@ -1,4 +1,5 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
|
import datetime
|
||||||
|
|
||||||
from nonebot import on_regex, on_command
|
from nonebot import on_regex, on_command
|
||||||
from nonebot.matcher import Matcher
|
from nonebot.matcher import Matcher
|
||||||
@ -12,8 +13,9 @@ from nonebot.typing import T_State
|
|||||||
from LittlePaimon import SUPERUSERS, DRIVER
|
from LittlePaimon import SUPERUSERS, DRIVER
|
||||||
from LittlePaimon.utils import logger
|
from LittlePaimon.utils import logger
|
||||||
from LittlePaimon.utils.message import CommandObjectID
|
from LittlePaimon.utils.message import CommandObjectID
|
||||||
from LittlePaimon.database.models import PluginPermission
|
from LittlePaimon.database.models import PluginPermission, PluginStatistics
|
||||||
from .manager import PluginManager, hidden_plugins
|
from .manager import PluginManager, hidden_plugins
|
||||||
|
from .model import MatcherInfo
|
||||||
from .draw_help import draw_help
|
from .draw_help import draw_help
|
||||||
|
|
||||||
plugin_manager = PluginManager()
|
plugin_manager = PluginManager()
|
||||||
@ -126,11 +128,26 @@ async def _(event: MessageEvent, matcher: Matcher):
|
|||||||
session_type = 'group'
|
session_type = 'group'
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
perm = await PluginPermission.get_or_none(name=matcher.plugin_name, session_id=session_id, session_type=session_type)
|
|
||||||
|
|
||||||
|
# 权限检查
|
||||||
|
perm = await PluginPermission.get_or_none(name=matcher.plugin_name, session_id=session_id, session_type=session_type)
|
||||||
if not perm:
|
if not perm:
|
||||||
return
|
return
|
||||||
if not perm.status:
|
if not perm.status:
|
||||||
raise IgnoredException('插件使用权限已禁用')
|
raise IgnoredException('插件使用权限已禁用')
|
||||||
if isinstance(event, GroupMessageEvent) and event.user_id in perm.ban:
|
if isinstance(event, GroupMessageEvent) and event.user_id in perm.ban:
|
||||||
raise IgnoredException('用户被禁止使用该插件')
|
raise IgnoredException('用户被禁止使用该插件')
|
||||||
|
|
||||||
|
# 命令调用统计
|
||||||
|
if matcher.plugin_name in plugin_manager.data and 'pm_name' in matcher.state:
|
||||||
|
if matcher_info := filter(lambda x: x.pm_name == matcher.state['pm_name'], plugin_manager.data[matcher.plugin_name].matchers):
|
||||||
|
matcher_info = list(matcher_info)[0]
|
||||||
|
await PluginStatistics.create(plugin_name=matcher.plugin_name,
|
||||||
|
matcher_name=matcher_info.pm_name,
|
||||||
|
matcher_usage=matcher_info.pm_usage,
|
||||||
|
group_id=event.group_id if isinstance(event, GroupMessageEvent) else None,
|
||||||
|
user_id=event.user_id,
|
||||||
|
message_type=session_type,
|
||||||
|
time=datetime.datetime.now())
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,10 +11,13 @@ from .model import MatcherInfo, PluginInfo, Config
|
|||||||
|
|
||||||
hidden_plugins = [
|
hidden_plugins = [
|
||||||
'LittlePaimon',
|
'LittlePaimon',
|
||||||
|
'config',
|
||||||
'nonebot_plugin_apscheduler',
|
'nonebot_plugin_apscheduler',
|
||||||
'nonebot_plugin_gocqhttp',
|
'nonebot_plugin_gocqhttp',
|
||||||
'nonebot_plugin_htmlrender',
|
'nonebot_plugin_htmlrender',
|
||||||
|
'nonebot_plugin_imageutils',
|
||||||
'plugin_manager',
|
'plugin_manager',
|
||||||
|
'database_manager',
|
||||||
'admin'
|
'admin'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -57,3 +57,5 @@ class Config(BaseModel):
|
|||||||
ssbq_begin: int = Field(0, alias='实时便签停止检查开始时间')
|
ssbq_begin: int = Field(0, alias='实时便签停止检查开始时间')
|
||||||
ssbq_end: int = Field(6, alias='实时便签停止检查结束时间')
|
ssbq_end: int = Field(6, alias='实时便签停止检查结束时间')
|
||||||
ssbq_check: int = Field(16, alias='实时便签检查间隔')
|
ssbq_check: int = Field(16, alias='实时便签检查间隔')
|
||||||
|
|
||||||
|
AI_voice_cooldown: int = Field(10, alias='原神AI语音合成冷却时间(秒)')
|
||||||
|
@ -3,7 +3,9 @@ from nonebot import on_regex
|
|||||||
from nonebot.plugin import PluginMetadata
|
from nonebot.plugin import PluginMetadata
|
||||||
from nonebot.params import RegexDict
|
from nonebot.params import RegexDict
|
||||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent, PrivateMessageEvent, MessageSegment
|
from nonebot.adapters.onebot.v11 import GroupMessageEvent, PrivateMessageEvent, MessageSegment
|
||||||
from nonebot.adapters.onebot.v11.helpers import Cooldown, CooldownIsolateLevel
|
from LittlePaimon.utils.tool import freq_limiter
|
||||||
|
from LittlePaimon.utils.filter import filter_msg
|
||||||
|
from LittlePaimon.manager.plugin_manager import plugin_manager as pm
|
||||||
|
|
||||||
__plugin_meta__ = PluginMetadata(
|
__plugin_meta__ = PluginMetadata(
|
||||||
name='原神语音合成',
|
name='原神语音合成',
|
||||||
@ -16,26 +18,30 @@ __plugin_meta__ = PluginMetadata(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
voice_cmd = on_regex(r'(?P<chara>\w*)说(?P<text>[\w,。!?、:;“”‘’〔()〕——!\?,\.`\'"\(\)\[\]{}~\s]+)', priority=20, block=True, state={
|
SUPPORTS_CHARA = ['派蒙', '凯亚', '安柏', '丽莎', '琴', '香菱', '枫原万叶', '迪卢克', '温迪', '可莉', '早柚', '托马', '芭芭拉',
|
||||||
'pm_name': '原神语音合成',
|
'优菈', '云堇', '钟离', '魈', '凝光', '雷电将军', '北斗', '甘雨', '七七', '刻晴', '神里绫华', '戴因斯雷布', '雷泽',
|
||||||
'pm_description': 'AI语音合成,让原神角色说任何话!',
|
'神里绫人', '罗莎莉亚', '阿贝多', '八重神子', '宵宫', '荒泷一斗', '九条裟罗', '夜兰', '珊瑚宫心海', '五郎', '散兵',
|
||||||
'pm_usage': '<角色名>说<话>',
|
'女士', '达达利亚', '莫娜', '班尼特', '申鹤', '行秋', '烟绯', '久岐忍', '辛焱', '砂糖', '胡桃', '重云', '菲谢尔',
|
||||||
'pm_priority': 10
|
'诺艾尔', '迪奥娜', '鹿野院平藏']
|
||||||
})
|
|
||||||
|
CHARA_RE = '|'.join(SUPPORTS_CHARA)
|
||||||
|
|
||||||
|
voice_cmd = on_regex(rf'(?P<chara>({CHARA_RE})?)说(?P<text>[\w,。!?、:;“”‘’〔()〕——!\?,\.`\'"\(\)\[\]{{}}~\s]+)', priority=90, block=True,
|
||||||
|
state={
|
||||||
|
'pm_name': '原神语音合成',
|
||||||
|
'pm_description': 'AI语音合成,让原神角色说任何话!',
|
||||||
|
'pm_usage': '<角色名>说<话>',
|
||||||
|
'pm_priority': 10
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
@voice_cmd.handle(parameterless=[Cooldown(cooldown=6, isolate_level=CooldownIsolateLevel.GROUP, prompt='冷却中...')])
|
@voice_cmd.handle()
|
||||||
async def _(event: Union[GroupMessageEvent, PrivateMessageEvent], regex_dict: dict = RegexDict()):
|
async def _(event: Union[GroupMessageEvent, PrivateMessageEvent], regex_dict: dict = RegexDict()):
|
||||||
regex_dict['text'] = regex_dict['text'].replace('\r', '').replace('\n', '')
|
|
||||||
if not regex_dict['chara']:
|
if not regex_dict['chara']:
|
||||||
regex_dict['chara'] = '派蒙'
|
regex_dict['chara'] = '派蒙'
|
||||||
elif regex_dict['chara'] not in ['派蒙', '凯亚', '安柏', '丽莎', '琴', '香菱', '枫原万叶', '迪卢克', '温迪', '可莉', '早柚', '托马', '芭芭拉',
|
regex_dict['text'] = filter_msg(regex_dict['text'].replace('\r', '').replace('\n', ''))
|
||||||
'优菈', '云堇', '钟离', '魈', '凝光', '雷电将军', '北斗', '甘雨', '七七', '刻晴', '神里绫华', '戴因斯雷布', '雷泽',
|
if not freq_limiter.check(f'genshin_ai_voice_{event.group_id if isinstance(event, GroupMessageEvent) else event.user_id}'):
|
||||||
'神里绫人', '罗莎莉亚', '阿贝多', '八重神子', '宵宫', '荒泷一斗', '九条裟罗', '夜兰', '珊瑚宫心海', '五郎', '散兵',
|
await voice_cmd.finish(f'原神语音合成冷却中...剩余{freq_limiter.left(f"genshin_ai_voice_{event.group_id if isinstance(event, GroupMessageEvent) else event.user_id}")}秒')
|
||||||
'女士', '达达利亚', '莫娜', '班尼特', '申鹤', '行秋', '烟绯', '久岐忍', '辛焱', '砂糖', '胡桃', '重云', '菲谢尔',
|
freq_limiter.start(f'genshin_ai_voice_{event.group_id if isinstance(event, GroupMessageEvent) else event.user_id}', pm.config.AI_voice_cooldown)
|
||||||
'诺艾尔', '迪奥娜', '鹿野院平藏']:
|
|
||||||
return
|
|
||||||
elif len(regex_dict['text']) > 20:
|
|
||||||
return
|
|
||||||
await voice_cmd.finish(MessageSegment.record(
|
await voice_cmd.finish(MessageSegment.record(
|
||||||
f'http://233366.proxy.nscc-gz.cn:8888/?text={regex_dict["text"]}&speaker={regex_dict["chara"]}'))
|
f'http://233366.proxy.nscc-gz.cn:8888/?text={regex_dict["text"]}&speaker={regex_dict["chara"]}'))
|
||||||
|
@ -63,14 +63,14 @@ async def get_rank(group_id: int):
|
|||||||
records = await GuessVoiceRank.filter(group_id=group_id,
|
records = await GuessVoiceRank.filter(group_id=group_id,
|
||||||
guess_time__gte=datetime.datetime.now() - datetime.timedelta(days=7))
|
guess_time__gte=datetime.datetime.now() - datetime.timedelta(days=7))
|
||||||
if not records:
|
if not records:
|
||||||
return '暂无排行榜数据'
|
return '本群本周暂无排行榜数据哦!'
|
||||||
rank = {}
|
rank = {}
|
||||||
for record in records:
|
for record in records:
|
||||||
if record.user_id in rank:
|
if record.user_id in rank:
|
||||||
rank[record.user_id] += 1
|
rank[record.user_id] += 1
|
||||||
else:
|
else:
|
||||||
rank[record.user_id] = 1
|
rank[record.user_id] = 1
|
||||||
msg = '猜语音排行榜\n'
|
msg = '本周猜语音排行榜\n'
|
||||||
for i, (user_id, count) in enumerate(sorted(rank.items(), key=lambda x: x[1], reverse=True), start=1):
|
for i, (user_id, count) in enumerate(sorted(rank.items(), key=lambda x: x[1], reverse=True), start=1):
|
||||||
msg += f'{i}.{user_id}: {count}次\n'
|
msg += f'{i}.{user_id}: {count}次\n'
|
||||||
return msg
|
return msg
|
||||||
@ -116,7 +116,4 @@ async def get_character_voice(character: str, language: str = '中'):
|
|||||||
|
|
||||||
async def get_voice_list(character: str, language: str = '中'):
|
async def get_voice_list(character: str, language: str = '中'):
|
||||||
voice_list = await GenshinVoice.filter(character=character, language=language).all()
|
voice_list = await GenshinVoice.filter(character=character, language=language).all()
|
||||||
if not voice_list:
|
return await draw_voice_list(voice_list) if voice_list else MessageSegment.text(f'暂无{character}的{language}语音资源,让超级用户[更新原神语音资源]吧!')
|
||||||
return MessageSegment.text(f'暂无{character}的{language}语音资源,让超级用户[更新原神语音资源]吧!')
|
|
||||||
else:
|
|
||||||
return await draw_voice_list(voice_list)
|
|
||||||
|
@ -133,9 +133,3 @@ async def check_note():
|
|||||||
# 等待一会再检查下一个,防止检查过快
|
# 等待一会再检查下一个,防止检查过快
|
||||||
await asyncio.sleep(random.randint(4, 8))
|
await asyncio.sleep(random.randint(4, 8))
|
||||||
logger.info('原神实时便签', f'树脂检查完成,共花费<m>{round((time.time() - t) / 60, 2)}</m>分钟')
|
logger.info('原神实时便签', f'树脂检查完成,共花费<m>{round((time.time() - t) / 60, 2)}</m>分钟')
|
||||||
|
|
||||||
|
|
||||||
@scheduler.scheduled_job('cron', hour=0, minute=0, misfire_grace_time=10)
|
|
||||||
async def _():
|
|
||||||
logger.info('原神实时便签', '清空每日提醒次数限制')
|
|
||||||
await DailyNoteSub.all().update(today_remind_num=0)
|
|
||||||
|
@ -5,10 +5,9 @@ from typing import Optional, List, Union, Tuple
|
|||||||
import pytz
|
import pytz
|
||||||
|
|
||||||
from LittlePaimon.config import JSON_DATA
|
from LittlePaimon.config import JSON_DATA
|
||||||
from LittlePaimon.database.models import PlayerInfo, Character, LastQuery, PrivateCookie, PublicCookie, CookieCache, \
|
from LittlePaimon.database.models import PlayerInfo, Character, LastQuery, PrivateCookie, AbyssInfo
|
||||||
AbyssInfo
|
|
||||||
from LittlePaimon.database.models import Artifact, CharacterProperty, Artifacts, Talents, Talent
|
from LittlePaimon.database.models import Artifact, CharacterProperty, Artifacts, Talents, Talent
|
||||||
from LittlePaimon.utils import logger, scheduler
|
from LittlePaimon.utils import logger
|
||||||
from LittlePaimon.utils.files import load_json
|
from LittlePaimon.utils.files import load_json
|
||||||
from LittlePaimon.utils.api import get_enka_data, get_mihoyo_public_data, get_mihoyo_private_data
|
from LittlePaimon.utils.api import get_enka_data, get_mihoyo_public_data, get_mihoyo_private_data
|
||||||
from LittlePaimon.utils.typing import DataSourceType
|
from LittlePaimon.utils.typing import DataSourceType
|
||||||
@ -394,10 +393,3 @@ class GenshinTools:
|
|||||||
if '防御力' in effective and '防御力' in prop_name:
|
if '防御力' in effective and '防御力' in prop_name:
|
||||||
return True
|
return True
|
||||||
return prop_name in effective
|
return prop_name in effective
|
||||||
|
|
||||||
|
|
||||||
@scheduler.scheduled_job('cron', hour=0, minute=0, misfire_grace_time=10)
|
|
||||||
async def _():
|
|
||||||
logger.info('原神Cookie', '清空每日Cookie缓存和限制')
|
|
||||||
await CookieCache.all().delete()
|
|
||||||
await PublicCookie.filter(status=2).update(status=1)
|
|
||||||
|
@ -8,7 +8,6 @@ from typing import Union, Optional, Tuple, List
|
|||||||
from PIL import Image
|
from PIL import Image
|
||||||
from nonebot import get_bot
|
from nonebot import get_bot
|
||||||
from nonebot.adapters.onebot.v11 import MessageEvent, Message, MessageSegment, GroupMessageEvent
|
from nonebot.adapters.onebot.v11 import MessageEvent, Message, MessageSegment, GroupMessageEvent
|
||||||
from nonebot.internal.params import Arg
|
|
||||||
from nonebot.matcher import Matcher
|
from nonebot.matcher import Matcher
|
||||||
from nonebot.params import CommandArg, Depends
|
from nonebot.params import CommandArg, Depends
|
||||||
from nonebot.typing import T_State
|
from nonebot.typing import T_State
|
||||||
@ -18,7 +17,8 @@ from LittlePaimon.utils import aiorequests, load_image
|
|||||||
from LittlePaimon.utils.alias import get_match_alias
|
from LittlePaimon.utils.alias import get_match_alias
|
||||||
from LittlePaimon.utils.image import PMImage
|
from LittlePaimon.utils.image import PMImage
|
||||||
from LittlePaimon.utils.filter import filter_msg
|
from LittlePaimon.utils.filter import filter_msg
|
||||||
from LittlePaimon.utils.typing import CHARACTERS, MALE_CHARACTERS, FEMALE_CHARACTERS, GIRL_CHARACTERS, BOY_CHARACTERS, LOLI_CHARACTERS
|
from LittlePaimon.utils.typing import CHARACTERS, MALE_CHARACTERS, FEMALE_CHARACTERS, GIRL_CHARACTERS, BOY_CHARACTERS, \
|
||||||
|
LOLI_CHARACTERS
|
||||||
|
|
||||||
|
|
||||||
class MessageBuild:
|
class MessageBuild:
|
||||||
@ -60,48 +60,6 @@ class MessageBuild:
|
|||||||
img.save(bio, format='JPEG' if img.mode == 'RGB' else 'PNG', quality=quality)
|
img.save(bio, format='JPEG' if img.mode == 'RGB' else 'PNG', quality=quality)
|
||||||
return MessageSegment.image(bio)
|
return MessageSegment.image(bio)
|
||||||
|
|
||||||
@classmethod
|
|
||||||
async def StaticImage(cls,
|
|
||||||
url: str,
|
|
||||||
size: Optional[Tuple[int, int]] = None,
|
|
||||||
crop: Optional[Tuple[int, int, int, int]] = None,
|
|
||||||
quality: Optional[int] = 100,
|
|
||||||
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() / 'resources' / url
|
|
||||||
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)
|
|
||||||
img = await aiorequests.get_img(url='https://static.cherishmoon.fun/' + url, save_path=path)
|
|
||||||
if img == 'No Such File':
|
|
||||||
return MessageBuild.Text(tips or '缺少该静态资源')
|
|
||||||
if size:
|
|
||||||
img = img.resize(size)
|
|
||||||
if crop:
|
|
||||||
img = img.crop(crop)
|
|
||||||
if mode:
|
|
||||||
img = img.convert(mode)
|
|
||||||
bio = BytesIO()
|
|
||||||
img.save(bio, format='JPEG' if img.mode == 'RGB' else 'PNG', quality=quality)
|
|
||||||
return MessageSegment.image(bio)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def Text(cls, text: str) -> MessageSegment:
|
def Text(cls, text: str) -> MessageSegment:
|
||||||
"""
|
"""
|
||||||
@ -134,21 +92,6 @@ class MessageBuild:
|
|||||||
def Video(cls, path: str) -> MessageSegment:
|
def Video(cls, path: str) -> MessageSegment:
|
||||||
return MessageSegment.video(path)
|
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=f'https://static.cherishmoon.fun/{url}')
|
|
||||||
content = resp.content
|
|
||||||
path.write_bytes(content)
|
|
||||||
return MessageSegment.video(file=path)
|
|
||||||
|
|
||||||
|
|
||||||
def CommandPlayer(limit: int = 3, only_cn: bool = True) -> List[Player]:
|
def CommandPlayer(limit: int = 3, only_cn: bool = True) -> List[Player]:
|
||||||
"""
|
"""
|
||||||
@ -385,18 +328,6 @@ def replace_all(raw_text: str, text_list: Union[str, list]) -> str:
|
|||||||
return raw_text
|
return raw_text
|
||||||
|
|
||||||
|
|
||||||
# def transform_uid(msg: Union[Message, str]) -> Union[List[str], str, None]:
|
|
||||||
# if isinstance(msg, Message):
|
|
||||||
# msg = msg.extract_plain_text().strip()
|
|
||||||
# check_uid = msg.split(' ')
|
|
||||||
# uid_list = []
|
|
||||||
# for check in check_uid:
|
|
||||||
# uid = re.search(r'(?P<uid>(1|2|5)\d{8})', check)
|
|
||||||
# if uid:
|
|
||||||
# uid_list.append(uid['uid'])
|
|
||||||
# return uid_list if len(uid_list) > 1 else uid_list[0] if uid_list else None
|
|
||||||
|
|
||||||
|
|
||||||
def check_time(time_stamp: float, days: int = 1):
|
def check_time(time_stamp: float, days: int = 1):
|
||||||
"""
|
"""
|
||||||
检查时间戳是否在指定天数内
|
检查时间戳是否在指定天数内
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from typing import Union, Tuple, Set
|
from typing import Union, Tuple, Set
|
||||||
|
|
||||||
from nonebot import on_command, on_regex, on_endswith, on_keyword
|
from nonebot import on_command, on_regex, on_endswith, on_keyword, on_startswith
|
||||||
import nonebot
|
import nonebot
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -24,6 +24,14 @@ def on_endswith_(msg: Union[str, Tuple[str, ...]], state: dict = None, *args, **
|
|||||||
return on_endswith(msg=msg, state=state, _depth=1, *args, **kwargs)
|
return on_endswith(msg=msg, state=state, _depth=1, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def on_startswith_(msg: Union[str, Tuple[str, ...]], state: dict = None, *args, **kwargs):
|
||||||
|
if state is None:
|
||||||
|
state = {}
|
||||||
|
if 'pm_name' not in state:
|
||||||
|
state['pm_name'] = msg if isinstance(msg, str) else msg[0]
|
||||||
|
return on_startswith(msg=msg, state=state, _depth=1, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def on_regex_(pattern: str, state: dict = None, *args, **kwargs):
|
def on_regex_(pattern: str, state: dict = None, *args, **kwargs):
|
||||||
if state is None:
|
if state is None:
|
||||||
state = {}
|
state = {}
|
||||||
@ -40,7 +48,9 @@ def on_keyword_(keywords: Set[str], state: dict = None, *args, **kwargs):
|
|||||||
return on_keyword(keywords=keywords, state=state, _depth=1, *args, **kwargs)
|
return on_keyword(keywords=keywords, state=state, _depth=1, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
nonebot.on_command = on_command_
|
nonebot.on_command = on_command_
|
||||||
nonebot.on_regex = on_regex_
|
nonebot.on_regex = on_regex_
|
||||||
|
nonebot.on_startswith = on_startswith_
|
||||||
nonebot.on_endswith = on_endswith_
|
nonebot.on_endswith = on_endswith_
|
||||||
nonebot.on_keyword = on_keyword_
|
nonebot.on_keyword = on_keyword_
|
||||||
|
Loading…
Reference in New Issue
Block a user