ErisPulse 2.7.0.dev5__tar.gz → 2.7.1.dev1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/PKG-INFO +1 -1
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/pyproject.toml +1 -1
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/commands/create.py +46 -13
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/commands/doctor.py +67 -10
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/commands/list.py +3 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/i18n/locales/en.py +3 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/i18n/locales/ja.py +3 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/i18n/locales/ru.py +3 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/i18n/locales/zh_cn.py +3 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/i18n/locales/zh_tw.py +3 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/utils/display.py +4 -1
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Bases/config_schema.py +52 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Event/base.py +9 -1
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Event/wrapper.py +8 -7
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/adapter.py +34 -34
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/config.py +53 -14
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/constants.py +20 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/i18n/locales/en.py +40 -2
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/i18n/locales/ja.py +40 -2
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/i18n/locales/ru.py +40 -2
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/i18n/locales/zh_cn.py +40 -2
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/i18n/locales/zh_tw.py +40 -2
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/logger.py +181 -30
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/module.py +42 -25
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/router.py +80 -3
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/finders/bases/finder.py +46 -9
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/loaders/adapter.py +8 -3
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/loaders/bases/loader.py +18 -6
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/loaders/module.py +98 -29
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/loaders/strict.py +32 -2
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/runtime/__init__.py +6 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/runtime/exceptions.py +58 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/runtime/frame_config.py +52 -5
- erispulse-2.7.1.dev1/src/ErisPulse/runtime/tasks.py +109 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/sdk.py +75 -11
- erispulse-2.7.0.dev5/src/ErisPulse/runtime/tasks.py +0 -63
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/.gitignore +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/LICENSE +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/README.pypi.md +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/__init__.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/base.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/cli.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/commands/__init__.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/commands/init.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/commands/install.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/commands/language.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/commands/list_remote.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/commands/run.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/commands/self_update.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/commands/types.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/commands/uninstall.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/commands/upgrade.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/console.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/constants.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/hints.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/i18n/__init__.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/i18n/locales/__init__.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/registry.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/utils/__init__.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/utils/file_watcher.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/utils/package_manager.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/CLI/utils/scaffold_text.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Bases/__init__.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Bases/adapter.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Bases/client.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Bases/converter.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Bases/errors.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Bases/i18n_schema.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Bases/kv_builder.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Bases/manager.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Bases/module.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Bases/router.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Bases/send_builder.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Bases/send_rules.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Bases/storage.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Bases/websocket.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Event/__init__.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Event/command.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Event/message.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Event/message_builder.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Event/meta.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Event/notice.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Event/request.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/Event/session_type.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/__init__.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/assets/__init__.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/assets/error.css +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/assets/error.html +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/assets/root.css +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/assets/root.html +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/client.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/i18n/__init__.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/i18n/constants.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/i18n/locales/__init__.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/lifecycle.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/master.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/Core/storage.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/__init__.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/__main__.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/finders/__init__.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/finders/adapter.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/finders/bases/__init__.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/finders/module.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/loaders/__init__.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/loaders/bases/__init__.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/loaders/strategy.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/py.typed +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/runtime/config_schema.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/runtime/context.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/runtime/diagnostics.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/runtime/hints.py +0 -0
- {erispulse-2.7.0.dev5 → erispulse-2.7.1.dev1}/src/ErisPulse/runtime/memory.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ErisPulse
|
|
3
|
-
Version: 2.7.
|
|
3
|
+
Version: 2.7.1.dev1
|
|
4
4
|
Summary: Event-driven modular async bot framework — write once, deploy to any platform | 事件驱动的模块化异步机器人框架,一次编写,多平台部署
|
|
5
5
|
Project-URL: Homepage, https://github.com/ErisPulse/ErisPulse
|
|
6
6
|
Project-URL: Documentation, https://www.erisdev.com#docs
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ErisPulse"
|
|
7
|
-
version = "2.7.
|
|
7
|
+
version = "2.7.1-dev.1"
|
|
8
8
|
description = "Event-driven modular async bot framework — write once, deploy to any platform | 事件驱动的模块化异步机器人框架,一次编写,多平台部署"
|
|
9
9
|
readme = "README.pypi.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -462,33 +462,50 @@ class {converter_name}(BaseConverter):
|
|
|
462
462
|
return None
|
|
463
463
|
"""
|
|
464
464
|
|
|
465
|
-
_README_MODULE = """
|
|
465
|
+
_README_MODULE = """<div align="center">
|
|
466
466
|
|
|
467
|
-
{
|
|
467
|
+
<img src="https://raw.githubusercontent.com/ErisPulse/ErisPulse/main/.github/assets/ErisPulseLogo.png" width="180" alt="{name}" />
|
|
468
|
+
|
|
469
|
+
# {name}
|
|
470
|
+
|
|
471
|
+
**{description}**
|
|
472
|
+
|
|
473
|
+
<p>
|
|
474
|
+
<a href="https://pypi.org/project/ErisPulse-{name}/"><img src="https://img.shields.io/pypi/v/ErisPulse-{name}?style=for-the-badge&logo=pypi&logoColor=white" alt="PyPI"></a>
|
|
475
|
+
<a href="https://pypi.org/project/ErisPulse-{name}/"><img src="https://img.shields.io/badge/Python-3.10+-FFD43B?style=for-the-badge&logo=python&logoColor=blue" alt="Python"></a>
|
|
476
|
+
<a href="./LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue?style=for-the-badge" alt="License"></a>
|
|
477
|
+
<a href="https://github.com/ErisPulse/ErisPulse"><img src="https://img.shields.io/badge/Powered_by-ErisPulse-FF6B9D?style=for-the-badge&logo=bookstack&logoColor=white" alt="ErisPulse"></a>
|
|
478
|
+
</p>
|
|
479
|
+
|
|
480
|
+
</div>
|
|
481
|
+
|
|
482
|
+
---
|
|
468
483
|
|
|
469
484
|
## 安装
|
|
470
485
|
|
|
471
486
|
```bash
|
|
472
487
|
epsdk install ErisPulse-{name}
|
|
473
488
|
```
|
|
489
|
+
"""
|
|
474
490
|
|
|
475
|
-
|
|
491
|
+
_README_ADAPTER = """<div align="center">
|
|
476
492
|
|
|
477
|
-
|
|
493
|
+
<img src="https://raw.githubusercontent.com/ErisPulse/ErisPulse/main/.github/assets/ErisPulseLogo.png" width="180" alt="{name}" />
|
|
478
494
|
|
|
479
|
-
|
|
495
|
+
# {name}
|
|
480
496
|
|
|
481
|
-
|
|
497
|
+
**{description}**
|
|
482
498
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
"""
|
|
499
|
+
<p>
|
|
500
|
+
<a href="https://pypi.org/project/ErisPulse-{name}/"><img src="https://img.shields.io/pypi/v/ErisPulse-{name}?style=for-the-badge&logo=pypi&logoColor=white" alt="PyPI"></a>
|
|
501
|
+
<a href="https://pypi.org/project/ErisPulse-{name}/"><img src="https://img.shields.io/badge/Python-3.10+-FFD43B?style=for-the-badge&logo=python&logoColor=blue" alt="Python"></a>
|
|
502
|
+
<a href="./LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue?style=for-the-badge" alt="License"></a>
|
|
503
|
+
<a href="https://github.com/ErisPulse/ErisPulse"><img src="https://img.shields.io/badge/Powered_by-ErisPulse-FF6B9D?style=for-the-badge&logo=bookstack&logoColor=white" alt="ErisPulse"></a>
|
|
504
|
+
</p>
|
|
488
505
|
|
|
489
|
-
|
|
506
|
+
</div>
|
|
490
507
|
|
|
491
|
-
|
|
508
|
+
---
|
|
492
509
|
|
|
493
510
|
## 安装
|
|
494
511
|
|
|
@@ -561,6 +578,22 @@ def _validate_name(name: str) -> bool:
|
|
|
561
578
|
return all(c.isalnum() or c == "_" for c in name)
|
|
562
579
|
|
|
563
580
|
|
|
581
|
+
def _copy_erispulse_logo(project_dir: Path) -> None:
|
|
582
|
+
"""
|
|
583
|
+
将 ErisPulseLogo.png 拷贝到项目的 .github/assets/ 目录
|
|
584
|
+
|
|
585
|
+
:param project_dir: [Path] 项目根目录
|
|
586
|
+
"""
|
|
587
|
+
import shutil
|
|
588
|
+
|
|
589
|
+
logo_src = Path(__file__).parent.parent / "assets" / "ErisPulseLogo.png"
|
|
590
|
+
if not logo_src.exists():
|
|
591
|
+
return
|
|
592
|
+
dest = project_dir / ".github" / "assets" / "ErisPulseLogo.png"
|
|
593
|
+
dest.parent.mkdir(parents=True, exist_ok=True)
|
|
594
|
+
shutil.copy2(logo_src, dest)
|
|
595
|
+
|
|
596
|
+
|
|
564
597
|
def _scaffold_text(name: str) -> dict:
|
|
565
598
|
"""
|
|
566
599
|
构建当前语言的脚手架文案映射,并预填充 {name} 占位符
|
|
@@ -43,13 +43,14 @@ class DoctorCommand(Command):
|
|
|
43
43
|
|
|
44
44
|
def execute(self, args):
|
|
45
45
|
pm = self.package_manager
|
|
46
|
-
rows: list[tuple[str, str]] = []
|
|
46
|
+
rows: list[tuple[str, str, str]] = []
|
|
47
47
|
failed = False
|
|
48
48
|
|
|
49
49
|
# 1. Python 解释器
|
|
50
50
|
py_ok = sys.version_info >= (3, 10)
|
|
51
51
|
rows.append(
|
|
52
52
|
(
|
|
53
|
+
self._status(py_ok),
|
|
53
54
|
i18n.t("cli.doctor.python"),
|
|
54
55
|
f"{platform.python_version()} ({sys.executable})",
|
|
55
56
|
)
|
|
@@ -60,27 +61,43 @@ class DoctorCommand(Command):
|
|
|
60
61
|
# 2. 安装后端(uv / pip)
|
|
61
62
|
uv_cmd = pm._get_uv_command()
|
|
62
63
|
if uv_cmd:
|
|
63
|
-
rows.append(
|
|
64
|
+
rows.append(
|
|
65
|
+
(self._status(True), i18n.t("cli.doctor.backend"), f"uv ({uv_cmd[0]})")
|
|
66
|
+
)
|
|
64
67
|
else:
|
|
65
|
-
rows.append(
|
|
68
|
+
rows.append(
|
|
69
|
+
(
|
|
70
|
+
self._status(True),
|
|
71
|
+
i18n.t("cli.doctor.backend"),
|
|
72
|
+
i18n.t("cli.doctor.backend_pip"),
|
|
73
|
+
)
|
|
74
|
+
)
|
|
66
75
|
|
|
67
76
|
# 3. 目标解释器(安装目标环境)
|
|
68
77
|
target_python = pm._get_target_python()
|
|
69
|
-
rows.append(
|
|
78
|
+
rows.append(
|
|
79
|
+
(self._status(True), i18n.t("cli.doctor.target_python"), target_python)
|
|
80
|
+
)
|
|
70
81
|
|
|
71
82
|
# 4. 配置文件
|
|
72
83
|
config_path = Path("config") / "config.toml"
|
|
73
84
|
if config_path.exists():
|
|
74
85
|
rows.append(
|
|
75
|
-
(
|
|
86
|
+
(
|
|
87
|
+
self._status(True),
|
|
88
|
+
i18n.t("cli.doctor.config"),
|
|
89
|
+
str(config_path.resolve()),
|
|
90
|
+
)
|
|
76
91
|
)
|
|
77
92
|
else:
|
|
78
93
|
rows.append(
|
|
79
94
|
(
|
|
95
|
+
self._status(False),
|
|
80
96
|
i18n.t("cli.doctor.config"),
|
|
81
97
|
f"{i18n.t('cli.doctor.config_missing')} ({config_path})",
|
|
82
98
|
)
|
|
83
99
|
)
|
|
100
|
+
failed = True
|
|
84
101
|
|
|
85
102
|
# 5. PyPI 连通性
|
|
86
103
|
try:
|
|
@@ -90,21 +107,40 @@ class DoctorCommand(Command):
|
|
|
90
107
|
)
|
|
91
108
|
rows.append(
|
|
92
109
|
(
|
|
110
|
+
self._status(True),
|
|
93
111
|
i18n.t("cli.doctor.pypi"),
|
|
94
112
|
i18n.t("cli.doctor.pypi_ok", count=pkg_count),
|
|
95
113
|
)
|
|
96
114
|
)
|
|
97
115
|
except Exception:
|
|
98
116
|
failed = True
|
|
99
|
-
rows.append(
|
|
117
|
+
rows.append(
|
|
118
|
+
(
|
|
119
|
+
self._status(False),
|
|
120
|
+
i18n.t("cli.doctor.pypi"),
|
|
121
|
+
i18n.t("cli.doctor.pypi_fail"),
|
|
122
|
+
)
|
|
123
|
+
)
|
|
100
124
|
|
|
101
125
|
# 6. 代理
|
|
102
126
|
proxy = pm._get_system_proxy()
|
|
103
127
|
if proxy:
|
|
104
128
|
https_proxy = proxy.get("https") or proxy.get("http", "")
|
|
105
|
-
rows.append(
|
|
129
|
+
rows.append(
|
|
130
|
+
(
|
|
131
|
+
self._status(True),
|
|
132
|
+
i18n.t("cli.doctor.proxy"),
|
|
133
|
+
https_proxy,
|
|
134
|
+
)
|
|
135
|
+
)
|
|
106
136
|
else:
|
|
107
|
-
rows.append(
|
|
137
|
+
rows.append(
|
|
138
|
+
(
|
|
139
|
+
self._status(True),
|
|
140
|
+
i18n.t("cli.doctor.proxy"),
|
|
141
|
+
i18n.t("cli.doctor.proxy_none"),
|
|
142
|
+
)
|
|
143
|
+
)
|
|
108
144
|
|
|
109
145
|
# 输出诊断报告
|
|
110
146
|
table = Table(
|
|
@@ -113,15 +149,36 @@ class DoctorCommand(Command):
|
|
|
113
149
|
pad_edge=False,
|
|
114
150
|
expand=True,
|
|
115
151
|
)
|
|
116
|
-
for label, detail in rows:
|
|
117
|
-
table.add_row(f"[info]{label}[/]", detail)
|
|
152
|
+
for status, label, detail in rows:
|
|
153
|
+
table.add_row(status, f"[info]{label}[/]", detail)
|
|
118
154
|
|
|
119
155
|
console.print(table)
|
|
120
156
|
|
|
121
157
|
if failed:
|
|
122
158
|
console.print(f"[error]{i18n.t('cli.doctor.failed')}[/]")
|
|
159
|
+
for status, label, _ in rows:
|
|
160
|
+
if status != self._status(True):
|
|
161
|
+
console.print(
|
|
162
|
+
f" [error]-[/] [info]{label}[/]"
|
|
163
|
+
)
|
|
123
164
|
else:
|
|
124
165
|
console.print(f"[success]{i18n.t('cli.doctor.all_ok')}[/]")
|
|
125
166
|
|
|
167
|
+
@staticmethod
|
|
168
|
+
def _status(ok: bool) -> str:
|
|
169
|
+
"""
|
|
170
|
+
生成诊断项的状态标记文本(OK / FAIL,不使用 emoji)
|
|
171
|
+
|
|
172
|
+
:param ok: bool 诊断项是否正常
|
|
173
|
+
:return: str 带样式的状态标记文本
|
|
174
|
+
"""
|
|
175
|
+
from ..i18n import i18n
|
|
176
|
+
|
|
177
|
+
return (
|
|
178
|
+
f"[success]{i18n.t('cli.doctor.status_ok')}[/]"
|
|
179
|
+
if ok
|
|
180
|
+
else f"[error]{i18n.t('cli.doctor.status_fail')}[/]"
|
|
181
|
+
)
|
|
182
|
+
|
|
126
183
|
|
|
127
184
|
__all__ = ["DoctorCommand"]
|
|
@@ -121,6 +121,7 @@ class ListCommand(Command):
|
|
|
121
121
|
self._print_package_scripts(installed["modules"])
|
|
122
122
|
else:
|
|
123
123
|
console.print(f"[dim] {i18n.t('cli.list.no_modules')}[/]")
|
|
124
|
+
console.print(f"[dim] {i18n.t('cli.list.empty_hint')}[/]")
|
|
124
125
|
|
|
125
126
|
elif pkg_type == "adapters" and installed["adapters"]:
|
|
126
127
|
table = Table(
|
|
@@ -154,11 +155,13 @@ class ListCommand(Command):
|
|
|
154
155
|
)
|
|
155
156
|
else:
|
|
156
157
|
console.print(f"[dim] {i18n.t('cli.list.no_adapters')}[/]")
|
|
158
|
+
console.print(f"[dim] {i18n.t('cli.list.empty_hint')}[/]")
|
|
157
159
|
|
|
158
160
|
elif not installed.get(pkg_type, {}):
|
|
159
161
|
console.print(
|
|
160
162
|
f"[dim] {i18n.t('cli.list.no_packages', pkg_type=pkg_type)}[/]"
|
|
161
163
|
)
|
|
164
|
+
console.print(f"[dim] {i18n.t('cli.list.empty_hint')}[/]")
|
|
162
165
|
|
|
163
166
|
def _is_package_outdated(
|
|
164
167
|
self,
|
|
@@ -205,6 +205,7 @@ TRANSLATIONS = {
|
|
|
205
205
|
"cli.list.count_adapters": "{count} adapter(s)",
|
|
206
206
|
"cli.list.no_adapters": "No matching adapters",
|
|
207
207
|
"cli.list.no_packages": "No {pkg_type}",
|
|
208
|
+
"cli.list.empty_hint": "Run 'epsdk install' to browse and install components, or 'epsdk init' to create a project",
|
|
208
209
|
# ==================== list-remote command ====================
|
|
209
210
|
"cli.list_remote.description": "List remote available components",
|
|
210
211
|
"cli.list_remote.type_help": "List type (default: all)",
|
|
@@ -416,6 +417,8 @@ TRANSLATIONS = {
|
|
|
416
417
|
"cli.doctor.proxy_none": "none detected",
|
|
417
418
|
"cli.doctor.failed": "[done] Issues found, see output above",
|
|
418
419
|
"cli.doctor.all_ok": "[done] Environment is healthy",
|
|
420
|
+
"cli.doctor.status_ok": "OK",
|
|
421
|
+
"cli.doctor.status_fail": "FAIL",
|
|
419
422
|
# ==================== types command ====================
|
|
420
423
|
"cli.types.description": "Generate type stub file to enable IDE completion",
|
|
421
424
|
"cli.types.output_help": "Output file path (default: ./_ep_types.py)",
|
|
@@ -205,6 +205,7 @@ TRANSLATIONS = {
|
|
|
205
205
|
"cli.list.count_adapters": "{count} 個のアダプター",
|
|
206
206
|
"cli.list.no_adapters": "該当するアダプターはありません",
|
|
207
207
|
"cli.list.no_packages": "{pkg_type} はありません",
|
|
208
|
+
"cli.list.empty_hint": "'epsdk install' でコンポーネントを閲覧・インストールするか、'epsdk init' でプロジェクトを作成できます",
|
|
208
209
|
# ==================== list-remote コマンド ====================
|
|
209
210
|
"cli.list_remote.description": "リモートで利用可能なコンポーネントを一覧表示",
|
|
210
211
|
"cli.list_remote.type_help": "一覧タイプ (デフォルト: all)",
|
|
@@ -416,6 +417,8 @@ TRANSLATIONS = {
|
|
|
416
417
|
"cli.doctor.proxy_none": "検出されません",
|
|
417
418
|
"cli.doctor.failed": "[完了] 対応が必要な問題があります。上記を確認してください",
|
|
418
419
|
"cli.doctor.all_ok": "[完了] 環境は正常です",
|
|
420
|
+
"cli.doctor.status_ok": "OK",
|
|
421
|
+
"cli.doctor.status_fail": "NG",
|
|
419
422
|
# ==================== types コマンド ====================
|
|
420
423
|
"cli.types.description": "型スタブファイルを生成して IDE 補完を有効化",
|
|
421
424
|
"cli.types.output_help": "出力ファイルパス(デフォルト: ./_ep_types.py)",
|
|
@@ -205,6 +205,7 @@ TRANSLATIONS = {
|
|
|
205
205
|
"cli.list.count_adapters": "{count} адаптера(ов)",
|
|
206
206
|
"cli.list.no_adapters": "Нет подходящих адаптеров",
|
|
207
207
|
"cli.list.no_packages": "Нет {pkg_type}",
|
|
208
|
+
"cli.list.empty_hint": "Выполните 'epsdk install' для просмотра и установки компонентов, или 'epsdk init' для создания проекта",
|
|
208
209
|
# ==================== команда list-remote ====================
|
|
209
210
|
"cli.list_remote.description": "Список удаленно доступных компонентов",
|
|
210
211
|
"cli.list_remote.type_help": "Тип списка (по умолчанию: all)",
|
|
@@ -416,6 +417,8 @@ TRANSLATIONS = {
|
|
|
416
417
|
"cli.doctor.proxy_none": "не обнаружен",
|
|
417
418
|
"cli.doctor.failed": "[готово] Есть проблемы, см. вывод выше",
|
|
418
419
|
"cli.doctor.all_ok": "[готово] Окружение в порядке",
|
|
420
|
+
"cli.doctor.status_ok": "OK",
|
|
421
|
+
"cli.doctor.status_fail": "FAIL",
|
|
419
422
|
# ==================== команда types ====================
|
|
420
423
|
"cli.types.description": "Сгенерировать файл заглушек типов для автодополнения IDE",
|
|
421
424
|
"cli.types.output_help": "Путь вывода (по умолчанию: ./_ep_types.py)",
|
|
@@ -205,6 +205,7 @@ TRANSLATIONS = {
|
|
|
205
205
|
"cli.list.count_adapters": "{count} 个适配器",
|
|
206
206
|
"cli.list.no_adapters": "没有符合条件的适配器",
|
|
207
207
|
"cli.list.no_packages": "没有{pkg_type}",
|
|
208
|
+
"cli.list.empty_hint": "可运行 'epsdk install' 浏览并安装组件,或运行 'epsdk init' 创建项目",
|
|
208
209
|
# ==================== list-remote 命令 ====================
|
|
209
210
|
"cli.list_remote.description": "列出远程可用的组件",
|
|
210
211
|
"cli.list_remote.type_help": "列出类型 (默认: all)",
|
|
@@ -416,6 +417,8 @@ TRANSLATIONS = {
|
|
|
416
417
|
"cli.doctor.proxy_none": "未检测到",
|
|
417
418
|
"cli.doctor.failed": "[诊断完成] 存在需要处理的问题,请参考上方输出",
|
|
418
419
|
"cli.doctor.all_ok": "[诊断完成] 环境正常",
|
|
420
|
+
"cli.doctor.status_ok": "正常",
|
|
421
|
+
"cli.doctor.status_fail": "异常",
|
|
419
422
|
# ==================== types 命令 ====================
|
|
420
423
|
"cli.types.description": "生成类型存根文件,启用 IDE 补全",
|
|
421
424
|
"cli.types.output_help": "输出文件路径(默认: ./_ep_types.py)",
|
|
@@ -205,6 +205,7 @@ TRANSLATIONS = {
|
|
|
205
205
|
"cli.list.count_adapters": "{count} 個適配器",
|
|
206
206
|
"cli.list.no_adapters": "沒有符合條件的適配器",
|
|
207
207
|
"cli.list.no_packages": "沒有{pkg_type}",
|
|
208
|
+
"cli.list.empty_hint": "可執行 'epsdk install' 瀏覽並安裝元件,或執行 'epsdk init' 建立專案",
|
|
208
209
|
# ==================== list-remote 命令 ====================
|
|
209
210
|
"cli.list_remote.description": "列出遠端可用的元件",
|
|
210
211
|
"cli.list_remote.type_help": "列出型別 (預設: all)",
|
|
@@ -416,6 +417,8 @@ TRANSLATIONS = {
|
|
|
416
417
|
"cli.doctor.proxy_none": "未偵測到",
|
|
417
418
|
"cli.doctor.failed": "[診斷完成] 存在需要處理的問題,請參考上方輸出",
|
|
418
419
|
"cli.doctor.all_ok": "[診斷完成] 環境正常",
|
|
420
|
+
"cli.doctor.status_ok": "正常",
|
|
421
|
+
"cli.doctor.status_fail": "異常",
|
|
419
422
|
# ==================== types 命令 ====================
|
|
420
423
|
"cli.types.description": "生成類型存根檔案,啟用 IDE 補全",
|
|
421
424
|
"cli.types.output_help": "輸出檔案路徑(預設: ./_ep_types.py)",
|
|
@@ -9,6 +9,7 @@ from collections.abc import Callable
|
|
|
9
9
|
from typing import Any
|
|
10
10
|
|
|
11
11
|
from rich.box import SIMPLE
|
|
12
|
+
from rich.markup import escape
|
|
12
13
|
from rich.prompt import Prompt
|
|
13
14
|
from rich.table import Table
|
|
14
15
|
from rich.text import Text
|
|
@@ -45,7 +46,9 @@ def _input(prompt_label: str = ">") -> str:
|
|
|
45
46
|
:param prompt_label: [str] 提示标签 (默认: ">")
|
|
46
47
|
:return: [str] 用户输入内容(已去除首尾空白)
|
|
47
48
|
"""
|
|
48
|
-
|
|
49
|
+
# 转义富文本标记
|
|
50
|
+
escaped = escape(prompt_label)
|
|
51
|
+
console.print(f" [dim]{escaped}[/] ", end="")
|
|
49
52
|
try:
|
|
50
53
|
return input().strip()
|
|
51
54
|
except (EOFError, KeyboardInterrupt):
|
|
@@ -424,6 +424,58 @@ def dict_to_dataclass(config_class: type, data: dict):
|
|
|
424
424
|
return config_class(**kwargs)
|
|
425
425
|
|
|
426
426
|
|
|
427
|
+
def _notify_instance_config_update(
|
|
428
|
+
instance: Any,
|
|
429
|
+
old_dict: dict | None,
|
|
430
|
+
new_dict: dict | None,
|
|
431
|
+
*,
|
|
432
|
+
i18n_key: str,
|
|
433
|
+
log_params: dict,
|
|
434
|
+
) -> None:
|
|
435
|
+
"""
|
|
436
|
+
调用实例的 ``on_config_update`` 回调,传入类型安全的配置对象
|
|
437
|
+
|
|
438
|
+
若实例声明了 ``ConfigClass``,则将字典通过 :func:`dict_to_dataclass`
|
|
439
|
+
转换为 dataclass 实例;否则原样传入字典。回调中抛出的异常会被捕获
|
|
440
|
+
并按指定的 i18n 键记录日志,不会向上传播。
|
|
441
|
+
|
|
442
|
+
供 ``ModuleManager`` 与 ``AdapterManager`` 的配置热更新路由共用,
|
|
443
|
+
避免在两处重复实现字典→dataclass 转换 + 异常兜底逻辑。
|
|
444
|
+
|
|
445
|
+
{!--< internal-use >!--}
|
|
446
|
+
{!--< /internal-use >!--}
|
|
447
|
+
|
|
448
|
+
:param instance: 模块/适配器实例(需实现 ``on_config_update``)
|
|
449
|
+
:param old_dict: 变更前的配置字典(可能为 None)
|
|
450
|
+
:param new_dict: 变更后的配置字典(可能为 None)
|
|
451
|
+
:param i18n_key: 回调异常日志的 i18n 键(如 ``core.module.config_update_failed``)
|
|
452
|
+
:param log_params: 异常日志的额外格式化参数(如 ``{"name": "MyModule"}``)
|
|
453
|
+
"""
|
|
454
|
+
config_class = getattr(instance, "ConfigClass", None)
|
|
455
|
+
try:
|
|
456
|
+
if config_class is not None:
|
|
457
|
+
old_config = (
|
|
458
|
+
dict_to_dataclass(config_class, old_dict) if old_dict else None
|
|
459
|
+
)
|
|
460
|
+
new_config = (
|
|
461
|
+
dict_to_dataclass(config_class, new_dict) if new_dict else None
|
|
462
|
+
)
|
|
463
|
+
else:
|
|
464
|
+
old_config = old_dict
|
|
465
|
+
new_config = new_dict
|
|
466
|
+
instance.on_config_update(old_config, new_config)
|
|
467
|
+
except Exception as e:
|
|
468
|
+
try:
|
|
469
|
+
from ErisPulse.Core.i18n import i18n
|
|
470
|
+
from ErisPulse.Core.logger import logger
|
|
471
|
+
|
|
472
|
+
params = dict(log_params)
|
|
473
|
+
params["error"] = e
|
|
474
|
+
logger.error(i18n.t(i18n_key, **params))
|
|
475
|
+
except Exception:
|
|
476
|
+
pass
|
|
477
|
+
|
|
478
|
+
|
|
427
479
|
def validate_config(instance) -> list[str]:
|
|
428
480
|
"""
|
|
429
481
|
校验 dataclass 实例
|
|
@@ -59,7 +59,15 @@ async def _invoke_handler(handler_info: dict, event: Event) -> None:
|
|
|
59
59
|
else:
|
|
60
60
|
handler(event)
|
|
61
61
|
except Exception as e:
|
|
62
|
-
logger.error(
|
|
62
|
+
logger.error(
|
|
63
|
+
i18n.t(
|
|
64
|
+
"core.event.handler_error",
|
|
65
|
+
handler=_hname,
|
|
66
|
+
type=event.get("type", "") if isinstance(event, dict) else "",
|
|
67
|
+
owner=_owner or "<unknown>",
|
|
68
|
+
error=e,
|
|
69
|
+
)
|
|
70
|
+
)
|
|
63
71
|
return
|
|
64
72
|
finally:
|
|
65
73
|
_elapsed = _time.monotonic() - _t
|
|
@@ -1576,8 +1576,8 @@ class Event(dict):
|
|
|
1576
1576
|
future.set_result(raw)
|
|
1577
1577
|
except asyncio.InvalidStateError:
|
|
1578
1578
|
pass
|
|
1579
|
-
except Exception:
|
|
1580
|
-
|
|
1579
|
+
except Exception as _e:
|
|
1580
|
+
logger.trace(f"[Event] onebot wait handler 异常: {_e}")
|
|
1581
1581
|
|
|
1582
1582
|
handler_wrapper = {"func": _temp_handler, "platform": None}
|
|
1583
1583
|
adapter._onebot_handlers[event_type].append(handler_wrapper)
|
|
@@ -1919,7 +1919,8 @@ class Conversation:
|
|
|
1919
1919
|
try:
|
|
1920
1920
|
if not cond(self.context):
|
|
1921
1921
|
continue
|
|
1922
|
-
except Exception:
|
|
1922
|
+
except Exception as _e:
|
|
1923
|
+
logger.trace(f"[Conversation] 字段 condition 执行异常,跳过: {_e}")
|
|
1923
1924
|
continue
|
|
1924
1925
|
filtered_fields.append(f)
|
|
1925
1926
|
|
|
@@ -2115,8 +2116,8 @@ class Conversation:
|
|
|
2115
2116
|
if event:
|
|
2116
2117
|
self._event = event
|
|
2117
2118
|
return True
|
|
2118
|
-
except Exception:
|
|
2119
|
-
|
|
2119
|
+
except Exception as _e:
|
|
2120
|
+
logger.trace(f"[Conversation] resume 失败: {_e}")
|
|
2120
2121
|
return False
|
|
2121
2122
|
|
|
2122
2123
|
async def clear_saved(self):
|
|
@@ -2133,8 +2134,8 @@ class Conversation:
|
|
|
2133
2134
|
platform = self._event.get_platform()
|
|
2134
2135
|
key = f"{CONVERSATION_KEY_PREFIX}:{platform}:{user_id}"
|
|
2135
2136
|
storage.delete(key)
|
|
2136
|
-
except Exception:
|
|
2137
|
-
|
|
2137
|
+
except Exception as _e:
|
|
2138
|
+
logger.trace(f"[Conversation] clear_saved 失败: {_e}")
|
|
2138
2139
|
|
|
2139
2140
|
|
|
2140
2141
|
__all__ = [
|
|
@@ -235,29 +235,15 @@ class AdapterManager(ManagerBase):
|
|
|
235
235
|
{!--< internal-use >!--}
|
|
236
236
|
调用适配器的 on_config_update 回调,传入类型安全的配置对象
|
|
237
237
|
"""
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
dict_to_dataclass(config_class, new_dict) if new_dict else None
|
|
248
|
-
)
|
|
249
|
-
else:
|
|
250
|
-
old_config = old_dict
|
|
251
|
-
new_config = new_dict
|
|
252
|
-
instance.on_config_update(old_config, new_config)
|
|
253
|
-
except Exception as e:
|
|
254
|
-
logger.error(
|
|
255
|
-
i18n.t(
|
|
256
|
-
"core.adapter.config_update_failed",
|
|
257
|
-
platform=platform or instance.__class__.__name__,
|
|
258
|
-
error=e,
|
|
259
|
-
)
|
|
260
|
-
)
|
|
238
|
+
from ..Core.Bases.config_schema import _notify_instance_config_update
|
|
239
|
+
|
|
240
|
+
_notify_instance_config_update(
|
|
241
|
+
instance,
|
|
242
|
+
old_dict,
|
|
243
|
+
new_dict,
|
|
244
|
+
i18n_key="core.adapter.config_update_failed",
|
|
245
|
+
log_params={"platform": platform or instance.__class__.__name__},
|
|
246
|
+
)
|
|
261
247
|
|
|
262
248
|
# ==================== 适配器注册与管理 ====================
|
|
263
249
|
|
|
@@ -1066,7 +1052,9 @@ class AdapterManager(ManagerBase):
|
|
|
1066
1052
|
logger.error(i18n.t("core.adapter.platform_not_exist", platform=platform))
|
|
1067
1053
|
return False
|
|
1068
1054
|
|
|
1069
|
-
config.setConfig(
|
|
1055
|
+
config.setConfig(
|
|
1056
|
+
CONFIG_KEY_ADAPTER_STATUS_OF.format(platform), True, immediate=True
|
|
1057
|
+
)
|
|
1070
1058
|
logger.info(i18n.t("core.adapter.platform_enabled", platform=platform))
|
|
1071
1059
|
return True
|
|
1072
1060
|
|
|
@@ -1089,7 +1077,9 @@ class AdapterManager(ManagerBase):
|
|
|
1089
1077
|
logger.error(i18n.t("core.adapter.platform_not_exist", platform=platform))
|
|
1090
1078
|
return False
|
|
1091
1079
|
|
|
1092
|
-
config.setConfig(
|
|
1080
|
+
config.setConfig(
|
|
1081
|
+
CONFIG_KEY_ADAPTER_STATUS_OF.format(platform), False, immediate=True
|
|
1082
|
+
)
|
|
1093
1083
|
logger.info(i18n.t("core.adapter.platform_disabled", platform=platform))
|
|
1094
1084
|
return True
|
|
1095
1085
|
|
|
@@ -1528,18 +1518,28 @@ class AdapterManager(ManagerBase):
|
|
|
1528
1518
|
# 调用过 wait_reply:纯等待属于交互白名单
|
|
1529
1519
|
if _pure > HANDLER_SLOW_THRESHOLD_SECS:
|
|
1530
1520
|
logger.warning(
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1521
|
+
i18n.t(
|
|
1522
|
+
"core.adapter.handler_slow",
|
|
1523
|
+
handler=_func_name,
|
|
1524
|
+
elapsed=f"{elapsed:.2f}",
|
|
1525
|
+
threshold=HANDLER_SLOW_THRESHOLD_SECS,
|
|
1526
|
+
type=event_type,
|
|
1527
|
+
platform=platform,
|
|
1528
|
+
tag=_owner_tag,
|
|
1529
|
+
)
|
|
1536
1530
|
)
|
|
1537
1531
|
else:
|
|
1538
1532
|
logger.trace(
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1533
|
+
i18n.t(
|
|
1534
|
+
"core.adapter.handler_slow_trace",
|
|
1535
|
+
handler=_func_name,
|
|
1536
|
+
elapsed=f"{elapsed:.2f}",
|
|
1537
|
+
wait=f"{_wait_total:.2f}",
|
|
1538
|
+
pure=f"{_pure:.2f}",
|
|
1539
|
+
type=event_type,
|
|
1540
|
+
platform=platform,
|
|
1541
|
+
tag=_owner_tag,
|
|
1542
|
+
)
|
|
1543
1543
|
)
|
|
1544
1544
|
elif elapsed > HANDLER_SLOW_THRESHOLD_SECS:
|
|
1545
1545
|
logger.warning(
|