1
0
forked from bot/app

新增on_keywords

This commit is contained in:
远野千束 2024-08-22 09:35:02 +08:00
parent a3a31a2c94
commit 4bf8512a7d
12 changed files with 137 additions and 22 deletions

View File

@ -33,7 +33,9 @@ __all__ = [
"logger", "logger",
] ]
__version__ = "6.3.8" # 测试版本号 __version__ = "6.3.9" # 测试版本号
# 6.3.9
# 更改了on语法
# 6.3.8 # 6.3.8
# 1. 初步添加对聊天的支持 # 1. 初步添加对聊天的支持

View File

@ -38,7 +38,7 @@ class Channel(Generic[T]):
有两种接收工作方式但是只能选择一种主动接收和被动接收主动接收使用 `receive` 方法被动接收使用 `on_receive` 装饰器 有两种接收工作方式但是只能选择一种主动接收和被动接收主动接收使用 `receive` 方法被动接收使用 `on_receive` 装饰器
""" """
def __init__(self, _id: str, type_check: Optional[bool] = None): def __init__(self, _id: str = "", type_check: Optional[bool] = None):
""" """
初始化通道 初始化通道
Args: Args:

View File

@ -8,7 +8,7 @@ from typing import Any, Coroutine, Optional, TypeAlias, Callable
from liteyuki.comm import channel from liteyuki.comm import channel
from liteyuki.comm.channel import Channel, ON_RECEIVE_FUNC, ASYNC_ON_RECEIVE_FUNC from liteyuki.comm.channel import Channel, ON_RECEIVE_FUNC, ASYNC_ON_RECEIVE_FUNC
from liteyuki.utils import IS_MAIN_PROCESS, is_coroutine_callable, run_coroutine from liteyuki.utils import IS_MAIN_PROCESS, is_coroutine_callable, run_coroutine, run_coroutine_in_thread
if IS_MAIN_PROCESS: if IS_MAIN_PROCESS:
_locks = {} _locks = {}
@ -220,10 +220,10 @@ class KeyValueStore:
""" """
if IS_MAIN_PROCESS: if IS_MAIN_PROCESS:
if channel_ in _on_main_subscriber_receive_funcs and _on_main_subscriber_receive_funcs[channel_]: if channel_ in _on_main_subscriber_receive_funcs and _on_main_subscriber_receive_funcs[channel_]:
run_coroutine(*[func(data) for func in _on_main_subscriber_receive_funcs[channel_]]) run_coroutine_in_thread(*[func(data) for func in _on_main_subscriber_receive_funcs[channel_]])
else: else:
if channel_ in _on_sub_subscriber_receive_funcs and _on_sub_subscriber_receive_funcs[channel_]: if channel_ in _on_sub_subscriber_receive_funcs and _on_sub_subscriber_receive_funcs[channel_]:
run_coroutine(*[func(data) for func in _on_sub_subscriber_receive_funcs[channel_]]) run_coroutine_in_thread(*[func(data) for func in _on_sub_subscriber_receive_funcs[channel_]])
def _start_receive_loop(self): def _start_receive_loop(self):
""" """

View File

@ -34,16 +34,17 @@ class Matcher:
def __str__(self): def __str__(self):
return f"Matcher(rule={self.rule}, priority={self.priority}, block={self.block})" return f"Matcher(rule={self.rule}, priority={self.priority}, block={self.block})"
def handle(self, handler: EventHandler) -> EventHandler: def handle(self) -> Callable[[EventHandler], EventHandler]:
""" """
添加处理函数装饰器 添加处理函数装饰器
Args:
handler:
Returns: Returns:
EventHandler 装饰器 handler
""" """
self.handlers.append(handler) def decorator(handler: EventHandler) -> EventHandler:
return handler self.handlers.append(handler)
return handler
return decorator
async def run(self, event: MessageEvent) -> None: async def run(self, event: MessageEvent) -> None:
""" """

View File

@ -15,7 +15,7 @@ from liteyuki.comm.storage import shared_memory
from liteyuki.log import logger from liteyuki.log import logger
from liteyuki.message.event import MessageEvent from liteyuki.message.event import MessageEvent
from liteyuki.message.matcher import Matcher from liteyuki.message.matcher import Matcher
from liteyuki.message.rule import Rule from liteyuki.message.rule import Rule, empty_rule
_matcher_list: list[Matcher] = [] _matcher_list: list[Matcher] = []
_queue: Queue = Queue() _queue: Queue = Queue()
@ -34,7 +34,7 @@ async def _(event: MessageEvent):
break break
def on_message(rule: Rule = Rule(), priority: int = 0, block: bool = True) -> Matcher: def on_message(rule: Rule = empty_rule, priority: int = 0, block: bool = False) -> Matcher:
matcher = Matcher(rule, priority, block) matcher = Matcher(rule, priority, block)
# 按照优先级插入 # 按照优先级插入
for i, m in enumerate(_matcher_list): for i, m in enumerate(_matcher_list):
@ -44,3 +44,10 @@ def on_message(rule: Rule = Rule(), priority: int = 0, block: bool = True) -> Ma
else: else:
_matcher_list.append(matcher) _matcher_list.append(matcher)
return matcher return matcher
def on_keywords(keywords: list[str], rule=empty_rule, priority: int = 0, block: bool = False) -> Matcher:
@Rule
async def on_keywords_rule(event: MessageEvent):
return any(keyword in event.raw_message for keyword in keywords)
return on_message(on_keywords_rule & rule, priority, block)

View File

