Draft pyauto

This commit is contained in:
Changhua
2023-10-07 15:29:50 +08:00
parent 0df5d27e5a
commit df9557cce8
19 changed files with 66 additions and 1077 deletions
+5
View File
@@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
from wcfauto.auto_res import Register
__version__ = "39.0.3.0"
@@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
from wcfauto.auto_res.bot import Register
from wcfauto.auto_res.core import load_function
Register = load_function(Register)
+113
View File
@@ -0,0 +1,113 @@
# -*- coding: utf-8 -*-
import logging
from abc import abstractmethod
from typing import Any, Callable
from wcfauto.event import Event
from wcferry.client import Wcf
class Register(Event):
def __init__(self, debug=True, **kwargs):
super(Register, self).__init__()
logging.basicConfig(level='DEBUG', format="%(asctime)s %(message)s")
self._LOG = logging.getLogger("Demo")
self._LOG.info("开始初始化...")
# 默认连接本地服务
self._wcf = Wcf(debug=debug, **kwargs)
@abstractmethod
def _process_msg(self, wcf: Wcf):
"""
有消息的时候,通知分发器分发消息
:param wcf: Wcf
:return: None
"""
raise NotImplementedError
@abstractmethod
def _register(self,
func: Callable[[Any], Any]):
"""
消息处理工厂, 所有消息处理函数都会汇总在这里提交给事件分发器
:param func: 被装饰的待处理消息函数
:return: func
"""
raise NotImplementedError
@abstractmethod
def _processing_async_func(self,
isGroup: bool,
isDivision: bool,
isPyq: bool):
"""
异步函数消息处理函数, 用来接受非协程函数
参数:
:param isGroup 对消息进行限制, 当为True时, 只接受群消息, 当为False时, 只接受私聊消息,
注意! 仅当isDivision为 True时, isGroup参数生效
:param isPyq 是否接受朋友圈消息
:param isDivision 是否对消息分组
"""
raise NotImplementedError
@abstractmethod
def _processing_universal_func(self,
isGroup: bool,
isDivision: bool,
isPyq: bool):
"""
同步函数消息处理函数, 用来接受非协程函数
参数:
:param isGroup 对消息进行限制, 当为True时, 只接受群消息, 当为False时, 只接受私聊消息,
注意! 仅当isDivision为 True时, isGroup参数生效
:param isPyq 是否接受朋友圈消息
:param isDivision 是否对消息分组
"""
raise NotImplementedError
@abstractmethod
def message_register(self,
isGroup: bool = False,
isDivision: bool = False,
isPyq: bool = False):
"""
外部可访问接口
消息处理函数注册器, 用来接受同步函数
参数:
:param isGroup 对消息进行限制, 当为True时, 只接受群消息, 当为False时, 只接受私聊消息,
注意! 仅当isDivision为 True时, isGroup参数生效
:param isPyq 是否接受朋友圈消息
:param isDivision 是否对消息分组
"""
raise NotImplementedError
@abstractmethod
def async_message_register(self,
isGroup: bool = False,
isDivision: bool = False,
isPyq: bool = False):
"""
外部可访问接口
消息处理函数注册器, 用来接受异步函数
参数:
:param isGroup 对消息进行限制, 当为True时, 只接受群消息, 当为False时, 只接受私聊消息,
注意! 仅当isDivision为 True时, isGroup参数生效
:param isPyq 是否接受朋友圈消息
:param isDivision 是否对消息分组
"""
raise NotImplementedError
@abstractmethod
def run(self, *args, **kwargs):
"""
启动程序, 开始接受消息
"""
raise NotImplementedError
@abstractmethod
def stop_receiving(self):
"""
停止接受消息
"""
raise NotImplementedError
+120
View File
@@ -0,0 +1,120 @@
# -*- coding: utf-8 -*-
import asyncio
import functools
import queue
import traceback
from threading import Thread
from typing import Any, Callable
from wcferry.client import Wcf
from wcferry.wxmsg import WxMsg
def load_function(cls):
cls._process_msg = _process_msg
cls._register = _register
cls._processing_async_func = _processing_async_func
cls._processing_universal_func = _processing_universal_func
cls.message_register = message_register
cls.async_message_register = async_message_register
cls.run = run
cls.stop_receiving = stop_receiving
return cls
def _process_msg(self, wcf: Wcf):
"""有消息的时候,通知分发器分发消息"""
while wcf.is_receiving_msg():
try:
msg = wcf.get_msg()
self._message = msg
self._run_func()
except queue.Empty:
pass
def _register(self,
func: Callable[[Any], Any]):
self._add_callback(func, self._wcf)
# 此处必须返回被装饰函数原函数, 否则丢失被装饰函数信息
return func
def _processing_async_func(self,
isGroup: bool,
isDivision: bool,
isPyq: bool,):
def _async_func(func):
@functools.wraps(func)
@self._register
async def __async_func(bot: Wcf, message: WxMsg):
try:
# 判断被装饰函数是否为协程函数, 本函数要求是协程函数
if not asyncio.iscoroutinefunction(func): raise ValueError(
f'这里应使用协程函数, 而被装饰函数-> ({func.__name__}) <-是非协程函数')
if message.is_pyq() and isPyq:
return await func(bot, message)
if not isDivision:
return await func(bot, message)
if message.from_group() and isGroup:
return await func(bot, message)
if not message.from_group() and not isGroup:
return await func(bot, message)
except:
traceback.print_exc()
return __async_func
return _async_func
def _processing_universal_func(self,
isGroup: bool,
isDivision: bool,
isPyq: bool, ):
def _universal_func(func):
@functools.wraps(func)
@self._register
def universal_func(bot: Wcf, message: WxMsg):
try:
# 判断被装饰函数是否为协程函数, 本函数要求是协程函数
if asyncio.iscoroutinefunction(func): raise ValueError(
f'这里应使用非协程函数, 而被装饰函数-> ({func.__name__}) <-协程函数')
if message.is_pyq() and isPyq:
return func(bot, message)
if not isDivision:
return func(bot, message)
if message.from_group() and isGroup:
return func(bot, message)
if not message.from_group() and not isGroup:
return func(bot, message)
except:
traceback.print_exc()
return None
return universal_func
return _universal_func
def message_register(self,
isGroup: bool = False,
isDivision: bool = False,
isPyq: bool = False):
return self._processing_universal_func(isGroup, isDivision, isPyq)
def async_message_register(self,
isGroup: bool = False,
isDivision: bool = False,
isPyq: bool = False):
return self._processing_async_func(isGroup, isDivision, isPyq)
def run(self, *args, **kwargs):
self._wcf.enable_receiving_msg(*args, pyq=True, **kwargs)
Thread(target=self._process_msg, name="GetMessage", args=(self._wcf,), daemon=True).start()
self._LOG.debug("开始接受消息")
self._wcf.keep_running()
def stop_receiving(self):
return self._wcf.disable_recv_msg()
+6
View File
@@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
from wcfauto.event.event import Event
from wcfauto.event.core import load_function
Event = load_function(Event)
+59
View File
@@ -0,0 +1,59 @@
# -*- coding: utf-8 -*-
import asyncio
import traceback
from threading import Thread
def load_function(cls):
cls._add_callback = _add_callback
cls._run_func = _run_func
return cls
def _add_callback(self, func, bot):
"""
消息处理函数加载器
:param func: 消息处理函数
:param args: 消息处理函数参数
:param kwargs: 消息处理函数参数
"""
if func in self._message_callback_func_list: return
self._message_callback_func_list.append(func)
self._message_callback_func[func] = bot
def _run_func(self):
"""
消息分发器, 将消息发送给所有消息处理函数
"""
try:
async_func = []
universal_func = []
for ele in self._message_callback_func:
if asyncio.iscoroutinefunction(ele):
async_func.append(ele)
else:
universal_func.append(ele)
# 同步函数运行器
def run_universal_func():
for fn in universal_func:
fn(self._message_callback_func[fn], self._message)
if len(universal_func) != 0: Thread(target=run_universal_func).start()
if len(async_func) == 0: return
# 异步函数运行器
async def _run_callback():
tasks = [asyncio.create_task(func(self._message_callback_func[func], self._message))
for func in async_func]
await asyncio.wait(tasks)
self._loop.run_until_complete(_run_callback())
except:
traceback.print_exc()
+33
View File
@@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
import asyncio
import logging
from abc import abstractmethod
class Event(object):
_message_callback_func = {}
_message_callback_func_list = []
_loop = asyncio.get_event_loop()
def __init__(self):
super(Event, self).__init__()
self._message = None
self._logger: logging = logging.getLogger()
@abstractmethod
def _add_callback(self, func, *args, **kwargs):
"""
消息处理函数加载器
:param func: 消息处理函数
:param args: 消息处理函数参数
:param kwargs: 消息处理函数参数
"""
raise NotImplementedError
@abstractmethod
def _run_func(self):
"""
消息分发器, 将消息发送给所有消息处理函数
"""
raise NotImplementedError