From 85c08727c28c9c5b94d1dc621fdfca7df7b11bbb Mon Sep 17 00:00:00 2001 From: liuwei Date: Fri, 6 Jun 2025 17:46:10 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=8A=9F=E8=83=BD=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/robot_menu/__init__.py | 7 ++ plugins/robot_menu/config.toml | 8 ++ plugins/robot_menu/main.py | 172 +++++++++++++++++++++++++++++++ utils/ai/pollinations_ai.py | 28 +++++ utils/robot_cmd/robot_command.py | 57 +--------- 5 files changed, 216 insertions(+), 56 deletions(-) create mode 100644 plugins/robot_menu/__init__.py create mode 100644 plugins/robot_menu/config.toml create mode 100644 plugins/robot_menu/main.py create mode 100644 utils/ai/pollinations_ai.py diff --git a/plugins/robot_menu/__init__.py b/plugins/robot_menu/__init__.py new file mode 100644 index 0000000..47e969e --- /dev/null +++ b/plugins/robot_menu/__init__.py @@ -0,0 +1,7 @@ +# 从当前包的main模块导入MusicPlugin类 +from .main import RobotMenuPlugin + +# 提供get_plugin函数,返回插件实例 +def get_plugin(): + """获取插件实例""" + return RobotMenuPlugin() \ No newline at end of file diff --git a/plugins/robot_menu/config.toml b/plugins/robot_menu/config.toml new file mode 100644 index 0000000..7da0887 --- /dev/null +++ b/plugins/robot_menu/config.toml @@ -0,0 +1,8 @@ +[RobotMenu] +enable = true +command = ["菜单", "功能菜单"] +command-format = """ +📝功能菜单指令: +菜单 - 显示功能菜单 +菜单 状态 - 显示功能状态 +""" diff --git a/plugins/robot_menu/main.py b/plugins/robot_menu/main.py new file mode 100644 index 0000000..a6d6b3b --- /dev/null +++ b/plugins/robot_menu/main.py @@ -0,0 +1,172 @@ +import base64 +from loguru import logger +from typing import Dict, Any, List, Optional, Tuple + +from base.plugin_common.message_plugin_interface import MessagePluginInterface +from base.plugin_common.plugin_interface import PluginStatus +from utils.decorator.plugin_decorators import plugin_stats_decorator +from utils.revoke.message_auto_revoke import MessageAutoRevoke +from utils.robot_cmd.robot_command import Feature, PermissionStatus, GroupBotManager +from utils.decorator.points_decorator import plugin_points_cost +from wechat_ipad import WechatAPIClient + + +class RobotMenuPlugin(MessagePluginInterface): + """功能菜单插件""" + + @property + def name(self) -> str: + return "功能菜单" + + @property + def version(self) -> str: + return "1.0.0" + + @property + def description(self) -> str: + return "提供功能菜单功能,支持查看和使用机器人功能" + + @property + def author(self) -> str: + return "Trae AI" + + @property + def command_prefix(self) -> Optional[str]: + return "" # 不需要前缀,直接匹配命令 + + @property + def commands(self) -> List[str]: + return self._commands + + def __init__(self): + super().__init__() + + def initialize(self, context: Dict[str, Any]) -> bool: + """初始化插件""" + self.LOG = logger + self.LOG.info(f"正在初始化 {self.name} 插件...") + + # 保存上下文对象 + self.event_system = context.get("event_system") + + # 从配置文件加载命令列表 + self._commands = self._config.get("RobotMenu", {}).get("command", ["菜单", "功能"]) + self.command_format = self._config.get("RobotMenu", {}).get("command-format", "菜单 功能名") + self.enable = self._config.get("RobotMenu", {}).get("enable", True) + + self.LOG.info(f"[{self.name}] 插件初始化完成,指令:{self._commands}") + return True + + def start(self) -> bool: + """启动插件""" + self.LOG.info(f"[{self.name}] 插件已启动") + self.status = PluginStatus.RUNNING + return True + + def stop(self) -> bool: + """停止插件""" + self.LOG.info(f"[{self.name}] 插件已停止") + self.status = PluginStatus.STOPPED + return True + + def can_process(self, message: Dict[str, Any]) -> bool: + """检查是否可以处理该消息""" + if not self.enable: + return False + + content = str(message.get("content", "")).strip() + command = content.split(" ")[0] + + return command in self._commands + + def display_menu_status(self, group_id: str) -> str: + """显示所有功能列表及其在指定群组中的当前状态,带emoji""" + menu = [] + for feature in Feature: + status = GroupBotManager.get_group_permission(group_id, feature) + status_emoji = "✅" if status == PermissionStatus.ENABLED else "❌" + status_str = "启用" if status == PermissionStatus.ENABLED else "关闭" + menu.append(f"{status_emoji} {status_str}-{feature.value}-{feature.description}") + return "\n".join(menu) + + def get_enabled_features(self, group_id: str) -> str: + """获取某个群已启用的功能列表及其描述,并返回格式化的字符串 + 只返回描述中包含指令(方括号[])的功能 + + Args: + group_id: 群ID + + Returns: + str: 格式化的已启用功能列表字符串 + """ + enabled_features = [] + + # 检查群是否在列表中 + if group_id not in GroupBotManager.local_cache["group_list"]: + return "该群未启用机器人功能" + + # 遍历所有功能,检查哪些已启用且包含指令 + for feature in Feature: + status = GroupBotManager.get_group_permission(group_id, feature) + # 只添加已启用且描述中包含方括号的功能 + if status == PermissionStatus.ENABLED and "[" in feature.description and "]" in feature.description: + enabled_features.append({ + "id": feature.value, + "name": feature.name, + "description": feature.description + }) + + # 如果没有启用任何带指令的功能 + if not enabled_features: + return "该群未启用任何带指令的功能" + + # 构建格式化的字符串 + result = f"不支持@交互,请通过指令触发\n 群功能菜单:\n" + for feature in enabled_features: + result += f"{feature['id']}.{feature['description']}\n" + + return result + + def get_group_list(self) -> str: + """返回所有启用了群机器人的群组清单""" + group_list = list(GroupBotManager.local_cache["group_list"]) + if not group_list: + return "当前没有启用机器人的群组" + return "\n".join(group_list) + + @plugin_stats_decorator(plugin_name="功能菜单") + async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: + """处理消息""" + content = str(message.get("content", "")).strip() + self.LOG.debug(f"插件执行: {self.name}:{content}") + command = content.split(" ")[0] + sender = message.get("sender") + roomid = message.get("roomid", "") + bot: WechatAPIClient = message.get("bot") + revoke: MessageAutoRevoke = message.get("revoke") + + # 检查命令格式 + if len(content.split(" ")) == 1: + # 显示功能菜单 + menu_text = self.get_enabled_features(roomid if roomid else sender) + + client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else sender), + menu_text, sender) + revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 30) + return True, "显示功能菜单" + + # 提取命令名 + cmd_name = content[len(command):].strip() + try: + # 处理特殊命令 + if cmd_name.upper() == "状态": + # 显示所有功能状态 + status_text = self.display_menu_status(roomid if roomid else sender) + client_msg_id, create_time, new_msg_id = await bot.send_text_message((roomid if roomid else sender), + status_text, sender) + revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 30) + return True, "显示功能状态" + + except Exception as e: + self.LOG.error(f"处理功能请求出错: {e}") + return False, f"处理出错: {e}" diff --git a/utils/ai/pollinations_ai.py b/utils/ai/pollinations_ai.py new file mode 100644 index 0000000..6092700 --- /dev/null +++ b/utils/ai/pollinations_ai.py @@ -0,0 +1,28 @@ +import requests +import urllib.parse + +prompt = "创作一幅超照片级的亚洲美女单人自拍肖像,仿若用高端智能手机(如iPhone 16 Pro或同等设备)拍摄。她具有[光泽柔顺的黑色波浪长发、杏仁状深棕色眼睛带细致虹膜纹理、光滑瓷白皮肤带微妙自然瑕疵、自信迷人的微笑]。自拍在[时尚的城市屋顶夜景灯光]中拍摄。她穿着[修身丝质连衣裙带微妙领口],散发优雅且微妙的性感气质。构图模仿自然自拍角度,面部略微偏离中心,持相机角度自然讨巧,姿势优雅放松,凸显魅力。皮肤、头发和眼睛的纹理超现实,包含细致细节如单根发丝、微小皮肤毛孔和眼中真实反射。光线自然动态,带有柔和阴影和高光,模仿现实世界条件(如黄金时段阳光或室内环境光),突出她的特征。表情自信迷人,带有随性、栩栩如生的氛围。背景清晰但自然模糊(浅景深效果,f/1.8光圈)。完全避免油画感、艺术化风格、笔触、卡通化元素,不要呈现文字或任何数字瑕疵。输出为高分辨率,超详细,与真实高分辨率照片无异。" +params = { + "width": 1080, + "height": 1920, + "seed": 44, + "model": "flux", + "nologo": "true", # Optional + # "transparent": "true", # Optional - generates transparent background (gptimage model only) + # "referrer": "MyPythonApp" # Optional +} +encoded_prompt = urllib.parse.quote(prompt) +url = f"https://image.pollinations.ai/prompt/{encoded_prompt}" + +try: + response = requests.get(url, params=params, timeout=300) # Increased timeout for image generation + response.raise_for_status() # Raise an exception for bad status codes + + with open('generated_image.jpg', 'wb') as f: + f.write(response.content) + print("Image saved as generated_image.jpg") + +except requests.exceptions.RequestException as e: + print(f"Error fetching image: {e}") + # Consider checking response.text for error messages from the API + # if response is not None: print(response.text) \ No newline at end of file diff --git a/utils/robot_cmd/robot_command.py b/utils/robot_cmd/robot_command.py index fcb2ffd..76bae4b 100644 --- a/utils/robot_cmd/robot_command.py +++ b/utils/robot_cmd/robot_command.py @@ -155,18 +155,10 @@ class GroupBotManager: @staticmethod def handle_command(group_id, command_str): """统一处理群功能指令""" - # print(f"PermissionStatus handle_command command_str: {command_str}") + # print(f"PermissionStatus robot_menu command_str: {command_str}") # 命令解析 command_parts = command_str.strip().split("-") - # 如果是MENU指令,返回功能列表 - if command_str.strip().upper() == "菜单": - return f"群ID:{group_id} \n {GroupBotManager.get_enabled_features(group_id)}" - - # 如果是MENU-STATUS指令,返回功能列表及其状态 - if command_str.strip().upper() == "菜单状态": - return f"群ID:{group_id} \n {GroupBotManager.display_menu_status(group_id)}" - # 如果是GROUP_LIST指令,返回 group:list 清单 if command_str.strip().upper() == "群列表": return GroupBotManager.get_group_list() @@ -239,53 +231,6 @@ class GroupBotManager: permissions[feature] = status if status else PermissionStatus.DISABLED # 默认为禁用状态 return permissions - @staticmethod - def display_menu(): - """显示所有功能列表及其当前状态""" - menu = [] - for feature in Feature: - menu.append(f"{feature.value}. {feature.description}") - return "\n".join(menu) - - @staticmethod - def get_enabled_features(group_id): - """获取某个群已启用的功能列表及其描述,并返回格式化的字符串 - 只返回描述中包含指令(方括号[])的功能 - - Args: - group_id: 群ID - - Returns: - str: 格式化的已启用功能列表字符串 - """ - enabled_features = [] - - # 检查群是否在列表中 - if group_id not in GroupBotManager.local_cache["group_list"]: - return "该群未启用机器人功能" - - # 遍历所有功能,检查哪些已启用且包含指令 - for feature in Feature: - status = GroupBotManager.get_group_permission(group_id, feature) - # 只添加已启用且描述中包含方括号的功能 - if status == PermissionStatus.ENABLED and "[" in feature.description and "]" in feature.description: - enabled_features.append({ - "id": feature.value, - "name": feature.name, - "description": feature.description - }) - - # 如果没有启用任何带指令的功能 - if not enabled_features: - return "该群未启用任何带指令的功能" - - # 构建格式化的字符串 - result = f"不支持@交互,请通过指令触发\n 群功能菜单:\n" - for feature in enabled_features: - result += f"{feature['id']}.{feature['description']}\n" - - return result - @staticmethod def get_group_list(): """返回所有启用了群机器人的群组清单,格式为集合"""