@ -8,26 +8,37 @@ Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
@File : rule.py @File : rule.py
@Software: PyCharm @Software: PyCharm
""" """
import inspect
from typing import Optional, TypeAlias, Callable, Coroutine from typing import Optional, TypeAlias, Callable, Coroutine
from liteyuki.message.event import MessageEvent from liteyuki.message.event import MessageEvent
RuleHandler: TypeAlias = Callable[[MessageEvent], Coroutine[None, None, bool]] RuleHandlerFunc: TypeAlias = Callable[[MessageEvent], Coroutine[None, None, bool]]
"""规则函数签名""" """规则函数签名"""
class Rule: class Rule:
def __init__(self, handler: Optional[RuleHandler] = None): def __init__(self, handler: RuleHandlerFunc):
self.handler = handler self.handler = handler
def __or__(self, other: "Rule") -> "Rule": def __or__(self, other: "Rule") -> "Rule":
return Rule(lambda event: self.handler(event) or other.handler(event)) async def combined_handler(event: MessageEvent) -> bool:
return await self.handler(event) or await other.handler(event)
return Rule(combined_handler)
def __and__(self, other: "Rule") -> "Rule": def __and__(self, other: "Rule") -> "Rule":
return Rule(lambda event: self.handler(event) and other.handler(event)) async def combined_handler(event: MessageEvent) -> bool:
return await self.handler(event) and await other.handler(event)
return Rule(combined_handler)
async def __call__(self, event: MessageEvent) -> bool: async def __call__(self, event: MessageEvent) -> bool:
if self.handler is None: if self.handler is None:
return True return True
return await self.handler(event) return await self.handler(event)
@Rule
async def empty_rule(event: MessageEvent) -> bool:
return True

View File

@ -5,6 +5,7 @@
import asyncio import asyncio
import inspect import inspect
import multiprocessing import multiprocessing
import threading
from pathlib import Path from pathlib import Path
from typing import Any, Callable, Coroutine from typing import Any, Callable, Coroutine
@ -61,6 +62,16 @@ def run_coroutine(*coro: Coroutine):
# 捕获其他异常,防止协程被重复等待 # 捕获其他异常,防止协程被重复等待
logger.error(f"Exception occurred: {e}") logger.error(f"Exception occurred: {e}")
def run_coroutine_in_thread(*coro: Coroutine):
"""
在新线程中运行协程
Args:
coro:
Returns:
"""
threading.Thread(target=run_coroutine, args=coro, daemon=True).start()
def path_to_module_name(path: Path) -> str: def path_to_module_name(path: Path) -> str:
""" """

View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
@Time : 2024/8/22 上午9:06
@Author : snowykami
@Email : snowykami@outlook.com
@File : anti_dislink.py
@Software: PyCharm
"""
import random
from liteyuki.plugin import PluginMetadata, PluginType
from liteyuki.message.on import on_keywords
__plugin_meta__ = PluginMetadata(
name="严禁断联化",
type=PluginType.APPLICATION
)
@on_keywords(["看看你的", "看看j", "给我看看"]).handle()
async def _(event):
event.reply(random.choice(["No dislink", "严禁断联化"]))

View File

@ -14,11 +14,11 @@ from liteyuki.message.event import MessageEvent
__plugin_meta__ = PluginMetadata( __plugin_meta__ = PluginMetadata(
name="你好轻雪", name="你好轻雪",
type=PluginType.TEST type=PluginType.APPLICATION
) )
@on_message().handle @on_message().handle()
async def _(event: MessageEvent): async def _(event: MessageEvent):
if str(event.raw_message) == "你好轻雪": if str(event.raw_message) == "你好轻雪":
event.reply("你好呀") event.reply("你好呀")

View File

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
@Time : 2024/8/22 上午8:37
@Author : snowykami
@Email : snowykami@outlook.com
@File : ts_chan_main.py
@Software: PyCharm
"""
import asyncio
from liteyuki.comm import Channel, set_channel, get_channel
from liteyuki import get_bot
set_channel("chan-main", Channel("chan-main"))
set_channel("chan-sub", Channel("chan-sub"))
chan_main = get_channel("chan-main")
# @get_bot().on_after_start
# async def _():
# while True:
# chan_main.send("Hello, World!")
# await asyncio.sleep(5)

View File

@ -41,6 +41,4 @@ async def _(bot: Bot, event: MessageEvent):
@shared_memory.on_subscriber_receive("event_to_nonebot") @shared_memory.on_subscriber_receive("event_to_nonebot")
async def _(event: LiteyukiMessageEvent): async def _(event: LiteyukiMessageEvent):
bot: Bot = get_bot(event.bot_id) bot: Bot = get_bot(event.bot_id)
print("A")
await bot.send_msg(message_type=event.message_type, user_id=int(event.session_id), group_id=int(event.session_id), message=event.data["message"]) await bot.send_msg(message_type=event.message_type, user_id=int(event.session_id), group_id=int(event.session_id), message=event.data["message"])
print("B")

View File

@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
@Time : 2024/8/22 上午8:39
@Author : snowykami
@Email : snowykami@outlook.com
@File : ts_chan_sub.py
@Software: PyCharm
"""
import asyncio
from liteyuki.comm import Channel, get_channel
from nonebot import get_bot
from nonebot.adapters.onebot.v11 import Bot
chan_main = get_channel("chan-main")
# @chan_main.on_receive()
# async def _(data: str):
# print("Received data from chan-main:", data)
# try:
# bot: Bot = get_bot("2443429204") # type: ignore
#
# def send_msg():
#
# bot.send_msg(message_type="private", user_id=2443429204, message=data)
#
# print("tsA")
# print("tsA1")
# await asyncio.ensure_future(c)
# print("tsB")
# except Exception as e:
# print(e)
# pass