This commit is contained in:
2025-12-31 17:47:39 +08:00
38 changed files with 4435 additions and 1343 deletions

View File

@@ -1,5 +1,12 @@
"""
消息处理装饰器模块
提供插件消息处理和定时任务的装饰器
使用工厂模式消除重复代码
"""
from functools import wraps
from typing import Callable, Union
from typing import Callable, Dict, Union
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from apscheduler.triggers.cron import CronTrigger
@@ -8,15 +15,16 @@ from apscheduler.triggers.interval import IntervalTrigger
scheduler = AsyncIOScheduler()
# ==================== 定时任务装饰器 ====================
def schedule(
trigger: Union[str, CronTrigger, IntervalTrigger],
**trigger_args
) -> Callable:
"""
定时任务装饰器
例子:
例子:
- @schedule('interval', seconds=30)
- @schedule('cron', hour=8, minute=30, second=30)
- @schedule('date', run_date='2024-01-01 00:00:00')
@@ -44,23 +52,16 @@ def add_job_safe(scheduler: AsyncIOScheduler, job_id: str, func: Callable, bot,
"""添加函数到定时任务中,如果存在则先删除现有的任务"""
try:
scheduler.remove_job(job_id)
except:
except Exception:
pass
# 读取调度器配置
# 使用统一配置管理器读取调度器配置
try:
import tomllib
from pathlib import Path
config_path = Path("main_config.toml")
if config_path.exists():
with open(config_path, "rb") as f:
config = tomllib.load(f)
scheduler_config = config.get("Scheduler", {})
else:
scheduler_config = {}
except:
from utils.config_manager import get_scheduler_config
scheduler_config = get_scheduler_config()
except Exception:
scheduler_config = {}
# 应用调度器配置
job_kwargs = {
"coalesce": scheduler_config.get("coalesce", True),
@@ -68,7 +69,7 @@ def add_job_safe(scheduler: AsyncIOScheduler, job_id: str, func: Callable, bot,
"misfire_grace_time": scheduler_config.get("misfire_grace_time", 30)
}
job_kwargs.update(trigger_args)
scheduler.add_job(func, trigger, args=[bot], id=job_id, **job_kwargs)
@@ -76,182 +77,106 @@ def remove_job_safe(scheduler: AsyncIOScheduler, job_id: str):
"""从定时任务中移除任务"""
try:
scheduler.remove_job(job_id)
except:
except Exception:
pass
def on_text_message(priority=50):
"""文本消息装饰器"""
# ==================== 消息装饰器工厂 ====================
def decorator(func):
if callable(priority): # 无参数调用时
f = priority
setattr(f, '_event_type', 'text_message')
setattr(f, '_priority', 50)
return f
# 有参数调用时
setattr(func, '_event_type', 'text_message')
setattr(func, '_priority', min(max(priority, 0), 99))
return func
def _create_message_decorator(event_type: str, description: str):
"""
消息装饰器工厂函数
return decorator if not callable(priority) else decorator(priority)
生成支持两种调用方式的装饰器:
- @on_xxx_message (无参数使用默认优先级50)
- @on_xxx_message(priority=80) (有参数,自定义优先级)
Args:
event_type: 事件类型字符串,如 'text_message'
description: 装饰器描述,用于生成文档字符串
def on_image_message(priority=50):
"""图片消息装饰器"""
Returns:
装饰器函数
"""
def decorator_factory(priority=50):
def decorator(func):
# 处理无参数调用: @on_xxx_message 时 priority 实际是被装饰的函数
if callable(priority):
target_func = priority
actual_priority = 50
else:
target_func = func
actual_priority = min(max(priority, 0), 99)
def decorator(func):
setattr(target_func, '_event_type', event_type)
setattr(target_func, '_priority', actual_priority)
return target_func
# 判断调用方式
if callable(priority):
f = priority
setattr(f, '_event_type', 'image_message')
setattr(f, '_priority', 50)
return f
setattr(func, '_event_type', 'image_message')
setattr(func, '_priority', min(max(priority, 0), 99))
return func
return decorator(priority)
return decorator
return decorator if not callable(priority) else decorator(priority)
decorator_factory.__doc__ = f"{description}装饰器"
decorator_factory.__name__ = f"on_{event_type}"
return decorator_factory
def on_voice_message(priority=50):
"""语音消息装饰器"""
# ==================== 消息类型定义 ====================
def decorator(func):
if callable(priority):
f = priority
setattr(f, '_event_type', 'voice_message')
setattr(f, '_priority', 50)
return f
setattr(func, '_event_type', 'voice_message')
setattr(func, '_priority', min(max(priority, 0), 99))
return func
return decorator if not callable(priority) else decorator(priority)
# 事件类型 -> 中文描述 映射表
MESSAGE_DECORATOR_TYPES: Dict[str, str] = {
'text_message': '文本消息',
'image_message': '图片消息',
'voice_message': '语音消息',
'video_message': '视频消息',
'emoji_message': '表情消息',
'file_message': '文件消息',
'quote_message': '引用消息',
'pat_message': '拍一拍',
'at_message': '@消息',
'system_message': '系统消息',
'other_message': '其他消息',
}
def on_emoji_message(priority=50):
"""表情消息装饰器"""
# ==================== 生成所有消息装饰器 ====================
def decorator(func):
if callable(priority):
f = priority
setattr(f, '_event_type', 'emoji_message')
setattr(f, '_priority', 50)
return f
setattr(func, '_event_type', 'emoji_message')
setattr(func, '_priority', min(max(priority, 0), 99))
return func
return decorator if not callable(priority) else decorator(priority)
# 使用工厂函数生成装饰器
on_text_message = _create_message_decorator('text_message', '文本消息')
on_image_message = _create_message_decorator('image_message', '图片消息')
on_voice_message = _create_message_decorator('voice_message', '语音消息')
on_video_message = _create_message_decorator('video_message', '视频消息')
on_emoji_message = _create_message_decorator('emoji_message', '表情消息')
on_file_message = _create_message_decorator('file_message', '文件消息')
on_quote_message = _create_message_decorator('quote_message', '引用消息')
on_pat_message = _create_message_decorator('pat_message', '拍一拍')
on_at_message = _create_message_decorator('at_message', '@消息')
on_system_message = _create_message_decorator('system_message', '系统消息')
on_other_message = _create_message_decorator('other_message', '其他消息')
def on_file_message(priority=50):
"""文件消息装饰器"""
# ==================== 导出列表 ====================
def decorator(func):
if callable(priority):
f = priority
setattr(f, '_event_type', 'file_message')
setattr(f, '_priority', 50)
return f
setattr(func, '_event_type', 'file_message')
setattr(func, '_priority', min(max(priority, 0), 99))
return func
return decorator if not callable(priority) else decorator(priority)
def on_quote_message(priority=50):
"""引用消息装饰器"""
def decorator(func):
if callable(priority):
f = priority
setattr(f, '_event_type', 'quote_message')
setattr(f, '_priority', 50)
return f
setattr(func, '_event_type', 'quote_message')
setattr(func, '_priority', min(max(priority, 0), 99))
return func
return decorator if not callable(priority) else decorator(priority)
def on_video_message(priority=50):
"""视频消息装饰器"""
def decorator(func):
if callable(priority):
f = priority
setattr(f, '_event_type', 'video_message')
setattr(f, '_priority', 50)
return f
setattr(func, '_event_type', 'video_message')
setattr(func, '_priority', min(max(priority, 0), 99))
return func
return decorator if not callable(priority) else decorator(priority)
def on_pat_message(priority=50):
"""拍一拍消息装饰器"""
def decorator(func):
if callable(priority):
f = priority
setattr(f, '_event_type', 'pat_message')
setattr(f, '_priority', 50)
return f
setattr(func, '_event_type', 'pat_message')
setattr(func, '_priority', min(max(priority, 0), 99))
return func
return decorator if not callable(priority) else decorator(priority)
def on_at_message(priority=50):
"""被@消息装饰器"""
def decorator(func):
if callable(priority):
f = priority
setattr(f, '_event_type', 'at_message')
setattr(f, '_priority', 50)
return f
setattr(func, '_event_type', 'at_message')
setattr(func, '_priority', min(max(priority, 0), 99))
return func
return decorator if not callable(priority) else decorator(priority)
def on_system_message(priority=50):
"""其他消息装饰器"""
def decorator(func):
if callable(priority):
f = priority
setattr(f, '_event_type', 'system_message')
setattr(f, '_priority', 50)
return f
setattr(func, '_event_type', 'other_message')
setattr(func, '_priority', min(max(priority, 0), 99))
return func
return decorator if not callable(priority) else decorator(priority)
def on_other_message(priority=50):
"""其他消息装饰器"""
def decorator(func):
if callable(priority):
f = priority
setattr(f, '_event_type', 'other_message')
setattr(f, '_priority', 50)
return f
setattr(func, '_event_type', 'other_message')
setattr(func, '_priority', min(max(priority, 0), 99))
return func
return decorator if not callable(priority) else decorator(priority)
__all__ = [
# 定时任务
'scheduler',
'schedule',
'add_job_safe',
'remove_job_safe',
# 消息装饰器
'on_text_message',
'on_image_message',
'on_voice_message',
'on_video_message',
'on_emoji_message',
'on_file_message',
'on_quote_message',
'on_pat_message',
'on_at_message',
'on_system_message',
'on_other_message',
# 工具
'MESSAGE_DECORATOR_TYPES',
'_create_message_decorator',
]