临时调整权限模块,备份
This commit is contained in:
118
base/auth/permission.py
Normal file
118
base/auth/permission.py
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
from typing import Dict, List, Optional
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from enum import Enum
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
from utils.logger import logger
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Permission:
|
||||||
|
"""权限类"""
|
||||||
|
key: str
|
||||||
|
name: str
|
||||||
|
description: str
|
||||||
|
value: int
|
||||||
|
plugin_id: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
|
class PermissionStatus(Enum):
|
||||||
|
"""权限状态枚举"""
|
||||||
|
ENABLED = 1
|
||||||
|
DISABLED = 0
|
||||||
|
|
||||||
|
|
||||||
|
class PermissionManager:
|
||||||
|
"""权限管理器(单例模式)"""
|
||||||
|
_instance = None
|
||||||
|
_initialized = False
|
||||||
|
|
||||||
|
def __new__(cls):
|
||||||
|
if cls._instance is None:
|
||||||
|
cls._instance = super().__new__(cls)
|
||||||
|
return cls._instance
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
if not self._initialized:
|
||||||
|
self._permissions: Dict[str, Permission] = {}
|
||||||
|
self._config_file = "config/permissions.json"
|
||||||
|
self._load_permissions()
|
||||||
|
self._initialized = True
|
||||||
|
|
||||||
|
def _load_permissions(self):
|
||||||
|
"""从配置文件加载权限"""
|
||||||
|
try:
|
||||||
|
if os.path.exists(self._config_file):
|
||||||
|
with open(self._config_file, 'r', encoding='utf-8') as f:
|
||||||
|
data = json.load(f)
|
||||||
|
for key, perm_data in data.items():
|
||||||
|
self._permissions[key] = Permission(**perm_data)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"加载权限配置失败: {e}")
|
||||||
|
|
||||||
|
def _save_permissions(self):
|
||||||
|
"""保存权限到配置文件"""
|
||||||
|
try:
|
||||||
|
os.makedirs(os.path.dirname(self._config_file), exist_ok=True)
|
||||||
|
with open(self._config_file, 'w', encoding='utf-8') as f:
|
||||||
|
json.dump(
|
||||||
|
{k: v.__dict__ for k, v in self._permissions.items()},
|
||||||
|
f,
|
||||||
|
ensure_ascii=False,
|
||||||
|
indent=2
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"保存权限配置失败: {e}")
|
||||||
|
|
||||||
|
def register_permission(
|
||||||
|
self,
|
||||||
|
key: str,
|
||||||
|
name: str,
|
||||||
|
description: str,
|
||||||
|
plugin_id: Optional[str] = None
|
||||||
|
) -> Permission:
|
||||||
|
"""注册新权限"""
|
||||||
|
if key in self._permissions:
|
||||||
|
return self._permissions[key]
|
||||||
|
|
||||||
|
value = len(self._permissions) + 1
|
||||||
|
permission = Permission(
|
||||||
|
key=key,
|
||||||
|
name=name,
|
||||||
|
description=description,
|
||||||
|
value=value,
|
||||||
|
plugin_id=plugin_id
|
||||||
|
)
|
||||||
|
self._permissions[key] = permission
|
||||||
|
self._save_permissions()
|
||||||
|
return permission
|
||||||
|
|
||||||
|
def get_permission(self, key: str) -> Optional[Permission]:
|
||||||
|
"""获取权限"""
|
||||||
|
return self._permissions.get(key)
|
||||||
|
|
||||||
|
def get_permission_by_value(self, value: int) -> Optional[Permission]:
|
||||||
|
"""通过值获取权限"""
|
||||||
|
for perm in self._permissions.values():
|
||||||
|
if perm.value == value:
|
||||||
|
return perm
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_all_permissions(self) -> List[Permission]:
|
||||||
|
"""获取所有权限"""
|
||||||
|
return list(self._permissions.values())
|
||||||
|
|
||||||
|
def get_plugin_permissions(self, plugin_id: str) -> List[Permission]:
|
||||||
|
"""获取插件的所有权限"""
|
||||||
|
return [
|
||||||
|
perm for perm in self._permissions.values()
|
||||||
|
if perm.plugin_id == plugin_id
|
||||||
|
]
|
||||||
|
|
||||||
|
def remove_permission(self, key: str) -> bool:
|
||||||
|
"""移除权限"""
|
||||||
|
if key in self._permissions:
|
||||||
|
del self._permissions[key]
|
||||||
|
self._save_permissions()
|
||||||
|
return True
|
||||||
|
return False
|
||||||
98
base/auth/test_permission.py
Normal file
98
base/auth/test_permission.py
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
from .permission import PermissionManager, PermissionStatus
|
||||||
|
from .group_permission import GroupPermissionManager
|
||||||
|
|
||||||
|
|
||||||
|
def test_permission_system():
|
||||||
|
# 获取权限管理器实例
|
||||||
|
perm_manager = PermissionManager()
|
||||||
|
group_manager = GroupPermissionManager()
|
||||||
|
|
||||||
|
# 测试注册权限
|
||||||
|
print("测试注册权限...")
|
||||||
|
robot_perm = perm_manager.register_permission(
|
||||||
|
"ROBOT",
|
||||||
|
"群机器人",
|
||||||
|
"🔧 群机器人 [总开关]"
|
||||||
|
)
|
||||||
|
print(f"注册权限: {robot_perm.key} = {robot_perm.value} - {robot_perm.description}")
|
||||||
|
|
||||||
|
# 测试重复注册
|
||||||
|
print("\n测试重复注册...")
|
||||||
|
same_perm = perm_manager.register_permission(
|
||||||
|
"ROBOT",
|
||||||
|
"群机器人",
|
||||||
|
"🔧 群机器人 [总开关]"
|
||||||
|
)
|
||||||
|
print(f"重复注册结果: {same_perm.key} = {same_perm.value} - {same_perm.description}")
|
||||||
|
|
||||||
|
# 测试注册新权限
|
||||||
|
print("\n测试注册新权限...")
|
||||||
|
news_perm = perm_manager.register_permission(
|
||||||
|
"NEWS",
|
||||||
|
"新闻播报",
|
||||||
|
"📰 每日新闻播报",
|
||||||
|
plugin_id="news_plugin"
|
||||||
|
)
|
||||||
|
print(f"新权限: {news_perm.key} = {news_perm.value} - {news_perm.description}")
|
||||||
|
|
||||||
|
# 测试获取权限
|
||||||
|
print("\n测试获取权限...")
|
||||||
|
retrieved_perm = perm_manager.get_permission("ROBOT")
|
||||||
|
print(f"获取权限: {retrieved_perm.key} = {retrieved_perm.value} - {retrieved_perm.description}")
|
||||||
|
|
||||||
|
# 测试通过值获取权限
|
||||||
|
print("\n测试通过值获取权限...")
|
||||||
|
perm_by_value = perm_manager.get_permission_by_value(1)
|
||||||
|
print(f"通过值获取: {perm_by_value.key} = {perm_by_value.value} - {perm_by_value.description}")
|
||||||
|
|
||||||
|
# 测试获取所有权限
|
||||||
|
print("\n测试获取所有权限...")
|
||||||
|
all_perms = perm_manager.get_all_permissions()
|
||||||
|
print("所有权限:")
|
||||||
|
for perm in all_perms:
|
||||||
|
print(f" {perm.key} = {perm.value} - {perm.description}")
|
||||||
|
|
||||||
|
# 测试获取插件权限
|
||||||
|
print("\n测试获取插件权限...")
|
||||||
|
plugin_perms = perm_manager.get_plugin_permissions("news_plugin")
|
||||||
|
print("插件权限:")
|
||||||
|
for perm in plugin_perms:
|
||||||
|
print(f" {perm.key} = {perm.value} - {perm.description}")
|
||||||
|
|
||||||
|
# 测试群组权限
|
||||||
|
print("\n测试群组权限...")
|
||||||
|
group_id = "test_group"
|
||||||
|
|
||||||
|
# 添加群组
|
||||||
|
group_manager.add_group(group_id)
|
||||||
|
print(f"添加群组: {group_id}")
|
||||||
|
|
||||||
|
# 设置群组权限
|
||||||
|
group_manager.set_group_permission(group_id, robot_perm, PermissionStatus.ENABLED)
|
||||||
|
print(f"设置权限: {group_id} - {robot_perm.key} = {PermissionStatus.ENABLED.value}")
|
||||||
|
|
||||||
|
# 获取群组权限
|
||||||
|
status = group_manager.get_group_permission(group_id, robot_perm)
|
||||||
|
print(f"获取权限状态: {group_id} - {robot_perm.key} = {status.value}")
|
||||||
|
|
||||||
|
# 检查权限
|
||||||
|
result = group_manager.check_permission(group_id, robot_perm)
|
||||||
|
print(f"检查权限: {group_id} - {robot_perm.key} = {result}")
|
||||||
|
|
||||||
|
# 列出群组权限
|
||||||
|
print("\n列出群组权限...")
|
||||||
|
perms = group_manager.list_group_permissions(group_id)
|
||||||
|
print(f"群组 {group_id} 的权限:")
|
||||||
|
for perm, status in perms.items():
|
||||||
|
print(f" {perm.key} = {status.value}")
|
||||||
|
|
||||||
|
# 移除群组
|
||||||
|
print("\n测试移除群组...")
|
||||||
|
if group_manager.remove_group(group_id):
|
||||||
|
print(f"成功移除群组: {group_id}")
|
||||||
|
else:
|
||||||
|
print(f"移除群组失败: {group_id}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test_permission_system()
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
from typing import Dict, Any, Tuple, Optional, List
|
from typing import Dict, Any, Tuple, Optional, List
|
||||||
from base.plugin_common.plugin_interface import PluginInterface
|
from base.plugin_common.plugin_interface import PluginInterface
|
||||||
from wechat_ipad import WechatAPIClient
|
from wechat_ipad import WechatAPIClient
|
||||||
|
from utils.robot_cmd.robot_command import Feature
|
||||||
|
|
||||||
|
|
||||||
class MessagePluginInterface(PluginInterface):
|
class MessagePluginInterface(PluginInterface):
|
||||||
@@ -16,6 +17,26 @@ class MessagePluginInterface(PluginInterface):
|
|||||||
"""支持的命令列表"""
|
"""支持的命令列表"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_key(self) -> Optional[str]:
|
||||||
|
"""插件对应的功能权限键名"""
|
||||||
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_description(self) -> Optional[str]:
|
||||||
|
"""插件对应的功能权限描述"""
|
||||||
|
return None
|
||||||
|
|
||||||
|
def register_feature(self) -> Optional[Feature]:
|
||||||
|
"""注册插件功能权限
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Feature: 注册的功能权限枚举,如果不需要权限则返回None
|
||||||
|
"""
|
||||||
|
if self.feature_key and self.feature_description:
|
||||||
|
return Feature.register_feature(self.feature_key, self.feature_description)
|
||||||
|
return None
|
||||||
|
|
||||||
# 需要完成jobs 的业务,所以完成bot注入
|
# 需要完成jobs 的业务,所以完成bot注入
|
||||||
def set_bot(self, bot: WechatAPIClient) -> None:
|
def set_bot(self, bot: WechatAPIClient) -> None:
|
||||||
self.bot: WechatAPIClient = bot
|
self.bot: WechatAPIClient = bot
|
||||||
|
|||||||
@@ -331,7 +331,7 @@ class PluginManager:
|
|||||||
return plugin
|
return plugin
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.LOG.error(f"PluginManager:加载插件模块 {module_name} 失败: {e}", exc_info=True)
|
self.LOG.exception(f"PluginManager:加载插件模块 {module_name} 失败: {e}", exc_info=True)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def unload_plugin(self, name: str) -> bool:
|
def unload_plugin(self, name: str) -> bool:
|
||||||
|
|||||||
@@ -14,6 +14,10 @@ from .bot_ai import InterventionBot
|
|||||||
class AIAutoResponsePlugin(MessagePluginInterface):
|
class AIAutoResponsePlugin(MessagePluginInterface):
|
||||||
"""AI自动对话插件"""
|
"""AI自动对话插件"""
|
||||||
|
|
||||||
|
# 功能权限常量
|
||||||
|
FEATURE_KEY = "AI_AUTO_RESPONSE"
|
||||||
|
FEATURE_DESCRIPTION = "🤖 AI自动对话功能 [自动对话]"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return "AI自动对话"
|
return "AI自动对话"
|
||||||
@@ -38,11 +42,21 @@ class AIAutoResponsePlugin(MessagePluginInterface):
|
|||||||
def commands(self) -> List[str]:
|
def commands(self) -> List[str]:
|
||||||
return self._commands
|
return self._commands
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_key(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_KEY
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_description(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_DESCRIPTION
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.intervention_bot = None
|
self.intervention_bot = None
|
||||||
self.group_messages = {} # 存储每个群的最近消息
|
self.group_messages = {} # 存储每个群的最近消息
|
||||||
self.max_messages = 20 # 每个群最多存储的消息数量
|
self.max_messages = 20 # 每个群最多存储的消息数量
|
||||||
|
# 注册功能权限
|
||||||
|
self.feature = self.register_feature()
|
||||||
|
|
||||||
# DIFY API配置
|
# DIFY API配置
|
||||||
self.dify_api_url = ""
|
self.dify_api_url = ""
|
||||||
@@ -89,7 +103,7 @@ class AIAutoResponsePlugin(MessagePluginInterface):
|
|||||||
content = str(message.get("content", "")).strip()
|
content = str(message.get("content", "")).strip()
|
||||||
roomid = message.get("roomid", "")
|
roomid = message.get("roomid", "")
|
||||||
|
|
||||||
if GroupBotManager.get_group_permission(roomid, Feature.AI_AUTO) == PermissionStatus.DISABLED:
|
if GroupBotManager.get_group_permission(roomid, self.feature) == PermissionStatus.DISABLED:
|
||||||
return False
|
return False
|
||||||
# 如果是群消息,且该群启用了自动回复,则处理
|
# 如果是群消息,且该群启用了自动回复,则处理
|
||||||
if roomid:
|
if roomid:
|
||||||
@@ -133,7 +147,7 @@ class AIAutoResponsePlugin(MessagePluginInterface):
|
|||||||
roomid = message.get("roomid", "")
|
roomid = message.get("roomid", "")
|
||||||
bot: WechatAPIClient = message.get("bot")
|
bot: WechatAPIClient = message.get("bot")
|
||||||
# 检查权限
|
# 检查权限
|
||||||
if roomid and GroupBotManager.get_group_permission(roomid, Feature.AI_AUTO) == PermissionStatus.DISABLED:
|
if roomid and GroupBotManager.get_group_permission(roomid, self.feature) == PermissionStatus.DISABLED:
|
||||||
return False, "没有权限"
|
return False, "没有权限"
|
||||||
# 处理自动回复
|
# 处理自动回复
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ from wechat_ipad import WechatAPIClient
|
|||||||
class BeautyLegPlugin(MessagePluginInterface):
|
class BeautyLegPlugin(MessagePluginInterface):
|
||||||
"""美腿图片插件"""
|
"""美腿图片插件"""
|
||||||
|
|
||||||
|
# 功能权限常量
|
||||||
|
FEATURE_KEY = "BEAUTY_LEG"
|
||||||
|
FEATURE_DESCRIPTION = "👠 美腿图片功能 [美腿, 腿来]"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return "美腿图片"
|
return "美腿图片"
|
||||||
@@ -39,8 +43,18 @@ class BeautyLegPlugin(MessagePluginInterface):
|
|||||||
def commands(self) -> List[str]:
|
def commands(self) -> List[str]:
|
||||||
return self._commands
|
return self._commands
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_key(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_KEY
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_description(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_DESCRIPTION
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
# 注册功能权限
|
||||||
|
self.feature = self.register_feature()
|
||||||
# 修改图片目录路径指向 resource/beauty_leg
|
# 修改图片目录路径指向 resource/beauty_leg
|
||||||
self.image_folder = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))),
|
self.image_folder = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))),
|
||||||
"resource", "beauty_leg")
|
"resource", "beauty_leg")
|
||||||
@@ -90,7 +104,7 @@ class BeautyLegPlugin(MessagePluginInterface):
|
|||||||
return command in self._commands
|
return command in self._commands
|
||||||
|
|
||||||
@plugin_stats_decorator(plugin_name="美腿图片")
|
@plugin_stats_decorator(plugin_name="美腿图片")
|
||||||
@plugin_points_cost(2, "美腿图片消耗积分", Feature.BEAUTY_LEG)
|
@plugin_points_cost(2, "美腿图片消耗积分", FEATURE_KEY)
|
||||||
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
||||||
"""处理消息"""
|
"""处理消息"""
|
||||||
content = str(message.get("content", "")).strip()
|
content = str(message.get("content", "")).strip()
|
||||||
@@ -101,7 +115,7 @@ class BeautyLegPlugin(MessagePluginInterface):
|
|||||||
bot: WechatAPIClient = message.get("bot")
|
bot: WechatAPIClient = message.get("bot")
|
||||||
|
|
||||||
# 检查权限
|
# 检查权限
|
||||||
if roomid and gbm.get_group_permission(roomid, Feature.BEAUTY_LEG) == PermissionStatus.DISABLED:
|
if roomid and gbm.get_group_permission(roomid, self.feature) == PermissionStatus.DISABLED:
|
||||||
return False, "没有权限"
|
return False, "没有权限"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -29,6 +29,10 @@ VIDEO_EXTENSIONS = {'.mp4', '.avi', '.mov', '.wmv', '.flv', '.mkv', '.webm'}
|
|||||||
class DifyPlugin(MessagePluginInterface):
|
class DifyPlugin(MessagePluginInterface):
|
||||||
"""Dify AI聊天插件"""
|
"""Dify AI聊天插件"""
|
||||||
|
|
||||||
|
# 功能权限常量
|
||||||
|
FEATURE_KEY = "AI_CAPABILITY"
|
||||||
|
FEATURE_DESCRIPTION = "🤖 AI聊天功能 [ai, dify, 聊天, AI]"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return "Dify聊天"
|
return "Dify聊天"
|
||||||
@@ -53,6 +57,14 @@ class DifyPlugin(MessagePluginInterface):
|
|||||||
def commands(self) -> List[str]:
|
def commands(self) -> List[str]:
|
||||||
return self._commands
|
return self._commands
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_key(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_KEY
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_description(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_DESCRIPTION
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
# 会话上下文管理,格式: {group_id/wxid: [conversation_history]}
|
# 会话上下文管理,格式: {group_id/wxid: [conversation_history]}
|
||||||
@@ -64,6 +76,8 @@ class DifyPlugin(MessagePluginInterface):
|
|||||||
# 会话过期时间(秒)
|
# 会话过期时间(秒)
|
||||||
self.conversation_timeout = 3600 # 1小时
|
self.conversation_timeout = 3600 # 1小时
|
||||||
self.last_activity: Dict[str, float] = {}
|
self.last_activity: Dict[str, float] = {}
|
||||||
|
# 注册功能权限
|
||||||
|
self.feature = self.register_feature()
|
||||||
|
|
||||||
def initialize(self, context: Dict[str, Any]) -> bool:
|
def initialize(self, context: Dict[str, Any]) -> bool:
|
||||||
"""初始化插件"""
|
"""初始化插件"""
|
||||||
@@ -120,7 +134,7 @@ class DifyPlugin(MessagePluginInterface):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
@plugin_stats_decorator(plugin_name="Dify聊天")
|
@plugin_stats_decorator(plugin_name="Dify聊天")
|
||||||
@plugin_points_cost(2, "AI聊天消耗积分", Feature.AI_CAPABILITY)
|
@plugin_points_cost(2, "AI聊天消耗积分", FEATURE_KEY)
|
||||||
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
||||||
"""处理消息"""
|
"""处理消息"""
|
||||||
content = str(message.get("content", "")).strip()
|
content = str(message.get("content", "")).strip()
|
||||||
@@ -135,7 +149,7 @@ class DifyPlugin(MessagePluginInterface):
|
|||||||
target = roomid if roomid else sender
|
target = roomid if roomid else sender
|
||||||
|
|
||||||
# 检查权限
|
# 检查权限
|
||||||
if roomid and gbm.get_group_permission(target, Feature.AI_CAPABILITY) == PermissionStatus.DISABLED:
|
if roomid and gbm.get_group_permission(target, self.feature) == PermissionStatus.DISABLED:
|
||||||
return False, "没有权限"
|
return False, "没有权限"
|
||||||
|
|
||||||
# 处理被@的消息
|
# 处理被@的消息
|
||||||
@@ -184,8 +198,8 @@ class DifyPlugin(MessagePluginInterface):
|
|||||||
revoke.add_message_to_revoke(target, client_msg_id, create_time, new_msg_id, 5)
|
revoke.add_message_to_revoke(target, client_msg_id, create_time, new_msg_id, 5)
|
||||||
return False, f"处理出错: {e}"
|
return False, f"处理出错: {e}"
|
||||||
|
|
||||||
async def _send_response(self, bot: WechatAPIClient, target: str, sender: str,
|
async def _send_response(self, bot: WechatAPIClient, target: str, sender: str,
|
||||||
response: str, roomid: str) -> Tuple[bool, str]:
|
response: str, roomid: str) -> Tuple[bool, str]:
|
||||||
"""发送响应消息的辅助方法"""
|
"""发送响应消息的辅助方法"""
|
||||||
try:
|
try:
|
||||||
# 判断是否为本地文件路径
|
# 判断是否为本地文件路径
|
||||||
|
|||||||
@@ -22,6 +22,10 @@ class DouyinParserError(Exception):
|
|||||||
class DouyinParserPlugin(MessagePluginInterface):
|
class DouyinParserPlugin(MessagePluginInterface):
|
||||||
"""抖音无水印解析插件"""
|
"""抖音无水印解析插件"""
|
||||||
|
|
||||||
|
# 功能权限常量
|
||||||
|
FEATURE_KEY = "DOUYIN_PARSER"
|
||||||
|
FEATURE_DESCRIPTION = "🎵 抖音解析功能 [自动解析抖音链接]"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return "抖音解析"
|
return "抖音解析"
|
||||||
@@ -46,10 +50,20 @@ class DouyinParserPlugin(MessagePluginInterface):
|
|||||||
def commands(self) -> List[str]:
|
def commands(self) -> List[str]:
|
||||||
return [] # 不使用命令触发,而是通过消息内容匹配
|
return [] # 不使用命令触发,而是通过消息内容匹配
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_key(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_KEY
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_description(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_DESCRIPTION
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.LOG = logger
|
self.LOG = logger
|
||||||
self.url_pattern = re.compile(r'https?://v\.douyin\.com/\w+/?')
|
self.url_pattern = re.compile(r'https?://v\.douyin\.com/\w+/?')
|
||||||
|
# 注册功能权限
|
||||||
|
self.feature = self.register_feature()
|
||||||
# 修改为使用插件目录下的down_load_dir文件夹
|
# 修改为使用插件目录下的down_load_dir文件夹
|
||||||
self.download_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "down_load_dir")
|
self.download_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "down_load_dir")
|
||||||
# 确保下载目录存在
|
# 确保下载目录存在
|
||||||
@@ -105,7 +119,7 @@ class DouyinParserPlugin(MessagePluginInterface):
|
|||||||
|
|
||||||
bot: WechatAPIClient = message.get("bot")
|
bot: WechatAPIClient = message.get("bot")
|
||||||
# 检查权限
|
# 检查权限
|
||||||
if roomid and gbm.get_group_permission(roomid, Feature.DOUYIN_PARSER) == PermissionStatus.DISABLED:
|
if roomid and gbm.get_group_permission(roomid, self.feature) == PermissionStatus.DISABLED:
|
||||||
return False, "没有权限"
|
return False, "没有权限"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -19,6 +19,18 @@ import json
|
|||||||
class GameTaskPlugin(MessagePluginInterface):
|
class GameTaskPlugin(MessagePluginInterface):
|
||||||
"""游戏任务插件"""
|
"""游戏任务插件"""
|
||||||
|
|
||||||
|
# 功能权限常量
|
||||||
|
FEATURE_KEY = "TASK_GAME"
|
||||||
|
FEATURE_DESCRIPTION = "🎮 百科问答功能 [/t, /a, /s, /r, /l, /h]"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_key(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_KEY
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_description(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_DESCRIPTION
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return "百科问答"
|
return "百科问答"
|
||||||
@@ -46,6 +58,8 @@ class GameTaskPlugin(MessagePluginInterface):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.LOG = logger
|
self.LOG = logger
|
||||||
|
# 注册功能权限
|
||||||
|
self.feature = self.register_feature()
|
||||||
async_job.at_times(["17:58"])(self.run_random_task_assignment)
|
async_job.at_times(["17:58"])(self.run_random_task_assignment)
|
||||||
|
|
||||||
def initialize(self, context: Dict[str, Any]) -> bool:
|
def initialize(self, context: Dict[str, Any]) -> bool:
|
||||||
@@ -123,7 +137,7 @@ class GameTaskPlugin(MessagePluginInterface):
|
|||||||
self.LOG.debug(f"插件执行: {self.name}:{content}")
|
self.LOG.debug(f"插件执行: {self.name}:{content}")
|
||||||
|
|
||||||
# 检查权限
|
# 检查权限
|
||||||
if roomid and gbm.get_group_permission(roomid, Feature.TASK_GAME) == PermissionStatus.DISABLED:
|
if roomid and gbm.get_group_permission(roomid, self.feature) == PermissionStatus.DISABLED:
|
||||||
return False, "没有权限"
|
return False, "没有权限"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -18,11 +18,15 @@ from .news_crawler import nbc, cnn, abc, fox, bbc
|
|||||||
|
|
||||||
|
|
||||||
class GlobalNewsPlugin(MessagePluginInterface):
|
class GlobalNewsPlugin(MessagePluginInterface):
|
||||||
"""全球政治经济新闻插件"""
|
"""全球新闻插件"""
|
||||||
|
|
||||||
|
# 功能权限常量
|
||||||
|
FEATURE_KEY = "GLOBAL_NEWS"
|
||||||
|
FEATURE_DESCRIPTION = "🌍 全球新闻功能 [全球新闻, 国际新闻, 环球新闻, 政经新闻]"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return "全球政治经济新闻"
|
return "全球新闻"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def version(self) -> str:
|
def version(self) -> str:
|
||||||
@@ -30,7 +34,7 @@ class GlobalNewsPlugin(MessagePluginInterface):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def description(self) -> str:
|
def description(self) -> str:
|
||||||
return "提供全球政治经济新闻,支持多个国际新闻源"
|
return "提供全球政治经济新闻查询功能"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def author(self) -> str:
|
def author(self) -> str:
|
||||||
@@ -44,11 +48,21 @@ class GlobalNewsPlugin(MessagePluginInterface):
|
|||||||
def commands(self) -> List[str]:
|
def commands(self) -> List[str]:
|
||||||
return self._commands
|
return self._commands
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_key(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_KEY
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_description(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_DESCRIPTION
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.bot: WechatAPIClient = None
|
self.bot: WechatAPIClient = None
|
||||||
self._news_tasks = {} # 存储正在进行的新闻抓取任务
|
self._news_tasks = {} # 存储正在进行的新闻抓取任务
|
||||||
|
# 注册功能权限
|
||||||
|
self.feature = self.register_feature()
|
||||||
|
|
||||||
def initialize(self, context: Dict[str, Any]) -> bool:
|
def initialize(self, context: Dict[str, Any]) -> bool:
|
||||||
"""初始化插件"""
|
"""初始化插件"""
|
||||||
@@ -89,8 +103,8 @@ class GlobalNewsPlugin(MessagePluginInterface):
|
|||||||
|
|
||||||
return command in self._commands
|
return command in self._commands
|
||||||
|
|
||||||
@plugin_stats_decorator(plugin_name="全球政治经济新闻")
|
@plugin_stats_decorator(plugin_name="全球新闻")
|
||||||
@plugin_points_cost(5, "全球新闻消耗积分", Feature.NEWS)
|
@plugin_points_cost(1, "全球新闻消耗积分", FEATURE_KEY)
|
||||||
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
||||||
"""处理消息"""
|
"""处理消息"""
|
||||||
content = str(message.get("content", "")).strip()
|
content = str(message.get("content", "")).strip()
|
||||||
@@ -98,10 +112,10 @@ class GlobalNewsPlugin(MessagePluginInterface):
|
|||||||
sender = message.get("sender")
|
sender = message.get("sender")
|
||||||
roomid = message.get("roomid", "")
|
roomid = message.get("roomid", "")
|
||||||
gbm: GroupBotManager = message.get("gbm")
|
gbm: GroupBotManager = message.get("gbm")
|
||||||
self.bot: WechatAPIClient = message.get("bot")
|
bot: WechatAPIClient = message.get("bot")
|
||||||
|
|
||||||
# 检查权限
|
# 检查权限
|
||||||
if roomid and gbm.get_group_permission(roomid, Feature.NEWS) == PermissionStatus.DISABLED:
|
if roomid and gbm.get_group_permission(roomid, self.feature) == PermissionStatus.DISABLED:
|
||||||
return False, "没有权限"
|
return False, "没有权限"
|
||||||
|
|
||||||
# 生成唯一任务ID
|
# 生成唯一任务ID
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from typing import Dict, Any, List, Optional, Tuple
|
|||||||
from base.plugin_common.message_plugin_interface import MessagePluginInterface
|
from base.plugin_common.message_plugin_interface import MessagePluginInterface
|
||||||
from base.plugin_common.plugin_interface import PluginStatus
|
from base.plugin_common.plugin_interface import PluginStatus
|
||||||
from utils.decorator.plugin_decorators import plugin_stats_decorator
|
from utils.decorator.plugin_decorators import plugin_stats_decorator
|
||||||
from utils.robot_cmd.robot_command import GroupBotManager
|
from utils.robot_cmd.robot_command import GroupBotManager, PermissionStatus
|
||||||
from utils.wechat.contact_manager import ContactManager
|
from utils.wechat.contact_manager import ContactManager
|
||||||
from wechat_ipad import WechatAPIClient
|
from wechat_ipad import WechatAPIClient
|
||||||
|
|
||||||
@@ -13,6 +13,10 @@ from wechat_ipad import WechatAPIClient
|
|||||||
class GroupAutoInvitePlugin(MessagePluginInterface):
|
class GroupAutoInvitePlugin(MessagePluginInterface):
|
||||||
"""自动加群功能插件"""
|
"""自动加群功能插件"""
|
||||||
|
|
||||||
|
# 功能权限常量
|
||||||
|
FEATURE_KEY = "GROUP_AUTO_INVITE"
|
||||||
|
FEATURE_DESCRIPTION = "🤝 自动加群功能 [#加群配置, #加群]"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return "自动加群功能"
|
return "自动加群功能"
|
||||||
@@ -37,12 +41,22 @@ class GroupAutoInvitePlugin(MessagePluginInterface):
|
|||||||
def commands(self) -> List[str]:
|
def commands(self) -> List[str]:
|
||||||
return self._commands
|
return self._commands
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_key(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_KEY
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_description(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_DESCRIPTION
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
# Redis 中存储群组映射的前缀
|
# Redis 中存储群组映射的前缀
|
||||||
self.mapping_prefix = "group:group_mapping:"
|
self.mapping_prefix = "group:group_mapping:"
|
||||||
self._commands = []
|
self._commands = []
|
||||||
self.bot: WechatAPIClient = None
|
self.bot: WechatAPIClient = None
|
||||||
|
# 注册功能权限
|
||||||
|
self.feature = self.register_feature()
|
||||||
|
|
||||||
def initialize(self, context: Dict[str, Any]) -> bool:
|
def initialize(self, context: Dict[str, Any]) -> bool:
|
||||||
"""初始化插件"""
|
"""初始化插件"""
|
||||||
@@ -86,6 +100,9 @@ class GroupAutoInvitePlugin(MessagePluginInterface):
|
|||||||
content = str(message.get("content", "")).strip()
|
content = str(message.get("content", "")).strip()
|
||||||
roomid = message.get("roomid", "")
|
roomid = message.get("roomid", "")
|
||||||
|
|
||||||
|
if GroupBotManager.get_group_permission(roomid, self.feature) == PermissionStatus.DISABLED:
|
||||||
|
return False
|
||||||
|
|
||||||
# 处理加群配置命令
|
# 处理加群配置命令
|
||||||
if content.startswith("#加群配置|"):
|
if content.startswith("#加群配置|"):
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -16,6 +16,10 @@ from wechat_ipad.models.appmsg_xml import LINK_XML
|
|||||||
class GroupMemberChangePlugin(MessagePluginInterface):
|
class GroupMemberChangePlugin(MessagePluginInterface):
|
||||||
"""群成员变更监控插件"""
|
"""群成员变更监控插件"""
|
||||||
|
|
||||||
|
# 功能权限常量
|
||||||
|
FEATURE_KEY = "GROUP_MEMBER_CHANGE"
|
||||||
|
FEATURE_DESCRIPTION = "👥 群成员变更监控 [自动监控群成员变动并发送通知]"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return "群成员变更监控"
|
return "群成员变更监控"
|
||||||
@@ -46,6 +50,8 @@ class GroupMemberChangePlugin(MessagePluginInterface):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
# 注册功能权限
|
||||||
|
self.feature = self.register_feature()
|
||||||
|
|
||||||
def initialize(self, context: Dict[str, Any]) -> bool:
|
def initialize(self, context: Dict[str, Any]) -> bool:
|
||||||
"""初始化插件"""
|
"""初始化插件"""
|
||||||
@@ -56,9 +62,15 @@ class GroupMemberChangePlugin(MessagePluginInterface):
|
|||||||
|
|
||||||
def can_process(self, message: Dict[str, Any]) -> bool:
|
def can_process(self, message: Dict[str, Any]) -> bool:
|
||||||
"""检查是否可以处理该消息"""
|
"""检查是否可以处理该消息"""
|
||||||
content = message.get("content")
|
if not self.enable:
|
||||||
if not content or "<sysmsg" not in content:
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
content = str(message.get("content", "")).strip()
|
||||||
|
roomid = message.get("roomid", "")
|
||||||
|
|
||||||
|
if GroupBotManager.get_group_permission(roomid, self.feature) == PermissionStatus.DISABLED:
|
||||||
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
||||||
@@ -74,7 +86,7 @@ class GroupMemberChangePlugin(MessagePluginInterface):
|
|||||||
|
|
||||||
bot: WechatAPIClient = message.get("bot")
|
bot: WechatAPIClient = message.get("bot")
|
||||||
# 检查权限
|
# 检查权限
|
||||||
if roomid and gbm.get_group_permission(roomid, Feature.GROUP_MEMBER_CHANGE) == PermissionStatus.DISABLED:
|
if roomid and gbm.get_group_permission(roomid, self.feature) == PermissionStatus.DISABLED:
|
||||||
return False, "没有权限"
|
return False, "没有权限"
|
||||||
|
|
||||||
xml_content = str(content).strip().replace("\n", "").replace("\t", "")
|
xml_content = str(content).strip().replace("\n", "").replace("\t", "")
|
||||||
@@ -146,6 +158,14 @@ class GroupMemberChangePlugin(MessagePluginInterface):
|
|||||||
"""插件支持的命令列表"""
|
"""插件支持的命令列表"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_key(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_KEY
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_description(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_DESCRIPTION
|
||||||
|
|
||||||
def get_help(self) -> str:
|
def get_help(self) -> str:
|
||||||
"""获取插件帮助信息"""
|
"""获取插件帮助信息"""
|
||||||
return "群成员变更监控插件:自动监控群成员变动并发送通知。"
|
return "群成员变更监控插件:自动监控群成员变动并发送通知。"
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ from typing import Dict, Any, List, Optional, Tuple
|
|||||||
|
|
||||||
from base.plugin_common.message_plugin_interface import MessagePluginInterface
|
from base.plugin_common.message_plugin_interface import MessagePluginInterface
|
||||||
from base.plugin_common.plugin_interface import PluginStatus
|
from base.plugin_common.plugin_interface import PluginStatus
|
||||||
|
from utils.robot_cmd.robot_command import GroupBotManager, PermissionStatus
|
||||||
from utils.wechat.contact_manager import ContactManager
|
from utils.wechat.contact_manager import ContactManager
|
||||||
from db.connection import DBConnectionManager
|
from db.connection import DBConnectionManager
|
||||||
from db.group_virtual_redis import GroupVirtualRedisDB
|
from db.group_virtual_redis import GroupVirtualRedisDB
|
||||||
@@ -12,6 +13,10 @@ from wechat_ipad.models.message import WxMessage
|
|||||||
class GroupVirtualPlugin(MessagePluginInterface):
|
class GroupVirtualPlugin(MessagePluginInterface):
|
||||||
"""跨群聊天插件"""
|
"""跨群聊天插件"""
|
||||||
|
|
||||||
|
# 功能权限常量
|
||||||
|
FEATURE_KEY = "GROUP_VIRTUAL"
|
||||||
|
FEATURE_DESCRIPTION = "🔄 跨群聊天功能 [自动转发群组间消息]"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return "跨群聊天"
|
return "跨群聊天"
|
||||||
@@ -36,11 +41,21 @@ class GroupVirtualPlugin(MessagePluginInterface):
|
|||||||
def commands(self) -> List[str]:
|
def commands(self) -> List[str]:
|
||||||
return [] # 不处理任何命令
|
return [] # 不处理任何命令
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_key(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_KEY
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_description(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_DESCRIPTION
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.data = None
|
self.data = None
|
||||||
self.message_cache = set() # 用于防止消息循环转发
|
self.message_cache = set() # 用于防止消息循环转发
|
||||||
self.group_virtual_redis = None
|
self.group_virtual_redis = None
|
||||||
|
# 注册功能权限
|
||||||
|
self.feature = self.register_feature()
|
||||||
|
|
||||||
def initialize(self, context: Dict[str, Any]) -> bool:
|
def initialize(self, context: Dict[str, Any]) -> bool:
|
||||||
"""初始化插件"""
|
"""初始化插件"""
|
||||||
@@ -79,8 +94,13 @@ class GroupVirtualPlugin(MessagePluginInterface):
|
|||||||
if not self.enable:
|
if not self.enable:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# 只处理群消息
|
content = str(message.get("content", "")).strip()
|
||||||
roomid = message.get("roomid", "")
|
roomid = message.get("roomid", "")
|
||||||
|
|
||||||
|
if GroupBotManager.get_group_permission(roomid, self.feature) == PermissionStatus.DISABLED:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 只处理群消息
|
||||||
if not roomid:
|
if not roomid:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|||||||
@@ -76,6 +76,10 @@ class GuessSongRedisDB:
|
|||||||
class GuessSongPlugin(MessagePluginInterface):
|
class GuessSongPlugin(MessagePluginInterface):
|
||||||
"""猜歌名游戏插件"""
|
"""猜歌名游戏插件"""
|
||||||
|
|
||||||
|
# 功能权限常量
|
||||||
|
FEATURE_KEY = "GUESS_MUSIC"
|
||||||
|
FEATURE_DESCRIPTION = "🎵 猜歌名游戏 [猜歌名]"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return "猜歌名游戏"
|
return "猜歌名游戏"
|
||||||
@@ -100,8 +104,17 @@ class GuessSongPlugin(MessagePluginInterface):
|
|||||||
def commands(self) -> List[str]:
|
def commands(self) -> List[str]:
|
||||||
return self._commands
|
return self._commands
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_key(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_KEY
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_description(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_DESCRIPTION
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
self.feature = self.register_feature()
|
||||||
self.redis_db = None
|
self.redis_db = None
|
||||||
|
|
||||||
def initialize(self, context: Dict[str, Any]) -> bool:
|
def initialize(self, context: Dict[str, Any]) -> bool:
|
||||||
@@ -166,35 +179,24 @@ class GuessSongPlugin(MessagePluginInterface):
|
|||||||
|
|
||||||
return command in self._commands
|
return command in self._commands
|
||||||
|
|
||||||
@plugin_stats_decorator(plugin_name="猜歌名游戏")
|
@plugin_stats_decorator(plugin_name="猜歌名")
|
||||||
|
@plugin_points_cost(2, "猜歌名消耗积分", FEATURE_KEY)
|
||||||
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
||||||
"""处理消息"""
|
"""处理消息"""
|
||||||
content = str(message.get("content", "")).strip()
|
content = str(message.get("content", "")).strip()
|
||||||
self.LOG.debug(f"插件执行: {self.name}:{content}")
|
self.LOG.debug(f"插件执行: {self.name}:{content}")
|
||||||
|
|
||||||
# 简化命令处理,只检查开头是否包含命令前缀
|
|
||||||
command_found = False
|
|
||||||
for cmd in self._commands:
|
|
||||||
if content.startswith(cmd):
|
|
||||||
command_found = True
|
|
||||||
content = content[len(cmd):].strip()
|
|
||||||
break
|
|
||||||
|
|
||||||
if not command_found:
|
|
||||||
return False, "不匹配的命令"
|
|
||||||
|
|
||||||
sender = message.get("sender")
|
sender = message.get("sender")
|
||||||
roomid = message.get("roomid", "")
|
roomid = message.get("roomid", "")
|
||||||
gbm: GroupBotManager = message.get("gbm")
|
gbm: GroupBotManager = message.get("gbm")
|
||||||
bot: WechatAPIClient = message.get("bot")
|
bot: WechatAPIClient = message.get("bot")
|
||||||
|
|
||||||
|
# 检查权限
|
||||||
|
if roomid and gbm.get_group_permission(roomid, self.feature) == PermissionStatus.DISABLED:
|
||||||
|
return False, "没有权限"
|
||||||
|
|
||||||
# 使用roomid或sender作为游戏会话ID
|
# 使用roomid或sender作为游戏会话ID
|
||||||
session_id = roomid if roomid else sender
|
session_id = roomid if roomid else sender
|
||||||
|
|
||||||
# 检查权限
|
|
||||||
if roomid and gbm.get_group_permission(roomid, Feature.GUESS_MUSIC) == PermissionStatus.DISABLED:
|
|
||||||
return False, "没有权限"
|
|
||||||
|
|
||||||
# 获取当前游戏会话
|
# 获取当前游戏会话
|
||||||
current_game = None
|
current_game = None
|
||||||
if self.redis_db:
|
if self.redis_db:
|
||||||
|
|||||||
@@ -151,6 +151,10 @@ class QL:
|
|||||||
|
|
||||||
class JDTokenPlugin(MessagePluginInterface):
|
class JDTokenPlugin(MessagePluginInterface):
|
||||||
"""京东签到Token设置插件"""
|
"""京东签到Token设置插件"""
|
||||||
|
|
||||||
|
# 功能权限常量
|
||||||
|
FEATURE_KEY = "JD_TOKEN"
|
||||||
|
FEATURE_DESCRIPTION = "🔑 京东签到Token设置 [设置京东]"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
@@ -176,8 +180,18 @@ class JDTokenPlugin(MessagePluginInterface):
|
|||||||
def commands(self) -> List[str]:
|
def commands(self) -> List[str]:
|
||||||
return self._commands
|
return self._commands
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_key(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_KEY
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_description(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_DESCRIPTION
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
# 注册功能权限
|
||||||
|
self.feature = self.register_feature()
|
||||||
|
|
||||||
def initialize(self, context: Dict[str, Any]) -> bool:
|
def initialize(self, context: Dict[str, Any]) -> bool:
|
||||||
"""初始化插件"""
|
"""初始化插件"""
|
||||||
@@ -221,9 +235,12 @@ class JDTokenPlugin(MessagePluginInterface):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
content = str(message.get("content", "")).strip()
|
content = str(message.get("content", "")).strip()
|
||||||
command = content.split(" ")[0]
|
roomid = message.get("roomid", "")
|
||||||
|
|
||||||
return command in self._commands
|
if GroupBotManager.get_group_permission(roomid, self.feature) == PermissionStatus.DISABLED:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
@plugin_stats_decorator(plugin_name="京东签到Token设置")
|
@plugin_stats_decorator(plugin_name="京东签到Token设置")
|
||||||
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
||||||
|
|||||||
@@ -45,6 +45,14 @@ class MessageSignPlugin(MessagePluginInterface):
|
|||||||
def commands(self) -> List[str]:
|
def commands(self) -> List[str]:
|
||||||
return self._commands
|
return self._commands
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_key(self) -> Optional[str]:
|
||||||
|
return "SIGN_IN"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_description(self) -> Optional[str]:
|
||||||
|
return "📝 签到功能 [签到]"
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.today_signin_count = {}
|
self.today_signin_count = {}
|
||||||
@@ -57,6 +65,8 @@ class MessageSignPlugin(MessagePluginInterface):
|
|||||||
"resource", "6 托福-乱序.txt")
|
"resource", "6 托福-乱序.txt")
|
||||||
self.vocab_list = []
|
self.vocab_list = []
|
||||||
self.bot: WechatAPIClient = None
|
self.bot: WechatAPIClient = None
|
||||||
|
# 注册功能权限
|
||||||
|
self.feature = self.register_feature()
|
||||||
|
|
||||||
def initialize(self, context: Dict[str, Any]) -> bool:
|
def initialize(self, context: Dict[str, Any]) -> bool:
|
||||||
"""初始化插件"""
|
"""初始化插件"""
|
||||||
|
|||||||
@@ -24,6 +24,10 @@ from wechat_ipad import WechatAPIClient
|
|||||||
class MessageSummaryPlugin(MessagePluginInterface):
|
class MessageSummaryPlugin(MessagePluginInterface):
|
||||||
"""消息总结插件,用于生成群聊消息总结"""
|
"""消息总结插件,用于生成群聊消息总结"""
|
||||||
|
|
||||||
|
# 功能权限常量
|
||||||
|
FEATURE_KEY = "SUMMARY_CAPABILITY"
|
||||||
|
FEATURE_DESCRIPTION = "📝 群聊总结功能 [总结]"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return "群聊总结"
|
return "群聊总结"
|
||||||
@@ -46,12 +50,24 @@ class MessageSummaryPlugin(MessagePluginInterface):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def commands(self) -> List[str]:
|
def commands(self) -> List[str]:
|
||||||
return ["总结", "summary"]
|
return self._commands
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_key(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_KEY
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_description(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_DESCRIPTION
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.bot: WechatAPIClient = None
|
self._commands = []
|
||||||
self.revoke: MessageAutoRevoke = None
|
self.message_storage = None
|
||||||
|
self.revoke = None
|
||||||
|
self.bot = None
|
||||||
|
# 注册功能权限
|
||||||
|
self.feature = self.register_feature()
|
||||||
|
|
||||||
def initialize(self, context: Dict[str, Any]) -> bool:
|
def initialize(self, context: Dict[str, Any]) -> bool:
|
||||||
"""初始化插件"""
|
"""初始化插件"""
|
||||||
@@ -242,3 +258,14 @@ class MessageSummaryPlugin(MessagePluginInterface):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.LOG.error(f"处理总结时出现未知错误: {e}")
|
self.LOG.error(f"处理总结时出现未知错误: {e}")
|
||||||
return f"生成总结时出现未知错误: {str(e)}", None
|
return f"生成总结时出现未知错误: {str(e)}", None
|
||||||
|
|
||||||
|
def can_process(self, message: Dict[str, Any]) -> bool:
|
||||||
|
"""检查是否可以处理该消息"""
|
||||||
|
if not self.enable:
|
||||||
|
return False
|
||||||
|
|
||||||
|
content = str(message.get("content", "")).strip()
|
||||||
|
roomid = message.get("roomid", "")
|
||||||
|
|
||||||
|
if GroupBotManager.get_group_permission(roomid, self.feature) == PermissionStatus.DISABLED:
|
||||||
|
return False
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ from wechat_ipad.models.appmsg_xml import MUSIC_XML
|
|||||||
class MusicPlugin(MessagePluginInterface):
|
class MusicPlugin(MessagePluginInterface):
|
||||||
"""音乐点播插件"""
|
"""音乐点播插件"""
|
||||||
|
|
||||||
|
# 功能权限常量
|
||||||
|
FEATURE_KEY = "MUSIC"
|
||||||
|
FEATURE_DESCRIPTION = "🎵 点歌功能 [点歌, 音乐, 音乐点播, 点播音乐, 音乐点歌]"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return "音乐点播"
|
return "音乐点播"
|
||||||
@@ -43,8 +47,18 @@ class MusicPlugin(MessagePluginInterface):
|
|||||||
def commands(self) -> List[str]:
|
def commands(self) -> List[str]:
|
||||||
return self._commands
|
return self._commands
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_key(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_KEY
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_description(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_DESCRIPTION
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
# 注册功能权限
|
||||||
|
self.feature = self.register_feature()
|
||||||
|
|
||||||
def initialize(self, context: Dict[str, Any]) -> bool:
|
def initialize(self, context: Dict[str, Any]) -> bool:
|
||||||
"""初始化插件"""
|
"""初始化插件"""
|
||||||
@@ -83,28 +97,27 @@ class MusicPlugin(MessagePluginInterface):
|
|||||||
|
|
||||||
return command in self._commands
|
return command in self._commands
|
||||||
|
|
||||||
@plugin_stats_decorator(plugin_name="音乐点播")
|
@plugin_stats_decorator(plugin_name="点歌")
|
||||||
@plugin_points_cost(2, "音乐点播消耗积分", Feature.MUSIC)
|
@plugin_points_cost(2, "点歌消耗积分", FEATURE_KEY)
|
||||||
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
||||||
"""处理消息"""
|
"""处理消息"""
|
||||||
content = str(message.get("content", "")).strip()
|
content = str(message.get("content", "")).strip()
|
||||||
self.LOG.debug(f"插件执行: {self.name}:{content}")
|
self.LOG.debug(f"插件执行: {self.name}:{content}")
|
||||||
command = content.split(" ")[0]
|
|
||||||
sender = message.get("sender")
|
sender = message.get("sender")
|
||||||
roomid = message.get("roomid", "")
|
roomid = message.get("roomid", "")
|
||||||
gbm: GroupBotManager = message.get("gbm")
|
gbm: GroupBotManager = message.get("gbm")
|
||||||
bot: WechatAPIClient = message.get("bot")
|
bot: WechatAPIClient = message.get("bot")
|
||||||
|
|
||||||
|
# 检查权限
|
||||||
|
if roomid and gbm.get_group_permission(roomid, self.feature) == PermissionStatus.DISABLED:
|
||||||
|
return False, "没有权限"
|
||||||
|
|
||||||
# 检查命令格式
|
# 检查命令格式
|
||||||
if len(content.split(" ")) == 1:
|
if len(content.split(" ")) == 1:
|
||||||
await bot.send_text_message((roomid if roomid else sender), f"❌命令格式错误!\n{self.command_format}"
|
await bot.send_text_message((roomid if roomid else sender), f"❌命令格式错误!\n{self.command_format}"
|
||||||
, sender)
|
, sender)
|
||||||
return False, "命令格式错误"
|
return False, "命令格式错误"
|
||||||
|
|
||||||
# 检查权限
|
|
||||||
if roomid and gbm.get_group_permission(roomid, Feature.MUSIC) == PermissionStatus.DISABLED:
|
|
||||||
return False, "没有权限"
|
|
||||||
|
|
||||||
# 提取歌曲名
|
# 提取歌曲名
|
||||||
user_song_name = content[len(command):].strip()
|
user_song_name = content[len(command):].strip()
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,14 @@ class PluginManagerPlugin(MessagePluginInterface):
|
|||||||
def commands(self) -> List[str]:
|
def commands(self) -> List[str]:
|
||||||
return self._commands
|
return self._commands
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_key(self) -> Optional[str]:
|
||||||
|
return "PLUGIN_MANAGER"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_description(self) -> Optional[str]:
|
||||||
|
return "🔧 插件管理功能 [插件管理]"
|
||||||
|
|
||||||
def start(self) -> bool:
|
def start(self) -> bool:
|
||||||
"""启动插件"""
|
"""启动插件"""
|
||||||
self.LOG.info(f"[{self.name}] 插件已启动")
|
self.LOG.info(f"[{self.name}] 插件已启动")
|
||||||
@@ -52,6 +60,8 @@ class PluginManagerPlugin(MessagePluginInterface):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.bot: WechatAPIClient = None
|
self.bot: WechatAPIClient = None
|
||||||
|
# 注册功能权限
|
||||||
|
self.feature = self.register_feature()
|
||||||
|
|
||||||
def initialize(self, context: Dict[str, Any]) -> bool:
|
def initialize(self, context: Dict[str, Any]) -> bool:
|
||||||
"""初始化插件"""
|
"""初始化插件"""
|
||||||
@@ -93,6 +103,10 @@ class PluginManagerPlugin(MessagePluginInterface):
|
|||||||
self.LOG.error("WechatAPIClient 未初始化")
|
self.LOG.error("WechatAPIClient 未初始化")
|
||||||
return False, "Bot 未初始化"
|
return False, "Bot 未初始化"
|
||||||
|
|
||||||
|
# 检查功能权限
|
||||||
|
if roomid and gbm.get_group_permission(roomid, self.feature) == PermissionStatus.DISABLED:
|
||||||
|
return False, "没有权限"
|
||||||
|
|
||||||
# 检查命令格式
|
# 检查命令格式
|
||||||
parts = content.split(" ")
|
parts = content.split(" ")
|
||||||
if len(parts) == 1:
|
if len(parts) == 1:
|
||||||
@@ -103,7 +117,7 @@ class PluginManagerPlugin(MessagePluginInterface):
|
|||||||
self.plugin_registry = PluginRegistry()
|
self.plugin_registry = PluginRegistry()
|
||||||
self.plugin_manager = PluginManager().get_instance()
|
self.plugin_manager = PluginManager().get_instance()
|
||||||
|
|
||||||
# 检查权限 (只允许管理员操作)
|
# 检查管理员权限
|
||||||
if not self._is_admin(sender, gbm):
|
if not self._is_admin(sender, gbm):
|
||||||
await self.bot.send_at_message(target, f"❌权限不足,只有管理员可以管理插件", [sender])
|
await self.bot.send_at_message(target, f"❌权限不足,只有管理员可以管理插件", [sender])
|
||||||
return True, "权限不足"
|
return True, "权限不足"
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ from wechat_ipad.models.message import WxMessage
|
|||||||
class PointTradePlugin(MessagePluginInterface):
|
class PointTradePlugin(MessagePluginInterface):
|
||||||
"""积分交易插件"""
|
"""积分交易插件"""
|
||||||
|
|
||||||
|
# 功能权限常量
|
||||||
|
FEATURE_KEY = "POINT_TRADE"
|
||||||
|
FEATURE_DESCRIPTION = "💱 积分交易功能 [积分交易, 积分转账, 我的积分, 积分排行, 打劫, 保释]"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return "积分交易"
|
return "积分交易"
|
||||||
@@ -45,11 +49,21 @@ class PointTradePlugin(MessagePluginInterface):
|
|||||||
def commands(self) -> List[str]:
|
def commands(self) -> List[str]:
|
||||||
return self._commands
|
return self._commands
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_key(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_KEY
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_description(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_DESCRIPTION
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.db_pool = None
|
self.db_pool = None
|
||||||
self.bot: WechatAPIClient = None
|
self.bot: WechatAPIClient = None
|
||||||
self.revoke: MessageAutoRevoke = None
|
self.revoke: MessageAutoRevoke = None
|
||||||
|
# 注册功能权限
|
||||||
|
self.feature = self.register_feature()
|
||||||
|
|
||||||
def initialize(self, context: Dict[str, Any]) -> bool:
|
def initialize(self, context: Dict[str, Any]) -> bool:
|
||||||
"""初始化插件"""
|
"""初始化插件"""
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from typing import Dict, Any, List, Optional, Tuple
|
|||||||
|
|
||||||
from base.plugin_common.message_plugin_interface import MessagePluginInterface
|
from base.plugin_common.message_plugin_interface import MessagePluginInterface
|
||||||
from base.plugin_common.plugin_interface import PluginStatus
|
from base.plugin_common.plugin_interface import PluginStatus
|
||||||
from utils.decorator.plugin_decorators import plugin_stats_decorator
|
from utils.decorator.plugin_decorators import plugin_stats_decorator, plugin_points_cost
|
||||||
from utils.revoke.message_auto_revoke import MessageAutoRevoke
|
from utils.revoke.message_auto_revoke import MessageAutoRevoke
|
||||||
from utils.robot_cmd.robot_command import Feature, PermissionStatus, GroupBotManager
|
from utils.robot_cmd.robot_command import Feature, PermissionStatus, GroupBotManager
|
||||||
from wechat_ipad import WechatAPIClient
|
from wechat_ipad import WechatAPIClient
|
||||||
@@ -12,6 +12,10 @@ from wechat_ipad import WechatAPIClient
|
|||||||
|
|
||||||
class RobotMenuPlugin(MessagePluginInterface):
|
class RobotMenuPlugin(MessagePluginInterface):
|
||||||
"""功能菜单插件"""
|
"""功能菜单插件"""
|
||||||
|
|
||||||
|
# 功能权限常量
|
||||||
|
FEATURE_KEY = "ROBOT_MENU"
|
||||||
|
FEATURE_DESCRIPTION = "📋 功能菜单 [菜单, 功能]"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
@@ -37,8 +41,18 @@ class RobotMenuPlugin(MessagePluginInterface):
|
|||||||
def commands(self) -> List[str]:
|
def commands(self) -> List[str]:
|
||||||
return self._commands
|
return self._commands
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_key(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_KEY
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_description(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_DESCRIPTION
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
# 注册功能权限
|
||||||
|
self.feature = self.register_feature()
|
||||||
|
|
||||||
def initialize(self, context: Dict[str, Any]) -> bool:
|
def initialize(self, context: Dict[str, Any]) -> bool:
|
||||||
"""初始化插件"""
|
"""初始化插件"""
|
||||||
@@ -133,17 +147,22 @@ class RobotMenuPlugin(MessagePluginInterface):
|
|||||||
return "当前没有启用机器人的群组"
|
return "当前没有启用机器人的群组"
|
||||||
return "\n".join(group_list)
|
return "\n".join(group_list)
|
||||||
|
|
||||||
@plugin_stats_decorator(plugin_name="功能菜单")
|
@plugin_stats_decorator(plugin_name="机器人菜单")
|
||||||
|
@plugin_points_cost(1, "机器人菜单消耗积分", FEATURE_KEY)
|
||||||
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
||||||
"""处理消息"""
|
"""处理消息"""
|
||||||
content = str(message.get("content", "")).strip()
|
content = str(message.get("content", "")).strip()
|
||||||
self.LOG.debug(f"插件执行: {self.name}:{content}")
|
self.LOG.debug(f"插件执行: {self.name}:{content}")
|
||||||
command = content.split(" ")[0]
|
|
||||||
sender = message.get("sender")
|
sender = message.get("sender")
|
||||||
roomid = message.get("roomid", "")
|
roomid = message.get("roomid", "")
|
||||||
|
gbm: GroupBotManager = message.get("gbm")
|
||||||
bot: WechatAPIClient = message.get("bot")
|
bot: WechatAPIClient = message.get("bot")
|
||||||
revoke: MessageAutoRevoke = message.get("revoke")
|
revoke: MessageAutoRevoke = message.get("revoke")
|
||||||
|
|
||||||
|
# 检查权限
|
||||||
|
if roomid and gbm.get_group_permission(roomid, self.feature) == PermissionStatus.DISABLED:
|
||||||
|
return False, "没有权限"
|
||||||
|
|
||||||
# 检查命令格式
|
# 检查命令格式
|
||||||
if len(content.split(" ")) == 1:
|
if len(content.split(" ")) == 1:
|
||||||
# 显示功能菜单
|
# 显示功能菜单
|
||||||
|
|||||||
@@ -13,6 +13,18 @@ from db.connection import DBConnectionManager
|
|||||||
class StatsCollectorPlugin(PluginInterface):
|
class StatsCollectorPlugin(PluginInterface):
|
||||||
"""统计收集插件"""
|
"""统计收集插件"""
|
||||||
|
|
||||||
|
# 功能权限常量
|
||||||
|
FEATURE_KEY = "STATS_COLLECTOR"
|
||||||
|
FEATURE_DESCRIPTION = "📊 指令记录功能 [自动记录指令使用情况]"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_key(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_KEY
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_description(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_DESCRIPTION
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return "指令记录"
|
return "指令记录"
|
||||||
@@ -38,10 +50,8 @@ class StatsCollectorPlugin(PluginInterface):
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.LOG = logger
|
self.LOG = logger
|
||||||
|
|
||||||
self.LOG.info(f"正在初始化 {self.name} 插件...")
|
self.LOG.info(f"正在初始化 {self.name} 插件...")
|
||||||
# 默认配置
|
# 默认配置
|
||||||
self.config = {
|
self.config = {
|
||||||
@@ -49,10 +59,11 @@ class StatsCollectorPlugin(PluginInterface):
|
|||||||
"record_all_plugins": True, # 是否记录所有插件的调用
|
"record_all_plugins": True, # 是否记录所有插件的调用
|
||||||
"excluded_plugins": [], # 排除的插件列表
|
"excluded_plugins": [], # 排除的插件列表
|
||||||
}
|
}
|
||||||
|
|
||||||
self.event_manager = EventManager.get_instance()
|
self.event_manager = EventManager.get_instance()
|
||||||
self.db_manager = DBConnectionManager.get_instance()
|
self.db_manager = DBConnectionManager.get_instance()
|
||||||
self.stats_db = StatsDBOperator(self.db_manager)
|
self.stats_db = StatsDBOperator(self.db_manager)
|
||||||
|
# 注册功能权限
|
||||||
|
self.feature = self.register_feature()
|
||||||
|
|
||||||
def initialize(self, config: Dict[str, Any]) -> bool:
|
def initialize(self, config: Dict[str, Any]) -> bool:
|
||||||
"""初始化插件"""
|
"""初始化插件"""
|
||||||
|
|||||||
@@ -5,13 +5,20 @@ from typing import Dict, Any, List, Optional, Tuple
|
|||||||
|
|
||||||
from base.plugin_common.message_plugin_interface import MessagePluginInterface
|
from base.plugin_common.message_plugin_interface import MessagePluginInterface
|
||||||
from base.plugin_common.plugin_interface import PluginStatus
|
from base.plugin_common.plugin_interface import PluginStatus
|
||||||
from utils.robot_cmd.robot_command import Feature, PermissionStatus
|
from utils.decorator.plugin_decorators import plugin_stats_decorator
|
||||||
|
from utils.decorator.points_decorator import plugin_points_cost
|
||||||
|
from utils.robot_cmd.robot_command import Feature, PermissionStatus, GroupBotManager
|
||||||
from wechat_ipad import WechatAPIClient
|
from wechat_ipad import WechatAPIClient
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SystemUpdaterPlugin(MessagePluginInterface):
|
class SystemUpdaterPlugin(MessagePluginInterface):
|
||||||
"""系统更新插件"""
|
"""系统更新插件"""
|
||||||
|
|
||||||
|
# 功能权限常量
|
||||||
|
FEATURE_KEY = "SYSTEM_UPDATER"
|
||||||
|
FEATURE_DESCRIPTION = "🔄 系统更新功能 [更新系统, 系统更新]"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return "系统更新"
|
return "系统更新"
|
||||||
@@ -36,11 +43,21 @@ class SystemUpdaterPlugin(MessagePluginInterface):
|
|||||||
def commands(self) -> List[str]:
|
def commands(self) -> List[str]:
|
||||||
return self._commands
|
return self._commands
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_key(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_KEY
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_description(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_DESCRIPTION
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.admin_wxids = []
|
self.admin_wxids = []
|
||||||
self.wait_time = 5 # 默认等待15秒
|
self.wait_time = 5 # 默认等待15秒
|
||||||
self.bot: WechatAPIClient = None
|
self.bot: WechatAPIClient = None
|
||||||
|
# 注册功能权限
|
||||||
|
self.feature = self.register_feature()
|
||||||
|
|
||||||
def initialize(self, context: Dict[str, Any]) -> bool:
|
def initialize(self, context: Dict[str, Any]) -> bool:
|
||||||
"""初始化插件"""
|
"""初始化插件"""
|
||||||
@@ -87,47 +104,31 @@ class SystemUpdaterPlugin(MessagePluginInterface):
|
|||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@plugin_stats_decorator(plugin_name="系统更新")
|
||||||
|
@plugin_points_cost(1, "系统更新消耗积分", FEATURE_KEY)
|
||||||
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
||||||
"""处理消息"""
|
"""处理消息"""
|
||||||
content = str(message.get("content", "")).strip()
|
content = str(message.get("content", "")).strip()
|
||||||
|
self.LOG.debug(f"插件执行: {self.name}:{content}")
|
||||||
sender = message.get("sender")
|
sender = message.get("sender")
|
||||||
roomid = message.get("roomid", "")
|
roomid = message.get("roomid", "")
|
||||||
gbm = message.get("gbm", None)
|
gbm: GroupBotManager = message.get("gbm")
|
||||||
|
bot: WechatAPIClient = message.get("bot")
|
||||||
|
|
||||||
self.bot: WechatAPIClient = message.get("bot")
|
|
||||||
# 检查权限
|
# 检查权限
|
||||||
if self.admin_wxids and sender not in self.admin_wxids:
|
if roomid and gbm.get_group_permission(roomid, self.feature) == PermissionStatus.DISABLED:
|
||||||
await self.bot.send_text_message((roomid if roomid else sender), "⚠️ 您没有执行此操作的权限",
|
return False, "没有权限"
|
||||||
sender)
|
|
||||||
return True, "无权限"
|
|
||||||
|
|
||||||
# 如果是群消息,检查群权限
|
# 检查是否是命令
|
||||||
if roomid and gbm and hasattr(gbm, 'get_group_permission'):
|
if content in self._commands:
|
||||||
if gbm.get_group_permission(roomid, Feature.ROBOT) == PermissionStatus.DISABLED:
|
return True, "命令已接收"
|
||||||
return False, "机器人功能已禁用"
|
|
||||||
|
|
||||||
# 提取等待时间参数
|
# 检查是否是带参数的更新命令
|
||||||
wait_time = self.wait_time
|
for cmd in self._commands:
|
||||||
command = content.split(" ")[0]
|
if content.startswith(f"{cmd} "):
|
||||||
|
return True, "带参数的命令已接收"
|
||||||
|
|
||||||
if len(content.split(" ")) > 1:
|
return False, "无法处理的消息"
|
||||||
try:
|
|
||||||
param = content.split(" ")[1].strip()
|
|
||||||
if param.isdigit():
|
|
||||||
wait_time = int(param)
|
|
||||||
self.LOG.info(f"使用自定义等待时间: {wait_time}秒")
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# 发送更新通知
|
|
||||||
await self.bot.send_text_message((roomid if roomid else sender),
|
|
||||||
f"🔄 系统即将更新并重启,等待时间设置为{wait_time}秒...",
|
|
||||||
sender)
|
|
||||||
|
|
||||||
# 执行系统更新脚本
|
|
||||||
self._execute_system_update()
|
|
||||||
|
|
||||||
return True, "系统更新中"
|
|
||||||
|
|
||||||
def _execute_system_update(self):
|
def _execute_system_update(self):
|
||||||
"""执行系统更新操作"""
|
"""执行系统更新操作"""
|
||||||
|
|||||||
@@ -18,6 +18,18 @@ from wechat_ipad import WechatAPIClient
|
|||||||
class VideoPlugin(MessagePluginInterface):
|
class VideoPlugin(MessagePluginInterface):
|
||||||
"""视频插件"""
|
"""视频插件"""
|
||||||
|
|
||||||
|
# 功能权限常量
|
||||||
|
FEATURE_KEY = "VIDEO"
|
||||||
|
FEATURE_DESCRIPTION = "🎥 黑丝视频功能 [黑丝视频, 黑丝, 来个黑丝, 搞个黑丝]"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_key(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_KEY
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_description(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_DESCRIPTION
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return "黑丝视频"
|
return "黑丝视频"
|
||||||
|
|||||||
@@ -13,11 +13,16 @@ from base.plugin_common.plugin_interface import PluginStatus
|
|||||||
from utils.decorator.plugin_decorators import plugin_stats_decorator
|
from utils.decorator.plugin_decorators import plugin_stats_decorator
|
||||||
from utils.decorator.points_decorator import plugin_points_cost
|
from utils.decorator.points_decorator import plugin_points_cost
|
||||||
from utils.robot_cmd.robot_command import Feature, PermissionStatus, GroupBotManager
|
from utils.robot_cmd.robot_command import Feature, PermissionStatus, GroupBotManager
|
||||||
|
from base.wechat_api.wechat_api_client import WechatAPIClient
|
||||||
|
|
||||||
|
|
||||||
class VideoManPlugin(MessagePluginInterface):
|
class VideoManPlugin(MessagePluginInterface):
|
||||||
"""猛男视频插件"""
|
"""猛男视频插件"""
|
||||||
|
|
||||||
|
# 功能权限常量
|
||||||
|
FEATURE_KEY = "VIDEO_MAN"
|
||||||
|
FEATURE_DESCRIPTION = "💪 猛男视频功能 [猛男视频, 猛男, 来个猛男, 搞个猛男]"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return "猛男视频"
|
return "猛男视频"
|
||||||
@@ -42,10 +47,20 @@ class VideoManPlugin(MessagePluginInterface):
|
|||||||
def commands(self) -> List[str]:
|
def commands(self) -> List[str]:
|
||||||
return self._commands
|
return self._commands
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_key(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_KEY
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_description(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_DESCRIPTION
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
# 使用插件目录下的down_load_dir文件夹
|
# 使用插件目录下的down_load_dir文件夹
|
||||||
self.download_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "down_load_dir")
|
self.download_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "down_load_dir")
|
||||||
|
# 注册功能权限
|
||||||
|
self.feature = self.register_feature()
|
||||||
|
|
||||||
def initialize(self, context: Dict[str, Any]) -> bool:
|
def initialize(self, context: Dict[str, Any]) -> bool:
|
||||||
"""初始化插件"""
|
"""初始化插件"""
|
||||||
@@ -90,7 +105,7 @@ class VideoManPlugin(MessagePluginInterface):
|
|||||||
return command in self._commands
|
return command in self._commands
|
||||||
|
|
||||||
@plugin_stats_decorator(plugin_name="猛男视频")
|
@plugin_stats_decorator(plugin_name="猛男视频")
|
||||||
@plugin_points_cost(2, "猛男视频消耗积分", Feature.VIDEO_MAN)
|
@plugin_points_cost(2, "猛男视频消耗积分", FEATURE_KEY)
|
||||||
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
||||||
"""处理消息"""
|
"""处理消息"""
|
||||||
content = str(message.get("content", "")).strip()
|
content = str(message.get("content", "")).strip()
|
||||||
@@ -98,9 +113,10 @@ class VideoManPlugin(MessagePluginInterface):
|
|||||||
sender = message.get("sender")
|
sender = message.get("sender")
|
||||||
roomid = message.get("roomid", "")
|
roomid = message.get("roomid", "")
|
||||||
gbm: GroupBotManager = message.get("gbm")
|
gbm: GroupBotManager = message.get("gbm")
|
||||||
|
bot: WechatAPIClient = message.get("bot")
|
||||||
|
|
||||||
# 检查权限
|
# 检查权限
|
||||||
if roomid and gbm.get_group_permission(roomid, Feature.VIDEO_MAN) == PermissionStatus.DISABLED:
|
if roomid and gbm.get_group_permission(roomid, self.feature) == PermissionStatus.DISABLED:
|
||||||
return False, "没有权限"
|
return False, "没有权限"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -108,12 +124,12 @@ class VideoManPlugin(MessagePluginInterface):
|
|||||||
file_abspath, first_frame = await self._download_video("https://api.52vmy.cn/api/video/boy?type=json")
|
file_abspath, first_frame = await self._download_video("https://api.52vmy.cn/api/video/boy?type=json")
|
||||||
# FIXME 需要换成web容器地址。否则无法获取。
|
# FIXME 需要换成web容器地址。否则无法获取。
|
||||||
if not file_abspath:
|
if not file_abspath:
|
||||||
await self.bot.send_text_message((roomid if roomid else sender), f"\n❌视频下载失败,请稍后再试",
|
await bot.send_text_message((roomid if roomid else sender), f"\n❌视频下载失败,请稍后再试",
|
||||||
sender)
|
sender)
|
||||||
return False, "视频下载失败"
|
return False, "视频下载失败"
|
||||||
|
|
||||||
# 发送视频
|
# 发送视频
|
||||||
result = await self.bot.send_video_message((roomid if roomid else sender), Path(file_abspath),
|
result = await bot.send_video_message((roomid if roomid else sender), Path(file_abspath),
|
||||||
Path(first_frame))
|
Path(first_frame))
|
||||||
self.LOG.info(f"发送视频结果: {result}")
|
self.LOG.info(f"发送视频结果: {result}")
|
||||||
return True, "发送成功"
|
return True, "发送成功"
|
||||||
|
|||||||
@@ -14,6 +14,10 @@ from wechat_ipad import WechatAPIClient
|
|||||||
class WeatherPlugin(MessagePluginInterface):
|
class WeatherPlugin(MessagePluginInterface):
|
||||||
"""天气查询插件"""
|
"""天气查询插件"""
|
||||||
|
|
||||||
|
# 功能权限常量
|
||||||
|
FEATURE_KEY = "WEATHER"
|
||||||
|
FEATURE_DESCRIPTION = "🌤️ 天气查询功能 [天气]"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return "天气查询"
|
return "天气查询"
|
||||||
@@ -38,9 +42,19 @@ class WeatherPlugin(MessagePluginInterface):
|
|||||||
def commands(self) -> List[str]:
|
def commands(self) -> List[str]:
|
||||||
return self._commands
|
return self._commands
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_key(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_KEY
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_description(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_DESCRIPTION
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.plugin_dir = os.path.dirname(os.path.abspath(__file__))
|
self.plugin_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
# 注册功能权限
|
||||||
|
self.feature = self.register_feature()
|
||||||
|
|
||||||
def initialize(self, context: Dict[str, Any]) -> bool:
|
def initialize(self, context: Dict[str, Any]) -> bool:
|
||||||
"""初始化插件"""
|
"""初始化插件"""
|
||||||
@@ -88,17 +102,18 @@ class WeatherPlugin(MessagePluginInterface):
|
|||||||
return command in self._commands
|
return command in self._commands
|
||||||
|
|
||||||
@plugin_stats_decorator(plugin_name="天气查询")
|
@plugin_stats_decorator(plugin_name="天气查询")
|
||||||
@plugin_points_cost(2, "天气查询消耗积分", Feature.WEATHER)
|
@plugin_points_cost(1, "天气查询消耗积分", FEATURE_KEY)
|
||||||
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
||||||
"""处理消息"""
|
"""处理消息"""
|
||||||
content = str(message.get("content", "")).strip()
|
content = str(message.get("content", "")).strip()
|
||||||
self.LOG.debug(f"插件执行: {self.name}:{content}")
|
self.LOG.debug(f"插件执行: {self.name}:{content}")
|
||||||
sender = message.get("sender")
|
sender = message.get("sender")
|
||||||
roomid = message.get("roomid", "")
|
roomid = message.get("roomid", "")
|
||||||
|
gbm: GroupBotManager = message.get("gbm")
|
||||||
bot: WechatAPIClient = message.get("bot")
|
bot: WechatAPIClient = message.get("bot")
|
||||||
|
|
||||||
# 检查权限
|
# 检查权限
|
||||||
if roomid and GroupBotManager.get_group_permission(roomid, Feature.WEATHER) == PermissionStatus.DISABLED:
|
if roomid and gbm.get_group_permission(roomid, self.feature) == PermissionStatus.DISABLED:
|
||||||
return False, "没有权限"
|
return False, "没有权限"
|
||||||
|
|
||||||
# 处理消息内容 - 不再使用jieba分词
|
# 处理消息内容 - 不再使用jieba分词
|
||||||
|
|||||||
@@ -18,6 +18,10 @@ from wechat_ipad import WechatAPIClient
|
|||||||
class XiurenImagePlugin(MessagePluginInterface):
|
class XiurenImagePlugin(MessagePluginInterface):
|
||||||
"""秀人图片插件"""
|
"""秀人图片插件"""
|
||||||
|
|
||||||
|
# 功能权限常量
|
||||||
|
FEATURE_KEY = "XIUREN_IMAGE"
|
||||||
|
FEATURE_DESCRIPTION = "🖼️ 秀人图片功能 [秀人]"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return "秀人图片"
|
return "秀人图片"
|
||||||
@@ -42,10 +46,20 @@ class XiurenImagePlugin(MessagePluginInterface):
|
|||||||
def commands(self) -> List[str]:
|
def commands(self) -> List[str]:
|
||||||
return self._commands
|
return self._commands
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_key(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_KEY
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_description(self) -> Optional[str]:
|
||||||
|
return self.FEATURE_DESCRIPTION
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
# 使用Path对象处理路径,自动适应不同操作系统
|
# 使用Path对象处理路径,自动适应不同操作系统
|
||||||
self.image_folder = str(Path(Path(__file__).parent.parent.parent, "xiuren"))
|
self.image_folder = str(Path(Path(__file__).parent.parent.parent, "xiuren"))
|
||||||
|
# 注册功能权限
|
||||||
|
self.feature = self.register_feature()
|
||||||
|
|
||||||
def initialize(self, context: Dict[str, Any]) -> bool:
|
def initialize(self, context: Dict[str, Any]) -> bool:
|
||||||
"""初始化插件"""
|
"""初始化插件"""
|
||||||
@@ -97,8 +111,8 @@ class XiurenImagePlugin(MessagePluginInterface):
|
|||||||
|
|
||||||
return command in self._commands
|
return command in self._commands
|
||||||
|
|
||||||
@plugin_stats_decorator(plugin_name="秀人图片")
|
@plugin_stats_decorator(plugin_name="秀人网图片")
|
||||||
@plugin_points_cost(9, "秀人图片消耗积分", Feature.PIC)
|
@plugin_points_cost(2, "秀人网图片消耗积分", FEATURE_KEY)
|
||||||
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
|
||||||
"""处理消息"""
|
"""处理消息"""
|
||||||
content = str(message.get("content", "")).strip()
|
content = str(message.get("content", "")).strip()
|
||||||
@@ -109,7 +123,7 @@ class XiurenImagePlugin(MessagePluginInterface):
|
|||||||
bot: WechatAPIClient = message.get("bot")
|
bot: WechatAPIClient = message.get("bot")
|
||||||
revoke: MessageAutoRevoke = message.get("revoke")
|
revoke: MessageAutoRevoke = message.get("revoke")
|
||||||
# 检查权限
|
# 检查权限
|
||||||
if roomid and gbm.get_group_permission(roomid, Feature.PIC) == PermissionStatus.DISABLED:
|
if roomid and gbm.get_group_permission(roomid, self.feature) == PermissionStatus.DISABLED:
|
||||||
return False, "没有权限"
|
return False, "没有权限"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -177,13 +177,13 @@ def points_reward_decorator(points_calculator: Union[int, Callable], source_type
|
|||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
def plugin_points_cost(points: int, description: str = None, feature: Feature = None):
|
def plugin_points_cost(points: int, description: str = None, feature_key: str = None):
|
||||||
"""插件积分消费装饰器
|
"""插件积分消费装饰器
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
points: 消费积分数量
|
points: 消费积分数量
|
||||||
description: 积分消费描述
|
description: 积分消费描述
|
||||||
feature: 功能权限枚举
|
feature_key: 功能权限键名
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
装饰器函数
|
装饰器函数
|
||||||
@@ -195,8 +195,10 @@ def plugin_points_cost(points: int, description: str = None, feature: Feature =
|
|||||||
try:
|
try:
|
||||||
# 检查权限
|
# 检查权限
|
||||||
roomid = message.get("roomid", "")
|
roomid = message.get("roomid", "")
|
||||||
if feature and roomid:
|
if feature_key and roomid:
|
||||||
if GroupBotManager.get_group_permission(roomid, feature) == PermissionStatus.DISABLED:
|
# 获取功能权限枚举
|
||||||
|
feature = getattr(Feature, feature_key, None)
|
||||||
|
if feature and GroupBotManager.get_group_permission(roomid, feature) == PermissionStatus.DISABLED:
|
||||||
return False, "没有权限"
|
return False, "没有权限"
|
||||||
|
|
||||||
# 检查是否开启了积分获取功能
|
# 检查是否开启了积分获取功能
|
||||||
@@ -271,16 +273,18 @@ def plugin_points_cost(points: int, description: str = None, feature: Feature =
|
|||||||
try:
|
try:
|
||||||
# 检查权限
|
# 检查权限
|
||||||
roomid = message.get("roomid", "")
|
roomid = message.get("roomid", "")
|
||||||
if feature and roomid:
|
if feature_key and roomid:
|
||||||
if GroupBotManager.get_group_permission(roomid, feature) == PermissionStatus.DISABLED:
|
# 获取功能权限枚举
|
||||||
|
feature = getattr(Feature, feature_key, None)
|
||||||
|
if feature and GroupBotManager.get_group_permission(roomid, feature) == PermissionStatus.DISABLED:
|
||||||
return False, "没有权限"
|
return False, "没有权限"
|
||||||
|
|
||||||
# 检查是否开启了积分获取功能
|
# 检查是否开启了积分获取功能
|
||||||
if (GroupBotManager.get_group_permission(roomid,
|
# if (GroupBotManager.get_group_permission(roomid,
|
||||||
Feature.SIGNIN) == PermissionStatus.DISABLED
|
# Feature.SIGNIN) == PermissionStatus.DISABLED
|
||||||
and GroupBotManager.get_group_permission(
|
# and GroupBotManager.get_group_permission(
|
||||||
roomid, Feature.TASK_GAME) == PermissionStatus.DISABLED):
|
# roomid, Feature.TASK_GAME) == PermissionStatus.DISABLED):
|
||||||
return func(self, message)
|
# return func(self, message)
|
||||||
|
|
||||||
# 获取消息信息
|
# 获取消息信息
|
||||||
sender = message.get("sender", "")
|
sender = message.get("sender", "")
|
||||||
|
|||||||
88
utils/robot_cmd/Feature.py
Normal file
88
utils/robot_cmd/Feature.py
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
from enum import Enum
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
|
||||||
|
class Feature(Enum):
|
||||||
|
"""功能权限枚举,带序号和描述"""
|
||||||
|
ROBOT = "🔧 群机器人 [总开关]"
|
||||||
|
|
||||||
|
def __new__(cls, *args):
|
||||||
|
if len(args) == 2:
|
||||||
|
value, description = args
|
||||||
|
elif len(args) == 1 and isinstance(args[0], tuple):
|
||||||
|
value, description = args[0]
|
||||||
|
else:
|
||||||
|
raise TypeError(f"Invalid arguments for Feature.__new__: {args}")
|
||||||
|
|
||||||
|
obj = object.__new__(cls)
|
||||||
|
obj._value_ = value
|
||||||
|
obj.description = description
|
||||||
|
return obj
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.description
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_max_value(cls) -> int:
|
||||||
|
return max(member.value for member in cls)
|
||||||
|
|
||||||
|
_dynamic_features = {}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def register_feature(cls, key: str, description: str) -> 'Feature':
|
||||||
|
if key in cls._dynamic_features:
|
||||||
|
return cls._dynamic_features[key]
|
||||||
|
|
||||||
|
new_value = cls.get_max_value() + 1
|
||||||
|
new_feature = object.__new__(cls)
|
||||||
|
new_feature._value_ = new_value
|
||||||
|
new_feature.description = description
|
||||||
|
cls._dynamic_features[key] = new_feature
|
||||||
|
return new_feature
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_feature(cls, key: str) -> 'Feature':
|
||||||
|
return cls._dynamic_features.get(key)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_all_features(cls) -> List['Feature']:
|
||||||
|
return list(cls) + list(cls._dynamic_features.values())
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _missing_(cls, value):
|
||||||
|
if isinstance(value, int):
|
||||||
|
for member in cls:
|
||||||
|
if member.value == value:
|
||||||
|
return member
|
||||||
|
for feature in cls._dynamic_features.values():
|
||||||
|
if feature.value == value:
|
||||||
|
return feature
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
# 测试新增功能
|
||||||
|
print("当前功能列表:")
|
||||||
|
for feature in Feature.get_all_features():
|
||||||
|
print(f"{feature.value} - {feature.description}")
|
||||||
|
|
||||||
|
# 测试注册新功能
|
||||||
|
print("\n注册新功能...")
|
||||||
|
new_feature = Feature.register_feature("TEST_FEATURE", "🧪 测试功能 [测试]")
|
||||||
|
print(f"新功能: {new_feature.value} - {new_feature.description}")
|
||||||
|
|
||||||
|
# 验证新功能是否添加成功
|
||||||
|
print("\n更新后的功能列表:")
|
||||||
|
for feature in Feature.get_all_features():
|
||||||
|
print(f"{feature.value} - {feature.description}")
|
||||||
|
|
||||||
|
# 测试重复注册
|
||||||
|
print("\n测试重复注册...")
|
||||||
|
same_feature = Feature.register_feature("TEST_FEATURE", "🧪 测试功能 [测试]")
|
||||||
|
print(f"重复注册结果: {same_feature.value} - {same_feature.description}")
|
||||||
|
|
||||||
|
# 测试获取功能
|
||||||
|
print("\n测试获取功能...")
|
||||||
|
retrieved_feature = Feature.get_feature("TEST_FEATURE")
|
||||||
|
print(f"获取到的功能: {retrieved_feature.value} - {retrieved_feature.description}")
|
||||||
@@ -29,39 +29,77 @@ class PermissionStatus(Enum):
|
|||||||
class Feature(Enum):
|
class Feature(Enum):
|
||||||
"""功能权限枚举,带序号"""
|
"""功能权限枚举,带序号"""
|
||||||
ROBOT = 1, "🔧 群机器人 [总开关]"
|
ROBOT = 1, "🔧 群机器人 [总开关]"
|
||||||
DAILY_NEWS = 2, "📰 每日新闻自动播报 [每日8:30定时发送]"
|
|
||||||
DAILY_SUMMARY = 3, "🕤 每日群发言总结 [每日9:30定时发送]"
|
|
||||||
AI_CAPABILITY = 4, "🤖 AI对话 [ai, 聊天, AI] 用法:ai 如何写一个机器人?"
|
|
||||||
SUMMARY_CAPABILITY = 5, "📝 群总结能力 [#总结]"
|
|
||||||
PDF_CAPABILITY = 6, "📄 sehuatang PDF能力 [无]"
|
|
||||||
EPIC = 7, "📊 EPIC自动播报 [每周五自动发送]" # 新增的功能
|
|
||||||
PIC = 8, "🖼️ 图来能力 [图来, 秀人]"
|
|
||||||
TASK_GAME = 9, "📚 百科答题 [/t, /s, /a 任务ID 答案]"
|
|
||||||
MUSIC = 10, "🎵 点歌功能 [点歌, 音乐, 音乐点播, 点播音乐, 音乐点歌]"
|
|
||||||
SIGNIN = 11, "✅ 签到功能 [签到, 每日签到, qd, Qd, QD, 上班, 牛马]"
|
|
||||||
POINT_TRADE = 12, "🎁 积分赠送 [积分赠送 1 @XX, 积分排行, 打劫 @XX, 保释 @XX]"
|
|
||||||
BEAUTY_LEG = 13, "🦵 腿来能力 [美腿, 腿来]"
|
|
||||||
VIDEO = 14, "🎥 黑丝视频 [黑丝视频, 黑丝, 来个黑丝, 搞个黑丝]"
|
|
||||||
VIDEO_MAN = 15, "💪 肌肉视频 [猛男, 肌肉, 帅哥]"
|
|
||||||
# GROUP_ADD = 16, "加群提醒"
|
|
||||||
DOUYIN_PARSER = 17, "🎥 抖音链接转视频"
|
|
||||||
GROUP_MEMBER_CHANGE = 18, "👥 群成员变更提醒 [自动触发]"
|
|
||||||
# KID_PHOTO_EXTRACT = 19, "儿童照片提取转发功能" # 小朋友照片提取功能
|
|
||||||
NEWS = 20, "🌍 全球政治经济新闻"
|
|
||||||
WEATHER = 21, "🌤️ 天气查询 [上海天气, 天气上海]"
|
|
||||||
JD_TOKEN = 22, "🔑 JD_京豆token设置 [设置京东 pt_key=xxx;pt_pin=xxx; 备注名称]"
|
|
||||||
AI_AUTO = 23, "💬 仿真对话"
|
|
||||||
GUESS_MUSIC = 24, "🎤 猜歌名游戏 [猜歌名 - 开始 | 猜歌名 歌手名 - 指定歌手 | 猜歌名 歌名 - 提交答案]"
|
|
||||||
|
|
||||||
def __new__(cls, value, description):
|
def __new__(cls, value, description):
|
||||||
obj = object.__new__(cls)
|
obj = object.__new__(cls)
|
||||||
obj._value_ = value
|
obj._value_ = value
|
||||||
obj.description = description # 添加描述
|
obj.description = description
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.description
|
return self.description
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_max_value(cls) -> int:
|
||||||
|
"""获取当前最大的枚举值"""
|
||||||
|
return max([member.value for member in cls])
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def register_feature(cls, key: str, description: str) -> 'Feature':
|
||||||
|
"""注册新的功能权限
|
||||||
|
|
||||||
|
Args:
|
||||||
|
key: 功能键名
|
||||||
|
description: 功能描述
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Feature: 新注册的功能枚举
|
||||||
|
"""
|
||||||
|
# 检查是否已经注册过
|
||||||
|
if key in cls._member_map_:
|
||||||
|
return cls._member_map_[key]
|
||||||
|
|
||||||
|
# 获取当前最大的枚举值并加1
|
||||||
|
new_value = cls.get_max_value() + 1
|
||||||
|
|
||||||
|
# 创建新的枚举成员
|
||||||
|
new_feature = cls(new_value, description)
|
||||||
|
cls._member_map_[key] = new_feature
|
||||||
|
cls._member_names_.append(key)
|
||||||
|
new_feature._name_ = key
|
||||||
|
|
||||||
|
return new_feature
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_feature(cls, key: str) -> 'Feature':
|
||||||
|
"""获取已注册的功能
|
||||||
|
|
||||||
|
Args:
|
||||||
|
key: 功能键名
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Feature: 功能枚举实例
|
||||||
|
"""
|
||||||
|
return cls._member_map_.get(key)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_all_features(cls) -> List['Feature']:
|
||||||
|
"""获取所有功能
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[Feature]: 所有功能列表
|
||||||
|
"""
|
||||||
|
return list(cls)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _missing_(cls, value):
|
||||||
|
"""处理未找到的枚举值"""
|
||||||
|
if isinstance(value, int):
|
||||||
|
for member in cls:
|
||||||
|
if member.value == value:
|
||||||
|
return member
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def get_redis_connection():
|
def get_redis_connection():
|
||||||
# 初始化时加载本地缓存
|
# 初始化时加载本地缓存
|
||||||
@@ -181,7 +219,7 @@ class GroupBotManager:
|
|||||||
if feature_str.isdigit():
|
if feature_str.isdigit():
|
||||||
feature_num = int(feature_str)
|
feature_num = int(feature_str)
|
||||||
try:
|
try:
|
||||||
feature = Feature(feature_num) # 使用枚举序号查找功能
|
feature = Feature(feature_num, "") # 使用枚举序号查找功能
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return "无效的功能序号"
|
return "无效的功能序号"
|
||||||
else:
|
else:
|
||||||
@@ -294,5 +332,56 @@ def simulate_commands():
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# 执行模拟命令
|
# 测试新增功能
|
||||||
simulate_commands()
|
print("当前功能列表:")
|
||||||
|
for feature in Feature.get_all_features():
|
||||||
|
print(f"{feature.name}: {feature.value} - {feature.description}")
|
||||||
|
|
||||||
|
# 测试注册新功能
|
||||||
|
print("\n注册新功能...")
|
||||||
|
new_feature = Feature.register_feature("TEST_FEATURE", "🧪 测试功能 [测试]")
|
||||||
|
print(f"新功能: {new_feature.name} = {new_feature.value} - {new_feature.description}")
|
||||||
|
|
||||||
|
# 验证新功能是否添加成功
|
||||||
|
print("\n更新后的功能列表:")
|
||||||
|
for feature in Feature.get_all_features():
|
||||||
|
print(f"{feature.name}: {feature.value} - {feature.description}")
|
||||||
|
|
||||||
|
# 测试重复注册
|
||||||
|
print("\n测试重复注册...")
|
||||||
|
same_feature = Feature.register_feature("TEST_FEATURE", "🧪 测试功能 [测试]")
|
||||||
|
print(f"重复注册结果: {same_feature.name} = {same_feature.value} - {same_feature.description}")
|
||||||
|
|
||||||
|
# 测试获取功能
|
||||||
|
print("\n测试获取功能...")
|
||||||
|
retrieved_feature = Feature.get_feature("TEST_FEATURE")
|
||||||
|
print(f"获取到的功能: {retrieved_feature.name} = {retrieved_feature.value} - {retrieved_feature.description}")
|
||||||
|
|
||||||
|
# 测试通过值查找功能
|
||||||
|
print("\n测试通过值查找功能...")
|
||||||
|
feature_by_value = Feature(1, "") # 查找 ROBOT
|
||||||
|
print(f"通过值1查找: {feature_by_value.name} = {feature_by_value.value} - {feature_by_value.description}")
|
||||||
|
feature_by_value = Feature(2, "") # 查找 TEST_FEATURE
|
||||||
|
print(f"通过值2查找: {feature_by_value.name} = {feature_by_value.value} - {feature_by_value.description}")
|
||||||
|
|
||||||
|
# 测试枚举属性访问
|
||||||
|
print("\n测试枚举属性访问...")
|
||||||
|
print(f"ROBOT.name: {Feature.ROBOT.name}")
|
||||||
|
print(f"ROBOT.value: {Feature.ROBOT.value}")
|
||||||
|
print(f"ROBOT.description: {Feature.ROBOT.description}")
|
||||||
|
print(f"TEST_FEATURE.name: {Feature.TEST_FEATURE.name}")
|
||||||
|
print(f"TEST_FEATURE.value: {Feature.TEST_FEATURE.value}")
|
||||||
|
print(f"TEST_FEATURE.description: {Feature.TEST_FEATURE.description}")
|
||||||
|
|
||||||
|
# 测试枚举比较
|
||||||
|
print("\n测试枚举比较...")
|
||||||
|
print(f"ROBOT == TEST_FEATURE: {Feature.ROBOT == Feature.TEST_FEATURE}")
|
||||||
|
print(f"ROBOT != TEST_FEATURE: {Feature.ROBOT != Feature.TEST_FEATURE}")
|
||||||
|
print(f"ROBOT == ROBOT: {Feature.ROBOT == Feature.ROBOT}")
|
||||||
|
print(f"TEST_FEATURE == TEST_FEATURE: {Feature.TEST_FEATURE == Feature.TEST_FEATURE}")
|
||||||
|
|
||||||
|
# 测试枚举迭代
|
||||||
|
print("\n测试枚举迭代...")
|
||||||
|
print("所有功能:")
|
||||||
|
for feature in Feature:
|
||||||
|
print(f" {feature.name}: {feature.value} - {feature.description}")
|
||||||
|
|||||||
Reference in New Issue
Block a user