mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-06-02 03:55:55 +00:00
chore: switch comments to en
This commit is contained in:
@@ -11,11 +11,11 @@ from ....core import app
|
||||
|
||||
|
||||
preregistered_groups: list[type[RouterGroup]] = []
|
||||
"""RouterGroup 的预注册列表"""
|
||||
"""Pre-registered list of RouterGroup"""
|
||||
|
||||
|
||||
def group_class(name: str, path: str) -> None:
|
||||
"""注册一个 RouterGroup"""
|
||||
"""Register a RouterGroup"""
|
||||
|
||||
def decorator(cls: typing.Type[RouterGroup]) -> typing.Type[RouterGroup]:
|
||||
cls.name = name
|
||||
@@ -27,7 +27,7 @@ def group_class(name: str, path: str) -> None:
|
||||
|
||||
|
||||
class AuthType(enum.Enum):
|
||||
"""认证类型"""
|
||||
"""Authentication type"""
|
||||
|
||||
NONE = 'none'
|
||||
USER_TOKEN = 'user-token'
|
||||
@@ -56,7 +56,7 @@ class RouterGroup(abc.ABC):
|
||||
auth_type: AuthType = AuthType.USER_TOKEN,
|
||||
**options: typing.Any,
|
||||
) -> typing.Callable[[RouteCallable], RouteCallable]: # decorator
|
||||
"""注册一个路由"""
|
||||
"""Register a route"""
|
||||
|
||||
def decorator(f: RouteCallable) -> RouteCallable:
|
||||
nonlocal rule
|
||||
@@ -64,11 +64,11 @@ class RouterGroup(abc.ABC):
|
||||
|
||||
async def handler_error(*args, **kwargs):
|
||||
if auth_type == AuthType.USER_TOKEN:
|
||||
# 从Authorization头中获取token
|
||||
# get token from Authorization header
|
||||
token = quart.request.headers.get('Authorization', '').replace('Bearer ', '')
|
||||
|
||||
if not token:
|
||||
return self.http_status(401, -1, '未提供有效的用户令牌')
|
||||
return self.http_status(401, -1, 'No valid user token provided')
|
||||
|
||||
try:
|
||||
user_email = await self.ap.user_service.verify_jwt_token(token)
|
||||
@@ -76,9 +76,9 @@ class RouterGroup(abc.ABC):
|
||||
# check if this account exists
|
||||
user = await self.ap.user_service.get_user_by_email(user_email)
|
||||
if not user:
|
||||
return self.http_status(401, -1, '用户不存在')
|
||||
return self.http_status(401, -1, 'User not found')
|
||||
|
||||
# 检查f是否接受user_email参数
|
||||
# check if f accepts user_email parameter
|
||||
if 'user_email' in f.__code__.co_varnames:
|
||||
kwargs['user_email'] = user_email
|
||||
except Exception as e:
|
||||
@@ -86,7 +86,7 @@ class RouterGroup(abc.ABC):
|
||||
|
||||
try:
|
||||
return await f(*args, **kwargs)
|
||||
except Exception: # 自动 500
|
||||
except Exception: # auto 500
|
||||
traceback.print_exc()
|
||||
# return self.http_status(500, -2, str(e))
|
||||
return self.http_status(500, -2, 'internal server error')
|
||||
@@ -101,7 +101,7 @@ class RouterGroup(abc.ABC):
|
||||
return decorator
|
||||
|
||||
def success(self, data: typing.Any = None) -> quart.Response:
|
||||
"""返回一个 200 响应"""
|
||||
"""Return a 200 response"""
|
||||
return quart.jsonify(
|
||||
{
|
||||
'code': 0,
|
||||
@@ -111,7 +111,7 @@ class RouterGroup(abc.ABC):
|
||||
)
|
||||
|
||||
def fail(self, code: int, msg: str) -> quart.Response:
|
||||
"""返回一个异常响应"""
|
||||
"""Return an error response"""
|
||||
|
||||
return quart.jsonify(
|
||||
{
|
||||
@@ -121,5 +121,5 @@ class RouterGroup(abc.ABC):
|
||||
)
|
||||
|
||||
def http_status(self, status: int, code: int, msg: str) -> quart.Response:
|
||||
"""返回一个指定状态码的响应"""
|
||||
"""Return a response with a specified status code"""
|
||||
return self.fail(code, msg), status
|
||||
|
||||
@@ -8,7 +8,7 @@ class WebChatDebugRouterGroup(group.RouterGroup):
|
||||
async def initialize(self) -> None:
|
||||
@self.route('/send', methods=['POST'])
|
||||
async def send_message(pipeline_uuid: str) -> str:
|
||||
"""发送调试消息到流水线"""
|
||||
"""Send a message to the pipeline for debugging"""
|
||||
try:
|
||||
data = await quart.request.get_json()
|
||||
session_type = data.get('session_type', 'person')
|
||||
@@ -38,7 +38,7 @@ class WebChatDebugRouterGroup(group.RouterGroup):
|
||||
|
||||
@self.route('/messages/<session_type>', methods=['GET'])
|
||||
async def get_messages(pipeline_uuid: str, session_type: str) -> str:
|
||||
"""获取调试消息历史"""
|
||||
"""Get the message history of the pipeline for debugging"""
|
||||
try:
|
||||
if session_type not in ['person', 'group']:
|
||||
return self.http_status(400, -1, 'session_type must be person or group')
|
||||
@@ -57,7 +57,7 @@ class WebChatDebugRouterGroup(group.RouterGroup):
|
||||
|
||||
@self.route('/reset/<session_type>', methods=['POST'])
|
||||
async def reset_session(session_type: str) -> str:
|
||||
"""重置调试会话"""
|
||||
"""Reset the debug session"""
|
||||
try:
|
||||
if session_type not in ['person', 'group']:
|
||||
return self.http_status(400, -1, 'session_type must be person or group')
|
||||
|
||||
@@ -40,7 +40,7 @@ class PluginsRouterGroup(group.RouterGroup):
|
||||
self.ap.plugin_mgr.update_plugin(plugin_name, task_context=ctx),
|
||||
kind='plugin-operation',
|
||||
name=f'plugin-update-{plugin_name}',
|
||||
label=f'更新插件 {plugin_name}',
|
||||
label=f'Updating plugin {plugin_name}',
|
||||
context=ctx,
|
||||
)
|
||||
return self.success(data={'task_id': wrapper.id})
|
||||
@@ -62,7 +62,7 @@ class PluginsRouterGroup(group.RouterGroup):
|
||||
self.ap.plugin_mgr.uninstall_plugin(plugin_name, task_context=ctx),
|
||||
kind='plugin-operation',
|
||||
name=f'plugin-remove-{plugin_name}',
|
||||
label=f'删除插件 {plugin_name}',
|
||||
label=f'Removing plugin {plugin_name}',
|
||||
context=ctx,
|
||||
)
|
||||
|
||||
@@ -102,7 +102,7 @@ class PluginsRouterGroup(group.RouterGroup):
|
||||
self.ap.plugin_mgr.install_plugin(data['source'], task_context=ctx),
|
||||
kind='plugin-operation',
|
||||
name='plugin-install-github',
|
||||
label=f'安装插件 ...{short_source_str}',
|
||||
label=f'Installing plugin ...{short_source_str}',
|
||||
context=ctx,
|
||||
)
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ class UserRouterGroup(group.RouterGroup):
|
||||
return self.success(data={'initialized': await self.ap.user_service.is_initialized()})
|
||||
|
||||
if await self.ap.user_service.is_initialized():
|
||||
return self.fail(1, '系统已初始化')
|
||||
return self.fail(1, 'System already initialized')
|
||||
|
||||
json_data = await quart.request.json
|
||||
|
||||
@@ -32,7 +32,7 @@ class UserRouterGroup(group.RouterGroup):
|
||||
try:
|
||||
token = await self.ap.user_service.authenticate(json_data['user'], json_data['password'])
|
||||
except argon2.exceptions.VerifyMismatchError:
|
||||
return self.fail(1, '用户名或密码错误')
|
||||
return self.fail(1, 'Invalid username or password')
|
||||
|
||||
return self.success(data={'token': token})
|
||||
|
||||
@@ -54,15 +54,15 @@ class UserRouterGroup(group.RouterGroup):
|
||||
await asyncio.sleep(3)
|
||||
|
||||
if not await self.ap.user_service.is_initialized():
|
||||
return self.http_status(400, -1, 'system not initialized')
|
||||
return self.http_status(400, -1, 'System not initialized')
|
||||
|
||||
user_obj = await self.ap.user_service.get_user_by_email(user_email)
|
||||
|
||||
if user_obj is None:
|
||||
return self.http_status(400, -1, 'user not found')
|
||||
return self.http_status(400, -1, 'User not found')
|
||||
|
||||
if recovery_key != self.ap.instance_config.data['system']['recovery_key']:
|
||||
return self.http_status(403, -1, 'invalid recovery key')
|
||||
return self.http_status(403, -1, 'Invalid recovery key')
|
||||
|
||||
await self.ap.user_service.reset_password(user_email, new_password)
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ class HTTPController:
|
||||
try:
|
||||
await self.quart_app.run_task(*args, **kwargs)
|
||||
except Exception as e:
|
||||
self.ap.logger.error(f'启动 HTTP 服务失败: {e}')
|
||||
self.ap.logger.error(f'Failed to start HTTP service: {e}')
|
||||
|
||||
self.ap.task_mgr.create_task(
|
||||
exception_handler(
|
||||
|
||||
@@ -10,7 +10,7 @@ from ....entity.persistence import pipeline as persistence_pipeline
|
||||
|
||||
|
||||
class BotService:
|
||||
"""机器人服务"""
|
||||
"""Bot service"""
|
||||
|
||||
ap: app.Application
|
||||
|
||||
@@ -18,7 +18,7 @@ class BotService:
|
||||
self.ap = ap
|
||||
|
||||
async def get_bots(self) -> list[dict]:
|
||||
"""获取所有机器人"""
|
||||
"""Get all bots"""
|
||||
result = await self.ap.persistence_mgr.execute_async(sqlalchemy.select(persistence_bot.Bot))
|
||||
|
||||
bots = result.all()
|
||||
@@ -26,7 +26,7 @@ class BotService:
|
||||
return [self.ap.persistence_mgr.serialize_model(persistence_bot.Bot, bot) for bot in bots]
|
||||
|
||||
async def get_bot(self, bot_uuid: str) -> dict | None:
|
||||
"""获取机器人"""
|
||||
"""Get bot"""
|
||||
result = await self.ap.persistence_mgr.execute_async(
|
||||
sqlalchemy.select(persistence_bot.Bot).where(persistence_bot.Bot.uuid == bot_uuid)
|
||||
)
|
||||
@@ -39,7 +39,7 @@ class BotService:
|
||||
return self.ap.persistence_mgr.serialize_model(persistence_bot.Bot, bot)
|
||||
|
||||
async def create_bot(self, bot_data: dict) -> str:
|
||||
"""创建机器人"""
|
||||
"""Create bot"""
|
||||
# TODO: 检查配置信息格式
|
||||
bot_data['uuid'] = str(uuid.uuid4())
|
||||
|
||||
@@ -63,7 +63,7 @@ class BotService:
|
||||
return bot_data['uuid']
|
||||
|
||||
async def update_bot(self, bot_uuid: str, bot_data: dict) -> None:
|
||||
"""更新机器人"""
|
||||
"""Update bot"""
|
||||
if 'uuid' in bot_data:
|
||||
del bot_data['uuid']
|
||||
|
||||
@@ -99,7 +99,7 @@ class BotService:
|
||||
session.using_conversation = None
|
||||
|
||||
async def delete_bot(self, bot_uuid: str) -> None:
|
||||
"""删除机器人"""
|
||||
"""Delete bot"""
|
||||
await self.ap.platform_mgr.remove_bot(bot_uuid)
|
||||
await self.ap.persistence_mgr.execute_async(
|
||||
sqlalchemy.delete(persistence_bot.Bot).where(persistence_bot.Bot.uuid == bot_uuid)
|
||||
|
||||
@@ -6,7 +6,7 @@ from .. import model as file_model
|
||||
|
||||
|
||||
class JSONConfigFile(file_model.ConfigFile):
|
||||
"""JSON配置文件"""
|
||||
"""JSON config file"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -42,7 +42,7 @@ class JSONConfigFile(file_model.ConfigFile):
|
||||
try:
|
||||
cfg = json.load(f)
|
||||
except json.JSONDecodeError as e:
|
||||
raise Exception(f'配置文件 {self.config_file_name} 语法错误: {e}')
|
||||
raise Exception(f'Syntax error in config file {self.config_file_name}: {e}')
|
||||
|
||||
if completion:
|
||||
for key in self.template_data:
|
||||
|
||||
@@ -7,13 +7,13 @@ from .. import model as file_model
|
||||
|
||||
|
||||
class PythonModuleConfigFile(file_model.ConfigFile):
|
||||
"""Python模块配置文件"""
|
||||
"""Python module config file"""
|
||||
|
||||
config_file_name: str = None
|
||||
"""配置文件名"""
|
||||
"""Config file name"""
|
||||
|
||||
template_file_name: str = None
|
||||
"""模板文件名"""
|
||||
"""Template file name"""
|
||||
|
||||
def __init__(self, config_file_name: str, template_file_name: str) -> None:
|
||||
self.config_file_name = config_file_name
|
||||
@@ -42,7 +42,7 @@ class PythonModuleConfigFile(file_model.ConfigFile):
|
||||
|
||||
cfg[key] = getattr(module, key)
|
||||
|
||||
# 从模板模块文件中进行补全
|
||||
# complete from template module file
|
||||
if completion:
|
||||
module_name = os.path.splitext(os.path.basename(self.template_file_name))[0]
|
||||
module = importlib.import_module(module_name)
|
||||
@@ -60,7 +60,7 @@ class PythonModuleConfigFile(file_model.ConfigFile):
|
||||
return cfg
|
||||
|
||||
async def save(self, data: dict):
|
||||
logging.warning('Python模块配置文件不支持保存')
|
||||
logging.warning('Python module config file does not support saving')
|
||||
|
||||
def save_sync(self, data: dict):
|
||||
logging.warning('Python模块配置文件不支持保存')
|
||||
logging.warning('Python module config file does not support saving')
|
||||
|
||||
@@ -6,7 +6,7 @@ from .. import model as file_model
|
||||
|
||||
|
||||
class YAMLConfigFile(file_model.ConfigFile):
|
||||
"""YAML配置文件"""
|
||||
"""YAML config file"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -42,7 +42,7 @@ class YAMLConfigFile(file_model.ConfigFile):
|
||||
try:
|
||||
cfg = yaml.load(f, Loader=yaml.FullLoader)
|
||||
except yaml.YAMLError as e:
|
||||
raise Exception(f'配置文件 {self.config_file_name} 语法错误: {e}')
|
||||
raise Exception(f'Syntax error in config file {self.config_file_name}: {e}')
|
||||
|
||||
if completion:
|
||||
for key in self.template_data:
|
||||
|
||||
@@ -5,27 +5,27 @@ from .impls import pymodule, json as json_file, yaml as yaml_file
|
||||
|
||||
|
||||
class ConfigManager:
|
||||
"""配置文件管理器"""
|
||||
"""Config file manager"""
|
||||
|
||||
name: str = None
|
||||
"""配置管理器名"""
|
||||
"""Config manager name"""
|
||||
|
||||
description: str = None
|
||||
"""配置管理器描述"""
|
||||
"""Config manager description"""
|
||||
|
||||
schema: dict = None
|
||||
"""配置文件 schema
|
||||
需要符合 JSON Schema Draft 7 规范
|
||||
"""Config file schema
|
||||
Must conform to JSON Schema Draft 7 specification
|
||||
"""
|
||||
|
||||
file: file_model.ConfigFile = None
|
||||
"""配置文件实例"""
|
||||
"""Config file instance"""
|
||||
|
||||
data: dict = None
|
||||
"""配置数据"""
|
||||
"""Config data"""
|
||||
|
||||
doc_link: str = None
|
||||
"""配置文件文档链接"""
|
||||
"""Config file documentation link"""
|
||||
|
||||
def __init__(self, cfg_file: file_model.ConfigFile) -> None:
|
||||
self.file = cfg_file
|
||||
@@ -42,15 +42,15 @@ class ConfigManager:
|
||||
|
||||
|
||||
async def load_python_module_config(config_name: str, template_name: str, completion: bool = True) -> ConfigManager:
|
||||
"""加载Python模块配置文件
|
||||
"""Load Python module config file
|
||||
|
||||
Args:
|
||||
config_name (str): 配置文件名
|
||||
template_name (str): 模板文件名
|
||||
completion (bool): 是否自动补全内存中的配置文件
|
||||
config_name (str): Config file name
|
||||
template_name (str): Template file name
|
||||
completion (bool): Whether to automatically complete the config file in memory
|
||||
|
||||
Returns:
|
||||
ConfigManager: 配置文件管理器
|
||||
ConfigManager: Config file manager
|
||||
"""
|
||||
cfg_inst = pymodule.PythonModuleConfigFile(config_name, template_name)
|
||||
|
||||
@@ -66,13 +66,13 @@ async def load_json_config(
|
||||
template_data: dict = None,
|
||||
completion: bool = True,
|
||||
) -> ConfigManager:
|
||||
"""加载JSON配置文件
|
||||
"""Load JSON config file
|
||||
|
||||
Args:
|
||||
config_name (str): 配置文件名
|
||||
template_name (str): 模板文件名
|
||||
template_data (dict): 模板数据
|
||||
completion (bool): 是否自动补全内存中的配置文件
|
||||
config_name (str): Config file name
|
||||
template_name (str): Template file name
|
||||
template_data (dict): Template data
|
||||
completion (bool): Whether to automatically complete the config file in memory
|
||||
"""
|
||||
cfg_inst = json_file.JSONConfigFile(config_name, template_name, template_data)
|
||||
|
||||
@@ -88,16 +88,16 @@ async def load_yaml_config(
|
||||
template_data: dict = None,
|
||||
completion: bool = True,
|
||||
) -> ConfigManager:
|
||||
"""加载YAML配置文件
|
||||
"""Load YAML config file
|
||||
|
||||
Args:
|
||||
config_name (str): 配置文件名
|
||||
template_name (str): 模板文件名
|
||||
template_data (dict): 模板数据
|
||||
completion (bool): 是否自动补全内存中的配置文件
|
||||
config_name (str): Config file name
|
||||
template_name (str): Template file name
|
||||
template_data (dict): Template data
|
||||
completion (bool): Whether to automatically complete the config file in memory
|
||||
|
||||
Returns:
|
||||
ConfigManager: 配置文件管理器
|
||||
ConfigManager: Config file manager
|
||||
"""
|
||||
cfg_inst = yaml_file.YAMLConfigFile(config_name, template_name, template_data)
|
||||
|
||||
|
||||
@@ -2,16 +2,16 @@ import abc
|
||||
|
||||
|
||||
class ConfigFile(metaclass=abc.ABCMeta):
|
||||
"""配置文件抽象类"""
|
||||
"""Config file abstract class"""
|
||||
|
||||
config_file_name: str = None
|
||||
"""配置文件名"""
|
||||
"""Config file name"""
|
||||
|
||||
template_file_name: str = None
|
||||
"""模板文件名"""
|
||||
"""Template file name"""
|
||||
|
||||
template_data: dict = None
|
||||
"""模板数据"""
|
||||
"""Template data"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def exists(self) -> bool:
|
||||
|
||||
@@ -30,7 +30,7 @@ from . import entities as core_entities
|
||||
|
||||
|
||||
class Application:
|
||||
"""运行时应用对象和上下文"""
|
||||
"""Runtime application object and context"""
|
||||
|
||||
event_loop: asyncio.AbstractEventLoop = None
|
||||
|
||||
@@ -47,10 +47,10 @@ class Application:
|
||||
|
||||
model_mgr: llm_model_mgr.ModelManager = None
|
||||
|
||||
# TODO 移动到 pipeline 里
|
||||
# TODO move to pipeline
|
||||
tool_mgr: llm_tool_mgr.ToolManager = None
|
||||
|
||||
# ======= 配置管理器 =======
|
||||
# ======= Config manager =======
|
||||
|
||||
command_cfg: config_mgr.ConfigManager = None # deprecated
|
||||
|
||||
@@ -64,7 +64,7 @@ class Application:
|
||||
|
||||
instance_config: config_mgr.ConfigManager = None
|
||||
|
||||
# ======= 元数据配置管理器 =======
|
||||
# ======= Metadata config manager =======
|
||||
|
||||
sensitive_meta: config_mgr.ConfigManager = None
|
||||
|
||||
@@ -154,11 +154,11 @@ class Application:
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
except Exception as e:
|
||||
self.logger.error(f'应用运行致命异常: {e}')
|
||||
self.logger.error(f'Application runtime fatal exception: {e}')
|
||||
self.logger.debug(f'Traceback: {traceback.format_exc()}')
|
||||
|
||||
async def print_web_access_info(self):
|
||||
"""打印访问 webui 的提示"""
|
||||
"""Print access webui tips"""
|
||||
|
||||
if not os.path.exists(os.path.join('.', 'web/out')):
|
||||
self.logger.warning('WebUI 文件缺失,请根据文档部署:https://docs.langbot.app/zh')
|
||||
@@ -190,7 +190,7 @@ class Application:
|
||||
):
|
||||
match scope:
|
||||
case core_entities.LifecycleControlScope.PLATFORM.value:
|
||||
self.logger.info('执行热重载 scope=' + scope)
|
||||
self.logger.info('Hot reload scope=' + scope)
|
||||
await self.platform_mgr.shutdown()
|
||||
|
||||
self.platform_mgr = im_mgr.PlatformManager(self)
|
||||
@@ -206,7 +206,7 @@ class Application:
|
||||
],
|
||||
)
|
||||
case core_entities.LifecycleControlScope.PLUGIN.value:
|
||||
self.logger.info('执行热重载 scope=' + scope)
|
||||
self.logger.info('Hot reload scope=' + scope)
|
||||
await self.plugin_mgr.destroy_plugins()
|
||||
|
||||
# 删除 sys.module 中所有的 plugins/* 下的模块
|
||||
@@ -222,7 +222,7 @@ class Application:
|
||||
await self.plugin_mgr.load_plugins()
|
||||
await self.plugin_mgr.initialize_plugins()
|
||||
case core_entities.LifecycleControlScope.PROVIDER.value:
|
||||
self.logger.info('执行热重载 scope=' + scope)
|
||||
self.logger.info('Hot reload scope=' + scope)
|
||||
|
||||
await self.tool_mgr.shutdown()
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ from . import app
|
||||
from . import stage
|
||||
from ..utils import constants, importutil
|
||||
|
||||
# 引入启动阶段实现以便注册
|
||||
# Import startup stage implementation to register
|
||||
from . import stages
|
||||
|
||||
importutil.import_modules_in_pkg(stages)
|
||||
@@ -25,7 +25,7 @@ stage_order = [
|
||||
|
||||
|
||||
async def make_app(loop: asyncio.AbstractEventLoop) -> app.Application:
|
||||
# 确定是否为调试模式
|
||||
# Determine if it is debug mode
|
||||
if 'DEBUG' in os.environ and os.environ['DEBUG'] in ['true', '1']:
|
||||
constants.debug_mode = True
|
||||
|
||||
@@ -33,7 +33,7 @@ async def make_app(loop: asyncio.AbstractEventLoop) -> app.Application:
|
||||
|
||||
ap.event_loop = loop
|
||||
|
||||
# 执行启动阶段
|
||||
# Execute startup stage
|
||||
for stage_name in stage_order:
|
||||
stage_cls = stage.preregistered_stages[stage_name]
|
||||
stage_inst = stage_cls()
|
||||
@@ -47,11 +47,11 @@ async def make_app(loop: asyncio.AbstractEventLoop) -> app.Application:
|
||||
|
||||
async def main(loop: asyncio.AbstractEventLoop):
|
||||
try:
|
||||
# 挂系统信号处理
|
||||
# Hang system signal processing
|
||||
import signal
|
||||
|
||||
def signal_handler(sig, frame):
|
||||
print('[Signal] 程序退出.')
|
||||
print('[Signal] Program exit.')
|
||||
# ap.shutdown()
|
||||
os._exit(0)
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ import pip
|
||||
import os
|
||||
from ...utils import pkgmgr
|
||||
|
||||
# 检查依赖,防止用户未安装
|
||||
# 左边为引入名称,右边为依赖名称
|
||||
# Check dependencies to prevent users from not installing
|
||||
# Left is the import name, right is the dependency name
|
||||
required_deps = {
|
||||
'requests': 'requests',
|
||||
'openai': 'openai',
|
||||
@@ -65,7 +65,7 @@ async def install_deps(deps: list[str]):
|
||||
async def precheck_plugin_deps():
|
||||
print('[Startup] Prechecking plugin dependencies...')
|
||||
|
||||
# 只有在plugins目录存在时才执行插件依赖安装
|
||||
# Only execute plugin dependency installation when the plugins directory exists
|
||||
if os.path.exists('plugins'):
|
||||
for dir in os.listdir('plugins'):
|
||||
subdir = os.path.join('plugins', dir)
|
||||
|
||||
@@ -17,7 +17,7 @@ log_colors_config = {
|
||||
|
||||
|
||||
async def init_logging(extra_handlers: list[logging.Handler] = None) -> logging.Logger:
|
||||
# 删除所有现有的logger
|
||||
# Remove all existing loggers
|
||||
for handler in logging.root.handlers[:]:
|
||||
logging.root.removeHandler(handler)
|
||||
|
||||
@@ -54,13 +54,13 @@ async def init_logging(extra_handlers: list[logging.Handler] = None) -> logging.
|
||||
handler.setFormatter(color_formatter)
|
||||
qcg_logger.addHandler(handler)
|
||||
|
||||
qcg_logger.debug('日志初始化完成,日志级别:%s' % level)
|
||||
qcg_logger.debug('Logging initialized, log level: %s' % level)
|
||||
logging.basicConfig(
|
||||
level=logging.CRITICAL, # 设置日志输出格式
|
||||
level=logging.CRITICAL, # Set log output format
|
||||
format='[DEPR][%(asctime)s.%(msecs)03d] %(pathname)s (%(lineno)d) - [%(levelname)s] :\n%(message)s',
|
||||
# 日志输出的格式
|
||||
# -8表示占位符,让输出左对齐,输出长度都为8位
|
||||
datefmt='%Y-%m-%d %H:%M:%S', # 时间输出的格式
|
||||
# Log output format
|
||||
# -8 is a placeholder, left-align the output, and output length is 8
|
||||
datefmt='%Y-%m-%d %H:%M:%S', # Time output format
|
||||
handlers=[logging.NullHandler()],
|
||||
)
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ from .. import note
|
||||
|
||||
@note.note_class('ClassicNotes', 1)
|
||||
class ClassicNotes(note.LaunchNote):
|
||||
"""经典启动信息"""
|
||||
"""Classic launch information"""
|
||||
|
||||
async def need_show(self) -> bool:
|
||||
return True
|
||||
|
||||
@@ -9,7 +9,7 @@ from .. import note
|
||||
|
||||
@note.note_class('SelectionModeOnWindows', 2)
|
||||
class SelectionModeOnWindows(note.LaunchNote):
|
||||
"""Windows 上的选择模式提示信息"""
|
||||
"""Selection mode prompt information on Windows"""
|
||||
|
||||
async def need_show(self) -> bool:
|
||||
return os.name == 'nt'
|
||||
@@ -19,3 +19,8 @@ class SelectionModeOnWindows(note.LaunchNote):
|
||||
"""您正在使用 Windows 系统,若窗口左上角显示处于”选择“模式,程序将被暂停运行,此时请右键窗口中空白区域退出选择模式。""",
|
||||
logging.INFO,
|
||||
)
|
||||
|
||||
yield (
|
||||
"""You are using Windows system, if the top left corner of the window displays "Selection" mode, the program will be paused running, please right-click on the blank area in the window to exit the selection mode.""",
|
||||
logging.INFO,
|
||||
)
|
||||
|
||||
@@ -24,10 +24,10 @@ from .. import taskmgr
|
||||
|
||||
@stage.stage_class('BuildAppStage')
|
||||
class BuildAppStage(stage.BootingStage):
|
||||
"""构建应用阶段"""
|
||||
"""Build LangBot application"""
|
||||
|
||||
async def run(self, ap: app.Application):
|
||||
"""构建app对象的各个组件对象并初始化"""
|
||||
"""Build LangBot application"""
|
||||
ap.task_mgr = taskmgr.AsyncTaskManager(ap)
|
||||
|
||||
discover = discover_engine.ComponentDiscoveryEngine(ap)
|
||||
@@ -42,7 +42,7 @@ class BuildAppStage(stage.BootingStage):
|
||||
await ver_mgr.initialize()
|
||||
ap.ver_mgr = ver_mgr
|
||||
|
||||
# 发送公告
|
||||
# Send announcement
|
||||
ann_mgr = announce.AnnouncementManager(ap)
|
||||
ap.ann_mgr = ann_mgr
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@ from .. import stage, app
|
||||
|
||||
@stage.stage_class('GenKeysStage')
|
||||
class GenKeysStage(stage.BootingStage):
|
||||
"""生成密钥阶段"""
|
||||
"""Generate keys stage"""
|
||||
|
||||
async def run(self, ap: app.Application):
|
||||
"""启动"""
|
||||
"""Generate keys"""
|
||||
|
||||
if not ap.instance_config.data['system']['jwt']['secret']:
|
||||
ap.instance_config.data['system']['jwt']['secret'] = secrets.token_hex(16)
|
||||
|
||||
@@ -8,10 +8,10 @@ from ..bootutils import config
|
||||
|
||||
@stage.stage_class('LoadConfigStage')
|
||||
class LoadConfigStage(stage.BootingStage):
|
||||
"""加载配置文件阶段"""
|
||||
"""Load config file stage"""
|
||||
|
||||
async def run(self, ap: app.Application):
|
||||
"""启动"""
|
||||
"""Load config file"""
|
||||
|
||||
# ======= deprecated =======
|
||||
if os.path.exists('data/config/command.json'):
|
||||
|
||||
@@ -11,10 +11,13 @@ importutil.import_modules_in_pkg(migrations)
|
||||
|
||||
@stage.stage_class('MigrationStage')
|
||||
class MigrationStage(stage.BootingStage):
|
||||
"""迁移阶段"""
|
||||
"""Migration stage
|
||||
|
||||
These migrations are legacy, only performed in version 3.x
|
||||
"""
|
||||
|
||||
async def run(self, ap: app.Application):
|
||||
"""启动"""
|
||||
"""Run migration"""
|
||||
|
||||
if any(
|
||||
[
|
||||
@@ -29,7 +32,7 @@ class MigrationStage(stage.BootingStage):
|
||||
|
||||
migrations = migration.preregistered_migrations
|
||||
|
||||
# 按照迁移号排序
|
||||
# Sort by migration number
|
||||
migrations.sort(key=lambda x: x.number)
|
||||
|
||||
for migration_cls in migrations:
|
||||
@@ -37,4 +40,4 @@ class MigrationStage(stage.BootingStage):
|
||||
|
||||
if await migration_instance.need_migrate():
|
||||
await migration_instance.run()
|
||||
print(f'已执行迁移 {migration_instance.name}')
|
||||
print(f'Migration {migration_instance.name} executed')
|
||||
|
||||
@@ -8,7 +8,7 @@ from ..bootutils import log
|
||||
|
||||
class PersistenceHandler(logging.Handler, object):
|
||||
"""
|
||||
保存日志到数据库
|
||||
Save logs to database
|
||||
"""
|
||||
|
||||
ap: app.Application
|
||||
@@ -19,9 +19,9 @@ class PersistenceHandler(logging.Handler, object):
|
||||
|
||||
def emit(self, record):
|
||||
"""
|
||||
emit函数为自定义handler类时必重写的函数,这里可以根据需要对日志消息做一些处理,比如发送日志到服务器
|
||||
emit function is a required function for custom handler classes, here you can process the log messages as needed, such as sending logs to the server
|
||||
|
||||
发出记录(Emit a record)
|
||||
Emit a record
|
||||
"""
|
||||
try:
|
||||
msg = self.format(record)
|
||||
@@ -34,10 +34,10 @@ class PersistenceHandler(logging.Handler, object):
|
||||
|
||||
@stage.stage_class('SetupLoggerStage')
|
||||
class SetupLoggerStage(stage.BootingStage):
|
||||
"""设置日志器阶段"""
|
||||
"""Setup logger stage"""
|
||||
|
||||
async def run(self, ap: app.Application):
|
||||
"""启动"""
|
||||
"""Setup logger"""
|
||||
persistence_handler = PersistenceHandler('LoggerHandler', ap)
|
||||
|
||||
extra_handlers = []
|
||||
|
||||
@@ -12,10 +12,10 @@ importutil.import_modules_in_pkg(notes)
|
||||
|
||||
@stage.stage_class('ShowNotesStage')
|
||||
class ShowNotesStage(stage.BootingStage):
|
||||
"""显示启动信息阶段"""
|
||||
"""Show notes stage"""
|
||||
|
||||
async def run(self, ap: app.Application):
|
||||
# 排序
|
||||
# Sort
|
||||
note.preregistered_notes.sort(key=lambda x: x.number)
|
||||
|
||||
for note_cls in note.preregistered_notes:
|
||||
|
||||
Reference in New Issue
Block a user