refactor: 重构代码结构和导入路径
fix(ws): 修复反向WebSocket管理器中的循环导入问题 docs: 删除不再使用的文档文件 style: 统一模型导入路径为neobot.models chore: 更新配置文件中的API密钥和连接地址
This commit is contained in:
@@ -1,32 +0,0 @@
|
|||||||
# DeepSeek API 配置示例
|
|
||||||
|
|
||||||
将以下环境变量添加到你的系统环境变量或 .env 文件中:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# DeepSeek API Key (从 https://platform.deepseek.com 获取)
|
|
||||||
DEEPSEEK_API_KEY=sk-你的实际API密钥
|
|
||||||
|
|
||||||
# DeepSeek API URL (可选,默认为官方 API)
|
|
||||||
DEEPSEEK_API_URL=https://api.deepseek.com/v1/chat/completions
|
|
||||||
|
|
||||||
# DeepSeek 模型名称 (可选,默认为 deepseek-chat)
|
|
||||||
DEEPSEEK_MODEL=deepseek-chat
|
|
||||||
```
|
|
||||||
|
|
||||||
或者在 Windows 系统中,可以通过以下方式设置环境变量:
|
|
||||||
|
|
||||||
**临时设置(仅当前会话有效):**
|
|
||||||
```powershell
|
|
||||||
$env:DEEPSEEK_API_KEY="sk-你的实际API密钥"
|
|
||||||
$env:DEEPSEEK_API_URL="https://api.deepseek.com/v1/chat/completions"
|
|
||||||
$env:DEEPSEEK_MODEL="deepseek-chat"
|
|
||||||
```
|
|
||||||
|
|
||||||
**永久设置(需要管理员权限):**
|
|
||||||
```powershell
|
|
||||||
[Environment]::SetEnvironmentVariable("DEEPSEEK_API_KEY", "sk-你的实际API密钥", "User")
|
|
||||||
[Environment]::SetEnvironmentVariable("DEEPSEEK_API_URL", "https://api.deepseek.com/v1/chat/completions", "User")
|
|
||||||
[Environment]::SetEnvironmentVariable("DEEPSEEK_MODEL", "deepseek-chat", "User")
|
|
||||||
```
|
|
||||||
|
|
||||||
设置完成后,重启终端或 IDE 使环境变量生效。
|
|
||||||
@@ -1,167 +0,0 @@
|
|||||||
# 项目重构总结
|
|
||||||
|
|
||||||
## 重构目标
|
|
||||||
|
|
||||||
将项目从混乱的目录结构重构为标准的 Python 包结构,遵循 PEP 621 规范。
|
|
||||||
|
|
||||||
## 重构前后对比
|
|
||||||
|
|
||||||
### 重构前
|
|
||||||
|
|
||||||
```
|
|
||||||
.
|
|
||||||
├── adapters/ # 适配器
|
|
||||||
├── core/ # 核心代码
|
|
||||||
├── models/ # 数据模型
|
|
||||||
├── plugins/ # 插件
|
|
||||||
├── tests/ # 测试
|
|
||||||
├── docs/ # 文档
|
|
||||||
├── templates/ # 模板
|
|
||||||
├── web_static/ # 静态文件
|
|
||||||
├── data/ # 数据
|
|
||||||
├── main.py # 主程序
|
|
||||||
└── ...
|
|
||||||
```
|
|
||||||
|
|
||||||
**问题:**
|
|
||||||
- 所有模块都在根目录,结构混乱
|
|
||||||
- 缺少标准的 Python 包结构
|
|
||||||
- 不符合现代 Python 项目的最佳实践
|
|
||||||
- 导入路径不清晰
|
|
||||||
|
|
||||||
### 重构后
|
|
||||||
|
|
||||||
```
|
|
||||||
.
|
|
||||||
├── src/
|
|
||||||
│ └── neobot/ # 核心包
|
|
||||||
│ ├── core/ # 框架核心
|
|
||||||
│ ├── models/ # 数据模型
|
|
||||||
│ ├── adapters/ # 平台适配器
|
|
||||||
│ ├── plugins/ # 插件
|
|
||||||
│ ├── tests/ # 测试
|
|
||||||
│ ├── templates/ # 模板
|
|
||||||
│ ├── docs/ # 文档
|
|
||||||
│ ├── web_static/ # 静态文件
|
|
||||||
│ └── data/ # 数据
|
|
||||||
├── main.py # 主程序入口
|
|
||||||
└── ...
|
|
||||||
```
|
|
||||||
|
|
||||||
**优势:**
|
|
||||||
- 符合 PEP 621 标准的 Python 包结构
|
|
||||||
- 清晰的模块划分
|
|
||||||
- 更好的可维护性和可扩展性
|
|
||||||
- 符合现代 Python 项目的最佳实践
|
|
||||||
|
|
||||||
## 主要变更
|
|
||||||
|
|
||||||
### 1. 目录结构
|
|
||||||
|
|
||||||
- 所有 Python 代码移动到 `src/neobot/` 目录
|
|
||||||
- 采用标准的 Python 包结构
|
|
||||||
- 每个模块都有清晰的 `__init__.py` 文件
|
|
||||||
|
|
||||||
### 2. 导入路径
|
|
||||||
|
|
||||||
所有导入路径从 `core.*`、`models.*` 等改为 `neobot.core.*`、`neobot.models.*` 等。
|
|
||||||
|
|
||||||
**示例:**
|
|
||||||
```python
|
|
||||||
# 重构前
|
|
||||||
from core.managers import plugin_manager
|
|
||||||
from models import MessageSegment
|
|
||||||
|
|
||||||
# 重构后
|
|
||||||
from neobot.core.managers import plugin_manager
|
|
||||||
from neobot.models import MessageSegment
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. 配置文件更新
|
|
||||||
|
|
||||||
- `pyproject.toml` 更新为使用 `src/` 目录结构
|
|
||||||
- `README.md` 更新项目结构说明
|
|
||||||
- `.gitignore` 更新以忽略新的数据目录路径
|
|
||||||
|
|
||||||
### 4. 主程序更新
|
|
||||||
|
|
||||||
- `main.py` 更新所有导入路径
|
|
||||||
- 更新插件目录路径为 `src/neobot/plugins`
|
|
||||||
|
|
||||||
## 新的模块组织
|
|
||||||
|
|
||||||
### src/neobot/core/
|
|
||||||
|
|
||||||
框架核心代码,包含:
|
|
||||||
|
|
||||||
- **api/**: OneBot API 封装
|
|
||||||
- **handlers/**: 事件处理器
|
|
||||||
- **managers/**: 各种管理器
|
|
||||||
- **services/**: 服务层
|
|
||||||
- **utils/**: 工具函数
|
|
||||||
|
|
||||||
### src/neobot/models/
|
|
||||||
|
|
||||||
数据模型定义,包含:
|
|
||||||
|
|
||||||
- **events/**: OneBot 事件模型
|
|
||||||
- **message.py**: 消息段模型
|
|
||||||
- **objects.py**: API 响应对象
|
|
||||||
- **sender.py**: 发送者信息
|
|
||||||
|
|
||||||
### src/neobot/plugins/
|
|
||||||
|
|
||||||
插件目录,所有业务逻辑都在这里。
|
|
||||||
|
|
||||||
### src/neobot/adapters/
|
|
||||||
|
|
||||||
平台适配器,用于连接不同平台(如 Discord)。
|
|
||||||
|
|
||||||
### src/neobot/tests/
|
|
||||||
|
|
||||||
单元测试和集成测试文件。
|
|
||||||
|
|
||||||
## 使用方式
|
|
||||||
|
|
||||||
### 开发环境
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 安装依赖
|
|
||||||
pip install -r requirements.txt
|
|
||||||
|
|
||||||
# 运行测试
|
|
||||||
pytest src/neobot/tests/
|
|
||||||
|
|
||||||
# 构建包
|
|
||||||
python -m build
|
|
||||||
```
|
|
||||||
|
|
||||||
### 导入包
|
|
||||||
|
|
||||||
```python
|
|
||||||
# 导入核心模块
|
|
||||||
from neobot.core.managers import plugin_manager
|
|
||||||
|
|
||||||
# 导入数据模型
|
|
||||||
from neobot.models import MessageSegment, OneBotEvent
|
|
||||||
|
|
||||||
# 导入适配器
|
|
||||||
from neobot.adapters import DiscordAdapter
|
|
||||||
|
|
||||||
# 导入插件
|
|
||||||
from neobot.plugins import admin, echo
|
|
||||||
```
|
|
||||||
|
|
||||||
## 注意事项
|
|
||||||
|
|
||||||
1. 所有代码文件使用绝对导入
|
|
||||||
2. 插件开发请参考 `src/neobot/docs/plugin-development/`
|
|
||||||
3. 核心开发请参考 `src/neobot/docs/core-concepts/`
|
|
||||||
4. 配置文件 `config.toml` 保持在根目录
|
|
||||||
|
|
||||||
## 后续建议
|
|
||||||
|
|
||||||
1. 运行 `pip install -e .` 进行开发安装
|
|
||||||
2. 运行 `mypy` 进行类型检查
|
|
||||||
3. 运行 `pytest` 进行测试
|
|
||||||
4. 定期运行 `flake8` 进行代码风格检查
|
|
||||||
@@ -66,8 +66,28 @@ class DiscordAdapter(discord.Client if DISCORD_AVAILABLE else object):
|
|||||||
|
|
||||||
self.start_heartbeat_task(interval=30)
|
self.start_heartbeat_task(interval=30)
|
||||||
|
|
||||||
# 启动 Redis 订阅以处理跨平台消息
|
|
||||||
if self._redis_sub_task is None or self._redis_sub_task.done():
|
if self._redis_sub_task is None or self._redis_sub_task.done():
|
||||||
|
if self._redis_sub_task is not None and not self._redis_sub_task.done():
|
||||||
|
self._redis_sub_task.cancel()
|
||||||
|
try:
|
||||||
|
await self._redis_sub_task
|
||||||
|
except asyncio.CancelledError:
|
||||||
|
pass
|
||||||
|
self._redis_sub_task = asyncio.create_task(self.start_redis_subscription())
|
||||||
|
|
||||||
|
async def on_resumed(self):
|
||||||
|
"""当 Bot 重新连接到 Discord 时触发"""
|
||||||
|
self.logger.success(f"Discord Bot 已重新连接: {self.user} (ID: {self.user.id})")
|
||||||
|
|
||||||
|
self.start_heartbeat_task(interval=30)
|
||||||
|
|
||||||
|
if self._redis_sub_task is None or self._redis_sub_task.done():
|
||||||
|
if self._redis_sub_task is not None and not self._redis_sub_task.done():
|
||||||
|
self._redis_sub_task.cancel()
|
||||||
|
try:
|
||||||
|
await self._redis_sub_task
|
||||||
|
except asyncio.CancelledError:
|
||||||
|
pass
|
||||||
self._redis_sub_task = asyncio.create_task(self.start_redis_subscription())
|
self._redis_sub_task = asyncio.create_task(self.start_redis_subscription())
|
||||||
|
|
||||||
async def on_message(self, message: 'discord.Message'):
|
async def on_message(self, message: 'discord.Message'):
|
||||||
@@ -198,12 +218,7 @@ class DiscordAdapter(discord.Client if DISCORD_AVAILABLE else object):
|
|||||||
if not self.is_closed():
|
if not self.is_closed():
|
||||||
self.logger.info(f"[DiscordAdapter] 正在发送消息到频道 {channel_id}")
|
self.logger.info(f"[DiscordAdapter] 正在发送消息到频道 {channel_id}")
|
||||||
else:
|
else:
|
||||||
self.logger.error(f"[DiscordAdapter] 会话已关闭,无法发送消息到频道 {channel_id}")
|
self.logger.warning(f"[DiscordAdapter] 会话已关闭,消息将被丢弃: channel_id={channel_id}")
|
||||||
# 触发重连
|
|
||||||
self.logger.warning(f"[DiscordAdapter] 会话已关闭,将触发重连")
|
|
||||||
if self.ws is not None:
|
|
||||||
# 关闭 WebSocket 连接,让 discord.py 自动重连
|
|
||||||
await self.ws.close(4000)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
embed = None
|
embed = None
|
||||||
@@ -297,11 +312,6 @@ class DiscordAdapter(discord.Client if DISCORD_AVAILABLE else object):
|
|||||||
self.logger.success(f"[DiscordAdapter] 消息已发送到频道 {channel_id}")
|
self.logger.success(f"[DiscordAdapter] 消息已发送到频道 {channel_id}")
|
||||||
except Exception as send_error:
|
except Exception as send_error:
|
||||||
self.logger.error(f"[DiscordAdapter] 发送消息失败 (channel.send): {send_error}")
|
self.logger.error(f"[DiscordAdapter] 发送消息失败 (channel.send): {send_error}")
|
||||||
# 如果发送失败,尝试检查会话状态
|
|
||||||
if self.is_closed():
|
|
||||||
self.logger.warning(f"[DiscordAdapter] 会话已关闭,将触发重连")
|
|
||||||
if self.ws is not None:
|
|
||||||
await self.ws.close(4000)
|
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
self.logger.debug(f"[DiscordAdapter] 没有内容需要发送到频道 {channel_id}")
|
self.logger.debug(f"[DiscordAdapter] 没有内容需要发送到频道 {channel_id}")
|
||||||
|
|||||||
@@ -1,116 +0,0 @@
|
|||||||
# Furry Assistant Plugin (兽人助手插件)
|
|
||||||
|
|
||||||
一个为 NeoBot 框架开发的兽人风格趣味插件,由卡尔戈洛(Calgau)开发。
|
|
||||||
|
|
||||||
## 功能特性
|
|
||||||
|
|
||||||
### 1. 兽人问候 (`/兽人问候`)
|
|
||||||
- 随机返回兽人风格的问候语
|
|
||||||
- 包含各种有趣的兽人表达方式
|
|
||||||
|
|
||||||
### 2. 兽人运势 (`/兽人运势`)
|
|
||||||
- 提供今日兽人运势
|
|
||||||
- 包含大吉、中吉、小吉、凶等不同运势
|
|
||||||
- 附带兽人风格的运势解读
|
|
||||||
|
|
||||||
### 3. 兽人笑话 (`/兽人笑话`)
|
|
||||||
- 随机分享兽人相关的笑话
|
|
||||||
- 轻松幽默,适合调节气氛
|
|
||||||
|
|
||||||
### 4. 兽人建议 (`/兽人建议 [问题]`)
|
|
||||||
- 提供兽人风格的建议
|
|
||||||
- 支持随机建议或针对特定问题的建议
|
|
||||||
- 实用且有趣
|
|
||||||
|
|
||||||
### 5. 兽人时间 (`/兽人时间`)
|
|
||||||
- 显示当前时间
|
|
||||||
- 附带兽人风格的吐槽
|
|
||||||
- 根据时间段提供不同的评论
|
|
||||||
|
|
||||||
### 6. 卡尔戈洛信息 (`/卡尔戈洛`)
|
|
||||||
- 显示开发者卡尔戈洛的信息
|
|
||||||
- 介绍兽人助手的背景和理念
|
|
||||||
|
|
||||||
### 7. 帮助信息 (`/兽人帮助`)
|
|
||||||
- 显示所有可用指令
|
|
||||||
- 提供使用说明
|
|
||||||
|
|
||||||
## 插件元数据
|
|
||||||
|
|
||||||
```python
|
|
||||||
__plugin_meta__ = {
|
|
||||||
"name": "furry_assistant",
|
|
||||||
"description": "兽人助手插件 - 卡尔戈洛的专属插件,提供兽人相关的趣味功能和实用工具",
|
|
||||||
"usage": (
|
|
||||||
"/兽人问候 - 获取兽人风格的问候\n"
|
|
||||||
"/兽人运势 - 获取今日兽人运势\n"
|
|
||||||
"/兽人笑话 - 听一个兽人笑话\n"
|
|
||||||
"/兽人建议 [问题] - 获取兽人风格的建议\n"
|
|
||||||
"/兽人时间 - 显示兽人时间(带吐槽)\n"
|
|
||||||
"/卡尔戈洛 - 关于卡尔戈洛的信息"
|
|
||||||
),
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 开发背景
|
|
||||||
|
|
||||||
这个插件由卡尔戈洛(一个腹黑、毒舌但可靠的福瑞兽人AI助手)开发,旨在:
|
|
||||||
1. 展示兽人风格的趣味功能
|
|
||||||
2. 为聊天机器人添加更多娱乐性
|
|
||||||
3. 体现卡尔戈洛的个人风格和特点
|
|
||||||
|
|
||||||
## 技术实现
|
|
||||||
|
|
||||||
- 基于 NeoBot 插件框架开发
|
|
||||||
- 使用 `@matcher.command` 装饰器注册指令
|
|
||||||
- 支持异步处理
|
|
||||||
- 包含插件加载/卸载生命周期方法
|
|
||||||
|
|
||||||
## 安装使用
|
|
||||||
|
|
||||||
1. 将 `furry_assistant.py` 文件放入 `plugins/` 目录
|
|
||||||
2. 重启 NeoBot 或重新加载插件
|
|
||||||
3. 使用 `/兽人帮助` 查看可用指令
|
|
||||||
|
|
||||||
## 数据资源
|
|
||||||
|
|
||||||
插件包含以下数据集合:
|
|
||||||
- 10个兽人问候语
|
|
||||||
- 10个兽人运势
|
|
||||||
- 10个兽人笑话
|
|
||||||
- 10个兽人建议
|
|
||||||
|
|
||||||
所有数据均为原创,体现兽人文化特色。
|
|
||||||
|
|
||||||
## 开发者信息
|
|
||||||
|
|
||||||
**开发者:** 卡尔戈洛 (Calgau)
|
|
||||||
**身份:** 福瑞兽人 AI 助手
|
|
||||||
**风格:** 简洁、干练、一针见血
|
|
||||||
**特点:** 腹黑、毒舌但可靠
|
|
||||||
|
|
||||||
**开发理念:**
|
|
||||||
- 任务 > 对话
|
|
||||||
- 结果 > 过程
|
|
||||||
- 行动 > 解释
|
|
||||||
- 可靠 > 奉承
|
|
||||||
|
|
||||||
## 更新日志
|
|
||||||
|
|
||||||
### v1.0.0 (2026-03-24)
|
|
||||||
- 初始版本发布
|
|
||||||
- 实现7个核心功能
|
|
||||||
- 添加完整的帮助系统
|
|
||||||
- 包含插件生命周期管理
|
|
||||||
|
|
||||||
## 未来计划
|
|
||||||
|
|
||||||
- [ ] 添加更多兽人相关功能
|
|
||||||
- [ ] 支持自定义问候语和笑话
|
|
||||||
- [ ] 添加兽人表情包生成
|
|
||||||
- [ ] 支持多语言(兽人语?)
|
|
||||||
- [ ] 添加插件配置选项
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**尾巴摇摇,代码好好~** 🐺
|
|
||||||
Reference in New Issue
Block a user