nonebot-plugin-lingchu-bot 0.7.0.dev1__tar.gz → 0.8.0.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.
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/PKG-INFO +2 -3
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/README.md +1 -1
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/pyproject.toml +20 -13
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/pyproject.toml.orig +30 -11
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/__init__.py +4 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/core/config.py +15 -1
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/database/orm_crud/_base.py +60 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/database/orm_crud/_bulk.py +24 -0
- nonebot_plugin_lingchu_bot-0.8.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/database/schema_guard.py +155 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/menu.py +4 -45
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/adapters/onebot11/default/block.py +27 -9
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/adapters/onebot11/default/common.py +78 -12
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/adapters/onebot11/default/kick.py +0 -24
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/adapters/onebot11/default/lifecycle.py +36 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/adapters/onebot11/default/mute.py +537 -3
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/adapters/onebot11/default/remote.py +16 -27
- nonebot_plugin_lingchu_bot-0.8.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/adapters/onebot11/llbot/__init__.py +10 -0
- nonebot_plugin_lingchu_bot-0.8.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/adapters/onebot11/llbot/mute_list.py +95 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/commands/announcement.py +1 -1
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/commands/block.py +6 -6
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/commands/bot_state.py +4 -4
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/commands/handle_defaults.py +1 -1
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/commands/kick.py +1 -1
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/commands/lifecycle.py +14 -3
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/commands/member.py +4 -4
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/commands/mute.py +30 -6
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/commands/profile.py +2 -2
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/commands/protect.py +4 -4
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/commands/remote.py +9 -9
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/commands/triggers.py +33 -0
- nonebot_plugin_lingchu_bot-0.8.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/i18n/locales/en_US/LC_MESSAGES/messages.mo +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/i18n/locales/en_US/LC_MESSAGES/messages.po +255 -177
- nonebot_plugin_lingchu_bot-0.8.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/i18n/locales/zh_CN/LC_MESSAGES/messages.mo +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/i18n/locales/zh_CN/LC_MESSAGES/messages.po +247 -175
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/i18n/messages.pot +190 -169
- nonebot_plugin_lingchu_bot-0.7.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/migrations/a1b2c3d4e5f6_permissions_schema.py → nonebot_plugin_lingchu_bot-0.8.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/migrations/1a2b3c4d5e6f_permissions_schema.py +2 -2
- nonebot_plugin_lingchu_bot-0.7.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/migrations/b7c8d9e0f1a2_event_policy_partitions.py → nonebot_plugin_lingchu_bot-0.8.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/migrations/2b3c4d5e6f7a_event_policy_partitions.py +4 -4
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/migrations/c3d4e5f6a7b8_scheduler_jobs.py +2 -2
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/permissions/service.py +3 -3
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/platforms/__init__.py +0 -2
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/platforms/registry.py +0 -22
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/repositories/blocklist.py +6 -1
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/repositories/message_store.py +56 -0
- nonebot_plugin_lingchu_bot-0.8.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/restart_worker.py +156 -0
- nonebot_plugin_lingchu_bot-0.8.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/services/restart_app.py +315 -0
- nonebot_plugin_lingchu_bot-0.8.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/services/webui/__init__.py +81 -0
- nonebot_plugin_lingchu_bot-0.8.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/services/webui/info.py +184 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/start/startup.py +24 -0
- nonebot_plugin_lingchu_bot-0.7.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/handle/telegram/__init__.py +0 -1
- nonebot_plugin_lingchu_bot-0.7.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/handle/telegram/adapters/__init__.py +0 -1
- nonebot_plugin_lingchu_bot-0.7.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/handle/telegram/adapters/default/__init__.py +0 -8
- nonebot_plugin_lingchu_bot-0.7.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/handle/telegram/adapters/default/bot_state.py +0 -91
- nonebot_plugin_lingchu_bot-0.7.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/handle/telegram/adapters/default/menu.py +0 -85
- nonebot_plugin_lingchu_bot-0.7.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/handle/telegram/adapters/default/moderation.py +0 -493
- nonebot_plugin_lingchu_bot-0.7.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/handle/telegram/adapters/default/mute.py +0 -157
- nonebot_plugin_lingchu_bot-0.7.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/handle/telegram/adapters/default/recall.py +0 -48
- nonebot_plugin_lingchu_bot-0.7.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/i18n/locales/en_US/LC_MESSAGES/messages.mo +0 -0
- nonebot_plugin_lingchu_bot-0.7.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/i18n/locales/zh_CN/LC_MESSAGES/messages.mo +0 -0
- nonebot_plugin_lingchu_bot-0.7.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/platforms/telegram/__init__.py +0 -1
- nonebot_plugin_lingchu_bot-0.7.0.dev1/src/plugins/nonebot_plugin_lingchu_bot/platforms/telegram/permissions.py +0 -76
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/CLA.md +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/LICENSE-apache +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/LICENSE-cc-by-sa +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/LICENSE-cc0 +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/LICENSE-code +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/LICENSE-docs +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/LICENSE-mit +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/Repository-Policy.md +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/_lingchu_bot_contracts/__init__.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/_lingchu_bot_contracts/runtime_settings.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/core/async_utils.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/core/bot_state.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/core/handle_config_defaults/__init__.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/core/handle_config_manager.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/core/handle_default_values.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/core/http_security.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/core/menu_config.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/core/mutable_settings.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/core/runtime_config.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/database/_dialect_compat.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/database/models/__init__.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/database/models/blocklist.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/database/models/identity.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/database/models/message.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/database/models/registry.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/database/models/scheduler.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/database/models/subject_policy.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/database/orm_crud/__init__.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/database/orm_crud/_single.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/database/persistence/__init__.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/database/persistence/atomic.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/database/persistence/checksum.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/database/persistence/journal.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/database/persistence/recovery.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/database/persistence/versioning.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/database/sqlite_pragmas.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/database/toml_store/__init__.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/database/toml_store/_helpers.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/database/toml_store/_sync.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/database/toml_store/exceptions.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/__init__.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/adapters/__init__.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/adapters/onebot11/__init__.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/adapters/onebot11/default/__init__.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/adapters/onebot11/default/announcement.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/adapters/onebot11/default/bot_state.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/adapters/onebot11/default/handle_defaults.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/adapters/onebot11/default/member.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/adapters/onebot11/default/menu.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/adapters/onebot11/default/profile.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/adapters/onebot11/default/protect.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/adapters/onebot11/default/protect_notice.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/adapters/onebot11/napcat/__init__.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/adapters/onebot11/napcat/announcement.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/adapters/onebot11/napcat/profile.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/commands/__init__.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/handle/qq/commands/common.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/hooks/__init__.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/hooks/adapters.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/hooks/handlers/__init__.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/hooks/handlers/api_audit.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/hooks/handlers/bot_connection.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/hooks/handlers/lifecycle.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/hooks/handlers/message_store.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/hooks/interfaces.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/i18n/__init__.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/i18n/babel.cfg +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/migrations/30f5a01259cd_initial_schema.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/migrations/cf2c06d51a17_blocklist_unique_constraint.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/migrations/d7e8f9a0b1c2_identity_integrity.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/migrations/f6a7b8c9d0e1_message_protocol_default.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/migrations/g7b8c9d0e1f2_protocol_id_not_null.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/permissions/__init__.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/permissions/admin.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/permissions/bootstrap.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/permissions/config.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/permissions/platforms.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/permissions/subject_policy.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/permissions/types.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/platforms/qq/__init__.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/platforms/qq/permissions.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/repositories/__init__.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/repositories/permissions.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/repositories/registry.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/repositories/scheduler_jobs.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/services/message_store.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/services/protocol_restart_feedback.py +0 -0
- {nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/src/plugins/nonebot_plugin_lingchu_bot/services/scheduler.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nonebot-plugin-lingchu-bot
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.0.dev1
|
|
4
4
|
Summary: 由NoneBot2驱动,面向多平台的管理机器人
|
|
5
5
|
Keywords: nonebot2,nonebot,bot,cross-platform,group-management
|
|
6
6
|
Author: xinvxueyuan
|
|
@@ -36,7 +36,6 @@ Requires-Dist: aiofiles>=25.1.0
|
|
|
36
36
|
Requires-Dist: babel>=2.18.0
|
|
37
37
|
Requires-Dist: rtoml>=0.13.0
|
|
38
38
|
Requires-Dist: packaging>=26.2
|
|
39
|
-
Requires-Dist: nonebot-adapter-telegram>=0.1.0b20
|
|
40
39
|
Requires-Dist: nonebot-plugin-docs>=2.5.0 ; extra == 'docs'
|
|
41
40
|
Requires-Dist: nonebot-plugin-htmlkit>=0.1.0rc5 ; extra == 'webui'
|
|
42
41
|
Requires-Dist: jinja2>=3.1.6 ; extra == 'webui'
|
|
@@ -100,7 +99,7 @@ Useful entry points:
|
|
|
100
99
|
| Capability | Description |
|
|
101
100
|
| --- | --- |
|
|
102
101
|
| Member moderation | Mute, unmute, kick, block, unblock, clear blocklist, protect, and unprotect. |
|
|
103
|
-
| Speech management | Member mute/unmute, whole-group mute/unmute, and recent message recall. |
|
|
102
|
+
| Speech management | Member mute/unmute, whole-group mute/unmute, bulk unmute of all muted members and a muted-member list when the protocol implementation supports it, and recent message recall. |
|
|
104
103
|
| Group operations | Set group name, set group avatar when supported, set member card/title/admin, send announcements when supported, and leave the current group. |
|
|
105
104
|
| Remote management | Operate on another group by group ID or fuzzy group name matching, including remote mute/unmute, whole-group mute/unmute, kick, block/unblock, and announcement. |
|
|
106
105
|
| Bot control | `silence` / `speak` suppress or resume response messages while still allowing commands to execute; `boot` / `shutdown` enable or disable command handlers. |
|
|
@@ -47,7 +47,7 @@ Useful entry points:
|
|
|
47
47
|
| Capability | Description |
|
|
48
48
|
| --- | --- |
|
|
49
49
|
| Member moderation | Mute, unmute, kick, block, unblock, clear blocklist, protect, and unprotect. |
|
|
50
|
-
| Speech management | Member mute/unmute, whole-group mute/unmute, and recent message recall. |
|
|
50
|
+
| Speech management | Member mute/unmute, whole-group mute/unmute, bulk unmute of all muted members and a muted-member list when the protocol implementation supports it, and recent message recall. |
|
|
51
51
|
| Group operations | Set group name, set group avatar when supported, set member card/title/admin, send announcements when supported, and leave the current group. |
|
|
52
52
|
| Remote management | Operate on another group by group ID or fuzzy group name matching, including remote mute/unmute, whole-group mute/unmute, kick, block/unblock, and announcement. |
|
|
53
53
|
| Bot control | `silence` / `speak` suppress or resume response messages while still allowing commands to execute; `boot` / `shutdown` enable or disable command handlers. |
|
{nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/pyproject.toml
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "nonebot-plugin-lingchu-bot"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.8.0.dev1"
|
|
4
4
|
description = "由NoneBot2驱动,面向多平台的管理机器人"
|
|
5
5
|
keywords = [
|
|
6
6
|
"nonebot2",
|
|
@@ -47,7 +47,6 @@ dependencies = [
|
|
|
47
47
|
"babel>=2.18.0",
|
|
48
48
|
"rtoml>=0.13.0",
|
|
49
49
|
"packaging>=26.2",
|
|
50
|
-
"nonebot-adapter-telegram>=0.1.0b20",
|
|
51
50
|
]
|
|
52
51
|
|
|
53
52
|
[[project.authors]]
|
|
@@ -91,10 +90,6 @@ plugin_dirs = ["src/plugins"]
|
|
|
91
90
|
name = "OneBot V11"
|
|
92
91
|
module_name = "nonebot.adapters.onebot.v11"
|
|
93
92
|
|
|
94
|
-
[[tool.nonebot.adapters.nonebot-adapter-telegram]]
|
|
95
|
-
name = "Telegram"
|
|
96
|
-
module_name = "nonebot.adapters.telegram"
|
|
97
|
-
|
|
98
93
|
[tool.nonebot.plugins]
|
|
99
94
|
nonebot-plugin-apscheduler = ["nonebot_plugin_apscheduler"]
|
|
100
95
|
nonebot-plugin-localstore = ["nonebot_plugin_localstore"]
|
|
@@ -239,6 +234,8 @@ allowed-confusables = [
|
|
|
239
234
|
"E501",
|
|
240
235
|
"F541",
|
|
241
236
|
"TRY003",
|
|
237
|
+
"PLR0911",
|
|
238
|
+
"PLR0912",
|
|
242
239
|
]
|
|
243
240
|
"src/plugins/nonebot_plugin_lingchu_bot/handle/**/adapters/onebot11/default/**.py" = [
|
|
244
241
|
"E402",
|
|
@@ -248,13 +245,6 @@ allowed-confusables = [
|
|
|
248
245
|
"TC001",
|
|
249
246
|
"TC002",
|
|
250
247
|
]
|
|
251
|
-
"src/plugins/nonebot_plugin_lingchu_bot/handle/telegram/adapters/default/**.py" = [
|
|
252
|
-
"E402",
|
|
253
|
-
"PLR0913",
|
|
254
|
-
"PLR0917",
|
|
255
|
-
"TC001",
|
|
256
|
-
"TC002",
|
|
257
|
-
]
|
|
258
248
|
"src/plugins/nonebot_plugin_lingchu_bot/hooks/handlers/message_store.py" = [
|
|
259
249
|
"TC002",
|
|
260
250
|
"BLE001",
|
|
@@ -319,6 +309,7 @@ allowed-confusables = [
|
|
|
319
309
|
"TRY003",
|
|
320
310
|
"E402",
|
|
321
311
|
]
|
|
312
|
+
"src/plugins/nonebot_plugin_lingchu_bot/database/schema_guard.py" = ["E402"]
|
|
322
313
|
"src/plugins/nonebot_plugin_lingchu_bot/database/toml_store/_helpers.py" = ["TRY003"]
|
|
323
314
|
"src/plugins/nonebot_plugin_lingchu_bot/core/bot_state.py" = [
|
|
324
315
|
"BLE001",
|
|
@@ -326,6 +317,17 @@ allowed-confusables = [
|
|
|
326
317
|
"TC003",
|
|
327
318
|
]
|
|
328
319
|
"src/plugins/nonebot_plugin_lingchu_bot/services/protocol_restart_feedback.py" = ["BLE001"]
|
|
320
|
+
"src/plugins/nonebot_plugin_lingchu_bot/services/restart_app.py" = [
|
|
321
|
+
"BLE001",
|
|
322
|
+
"C901",
|
|
323
|
+
"PLR0911",
|
|
324
|
+
"PLR0913",
|
|
325
|
+
"TC002",
|
|
326
|
+
]
|
|
327
|
+
"src/plugins/nonebot_plugin_lingchu_bot/restart_worker.py" = [
|
|
328
|
+
"T201",
|
|
329
|
+
"TRY003",
|
|
330
|
+
]
|
|
329
331
|
"src/plugins/nonebot_plugin_lingchu_bot/start/startup.py" = [
|
|
330
332
|
"BLE001",
|
|
331
333
|
"E402",
|
|
@@ -369,6 +371,11 @@ allowed-confusables = [
|
|
|
369
371
|
"TRY003",
|
|
370
372
|
"PLR0913",
|
|
371
373
|
]
|
|
374
|
+
"src/plugins/nonebot_plugin_lingchu_bot/services/webui/**.py" = [
|
|
375
|
+
"TC002",
|
|
376
|
+
"BLE001",
|
|
377
|
+
"PLR2004",
|
|
378
|
+
]
|
|
372
379
|
"src/plugins/nonebot_plugin_lingchu_bot/database/orm_crud/_single.py" = [
|
|
373
380
|
"E402",
|
|
374
381
|
"TRY003",
|
{nonebot_plugin_lingchu_bot-0.7.0.dev1 → nonebot_plugin_lingchu_bot-0.8.0.dev1}/pyproject.toml.orig
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "nonebot-plugin-lingchu-bot"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.8.0.dev1"
|
|
4
4
|
# dynamic = ["version"]
|
|
5
5
|
description = "由NoneBot2驱动,面向多平台的管理机器人"
|
|
6
6
|
keywords = ["nonebot2", "nonebot", "bot", "cross-platform", "group-management"]
|
|
@@ -44,7 +44,6 @@ dependencies = [
|
|
|
44
44
|
"babel>=2.18.0",
|
|
45
45
|
"rtoml>=0.13.0",
|
|
46
46
|
"packaging>=26.2",
|
|
47
|
-
"nonebot-adapter-telegram>=0.1.0b20",
|
|
48
47
|
]
|
|
49
48
|
|
|
50
49
|
[project.optional-dependencies]
|
|
@@ -114,7 +113,6 @@ nonebot-adapter-onebot = [
|
|
|
114
113
|
{ name = "OneBot V11", module_name = "nonebot.adapters.onebot.v11" },
|
|
115
114
|
]
|
|
116
115
|
"@local" = []
|
|
117
|
-
nonebot-adapter-telegram = [{name = "Telegram", module_name = "nonebot.adapters.telegram"}]
|
|
118
116
|
|
|
119
117
|
[tool.nonebot.plugins]
|
|
120
118
|
nonebot-plugin-apscheduler = ["nonebot_plugin_apscheduler"]
|
|
@@ -260,6 +258,11 @@ allowed-confusables = [
|
|
|
260
258
|
"E501", # line-too-long
|
|
261
259
|
"F541", # f-string-without-placeholders
|
|
262
260
|
"TRY003", # raise-vanilla-args: CI scripts use SystemExit with inline messages
|
|
261
|
+
# ci_version_bump_args.py: the uv-semantics decision table is inherently a
|
|
262
|
+
# branch matrix (stable/pre/dev/alpha/beta/rc x level x prerelease); each
|
|
263
|
+
# branch is a single return, so the return/branch counts are structural.
|
|
264
|
+
"PLR0911", # too-many-return-statements
|
|
265
|
+
"PLR0912", # too-many-branches
|
|
263
266
|
]
|
|
264
267
|
# handle handlers may have complex logic with many return paths and NoneBot-mandated parameters
|
|
265
268
|
# E402: nonebot2 require() must precede cross-plugin imports at module level
|
|
@@ -271,14 +274,6 @@ allowed-confusables = [
|
|
|
271
274
|
"TC001", # typing-only-first-party-import (NoneBot evaluates type hints at runtime)
|
|
272
275
|
"TC002", # typing-only-third-party-import (Bot/Event imports needed by get_type_hints())
|
|
273
276
|
]
|
|
274
|
-
# Telegram handlers use the same NoneBot runtime annotation and DI contract.
|
|
275
|
-
"src/plugins/nonebot_plugin_lingchu_bot/handle/telegram/adapters/default/**.py" = [
|
|
276
|
-
"E402", # module-import-not-at-top-of-file (nonebot2 require() pattern)
|
|
277
|
-
"PLR0913", # too-many-arguments (NoneBot handler + Telegram API signatures)
|
|
278
|
-
"PLR0917", # too-many-positional-arguments (NoneBot DI injection contract)
|
|
279
|
-
"TC001", # typing-only-first-party-import (NoneBot evaluates annotations)
|
|
280
|
-
"TC002", # typing-only-third-party-import (NoneBot evaluates annotations)
|
|
281
|
-
]
|
|
282
277
|
# TC001/TC002/TC003: NoneBot evaluates forward references at hook registration time;
|
|
283
278
|
# these runtime imports must not be hidden behind TYPE_CHECKING.
|
|
284
279
|
# Additionally, with future-annotations = true in ruff config, TC rules suggest moving
|
|
@@ -332,12 +327,28 @@ allowed-confusables = [
|
|
|
332
327
|
"src/plugins/nonebot_plugin_lingchu_bot/core/handle_config_manager.py" = ["TRY003", "BLE001", "E402"]
|
|
333
328
|
"src/plugins/nonebot_plugin_lingchu_bot/core/handle_config_defaults/__init__.py" = ["TRY003", "E402"]
|
|
334
329
|
"src/plugins/nonebot_plugin_lingchu_bot/database/orm_crud/_base.py" = ["TRY003", "E402"]
|
|
330
|
+
# E402: nonebot2 require() must precede cross-plugin imports at module level
|
|
331
|
+
"src/plugins/nonebot_plugin_lingchu_bot/database/schema_guard.py" = ["E402"]
|
|
335
332
|
"src/plugins/nonebot_plugin_lingchu_bot/database/toml_store/_helpers.py" = ["TRY003"]
|
|
336
333
|
|
|
337
334
|
# BLE001: startup/probe code uses intentional fail-closed/fail-soft exception handling
|
|
338
335
|
# E402: nonebot2 require() must precede cross-plugin imports at module level
|
|
339
336
|
"src/plugins/nonebot_plugin_lingchu_bot/core/bot_state.py" = ["BLE001", "E402", "TC003"]
|
|
340
337
|
"src/plugins/nonebot_plugin_lingchu_bot/services/protocol_restart_feedback.py" = ["BLE001"]
|
|
338
|
+
# BLE001: fail-soft notification/send paths must never break event dispatch.
|
|
339
|
+
# C901/PLR0911: adapter event type dispatch branches per platform event class.
|
|
340
|
+
# PLR0913: register_pending_restart_app signature is a cross-task contract.
|
|
341
|
+
# TC002: NoneBot inspects Bot/Event handler annotations at runtime via get_type_hints().
|
|
342
|
+
"src/plugins/nonebot_plugin_lingchu_bot/services/restart_app.py" = [
|
|
343
|
+
"BLE001",
|
|
344
|
+
"C901",
|
|
345
|
+
"PLR0911",
|
|
346
|
+
"PLR0913",
|
|
347
|
+
"TC002",
|
|
348
|
+
]
|
|
349
|
+
# T201: standalone restart worker script prints diagnostics to stderr.
|
|
350
|
+
# TRY003: vanilla raise messages are intentional for a self-contained script.
|
|
351
|
+
"src/plugins/nonebot_plugin_lingchu_bot/restart_worker.py" = ["T201", "TRY003"]
|
|
341
352
|
# E402: nonebot2 require() must precede cross-plugin imports at module level
|
|
342
353
|
"src/plugins/nonebot_plugin_lingchu_bot/start/startup.py" = ["BLE001", "E402"]
|
|
343
354
|
"src/plugins/nonebot_plugin_lingchu_bot/platforms/qq/permissions.py" = ["BLE001"]
|
|
@@ -383,6 +394,14 @@ allowed-confusables = [
|
|
|
383
394
|
"TRY003", # vanilla exceptions for CRUD validation
|
|
384
395
|
"PLR0913", # parameter-heavy generic CRUD functions
|
|
385
396
|
]
|
|
397
|
+
# TC002: Starlette Request is evaluated at runtime in endpoint annotations.
|
|
398
|
+
# BLE001: fail-soft upstream/JSON handling must never break request dispatch.
|
|
399
|
+
# PLR2004: QQ id length bounds (4-15) are domain constants kept inline.
|
|
400
|
+
"src/plugins/nonebot_plugin_lingchu_bot/services/webui/**.py" = [
|
|
401
|
+
"TC002",
|
|
402
|
+
"BLE001",
|
|
403
|
+
"PLR2004",
|
|
404
|
+
]
|
|
386
405
|
"src/plugins/nonebot_plugin_lingchu_bot/database/orm_crud/_single.py" = [
|
|
387
406
|
"E402", # module-import-not-at-top-of-file (nonebot2 require() pattern)
|
|
388
407
|
"TRY003", # vanilla exceptions for CRUD validation
|
|
@@ -60,6 +60,10 @@ from .start.startup import startup as startup
|
|
|
60
60
|
# services.message_store and start.startup.
|
|
61
61
|
from . import hooks as hooks
|
|
62
62
|
|
|
63
|
+
# WebUI 动态运行时端点(只读 + 登录密码校验,无登录/JWT/令牌功能)。
|
|
64
|
+
# 导入即触发 on_startup 挂载逻辑。
|
|
65
|
+
from .services import webui as webui
|
|
66
|
+
|
|
63
67
|
# zhenxun 等宿主环境同时注册 150+ 插件的 Alconna 命令,默认上限 200 会被突破。
|
|
64
68
|
# 在 lingchu 自身命令注册前抬高全局上限,避免 ExceedMaxCount。
|
|
65
69
|
from arclet.alconna.config import config as _alconna_config
|
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from collections.abc import Mapping
|
|
6
6
|
from dataclasses import dataclass, field, fields
|
|
7
|
+
import os
|
|
7
8
|
from pathlib import Path
|
|
8
9
|
import platform
|
|
9
10
|
from typing import Any, Final, Literal, cast
|
|
@@ -114,6 +115,7 @@ class Config(DeploymentSettings):
|
|
|
114
115
|
data_dir: 数据存储目录路径。
|
|
115
116
|
config_dir: 配置文件存储目录路径。
|
|
116
117
|
cache_dir: 缓存文件存储目录路径。
|
|
118
|
+
lingchu_webui_password: WebUI 只读端点的简易字符串密码(默认空,空则不鉴权)。
|
|
117
119
|
superuser_key: 运行时超级用户密钥。
|
|
118
120
|
message_store_enabled: 是否启用消息存储。
|
|
119
121
|
lingchu_superusers: 结构化超级用户平台账号绑定。
|
|
@@ -121,11 +123,12 @@ class Config(DeploymentSettings):
|
|
|
121
123
|
|
|
122
124
|
"""
|
|
123
125
|
|
|
124
|
-
core_version: str = "0.
|
|
126
|
+
core_version: str = "0.8.0.dev1"
|
|
125
127
|
data_dir: Path = field(default_factory=get_plugin_data_dir)
|
|
126
128
|
config_dir: Path = field(default_factory=get_plugin_config_dir)
|
|
127
129
|
cache_dir: Path = field(default_factory=get_plugin_cache_dir)
|
|
128
130
|
in_containers: bool = False
|
|
131
|
+
lingchu_webui_password: str = ""
|
|
129
132
|
|
|
130
133
|
@classmethod
|
|
131
134
|
def from_nonebot(cls) -> Config:
|
|
@@ -163,6 +166,17 @@ class Config(DeploymentSettings):
|
|
|
163
166
|
config_dir=get_plugin_config_dir(),
|
|
164
167
|
cache_dir=get_plugin_cache_dir(),
|
|
165
168
|
in_containers=in_containers,
|
|
169
|
+
# .env 的 LINGCHU_WEBUI_PASSWORD 可能被解析为 int(如 123456),
|
|
170
|
+
# 与字段声明 str 不符,统一强转为 str 供 hmac.compare_digest 使用。
|
|
171
|
+
lingchu_webui_password=str(
|
|
172
|
+
values.get(
|
|
173
|
+
"LINGCHU_WEBUI_PASSWORD",
|
|
174
|
+
values.get(
|
|
175
|
+
"lingchu_webui_password",
|
|
176
|
+
os.environ.get("LINGCHU_WEBUI_PASSWORD", ""),
|
|
177
|
+
),
|
|
178
|
+
)
|
|
179
|
+
),
|
|
166
180
|
)
|
|
167
181
|
|
|
168
182
|
# --- 平台检测 Properties ---
|
|
@@ -10,6 +10,7 @@ from nonebot import require
|
|
|
10
10
|
|
|
11
11
|
require("nonebot_plugin_orm")
|
|
12
12
|
from nonebot_plugin_orm import Model
|
|
13
|
+
from sqlalchemy import Table, UniqueConstraint
|
|
13
14
|
from sqlalchemy.exc import IntegrityError, SQLAlchemyError
|
|
14
15
|
from sqlalchemy.inspection import inspect
|
|
15
16
|
|
|
@@ -141,6 +142,65 @@ def _orders[T: Model](
|
|
|
141
142
|
return o
|
|
142
143
|
|
|
143
144
|
|
|
145
|
+
def declared_unique_targets[T: Model](model: type[T]) -> set[frozenset[str]]:
|
|
146
|
+
"""返回模型声明的**非主键**唯一目标(唯一约束 / 唯一索引)。
|
|
147
|
+
|
|
148
|
+
用于 upsert 冲突目标校验与数据库模式自检:SQLite 的 ``ON CONFLICT`` 必须与某个
|
|
149
|
+
唯一索引逐列精确匹配;主键不含在内,因为 SQLite 的 ``INTEGER PRIMARY KEY`` 是
|
|
150
|
+
rowid 别名,不会出现在 ``PRAGMA index_list`` 里,纳入会产生假告警。
|
|
151
|
+
|
|
152
|
+
Args:
|
|
153
|
+
model: ORM 模型类 / ORM model class.
|
|
154
|
+
|
|
155
|
+
Returns:
|
|
156
|
+
每个唯一目标的列名集合;无法内省(如测试用抽象模型)时为空集合。
|
|
157
|
+
"""
|
|
158
|
+
try:
|
|
159
|
+
table = inspect(model).local_table
|
|
160
|
+
except (AttributeError, SQLAlchemyError, TypeError):
|
|
161
|
+
logger.debug(
|
|
162
|
+
"Cannot inspect unique targets for model %s; skipping",
|
|
163
|
+
model.__name__,
|
|
164
|
+
)
|
|
165
|
+
return set()
|
|
166
|
+
if not isinstance(table, Table):
|
|
167
|
+
logger.debug(
|
|
168
|
+
"Model %s has no local Table; skipping unique target inspection",
|
|
169
|
+
model.__name__,
|
|
170
|
+
)
|
|
171
|
+
return set()
|
|
172
|
+
|
|
173
|
+
targets: set[frozenset[str]] = set()
|
|
174
|
+
try:
|
|
175
|
+
for constraint in table.constraints:
|
|
176
|
+
if isinstance(constraint, UniqueConstraint):
|
|
177
|
+
columns = frozenset(column.name for column in constraint.columns)
|
|
178
|
+
if columns:
|
|
179
|
+
targets.add(columns)
|
|
180
|
+
for index in table.indexes:
|
|
181
|
+
if index.unique:
|
|
182
|
+
columns = frozenset(column.name for column in index.columns)
|
|
183
|
+
if columns:
|
|
184
|
+
targets.add(columns)
|
|
185
|
+
except (AttributeError, SQLAlchemyError, TypeError):
|
|
186
|
+
return set()
|
|
187
|
+
return targets
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def primary_key_columns[T: Model](model: type[T]) -> frozenset[str]:
|
|
191
|
+
"""返回模型主键列名集合(无法内省时为空集合)。"""
|
|
192
|
+
try:
|
|
193
|
+
table = inspect(model).local_table
|
|
194
|
+
except (AttributeError, SQLAlchemyError, TypeError):
|
|
195
|
+
return frozenset()
|
|
196
|
+
if not isinstance(table, Table):
|
|
197
|
+
return frozenset()
|
|
198
|
+
try:
|
|
199
|
+
return frozenset(column.name for column in table.primary_key.columns)
|
|
200
|
+
except (AttributeError, SQLAlchemyError, TypeError):
|
|
201
|
+
return frozenset()
|
|
202
|
+
|
|
203
|
+
|
|
144
204
|
def _get_column_map[T: Model](model: type[T]) -> dict[str, Any]:
|
|
145
205
|
"""获取模型可用的数据库列映射。
|
|
146
206
|
|
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from collections.abc import Awaitable, Callable, Sequence
|
|
6
6
|
from dataclasses import dataclass
|
|
7
|
+
from functools import cache
|
|
7
8
|
from typing import TYPE_CHECKING, Any
|
|
8
9
|
|
|
9
10
|
from nonebot import require
|
|
@@ -23,7 +24,9 @@ from ._base import (
|
|
|
23
24
|
_get_session_dialect_name,
|
|
24
25
|
_orders,
|
|
25
26
|
_validate_column_values,
|
|
27
|
+
declared_unique_targets,
|
|
26
28
|
logger,
|
|
29
|
+
primary_key_columns,
|
|
27
30
|
)
|
|
28
31
|
|
|
29
32
|
if TYPE_CHECKING:
|
|
@@ -120,6 +123,16 @@ async def bulk_create[T: Model](
|
|
|
120
123
|
return created, failed
|
|
121
124
|
|
|
122
125
|
|
|
126
|
+
@cache
|
|
127
|
+
def _cached_unique_targets(model: type[Model]) -> frozenset[frozenset[str]]:
|
|
128
|
+
"""缓存模型声明的唯一冲突目标(主键 + 唯一约束/索引),避免热路径重复内省。"""
|
|
129
|
+
targets = set(declared_unique_targets(model))
|
|
130
|
+
primary_key = primary_key_columns(model)
|
|
131
|
+
if primary_key:
|
|
132
|
+
targets.add(primary_key)
|
|
133
|
+
return frozenset(targets)
|
|
134
|
+
|
|
135
|
+
|
|
123
136
|
def _validate_upsert_conflict_target[T: Model](
|
|
124
137
|
model: type[T],
|
|
125
138
|
columns: dict[str, Any],
|
|
@@ -136,6 +149,17 @@ def _validate_upsert_conflict_target[T: Model](
|
|
|
136
149
|
for key in conflict_keys:
|
|
137
150
|
if key not in columns:
|
|
138
151
|
raise ValueError(f"Unknown column '{key}' for model '{model.__name__}'")
|
|
152
|
+
|
|
153
|
+
targets = _cached_unique_targets(model)
|
|
154
|
+
if conflict_keys and targets and frozenset(conflict_keys) not in targets:
|
|
155
|
+
declared = "; ".join(
|
|
156
|
+
",".join(sorted(target)) for target in sorted(targets, key=sorted)
|
|
157
|
+
)
|
|
158
|
+
raise ValueError(
|
|
159
|
+
f"Upsert conflict target {tuple(conflict_keys)} does not match any "
|
|
160
|
+
f"unique constraint, unique index or primary key declared on "
|
|
161
|
+
f"'{model.__name__}' (declared: {declared})"
|
|
162
|
+
)
|
|
139
163
|
return conflict_keys
|
|
140
164
|
|
|
141
165
|
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"""数据库模式自检:比对模型声明的唯一目标与数据库实际的唯一索引。
|
|
2
|
+
|
|
3
|
+
为什么不依赖迁移就够了:生产库的表可能是早期 ``create_all`` 建的(或由外部工具改过),
|
|
4
|
+
而 ``create_all`` **不会**修改既有表结构;``ALEMBIC_STARTUP_CHECK=false`` 时 ORM 走
|
|
5
|
+
``migrate.sync``(alembic autogenerate 同步),在 SQLite 上识别唯一约束差异并不可靠。
|
|
6
|
+
|
|
7
|
+
一旦唯一索引与模型声明不一致,SQLite 的 ``ON CONFLICT`` 会在运行期报
|
|
8
|
+
``ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint``,在业务层
|
|
9
|
+
表现为「xxx失败,数据库异常: DatabaseError('Upsert failed')」。本模块在启动时**只读**
|
|
10
|
+
检查并输出告警,让这种漂移在日志里第一时间可见,且绝不阻断启动。
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
from typing import TYPE_CHECKING, Any
|
|
16
|
+
|
|
17
|
+
from nonebot import logger, require
|
|
18
|
+
|
|
19
|
+
require("nonebot_plugin_orm")
|
|
20
|
+
from nonebot_plugin_orm import Model, get_session
|
|
21
|
+
from sqlalchemy import inspect
|
|
22
|
+
from sqlalchemy.exc import SQLAlchemyError
|
|
23
|
+
|
|
24
|
+
from . import models as models_module
|
|
25
|
+
from .orm_crud._base import declared_unique_targets
|
|
26
|
+
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
from collections.abc import Iterable
|
|
29
|
+
|
|
30
|
+
from sqlalchemy.ext.asyncio import AsyncConnection
|
|
31
|
+
|
|
32
|
+
#: 唯一目标集合的类型别名(表名 → 该表所有唯一目标的列名集合)。
|
|
33
|
+
UniqueTargets = dict[str, set[frozenset[str]]]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def collect_declared_unique_targets() -> UniqueTargets:
|
|
37
|
+
"""收集本插件全部模型声明的**非主键**唯一目标。
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
表名到唯一目标集合的映射;没有声明唯一目标的模型不会出现在结果里。
|
|
41
|
+
"""
|
|
42
|
+
declared: UniqueTargets = {}
|
|
43
|
+
for name in getattr(models_module, "__all__", ()):
|
|
44
|
+
model = getattr(models_module, name, None)
|
|
45
|
+
if not isinstance(model, type) or not issubclass(model, Model):
|
|
46
|
+
continue
|
|
47
|
+
table_name = getattr(model, "__tablename__", None)
|
|
48
|
+
if not isinstance(table_name, str):
|
|
49
|
+
continue
|
|
50
|
+
targets = declared_unique_targets(model)
|
|
51
|
+
if targets:
|
|
52
|
+
declared.setdefault(table_name, set()).update(targets)
|
|
53
|
+
return declared
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _inspector_unique_targets(inspector: Any, table: str) -> set[frozenset[str]] | None:
|
|
57
|
+
"""用 inspector 读取唯一约束 / 唯一索引;读取失败时返回 None。"""
|
|
58
|
+
found: set[frozenset[str]] = set()
|
|
59
|
+
try:
|
|
60
|
+
for constraint in inspector.get_unique_constraints(table):
|
|
61
|
+
columns = constraint.get("column_names") or []
|
|
62
|
+
if columns:
|
|
63
|
+
found.add(frozenset(columns))
|
|
64
|
+
for index in inspector.get_indexes(table):
|
|
65
|
+
if index.get("unique"):
|
|
66
|
+
columns = index.get("column_names") or []
|
|
67
|
+
if columns:
|
|
68
|
+
found.add(frozenset(columns))
|
|
69
|
+
except (SQLAlchemyError, NotImplementedError):
|
|
70
|
+
logger.debug("Inspector cannot read unique targets for table {}", table)
|
|
71
|
+
return None
|
|
72
|
+
return found
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def read_actual_unique_targets(
|
|
76
|
+
connection: AsyncConnection | Any, tables: Iterable[str]
|
|
77
|
+
) -> UniqueTargets:
|
|
78
|
+
"""读取数据库里各表的实际唯一目标(同步函数,供 ``run_sync`` 调用)。
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
connection: 同步连接(``AsyncConnection.run_sync`` 会传入)。
|
|
82
|
+
tables: 待检查的表名。
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
表名到实际唯一目标集合的映射;表不存在或无法读取时为**空集合**(表示未知)。
|
|
86
|
+
"""
|
|
87
|
+
inspector = inspect(connection)
|
|
88
|
+
if inspector is None: # pragma: no cover - 防御性分支,非 Connection 才可能为 None
|
|
89
|
+
logger.debug("Inspector unavailable; skipping schema drift inspection")
|
|
90
|
+
return {table: set() for table in tables}
|
|
91
|
+
existing = set(inspector.get_table_names())
|
|
92
|
+
actual: UniqueTargets = {}
|
|
93
|
+
for table in tables:
|
|
94
|
+
if table not in existing:
|
|
95
|
+
actual[table] = set()
|
|
96
|
+
continue
|
|
97
|
+
found = _inspector_unique_targets(inspector, table)
|
|
98
|
+
if found is None:
|
|
99
|
+
actual[table] = set()
|
|
100
|
+
continue
|
|
101
|
+
actual[table] = found
|
|
102
|
+
return actual
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def schema_drift_report(declared: UniqueTargets, actual: UniqueTargets) -> list[str]:
|
|
106
|
+
"""比对声明与实际,返回不一致的说明列表(纯函数,便于测试)。
|
|
107
|
+
|
|
108
|
+
只在「模型声明了某唯一目标、但数据库里读不到」时报告;数据库里多出来的唯一索引
|
|
109
|
+
不影响 upsert,故不计入。
|
|
110
|
+
"""
|
|
111
|
+
lines: list[str] = []
|
|
112
|
+
for table in sorted(declared):
|
|
113
|
+
present = actual.get(table)
|
|
114
|
+
if present is None:
|
|
115
|
+
continue
|
|
116
|
+
lines.extend(
|
|
117
|
+
f"{table}: 模型声明的唯一目标 ({','.join(sorted(target))}) 在数据库中不存在"
|
|
118
|
+
for target in sorted(declared[table] - present, key=sorted)
|
|
119
|
+
)
|
|
120
|
+
return lines
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
async def find_schema_drift() -> list[str]:
|
|
124
|
+
"""只读检查数据库模式与模型声明的差异。
|
|
125
|
+
|
|
126
|
+
Returns:
|
|
127
|
+
差异说明列表;无差异或无法检查时为空列表(本函数不抛异常)。
|
|
128
|
+
"""
|
|
129
|
+
declared = collect_declared_unique_targets()
|
|
130
|
+
if not declared:
|
|
131
|
+
return []
|
|
132
|
+
try:
|
|
133
|
+
async with get_session() as session:
|
|
134
|
+
connection = await session.connection()
|
|
135
|
+
actual = await connection.run_sync(
|
|
136
|
+
read_actual_unique_targets, tuple(declared)
|
|
137
|
+
)
|
|
138
|
+
except (SQLAlchemyError, AttributeError, TypeError) as exc:
|
|
139
|
+
logger.debug("Schema drift check skipped: {}", exc)
|
|
140
|
+
return []
|
|
141
|
+
return schema_drift_report(declared, actual)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
async def log_schema_drift() -> None:
|
|
145
|
+
"""启动时只读自检:发现漂移只告警,绝不阻断启动。"""
|
|
146
|
+
try:
|
|
147
|
+
drift = await find_schema_drift()
|
|
148
|
+
except Exception as exc: # noqa: BLE001 - 自检不得影响启动流程
|
|
149
|
+
logger.debug("Schema drift check failed: {}", exc)
|
|
150
|
+
return
|
|
151
|
+
if not drift:
|
|
152
|
+
return
|
|
153
|
+
logger.warning("数据库模式与模型声明不一致({} 处):", len(drift))
|
|
154
|
+
for line in drift:
|
|
155
|
+
logger.warning(" - {}", line)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from dataclasses import dataclass
|
|
3
|
+
from dataclasses import dataclass
|
|
4
4
|
from typing import TYPE_CHECKING, Any, Final
|
|
5
5
|
|
|
6
6
|
from arclet.alconna import Alconna
|
|
@@ -14,7 +14,6 @@ from ..core.mutable_settings import get_mutable_settings
|
|
|
14
14
|
from ..i18n import get_configured_locale, gettext, normalize_locale
|
|
15
15
|
from ..platforms import (
|
|
16
16
|
QQ_CAPABILITIES,
|
|
17
|
-
TELEGRAM_CAPABILITIES,
|
|
18
17
|
PlatformCapability,
|
|
19
18
|
)
|
|
20
19
|
from .qq.commands.triggers import COMMAND_TRIGGERS
|
|
@@ -25,8 +24,6 @@ if TYPE_CHECKING:
|
|
|
25
24
|
_MENU = COMMAND_TRIGGERS["menu"]
|
|
26
25
|
QQ_PLATFORM_ID: Final = "qq"
|
|
27
26
|
ONEBOT_V11_ADAPTER_ID: Final = "~onebot.v11"
|
|
28
|
-
TELEGRAM_PLATFORM_ID: Final = "telegram"
|
|
29
|
-
TELEGRAM_ADAPTER_ID: Final = "~telegram"
|
|
30
27
|
NAPCAT_IMPL: Final = "NapCat.Onebot"
|
|
31
28
|
|
|
32
29
|
menu_cmd: type[AlconnaMatcher] = on_alconna(
|
|
@@ -34,7 +31,7 @@ menu_cmd: type[AlconnaMatcher] = on_alconna(
|
|
|
34
31
|
aliases=_MENU.aliases,
|
|
35
32
|
priority=805,
|
|
36
33
|
block=True,
|
|
37
|
-
use_cmd_sep=
|
|
34
|
+
use_cmd_sep=False,
|
|
38
35
|
use_cmd_start=True,
|
|
39
36
|
)
|
|
40
37
|
|
|
@@ -181,7 +178,7 @@ menu_page_cmds: Final[dict[str, type[AlconnaMatcher]]] = {
|
|
|
181
178
|
command=Alconna(_menu_page_command(page)),
|
|
182
179
|
priority=805,
|
|
183
180
|
block=True,
|
|
184
|
-
use_cmd_sep=
|
|
181
|
+
use_cmd_sep=False,
|
|
185
182
|
use_cmd_start=True,
|
|
186
183
|
)
|
|
187
184
|
for page in _page_commands_from_pages(_DEFAULT_MENU_PAGES)
|
|
@@ -594,37 +591,7 @@ _BASE_MENU_FEATURES: Final[tuple[MenuFeature, ...]] = (
|
|
|
594
591
|
),
|
|
595
592
|
)
|
|
596
593
|
|
|
597
|
-
|
|
598
|
-
"block_member",
|
|
599
|
-
"bot_boot",
|
|
600
|
-
"bot_shutdown",
|
|
601
|
-
"bot_silence",
|
|
602
|
-
"bot_speak",
|
|
603
|
-
"kick_member",
|
|
604
|
-
"leave_group",
|
|
605
|
-
"member_mute",
|
|
606
|
-
"member_unmute",
|
|
607
|
-
"recall_message",
|
|
608
|
-
"set_group_name",
|
|
609
|
-
"set_member_admin",
|
|
610
|
-
"unblock_member",
|
|
611
|
-
"unset_member_admin",
|
|
612
|
-
"whole_mute",
|
|
613
|
-
"whole_unmute",
|
|
614
|
-
})
|
|
615
|
-
_TELEGRAM_AVAILABILITY: Final = MenuAvailability(
|
|
616
|
-
TELEGRAM_PLATFORM_ID,
|
|
617
|
-
TELEGRAM_ADAPTER_ID,
|
|
618
|
-
)
|
|
619
|
-
_DEFAULT_MENU_FEATURES: Final = tuple(
|
|
620
|
-
replace(
|
|
621
|
-
feature,
|
|
622
|
-
availability=(*feature.availability, _TELEGRAM_AVAILABILITY),
|
|
623
|
-
)
|
|
624
|
-
if feature.command_key in _TELEGRAM_COMMAND_KEYS
|
|
625
|
-
else feature
|
|
626
|
-
for feature in _BASE_MENU_FEATURES
|
|
627
|
-
)
|
|
594
|
+
_DEFAULT_MENU_FEATURES: Final = _BASE_MENU_FEATURES
|
|
628
595
|
MENU_FEATURES: tuple[MenuFeature, ...] = _DEFAULT_MENU_FEATURES
|
|
629
596
|
|
|
630
597
|
|
|
@@ -747,14 +714,6 @@ def qq_menu_context(
|
|
|
747
714
|
)
|
|
748
715
|
|
|
749
716
|
|
|
750
|
-
def telegram_menu_context() -> MenuRuntimeContext:
|
|
751
|
-
return MenuRuntimeContext(
|
|
752
|
-
platform_id=TELEGRAM_PLATFORM_ID,
|
|
753
|
-
adapter_id=TELEGRAM_ADAPTER_ID,
|
|
754
|
-
platform_capabilities=TELEGRAM_CAPABILITIES,
|
|
755
|
-
)
|
|
756
|
-
|
|
757
|
-
|
|
758
717
|
def _render_section(
|
|
759
718
|
section: MenuSection,
|
|
760
719
|
context: MenuRuntimeContext,
|