优化群聊学习主动发言,优化更新指令

This commit is contained in:
CMHopeSunshine 2023-01-13 18:07:23 +08:00
parent 95a47d8edb
commit f0dc29ae26
5 changed files with 1073 additions and 904 deletions

View File

@ -76,7 +76,6 @@ class LearningChat:
self.ban_words = set(chat_config.ban_words + self.config.ban_words)
async def _learn(self) -> Result:
# logger.debug('群聊学习', f'收到来自群<m>{self.data.group_id}</m>的消息<m>{self.data.message}</m>')
if self.to_me and any(
w in self.data.message for w in {'学说话', '快学', '开启学习'}):
return Result.SetEnable
@ -374,6 +373,7 @@ class LearningChat:
logger.debug('群聊学习', f'主动发言:群热度排行<m>{">>".join([str(g[0]) for g in popularity])}</m>')
for group_id, messages in popularity:
if len(messages) < 30:
logger.debug('群聊学习', f'主动发言:群<m>{group_id}</m>消息小于30条不发言')
continue
config = config_manager.get_group_config(group_id)
@ -382,26 +382,35 @@ class LearningChat:
'[CQ:share'])
# 是否开启了主动发言
if not config.speak_enable:
if not config.speak_enable or not config.enable:
logger.debug('群聊学习', f'主动发言:群<m>{group_id}</m>未开启,不发言')
continue
# 如果最后一条消息是自己发的,则不主动发言
last_reply = await ChatMessage.filter(group_id=group_id, user_id=self_id).first()
if last_reply and last_reply.time >= messages[0].time:
logger.debug('群聊学习', f'主动发言:群<m>{group_id}</m>最后一条消息是{NICKNAME}发的{last_reply.message},不发言')
continue
if cur_time - last_reply.time < config.speak_min_interval:
logger.debug('群聊学习', f'主动发言:群<m>{group_id}</m>上次主动发言时间小于主动发言最小间隔,不发言')
continue
# 该群每多少秒发一条消息
avg_interval = (messages[0].time - messages[-1].time) / len(messages)
# 如果该群已沉默的时间小于阈值,则不主动发言
if cur_time - messages[0].time < avg_interval * config.speak_threshold + config.speak_min_interval:
silent_time = cur_time - messages[0].time
threshold = avg_interval * config.speak_threshold
if silent_time < threshold:
logger.debug('群聊学习', f'主动发言:群<m>{group_id}</m>已沉默时间({silent_time})小于阈值({int(threshold)}),不发言')
continue
if contexts := await ChatContext.filter(count__gte=config.answer_threshold).all():
speak_list = []
# context = random.choices(contexts, weights=[context.count for context in contexts])[0]
contexts.sort(key=lambda x: x.count)
# contexts.sort(key=lambda x: x.count, reverse=True)
random.shuffle(contexts)
for context in contexts:
if (random.random() < config.speak_continuously_probability or not len(speak_list)) and len(
if (not speak_list or random.random() < config.speak_continuously_probability) and len(
speak_list) < config.speak_continuously_max_len and (
answers := await ChatAnswer.filter(context=context,
group_id=group_id,
@ -417,9 +426,10 @@ class LearningChat:
if any(word in message for word in ban_words):
continue
speak_list.append(message)
follow_answers = answer
while random.random() < config.speak_continuously_probability and len(
speak_list) < config.speak_continuously_max_len:
if (follow_context := await ChatContext.filter(keywords=answer.keywords).first()) and (
if (follow_context := await ChatContext.filter(keywords=follow_answers.keywords).first()) and (
follow_answers := await ChatAnswer.filter(
group_id=group_id,
context=follow_context,
@ -436,17 +446,18 @@ class LearningChat:
speak_list.append(message)
else:
break
else:
elif len(speak_list) >= config.speak_continuously_max_len:
break
if speak_list:
# logger.debug('群聊学习', f'主动发言:将向群<m>{group_id}</m>主动发言<m>{" ".join(speak_list)}</m>')
if random.random() < config.speak_poke_probability:
last_speak_users = {message.user_id for message in messages[:5] if message.user_id != self_id}
select_user = random.choice(list(last_speak_users))
speak_list.append(MessageSegment('poke', {'qq': select_user}))
return group_id, speak_list
else:
return None
else:
logger.debug('群聊学习', f'主动发言:群<m>{group_id}</m>没有找到符合条件的发言,不发言')
logger.debug('群聊学习', '主动发言:没有符合条件的群,不主动发言')
return None
async def _set_answer(self, message: ChatMessage):
if context := await ChatContext.filter(keywords=message.keywords).first():
@ -481,21 +492,16 @@ class LearningChat:
async def _check_allow(self, message: Union[ChatMessage, ChatAnswer]) -> bool:
raw_message = message.message if isinstance(message, ChatMessage) else message.messages[0]
if len(raw_message) < 2:
return False
# if len(raw_message) < 2:
# return False
if any(i in raw_message for i in
{'[CQ:xml', '[CQ:json', '[CQ:at', '[CQ:video', '[CQ:record', '[CQ:share'}):
# logger.debug('群聊学习', f'➤检验<m>{keywords}</m><r>不通过</r>')
return False
if any(i in raw_message for i in self.ban_words):
# logger.debug('群聊学习', f'➤检验<m>{keywords}</m><r>不通过</r>')
return False
if raw_message.startswith('&#91;') and raw_message.endswith('&#93;'):
# logger.debug('群聊学习', f'➤检验<m>{keywords}</m><r>不通过</r>')
return False
if ban_word := await ChatBlackList.filter(keywords=message.keywords).first():
if ban_word.global_ban or message.group_id in ban_word.ban_group_id:
# logger.debug('群聊学习', f'➤检验<m>{keywords}</m><r>不通过</r>')
return False
# logger.debug('群聊学习', f'➤检验<m>{keywords}</m><g>通过</g>')
return True

View File

@ -3,11 +3,12 @@ import re
from pathlib import Path
import git
from git.exc import InvalidGitRepositoryError
from git.exc import InvalidGitRepositoryError, GitCommandError
from nonebot.utils import run_sync
from . import __version__, NICKNAME
from .requests import aiorequests
from .logger import logger
async def check_update():
@ -43,28 +44,44 @@ def update():
repo = git.Repo(Path().absolute())
except InvalidGitRepositoryError:
return '没有发现git仓库无法通过git更新请手动下载最新版本的文件进行替换。'
logger.info('派蒙更新', '开始执行<m>git pull</m>更新操作')
origin = repo.remotes.origin
pyproject_file = Path().parent / 'pyproject.toml'
pyproject_raw_content = pyproject_file.read_text(encoding='utf-8')
if raw_plugins_load := re.search(r'^plugins = \[.+]$', pyproject_raw_content, flags=re.M):
pyproject_new_content = pyproject_raw_content.replace(raw_plugins_load.group(), 'plugins = []')
else:
pyproject_new_content = pyproject_raw_content
pyproject_file.write_text(pyproject_new_content, encoding='utf-8')
try:
origin.pull()
msg = f'更新完成,版本:{__version__}\n最新更新日志为:\n{repo.head.commit.message.replace(":bug:", "🐛").replace(":sparkles:", "").replace(":memo:", "📝")}\n可使用命令[@bot 重启]重启{NICKNAME}'
except Exception as e:
if 'timeout' in e or 'unable to access' in e:
except GitCommandError as e:
emsg = e.stdout + '\n' + e.stderr
if 'timeout' in emsg or 'unable to access' in emsg:
msg = '更新失败连接git仓库超时请重试或修改源为代理源后再重试。'
elif ' Your local changes to the following files would be overwritten by merge' in e:
msg = ('error: Your local changes to the following files would be overwritten by merge\n'
'更新失败本地修改过文件导致冲突可在命令行运行git pull查看冲突的文件是哪些请解决冲突后再更新。')
else:
msg = f'更新失败,错误信息:{e},请尝试手动进行更新'
finally:
if raw_plugins_load:
pyproject_new_content = pyproject_file.read_text(encoding='utf-8')
pyproject_new_content = pyproject_new_content.replace('plugins = []', raw_plugins_load.group())
elif 'Your local changes' in emsg:
pyproject_file = Path().parent / 'pyproject.toml'
pyproject_raw_content = pyproject_file.read_text(encoding='utf-8')
if raw_plugins_load := re.search(r'^plugins = \[.+]$', pyproject_raw_content, flags=re.M):
pyproject_new_content = pyproject_raw_content.replace(raw_plugins_load.group(), 'plugins = []')
logger.info('派蒙更新', f'检测到已安装插件:{raw_plugins_load.group()},暂时重置')
else:
pyproject_new_content = pyproject_raw_content
pyproject_file.write_text(pyproject_new_content, encoding='utf-8')
try:
origin.pull()
msg = f'更新完成,版本:{__version__}\n最新更新日志为:\n{repo.head.commit.message.replace(":bug:", "🐛").replace(":sparkles:", "").replace(":memo:", "📝")}\n可使用命令[@bot 重启]重启{NICKNAME}'
except GitCommandError as e:
emsg = e.stdout + '\n' + e.stderr
if 'timeout' in emsg or 'unable to access' in emsg:
msg = '更新失败连接git仓库超时请重试或修改源为代理源后再重试。'
elif ' Your local changes' in emsg:
msg = f'更新失败,本地修改过文件导致冲突,请解决冲突后再更新。\n{emsg}'
else:
msg = f'更新失败,错误信息:{emsg},请尝试手动进行更新'
finally:
if raw_plugins_load:
pyproject_new_content = pyproject_file.read_text(encoding='utf-8')
pyproject_new_content = re.sub(r'^plugins = \[.*]$', raw_plugins_load.group(),
pyproject_new_content)
pyproject_new_content = pyproject_new_content.replace('plugins = []', raw_plugins_load.group())
pyproject_file.write_text(pyproject_new_content, encoding='utf-8')
logger.info('派蒙更新', f'更新结束,还原插件:{raw_plugins_load.group()}')
return msg
else:
msg = f'更新失败,错误信息:{emsg},请尝试手动进行更新'
return msg

1810
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,18 @@
[tool.poetry]
name = "LittlePaimon"
version = "3.0.0rc7"
version = "3.0.4"
description = "小派蒙原神qq群机器人基于NoneBot2的UID查询、抽卡导出分析、模拟抽卡、实时便签、札记等多功能小助手。"
authors = ["惜月 <277073121@qq.com>"]
license = "AGPL"
[[tool.poetry.source]]
name = "tsinghua"
name = "aliyun"
default = true
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
url = "https://mirrors.aliyun.com/pypi/simple/"
[tool.poetry.dependencies]
python = "^3.8"
nonebot2 = "~2.0.0-beta.5"
nonebot2 = {extras = ["fastapi"], version = "^2.0.0-rc.2"}
nonebot-adapter-onebot = "^2.1"
beautifulsoup4 = "^4.10.0"
httpx = "^0.23.0"
@ -41,7 +41,7 @@ qrcode = "^7.3.1"
nb-cli = "^0.6.7"
[tool.nonebot]
plugins = []
plugins = ['1231', '421412']
plugin_dirs = ["src/plugins"]
[build-system]

View File

@ -1,4 +1,4 @@
--index-url https://pypi.tuna.tsinghua.edu.cn/simple
--index-url https://mirrors.aliyun.com/pypi/simple
aiosqlite==0.17.0; python_version >= "3.7" and python_version < "4.0"
amis-python==1.0.6; python_version >= "3.7" and python_version < "4.0"
@ -6,22 +6,22 @@ anyio==3.6.2; python_full_version >= "3.6.2" and python_version >= "3.8" and pyt
apscheduler==3.9.1.post1; python_version >= "3.8" and python_version < "4.0" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4" and python_version >= "3.8"
backports.zoneinfo==0.2.1; python_version >= "3.8" and python_version < "3.9" and python_full_version < "3.0.0" and (python_version >= "3.8" and python_full_version < "3.0.0" and python_version < "4.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.8") or python_full_version >= "3.5.0" and python_version < "3.9" and python_version >= "3.8" and (python_version >= "3.8" and python_full_version < "3.0.0" and python_version < "4.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.8")
beautifulsoup4==4.11.1; python_full_version >= "3.6.0"
certifi==2022.9.24; python_version >= "3.7"
certifi==2022.12.7; python_version >= "3.7"
click==8.1.3; python_version >= "3.8" and python_version < "4.0"
colorama==0.4.6; python_version >= "3.8" and python_full_version < "3.0.0" and platform_system == "Windows" and python_version < "4.0" and sys_platform == "win32" or python_full_version >= "3.7.0" and platform_system == "Windows" and python_version >= "3.8" and python_version < "4.0" and sys_platform == "win32"
contourpy==1.0.6; python_version >= "3.8"
cycler==0.11.0; python_version >= "3.8"
ecdsa==0.18.0; python_version >= "2.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0"
expandvars==0.9.0; python_version >= "3.4"
fastapi==0.79.1; python_version >= "3.8" and python_version < "4.0" and python_full_version >= "3.6.1"
fastapi==0.89.1; python_version >= "3.8" and python_version < "4.0"
fonttools==4.38.0; python_version >= "3.8"
gitdb==4.0.9; python_version >= "3.7"
gitpython==3.1.29; python_version >= "3.7"
greenlet==1.1.3; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7"
h11==0.12.0; python_version >= "3.8" and python_version < "4.0"
httpcore==0.15.0; python_version >= "3.7"
gitdb==4.0.10; python_version >= "3.7"
gitpython==3.1.30; python_version >= "3.7"
greenlet==2.0.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7"
h11==0.14.0; python_version >= "3.8" and python_version < "4.0"
httpcore==0.16.3; python_version >= "3.7"
httptools==0.5.0; python_version >= "3.8" and python_version < "4.0" and python_full_version >= "3.5.0"
httpx==0.23.0; python_version >= "3.7"
httpx==0.23.3; python_version >= "3.7"
idna==3.4
iso8601==1.1.0; python_full_version >= "3.6.2" and python_version < "4.0" and python_version >= "3.7"
jieba==0.42.1
@ -29,22 +29,22 @@ jinja2==3.1.2; python_version >= "3.7" and python_version < "4.0"
joblib==1.2.0; python_version >= "3.8"
kiwisolver==1.4.4; python_version >= "3.8"
loguru==0.6.0; python_version >= "3.8" and python_version < "4.0"
lxml==4.9.1; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0")
lxml==4.9.2; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0")
markupsafe==2.1.1; python_version >= "3.7" and python_version < "4.0"
matplotlib==3.6.2; python_version >= "3.8"
matplotlib==3.6.3; python_version >= "3.8"
msgpack==1.0.4; python_version >= "3.8" and python_version < "4.0"
multidict==6.0.2; python_version >= "3.8" and python_version < "4.0"
nonebot-adapter-onebot==2.1.5; python_version >= "3.8" and python_version < "4.0"
multidict==6.0.4; python_version >= "3.8" and python_version < "4.0"
nonebot-adapter-onebot==2.2.0; python_version >= "3.8" and python_version < "4.0"
nonebot-plugin-apscheduler==0.2.0; python_version >= "3.8" and python_version < "4.0"
nonebot2==2.0.0rc1; python_version >= "3.8" and python_version < "4.0"
numpy==1.23.4; python_version >= "3.8"
packaging==21.3; python_version >= "3.8"
pillow==9.3.0; python_version >= "3.7"
playwright==1.27.1; python_version >= "3.7"
nonebot2==2.0.0rc2; python_version >= "3.8" and python_version < "4.0"
numpy==1.24.1; python_version >= "3.8"
packaging==23.0; python_version >= "3.8"
pillow==9.4.0; python_version >= "3.7"
playwright==1.29.1; python_version >= "3.7"
psutil==5.9.4; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0")
pyasn1==0.4.8; python_version >= "3.6" and python_version < "4"
pydantic==1.9.2; python_version >= "3.8" and python_version < "4.0" and python_full_version >= "3.6.1"
pyee==8.1.0; python_version >= "3.7"
pydantic==1.10.4; python_version >= "3.8" and python_version < "4.0"
pyee==9.0.4; python_version >= "3.7"
pygtrie==2.5.0; python_version >= "3.8" and python_version < "4.0"
pyparsing==3.0.9; python_full_version >= "3.6.8" and python_version >= "3.8"
pypika-tortoise==0.1.6; python_version >= "3.7" and python_version < "4.0"
@ -53,34 +53,34 @@ python-dateutil==2.8.2; python_version >= "3.8" and python_full_version < "3.0.0
python-dotenv==0.21.0
python-jose==3.3.0
pytz-deprecation-shim==0.1.0.post0; python_version >= "3.8" and python_full_version < "3.0.0" and python_version < "4.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.8"
pytz==2022.6; python_version >= "3.7" and python_version < "4.0" and (python_version >= "3.8" and python_version < "4.0" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4" and python_version >= "3.8")
pytz==2022.7; python_version >= "3.7" and python_version < "4.0" and (python_version >= "3.8" and python_version < "4.0" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4" and python_version >= "3.8")
pyyaml==6.0; python_version >= "3.8" and python_version < "4.0"
qrcode==7.3.1; python_version >= "3.6"
rfc3986==1.5.0; python_version >= "3.7"
rsa==4.9; python_version >= "3.6" and python_version < "4"
ruamel.yaml.clib==0.2.7; platform_python_implementation == "CPython" and python_version < "3.11" and python_version >= "3.5"
ruamel.yaml==0.17.21; python_version >= "3"
scikit-learn==1.1.3; python_version >= "3.8"
scikit-learn==1.2.0; python_version >= "3.8"
scipy==1.9.3; python_version >= "3.8"
setuptools-scm==7.0.5; python_version >= "3.8"
setuptools-scm==7.1.0; python_version >= "3.8"
shapely==1.8.5.post1; python_version >= "3.6"
six==1.16.0; python_version >= "3.8" and python_full_version < "3.0.0" and python_version < "4.0" or python_full_version >= "3.5.0" and python_version >= "3.8" and python_version < "4"
smmap==5.0.0; python_version >= "3.7"
sniffio==1.3.0; python_full_version >= "3.6.2" and python_version >= "3.8" and python_version < "4.0"
soupsieve==2.3.2.post1; python_version >= "3.6" and python_full_version >= "3.6.0"
starlette==0.19.1; python_version >= "3.8" and python_version < "4.0" and python_full_version >= "3.6.1"
starlette==0.22.0; python_version >= "3.8" and python_version < "4.0"
threadpoolctl==3.1.0; python_version >= "3.8"
tomli==2.0.1; python_version >= "3.8"
tomlkit==0.10.2; python_version >= "3.8" and python_version < "4.0"
tomli==2.0.1; python_version < "3.11" and python_version >= "3.8"
tomlkit==0.11.6; python_version >= "3.8" and python_version < "4.0"
tortoise-orm==0.19.2; python_version >= "3.7" and python_version < "4.0"
tqdm==4.64.1; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0")
typing-extensions==4.4.0; python_version >= "3.8" and python_version <= "3.8" and python_full_version >= "3.6.1"
tzdata==2022.6; python_version >= "3.8" and python_version < "4.0" and python_full_version < "3.0.0" and platform_system == "Windows" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.8" and platform_system == "Windows"
typing-extensions==4.4.0; python_version >= "3.8" and python_version <= "3.8"
tzdata==2022.7; python_version >= "3.8" and python_version < "4.0" and python_full_version < "3.0.0" and platform_system == "Windows" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.8" and platform_system == "Windows"
tzlocal==4.2; python_version >= "3.8" and python_version < "4.0" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4" and python_version >= "3.8"
ujson==5.5.0; python_version >= "3.7"
uvicorn==0.18.3; python_version >= "3.8" and python_version < "4.0"
ujson==5.7.0; python_version >= "3.7"
uvicorn==0.20.0; python_version >= "3.8" and python_version < "4.0"
uvloop==0.17.0; sys_platform != "win32" and sys_platform != "cygwin" and platform_python_implementation != "PyPy" and python_version >= "3.8" and python_version < "4.0"
watchfiles==0.18.1; python_version >= "3.8" and python_version < "4.0"
websockets==10.4; python_version >= "3.8" and python_version < "4.0"
win32-setctime==1.1.0; python_version >= "3.8" and python_version < "4.0" and sys_platform == "win32"
yarl==1.8.1; python_version >= "3.8" and python_version < "4.0"
yarl==1.8.2; python_version >= "3.8" and python_version < "4.0"