nonebot2/nonebot/plugin/__init__.py

1200 lines
40 KiB
Python
Raw Normal View History

2020-10-18 15:04:45 +08:00
"""
插件
====
NoneBot 插件开发提供便携的定义函数
"""
2020-08-17 16:09:41 +08:00
import re
import json
2020-12-06 02:30:19 +08:00
from types import ModuleType
from dataclasses import dataclass
2020-11-21 20:40:09 +08:00
from contextvars import Context, ContextVar, copy_context
2021-02-07 23:36:04 +08:00
from typing import Any, Set, List, Dict, Type, Tuple, Union, Optional, TYPE_CHECKING
2020-06-30 10:13:58 +08:00
import tomlkit
2020-07-05 20:39:34 +08:00
from nonebot.log import logger
2020-10-22 22:08:19 +08:00
from nonebot.matcher import Matcher
2020-08-20 17:15:05 +08:00
from nonebot.permission import Permission
from nonebot.typing import T_State, T_StateFactory, T_Handler, T_RuleChecker
2021-02-02 11:59:14 +08:00
from nonebot.rule import Rule, startswith, endswith, keyword, command, shell_command, ArgumentParser, regex
2020-06-30 10:13:58 +08:00
2021-02-19 14:58:26 +08:00
from .manager import PluginManager
2020-12-30 12:42:10 +08:00
if TYPE_CHECKING:
2021-02-19 14:58:26 +08:00
from nonebot.adapters import Bot, Event
2020-12-30 12:42:10 +08:00
2020-06-30 10:13:58 +08:00
plugins: Dict[str, "Plugin"] = {}
2020-10-18 15:04:45 +08:00
"""
:类型: ``Dict[str, Plugin]``
:说明: 已加载的插件
"""
2021-02-19 14:58:26 +08:00
PLUGIN_NAMESPACE = "nonebot.loaded_plugins"
2020-06-30 10:13:58 +08:00
2020-11-21 20:40:09 +08:00
_export: ContextVar["Export"] = ContextVar("_export")
2020-12-07 00:06:09 +08:00
_tmp_matchers: ContextVar[Set[Type[Matcher]]] = ContextVar("_tmp_matchers")
2020-11-21 20:40:09 +08:00
class Export(dict):
"""
:说明:
2020-11-30 11:08:00 +08:00
2020-11-21 20:40:09 +08:00
插件导出内容以使得其他插件可以获得
2020-11-30 11:08:00 +08:00
2020-11-21 20:40:09 +08:00
:示例:
.. code-block:: python
nonebot.export().default = "bar"
@nonebot.export()
def some_function():
pass
2020-11-30 12:43:44 +08:00
# this doesn't work before python 3.9
2020-11-21 20:50:33 +08:00
# use
# export = nonebot.export(); @export.sub
# instead
2020-11-30 12:43:44 +08:00
# See also PEP-614: https://www.python.org/dev/peps/pep-0614/
2020-11-21 20:40:09 +08:00
@nonebot.export().sub
def something_else():
pass
"""
def __call__(self, func, **kwargs):
self[func.__name__] = func
self.update(kwargs)
return func
def __setitem__(self, key, value):
super().__setitem__(key,
Export(value) if isinstance(value, dict) else value)
def __setattr__(self, name, value):
self[name] = Export(value) if isinstance(value, dict) else value
def __getattr__(self, name):
if name not in self:
self[name] = Export()
return self[name]
2020-06-30 10:13:58 +08:00
@dataclass(eq=False)
2020-06-30 10:13:58 +08:00
class Plugin(object):
2020-10-18 15:04:45 +08:00
"""存储插件信息"""
name: str
2020-10-18 15:04:45 +08:00
"""
- **类型**: ``str``
- **说明**: 插件名称使用 文件/文件夹 名称作为插件名
"""
module: ModuleType
2020-10-18 15:04:45 +08:00
"""
- **类型**: ``ModuleType``
- **说明**: 插件模块对象
"""
matcher: Set[Type[Matcher]]
2020-10-18 15:04:45 +08:00
"""
- **类型**: ``Set[Type[Matcher]]``
- **说明**: 插件内定义的 ``Matcher``
"""
2020-11-21 20:40:09 +08:00
export: Export
2020-11-21 20:50:33 +08:00
"""
- **类型**: ``Export``
- **说明**: 插件内定义的导出内容
"""
2020-06-30 10:13:58 +08:00
2020-10-16 15:12:15 +08:00
def on(type: str = "",
2020-12-17 21:09:30 +08:00
rule: Optional[Union[Rule, T_RuleChecker]] = None,
2020-09-27 18:05:13 +08:00
permission: Optional[Permission] = None,
2020-08-20 17:15:05 +08:00
*,
2020-12-17 21:09:30 +08:00
handlers: Optional[List[T_Handler]] = None,
temp: bool = False,
2020-08-20 17:15:05 +08:00
priority: int = 1,
block: bool = False,
state: Optional[T_State] = None,
state_factory: Optional[T_StateFactory] = None) -> Type[Matcher]:
2020-10-18 15:04:45 +08:00
"""
:说明:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
注册一个基础事件响应器可自定义类型
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:参数:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
* ``type: str``: 事件响应器类型
2020-12-17 21:09:30 +08:00
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
2020-10-18 15:04:45 +08:00
* ``permission: Optional[Permission]``: 事件响应权限
2020-12-17 21:09:30 +08:00
* ``handlers: Optional[List[T_Handler]]``: 事件处理函数列表
2020-10-18 15:04:45 +08:00
* ``temp: bool``: 是否为临时事件响应器仅执行一次
* ``priority: int``: 事件响应器优先级
* ``block: bool``: 是否阻止事件向更低优先级传递
* ``state: Optional[T_State]``: 默认 state
* ``state_factory: Optional[T_StateFactory]``: 默认 state 的工厂函数
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:返回:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
- ``Type[Matcher]``
"""
2020-10-16 15:12:15 +08:00
matcher = Matcher.new(type,
2020-08-20 17:15:05 +08:00
Rule() & rule,
2020-09-27 18:05:13 +08:00
permission or Permission(),
2020-08-20 17:15:05 +08:00
temp=temp,
priority=priority,
block=block,
2020-08-20 17:15:05 +08:00
handlers=handlers,
default_state=state,
default_state_factory=state_factory)
2020-11-21 20:40:09 +08:00
_tmp_matchers.get().add(matcher)
2020-08-20 17:15:05 +08:00
return matcher
def on_metaevent(
rule: Optional[Union[Rule, T_RuleChecker]] = None,
*,
handlers: Optional[List[T_Handler]] = None,
temp: bool = False,
priority: int = 1,
block: bool = False,
state: Optional[T_State] = None,
state_factory: Optional[T_StateFactory] = None) -> Type[Matcher]:
2020-10-18 15:04:45 +08:00
"""
:说明:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
注册一个元事件响应器
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:参数:
2020-11-30 11:08:00 +08:00
2020-12-17 21:09:30 +08:00
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
* ``handlers: Optional[List[T_Handler]]``: 事件处理函数列表
2020-10-18 15:04:45 +08:00
* ``temp: bool``: 是否为临时事件响应器仅执行一次
* ``priority: int``: 事件响应器优先级
* ``block: bool``: 是否阻止事件向更低优先级传递
* ``state: Optional[T_State]``: 默认 state
* ``state_factory: Optional[T_StateFactory]``: 默认 state 的工厂函数
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:返回:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
- ``Type[Matcher]``
"""
2020-08-20 17:15:05 +08:00
matcher = Matcher.new("meta_event",
Rule() & rule,
Permission(),
2020-07-25 12:28:30 +08:00
temp=temp,
priority=priority,
block=block,
2020-07-25 12:28:30 +08:00
handlers=handlers,
default_state=state,
default_state_factory=state_factory)
2020-11-21 20:40:09 +08:00
_tmp_matchers.get().add(matcher)
2020-07-25 12:28:30 +08:00
return matcher
2020-12-17 21:09:30 +08:00
def on_message(rule: Optional[Union[Rule, T_RuleChecker]] = None,
2020-09-27 18:05:13 +08:00
permission: Optional[Permission] = None,
2020-06-30 10:13:58 +08:00
*,
2020-12-17 21:09:30 +08:00
handlers: Optional[List[T_Handler]] = None,
temp: bool = False,
2020-06-30 10:13:58 +08:00
priority: int = 1,
block: bool = True,
state: Optional[T_State] = None,
state_factory: Optional[T_StateFactory] = None) -> Type[Matcher]:
2020-10-18 15:04:45 +08:00
"""
:说明:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
注册一个消息事件响应器
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:参数:
2020-11-30 11:08:00 +08:00
2020-12-17 21:09:30 +08:00
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
2020-10-18 15:04:45 +08:00
* ``permission: Optional[Permission]``: 事件响应权限
2020-12-17 21:09:30 +08:00
* ``handlers: Optional[List[T_Handler]]``: 事件处理函数列表
2020-10-18 15:04:45 +08:00
* ``temp: bool``: 是否为临时事件响应器仅执行一次
* ``priority: int``: 事件响应器优先级
* ``block: bool``: 是否阻止事件向更低优先级传递
* ``state: Optional[T_State]``: 默认 state
* ``state_factory: Optional[T_StateFactory]``: 默认 state 的工厂函数
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:返回:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
- ``Type[Matcher]``
"""
2020-08-20 17:15:05 +08:00
matcher = Matcher.new("message",
Rule() & rule,
2020-09-27 18:05:13 +08:00
permission or Permission(),
2020-07-25 12:28:30 +08:00
temp=temp,
priority=priority,
block=block,
2020-07-25 12:28:30 +08:00
handlers=handlers,
default_state=state,
default_state_factory=state_factory)
2020-11-21 20:40:09 +08:00
_tmp_matchers.get().add(matcher)
2020-07-25 12:28:30 +08:00
return matcher
2020-12-17 21:09:30 +08:00
def on_notice(rule: Optional[Union[Rule, T_RuleChecker]] = None,
2020-07-25 12:28:30 +08:00
*,
2020-12-17 21:09:30 +08:00
handlers: Optional[List[T_Handler]] = None,
temp: bool = False,
2020-07-25 12:28:30 +08:00
priority: int = 1,
block: bool = False,
state: Optional[T_State] = None,
state_factory: Optional[T_StateFactory] = None) -> Type[Matcher]:
2020-10-18 15:04:45 +08:00
"""
:说明:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
注册一个通知事件响应器
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:参数:
2020-11-30 11:08:00 +08:00
2020-12-17 21:09:30 +08:00
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
* ``handlers: Optional[List[T_Handler]]``: 事件处理函数列表
2020-10-18 15:04:45 +08:00
* ``temp: bool``: 是否为临时事件响应器仅执行一次
* ``priority: int``: 事件响应器优先级
* ``block: bool``: 是否阻止事件向更低优先级传递
* ``state: Optional[T_State]``: 默认 state
* ``state_factory: Optional[T_StateFactory]``: 默认 state 的工厂函数
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:返回:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
- ``Type[Matcher]``
"""
2020-08-20 17:15:05 +08:00
matcher = Matcher.new("notice",
Rule() & rule,
Permission(),
2020-07-25 12:28:30 +08:00
temp=temp,
priority=priority,
block=block,
2020-07-25 12:28:30 +08:00
handlers=handlers,
default_state=state,
default_state_factory=state_factory)
2020-11-21 20:40:09 +08:00
_tmp_matchers.get().add(matcher)
2020-07-25 12:28:30 +08:00
return matcher
2020-12-17 21:09:30 +08:00
def on_request(rule: Optional[Union[Rule, T_RuleChecker]] = None,
2020-07-25 12:28:30 +08:00
*,
2020-12-17 21:09:30 +08:00
handlers: Optional[List[T_Handler]] = None,
temp: bool = False,
2020-07-25 12:28:30 +08:00
priority: int = 1,
block: bool = False,
state: Optional[T_State] = None,
state_factory: Optional[T_StateFactory] = None) -> Type[Matcher]:
2020-10-18 15:04:45 +08:00
"""
:说明:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
注册一个请求事件响应器
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:参数:
2020-11-30 11:08:00 +08:00
2020-12-17 21:09:30 +08:00
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
* ``handlers: Optional[List[T_Handler]]``: 事件处理函数列表
2020-10-18 15:04:45 +08:00
* ``temp: bool``: 是否为临时事件响应器仅执行一次
* ``priority: int``: 事件响应器优先级
* ``block: bool``: 是否阻止事件向更低优先级传递
* ``state: Optional[T_State]``: 默认 state
* ``state_factory: Optional[T_StateFactory]``: 默认 state 的工厂函数
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:返回:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
- ``Type[Matcher]``
"""
2020-08-20 17:15:05 +08:00
matcher = Matcher.new("request",
Rule() & rule,
Permission(),
2020-06-30 10:13:58 +08:00
temp=temp,
priority=priority,
block=block,
2020-06-30 10:13:58 +08:00
handlers=handlers,
default_state=state,
default_state_factory=state_factory)
2020-11-21 20:40:09 +08:00
_tmp_matchers.get().add(matcher)
2020-06-30 10:13:58 +08:00
return matcher
2020-08-17 16:09:41 +08:00
def on_startswith(msg: str,
2020-12-17 21:09:30 +08:00
rule: Optional[Optional[Union[Rule, T_RuleChecker]]] = None,
2020-08-17 16:09:41 +08:00
**kwargs) -> Type[Matcher]:
2020-10-18 15:04:45 +08:00
"""
:说明:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
注册一个消息事件响应器并且当消息的**文本部分**以指定内容开头时响应
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:参数:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
* ``msg: str``: 指定消息开头内容
2020-12-17 21:09:30 +08:00
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
2020-10-18 15:04:45 +08:00
* ``permission: Optional[Permission]``: 事件响应权限
2020-12-17 21:09:30 +08:00
* ``handlers: Optional[List[T_Handler]]``: 事件处理函数列表
2020-10-18 15:04:45 +08:00
* ``temp: bool``: 是否为临时事件响应器仅执行一次
* ``priority: int``: 事件响应器优先级
* ``block: bool``: 是否阻止事件向更低优先级传递
* ``state: Optional[T_State]``: 默认 state
* ``state_factory: Optional[T_StateFactory]``: 默认 state 的工厂函数
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:返回:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
- ``Type[Matcher]``
"""
return on_message(startswith(msg) & rule, **kwargs)
2020-08-17 16:09:41 +08:00
def on_endswith(msg: str,
2020-12-17 21:09:30 +08:00
rule: Optional[Optional[Union[Rule, T_RuleChecker]]] = None,
2020-08-17 16:09:41 +08:00
**kwargs) -> Type[Matcher]:
2020-10-18 15:04:45 +08:00
"""
:说明:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
注册一个消息事件响应器并且当消息的**文本部分**以指定内容结尾时响应
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:参数:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
* ``msg: str``: 指定消息结尾内容
2020-12-17 21:09:30 +08:00
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
2020-10-18 15:04:45 +08:00
* ``permission: Optional[Permission]``: 事件响应权限
2020-12-17 21:09:30 +08:00
* ``handlers: Optional[List[T_Handler]]``: 事件处理函数列表
2020-10-18 15:04:45 +08:00
* ``temp: bool``: 是否为临时事件响应器仅执行一次
* ``priority: int``: 事件响应器优先级
* ``block: bool``: 是否阻止事件向更低优先级传递
* ``state: Optional[T_State]``: 默认 state
* ``state_factory: Optional[T_StateFactory]``: 默认 state 的工厂函数
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:返回:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
- ``Type[Matcher]``
"""
return on_message(endswith(msg) & rule, **kwargs)
def on_keyword(keywords: Set[str],
2020-12-17 21:09:30 +08:00
rule: Optional[Union[Rule, T_RuleChecker]] = None,
**kwargs) -> Type[Matcher]:
"""
:说明:
2020-11-30 11:08:00 +08:00
注册一个消息事件响应器并且当消息纯文本部分包含关键词时响应
2020-11-30 11:08:00 +08:00
:参数:
2020-11-30 11:08:00 +08:00
* ``keywords: Set[str]``: 关键词列表
2020-12-17 21:09:30 +08:00
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
* ``permission: Optional[Permission]``: 事件响应权限
2020-12-17 21:09:30 +08:00
* ``handlers: Optional[List[T_Handler]]``: 事件处理函数列表
* ``temp: bool``: 是否为临时事件响应器仅执行一次
* ``priority: int``: 事件响应器优先级
* ``block: bool``: 是否阻止事件向更低优先级传递
* ``state: Optional[T_State]``: 默认 state
* ``state_factory: Optional[T_StateFactory]``: 默认 state 的工厂函数
2020-11-30 11:08:00 +08:00
:返回:
2020-11-30 11:08:00 +08:00
- ``Type[Matcher]``
"""
return on_message(keyword(*keywords) & rule, **kwargs)
2020-08-17 16:09:41 +08:00
2020-08-23 20:01:58 +08:00
def on_command(cmd: Union[str, Tuple[str, ...]],
2020-12-17 21:09:30 +08:00
rule: Optional[Union[Rule, T_RuleChecker]] = None,
2020-09-28 12:45:55 +08:00
aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = None,
2020-10-22 22:08:19 +08:00
**kwargs) -> Type[Matcher]:
2020-10-18 15:04:45 +08:00
"""
:说明:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
注册一个消息事件响应器并且当消息以指定命令开头时响应
命令匹配规则参考: `命令形式匹配 <rule.html#command-command>`_
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:参数:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
* ``cmd: Union[str, Tuple[str, ...]]``: 指定命令内容
2020-12-17 21:09:30 +08:00
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
2020-10-18 15:04:45 +08:00
* ``aliases: Optional[Set[Union[str, Tuple[str, ...]]]]``: 命令别名
* ``permission: Optional[Permission]``: 事件响应权限
2020-12-17 21:09:30 +08:00
* ``handlers: Optional[List[T_Handler]]``: 事件处理函数列表
2020-10-18 15:04:45 +08:00
* ``temp: bool``: 是否为临时事件响应器仅执行一次
* ``priority: int``: 事件响应器优先级
* ``block: bool``: 是否阻止事件向更低优先级传递
* ``state: Optional[T_State]``: 默认 state
* ``state_factory: Optional[T_StateFactory]``: 默认 state 的工厂函数
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:返回:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
- ``Type[Matcher]``
"""
2020-12-30 12:42:10 +08:00
async def _strip_cmd(bot: "Bot", event: "Event", state: T_State):
2021-02-07 02:27:09 +08:00
message = event.get_message()
2021-02-07 20:57:08 +08:00
segment = message.pop(0)
new_message = message.__class__(
2021-02-23 22:50:25 +08:00
str(segment).lstrip()
2021-02-07 20:57:08 +08:00
[len(state["_prefix"]["raw_command"]):].lstrip()) # type: ignore
for new_segment in reversed(new_message):
message.insert(0, new_segment)
handlers = kwargs.pop("handlers", [])
handlers.insert(0, _strip_cmd)
2020-10-22 22:08:19 +08:00
commands = set([cmd]) | (aliases or set())
return on_message(command(*commands) & rule, handlers=handlers, **kwargs)
2020-08-17 16:09:41 +08:00
2021-02-02 11:59:14 +08:00
def on_shell_command(cmd: Union[str, Tuple[str, ...]],
rule: Optional[Union[Rule, T_RuleChecker]] = None,
aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = None,
parser: Optional[ArgumentParser] = None,
**kwargs) -> Type[Matcher]:
2021-02-01 22:28:48 +08:00
"""
:说明:
注册一个支持 ``shell_like`` 解析参数的命令消息事件响应器
2021-02-02 11:59:14 +08:00
与普通的 ``on_command`` 不同的是在添加 ``parser`` 参数时, 响应器会自动处理消息
2021-02-01 22:28:48 +08:00
2021-02-02 11:59:14 +08:00
并将用户输入的原始参数列表保存在 ``state["argv"]``, ``parser`` 处理的参数保存在 ``state["args"]``
2021-02-01 22:28:48 +08:00
:参数:
* ``cmd: Union[str, Tuple[str, ...]]``: 指定命令内容
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
* ``aliases: Optional[Set[Union[str, Tuple[str, ...]]]]``: 命令别名
2021-02-02 11:59:14 +08:00
* ``parser: Optional[ArgumentParser]``: ``nonebot.rule.ArgumentParser`` 对象
2021-02-01 22:28:48 +08:00
* ``permission: Optional[Permission]``: 事件响应权限
* ``handlers: Optional[List[T_Handler]]``: 事件处理函数列表
* ``temp: bool``: 是否为临时事件响应器仅执行一次
* ``priority: int``: 事件响应器优先级
* ``block: bool``: 是否阻止事件向更低优先级传递
* ``state: Optional[T_State]``: 默认 state
* ``state_factory: Optional[T_StateFactory]``: 默认 state 的工厂函数
:返回:
- ``Type[Matcher]``
"""
async def _strip_cmd(bot: "Bot", event: "Event", state: T_State):
message = event.get_message()
segment = message.pop(0)
new_message = message.__class__(
str(segment)
[len(state["_prefix"]["raw_command"]):].strip()) # type: ignore
for new_segment in reversed(new_message):
message.insert(0, new_segment)
handlers = kwargs.pop("handlers", [])
handlers.insert(0, _strip_cmd)
commands = set([cmd]) | (aliases or set())
2021-02-02 11:59:14 +08:00
return on_message(shell_command(*commands, parser=parser) & rule,
handlers=handlers,
**kwargs)
2021-02-01 22:28:48 +08:00
2020-08-17 16:09:41 +08:00
def on_regex(pattern: str,
flags: Union[int, re.RegexFlag] = 0,
2021-03-13 15:35:13 +08:00
rule: Optional[Union[Rule, T_RuleChecker]] = None,
2020-08-17 16:09:41 +08:00
**kwargs) -> Type[Matcher]:
2020-10-18 15:04:45 +08:00
"""
:说明:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
注册一个消息事件响应器并且当消息匹配正则表达式时响应
命令匹配规则参考: `正则匹配 <rule.html#regex-regex-flags-0>`_
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:参数:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
* ``pattern: str``: 正则表达式
* ``flags: Union[int, re.RegexFlag]``: 正则匹配标志
2020-12-17 21:09:30 +08:00
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
2020-10-18 15:04:45 +08:00
* ``permission: Optional[Permission]``: 事件响应权限
2020-12-17 21:09:30 +08:00
* ``handlers: Optional[List[T_Handler]]``: 事件处理函数列表
2020-10-18 15:04:45 +08:00
* ``temp: bool``: 是否为临时事件响应器仅执行一次
* ``priority: int``: 事件响应器优先级
* ``block: bool``: 是否阻止事件向更低优先级传递
* ``state: Optional[T_State]``: 默认 state
* ``state_factory: Optional[T_StateFactory]``: 默认 state 的工厂函数
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:返回:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
- ``Type[Matcher]``
"""
return on_message(regex(pattern, flags) & rule, **kwargs)
2020-06-30 10:13:58 +08:00
2020-10-18 15:04:45 +08:00
class CommandGroup:
"""命令组,用于声明一组有相同名称前缀的命令。"""
def __init__(self, cmd: Union[str, Tuple[str, ...]], **kwargs):
"""
:参数:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
* ``cmd: Union[str, Tuple[str, ...]]``: 命令前缀
* ``**kwargs``: 其他传递给 ``on_command`` 的参数默认值参考 `on_command <#on-command-cmd-rule-none-aliases-none-kwargs>`_
"""
self.basecmd: Tuple[str, ...] = (cmd,) if isinstance(cmd, str) else cmd
"""
- **类型**: ``Tuple[str, ...]``
- **说明**: 命令前缀
"""
if "aliases" in kwargs:
del kwargs["aliases"]
self.base_kwargs: Dict[str, Any] = kwargs
"""
- **类型**: ``Dict[str, Any]``
- **说明**: 其他传递给 ``on_command`` 的参数默认值
"""
def command(self, cmd: Union[str, Tuple[str, ...]],
2020-10-22 22:08:19 +08:00
**kwargs) -> Type[Matcher]:
2020-10-18 15:04:45 +08:00
"""
:说明:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
注册一个新的命令
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:参数:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
* ``cmd: Union[str, Tuple[str, ...]]``: 命令前缀
* ``**kwargs``: 其他传递给 ``on_command`` 的参数将会覆盖命令组默认值
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:返回:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
- ``Type[Matcher]``
"""
sub_cmd = (cmd,) if isinstance(cmd, str) else cmd
cmd = self.basecmd + sub_cmd
final_kwargs = self.base_kwargs.copy()
final_kwargs.update(kwargs)
return on_command(cmd, **final_kwargs)
2021-02-02 11:59:14 +08:00
def shell_command(self, cmd: Union[str, Tuple[str, ...]],
**kwargs) -> Type[Matcher]:
"""
:说明:
注册一个新的命令
:参数:
* ``cmd: Union[str, Tuple[str, ...]]``: 命令前缀
* ``**kwargs``: 其他传递给 ``on_command`` 的参数将会覆盖命令组默认值
:返回:
- ``Type[Matcher]``
"""
sub_cmd = (cmd,) if isinstance(cmd, str) else cmd
cmd = self.basecmd + sub_cmd
final_kwargs = self.base_kwargs.copy()
final_kwargs.update(kwargs)
return on_shell_command(cmd, **final_kwargs)
2020-10-18 15:04:45 +08:00
class MatcherGroup:
"""事件响应器组合,统一管理。为 ``Matcher`` 创建提供默认属性。"""
def __init__(self, **kwargs):
"""
:说明:
创建一个事件响应器组合参数为默认值 ``on`` 一致
"""
self.matchers: List[Type[Matcher]] = []
"""
:类型: ``List[Type[Matcher]]``
:说明: 组内事件响应器列表
"""
self.base_kwargs: Dict[str, Any] = kwargs
"""
- **类型**: ``Dict[str, Any]``
- **说明**: 其他传递给 ``on`` 的参数默认值
"""
def on(self, **kwargs) -> Type[Matcher]:
"""
:说明:
注册一个基础事件响应器可自定义类型
:参数:
* ``type: str``: 事件响应器类型
2020-12-17 21:09:30 +08:00
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
* ``permission: Optional[Permission]``: 事件响应权限
2020-12-17 21:09:30 +08:00
* ``handlers: Optional[List[T_Handler]]``: 事件处理函数列表
* ``temp: bool``: 是否为临时事件响应器仅执行一次
* ``priority: int``: 事件响应器优先级
* ``block: bool``: 是否阻止事件向更低优先级传递
* ``state: Optional[T_State]``: 默认 state
* ``state_factory: Optional[T_StateFactory]``: 默认 state 的工厂函数
:返回:
- ``Type[Matcher]``
"""
final_kwargs = self.base_kwargs.copy()
final_kwargs.update(kwargs)
matcher = on(**final_kwargs)
self.matchers.append(matcher)
return matcher
def on_metaevent(self, **kwargs) -> Type[Matcher]:
"""
:说明:
注册一个元事件响应器
:参数:
2020-12-17 21:09:30 +08:00
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
* ``handlers: Optional[List[T_Handler]]``: 事件处理函数列表
* ``temp: bool``: 是否为临时事件响应器仅执行一次
* ``priority: int``: 事件响应器优先级
* ``block: bool``: 是否阻止事件向更低优先级传递
* ``state: Optional[T_State]``: 默认 state
* ``state_factory: Optional[T_StateFactory]``: 默认 state 的工厂函数
:返回:
- ``Type[Matcher]``
"""
final_kwargs = self.base_kwargs.copy()
final_kwargs.update(kwargs)
2020-12-04 01:55:03 +08:00
final_kwargs.pop("type", None)
matcher = on_metaevent(**final_kwargs)
self.matchers.append(matcher)
return matcher
def on_message(self, **kwargs) -> Type[Matcher]:
"""
:说明:
注册一个消息事件响应器
:参数:
2020-12-17 21:09:30 +08:00
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
* ``permission: Optional[Permission]``: 事件响应权限
2020-12-17 21:09:30 +08:00
* ``handlers: Optional[List[T_Handler]]``: 事件处理函数列表
* ``temp: bool``: 是否为临时事件响应器仅执行一次
* ``priority: int``: 事件响应器优先级
* ``block: bool``: 是否阻止事件向更低优先级传递
* ``state: Optional[T_State]``: 默认 state
* ``state_factory: Optional[T_StateFactory]``: 默认 state 的工厂函数
:返回:
- ``Type[Matcher]``
"""
final_kwargs = self.base_kwargs.copy()
final_kwargs.update(kwargs)
2020-12-04 01:55:03 +08:00
final_kwargs.pop("type", None)
matcher = on_message(**final_kwargs)
self.matchers.append(matcher)
return matcher
def on_notice(self, **kwargs) -> Type[Matcher]:
"""
:说明:
注册一个通知事件响应器
:参数:
2020-12-17 21:09:30 +08:00
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
* ``handlers: Optional[List[T_Handler]]``: 事件处理函数列表
* ``temp: bool``: 是否为临时事件响应器仅执行一次
* ``priority: int``: 事件响应器优先级
* ``block: bool``: 是否阻止事件向更低优先级传递
* ``state: Optional[T_State]``: 默认 state
* ``state_factory: Optional[T_StateFactory]``: 默认 state 的工厂函数
:返回:
- ``Type[Matcher]``
"""
final_kwargs = self.base_kwargs.copy()
final_kwargs.update(kwargs)
2020-12-04 01:55:03 +08:00
final_kwargs.pop("type", None)
matcher = on_notice(**final_kwargs)
self.matchers.append(matcher)
return matcher
def on_request(self, **kwargs) -> Type[Matcher]:
"""
:说明:
注册一个请求事件响应器
:参数:
2020-12-17 21:09:30 +08:00
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
* ``handlers: Optional[List[T_Handler]]``: 事件处理函数列表
* ``temp: bool``: 是否为临时事件响应器仅执行一次
* ``priority: int``: 事件响应器优先级
* ``block: bool``: 是否阻止事件向更低优先级传递
* ``state: Optional[T_State]``: 默认 state
* ``state_factory: Optional[T_StateFactory]``: 默认 state 的工厂函数
:返回:
- ``Type[Matcher]``
"""
final_kwargs = self.base_kwargs.copy()
final_kwargs.update(kwargs)
2020-12-04 01:55:03 +08:00
final_kwargs.pop("type", None)
matcher = on_request(**final_kwargs)
self.matchers.append(matcher)
return matcher
2021-02-05 11:49:12 +08:00
def on_startswith(self, msg: str, **kwargs) -> Type[Matcher]:
"""
:说明:
注册一个消息事件响应器并且当消息的**文本部分**以指定内容开头时响应
:参数:
* ``msg: str``: 指定消息开头内容
2020-12-17 21:09:30 +08:00
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
* ``permission: Optional[Permission]``: 事件响应权限
2020-12-17 21:09:30 +08:00
* ``handlers: Optional[List[T_Handler]]``: 事件处理函数列表
* ``temp: bool``: 是否为临时事件响应器仅执行一次
* ``priority: int``: 事件响应器优先级
* ``block: bool``: 是否阻止事件向更低优先级传递
* ``state: Optional[T_State]``: 默认 state
* ``state_factory: Optional[T_StateFactory]``: 默认 state 的工厂函数
:返回:
- ``Type[Matcher]``
"""
2021-02-05 11:49:12 +08:00
final_kwargs = self.base_kwargs.copy()
final_kwargs.update(kwargs)
final_kwargs.pop("type", None)
matcher = on_startswith(msg, **final_kwargs)
self.matchers.append(matcher)
return matcher
2021-02-05 11:49:12 +08:00
def on_endswith(self, msg: str, **kwargs) -> Type[Matcher]:
"""
:说明:
注册一个消息事件响应器并且当消息的**文本部分**以指定内容结尾时响应
:参数:
* ``msg: str``: 指定消息结尾内容
2020-12-17 21:09:30 +08:00
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
* ``permission: Optional[Permission]``: 事件响应权限
2020-12-17 21:09:30 +08:00
* ``handlers: Optional[List[T_Handler]]``: 事件处理函数列表
* ``temp: bool``: 是否为临时事件响应器仅执行一次
* ``priority: int``: 事件响应器优先级
* ``block: bool``: 是否阻止事件向更低优先级传递
* ``state: Optional[T_State]``: 默认 state
* ``state_factory: Optional[T_StateFactory]``: 默认 state 的工厂函数
:返回:
- ``Type[Matcher]``
"""
2021-02-05 11:49:12 +08:00
final_kwargs = self.base_kwargs.copy()
final_kwargs.update(kwargs)
final_kwargs.pop("type", None)
matcher = on_endswith(msg, **final_kwargs)
self.matchers.append(matcher)
return matcher
2021-02-05 11:49:12 +08:00
def on_keyword(self, keywords: Set[str], **kwargs) -> Type[Matcher]:
"""
:说明:
注册一个消息事件响应器并且当消息纯文本部分包含关键词时响应
:参数:
* ``keywords: Set[str]``: 关键词列表
2020-12-17 21:09:30 +08:00
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
* ``permission: Optional[Permission]``: 事件响应权限
2020-12-17 21:09:30 +08:00
* ``handlers: Optional[List[T_Handler]]``: 事件处理函数列表
* ``temp: bool``: 是否为临时事件响应器仅执行一次
* ``priority: int``: 事件响应器优先级
* ``block: bool``: 是否阻止事件向更低优先级传递
* ``state: Optional[T_State]``: 默认 state
* ``state_factory: Optional[T_StateFactory]``: 默认 state 的工厂函数
:返回:
- ``Type[Matcher]``
"""
2021-02-05 11:49:12 +08:00
final_kwargs = self.base_kwargs.copy()
final_kwargs.update(kwargs)
final_kwargs.pop("type", None)
matcher = on_keyword(keywords, **final_kwargs)
self.matchers.append(matcher)
return matcher
def on_command(self,
cmd: Union[str, Tuple[str, ...]],
aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = None,
**kwargs) -> Type[Matcher]:
"""
:说明:
注册一个消息事件响应器并且当消息以指定命令开头时响应
命令匹配规则参考: `命令形式匹配 <rule.html#command-command>`_
:参数:
* ``cmd: Union[str, Tuple[str, ...]]``: 指定命令内容
* ``aliases: Optional[Set[Union[str, Tuple[str, ...]]]]``: 命令别名
2021-02-05 11:49:12 +08:00
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
* ``permission: Optional[Permission]``: 事件响应权限
2020-12-17 21:09:30 +08:00
* ``handlers: Optional[List[T_Handler]]``: 事件处理函数列表
* ``temp: bool``: 是否为临时事件响应器仅执行一次
* ``priority: int``: 事件响应器优先级
* ``block: bool``: 是否阻止事件向更低优先级传递
* ``state: Optional[T_State]``: 默认 state
* ``state_factory: Optional[T_StateFactory]``: 默认 state 的工厂函数
:返回:
- ``Type[Matcher]``
"""
2021-02-05 11:49:12 +08:00
final_kwargs = self.base_kwargs.copy()
final_kwargs.update(kwargs)
final_kwargs.pop("type", None)
matcher = on_command(cmd, aliases=aliases, **final_kwargs)
self.matchers.append(matcher)
return matcher
2021-02-02 11:59:14 +08:00
def on_shell_command(self,
cmd: Union[str, Tuple[str, ...]],
aliases: Optional[Set[Union[str, Tuple[str,
...]]]] = None,
parser: Optional[ArgumentParser] = None,
**kwargs) -> Type[Matcher]:
"""
:说明:
2021-02-05 11:49:12 +08:00
注册一个支持 ``shell_like`` 解析参数的命令消息事件响应器
2021-02-02 11:59:14 +08:00
2021-02-05 11:49:12 +08:00
与普通的 ``on_command`` 不同的是在添加 ``parser`` 参数时, 响应器会自动处理消息
2021-02-02 11:59:14 +08:00
2021-02-05 11:49:12 +08:00
并将用户输入的原始参数列表保存在 ``state["argv"]``, ``parser`` 处理的参数保存在 ``state["args"]``
2021-02-02 11:59:14 +08:00
:参数:
2021-02-05 11:49:12 +08:00
* ``cmd: Union[str, Tuple[str, ...]]``: 指定命令内容
* ``aliases: Optional[Set[Union[str, Tuple[str, ...]]]]``: 命令别名
* ``parser: Optional[ArgumentParser]``: ``nonebot.rule.ArgumentParser`` 对象
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
* ``permission: Optional[Permission]``: 事件响应权限
* ``handlers: Optional[List[T_Handler]]``: 事件处理函数列表
* ``temp: bool``: 是否为临时事件响应器仅执行一次
* ``priority: int``: 事件响应器优先级
* ``block: bool``: 是否阻止事件向更低优先级传递
* ``state: Optional[T_State]``: 默认 state
* ``state_factory: Optional[T_StateFactory]``: 默认 state 的工厂函数
2021-02-02 11:59:14 +08:00
:返回:
2021-02-05 11:49:12 +08:00
- ``Type[Matcher]``
2021-02-02 11:59:14 +08:00
"""
2021-02-05 11:49:12 +08:00
final_kwargs = self.base_kwargs.copy()
final_kwargs.update(kwargs)
final_kwargs.pop("type", None)
matcher = on_shell_command(cmd,
aliases=aliases,
parser=parser,
**final_kwargs)
self.matchers.append(matcher)
return matcher
2021-02-02 11:59:14 +08:00
def on_regex(self,
pattern: str,
flags: Union[int, re.RegexFlag] = 0,
**kwargs) -> Type[Matcher]:
"""
:说明:
注册一个消息事件响应器并且当消息匹配正则表达式时响应
命令匹配规则参考: `正则匹配 <rule.html#regex-regex-flags-0>`_
:参数:
* ``pattern: str``: 正则表达式
* ``flags: Union[int, re.RegexFlag]``: 正则匹配标志
2020-12-17 21:09:30 +08:00
* ``rule: Optional[Union[Rule, T_RuleChecker]]``: 事件响应规则
* ``permission: Optional[Permission]``: 事件响应权限
2020-12-17 21:09:30 +08:00
* ``handlers: Optional[List[T_Handler]]``: 事件处理函数列表
* ``temp: bool``: 是否为临时事件响应器仅执行一次
* ``priority: int``: 事件响应器优先级
* ``block: bool``: 是否阻止事件向更低优先级传递
* ``state: Optional[T_State]``: 默认 state
* ``state_factory: Optional[T_StateFactory]``: 默认 state 的工厂函数
:返回:
- ``Type[Matcher]``
"""
2021-02-05 11:49:12 +08:00
final_kwargs = self.base_kwargs.copy()
final_kwargs.update(kwargs)
final_kwargs.pop("type", None)
matcher = on_regex(pattern, flags=flags, **final_kwargs)
self.matchers.append(matcher)
return matcher
2021-02-19 15:15:46 +08:00
def _load_plugin(manager: PluginManager, plugin_name: str) -> Optional[Plugin]:
if plugin_name.startswith("_"):
return None
_tmp_matchers.set(set())
_export.set(Export())
if plugin_name in plugins:
return None
try:
module = manager.load_plugin(plugin_name)
for m in _tmp_matchers.get():
m.module = plugin_name
plugin = Plugin(plugin_name, module, _tmp_matchers.get(), _export.get())
plugins[plugin_name] = plugin
logger.opt(
colors=True).info(f'Succeeded to import "<y>{plugin_name}</y>"')
return plugin
except Exception as e:
logger.opt(colors=True, exception=e).error(
f'<r><bg #f8bbd0>Failed to import "{plugin_name}"</bg #f8bbd0></r>')
return None
2020-06-30 10:13:58 +08:00
def load_plugin(module_path: str) -> Optional[Plugin]:
2020-10-18 15:04:45 +08:00
"""
:说明:
2020-11-30 11:08:00 +08:00
2021-02-19 14:58:26 +08:00
使用 ``PluginManager`` 加载单个插件可以是本地插件或是通过 ``pip`` 安装的插件
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:参数:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
* ``module_path: str``: 插件名称 ``path.to.your.plugin``
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:返回:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
- ``Optional[Plugin]``
"""
2020-11-21 20:40:09 +08:00
context: Context = copy_context()
2021-02-19 15:15:46 +08:00
manager = PluginManager(PLUGIN_NAMESPACE, plugins=[module_path])
return context.run(_load_plugin, manager, module_path)
2020-06-30 10:13:58 +08:00
2020-08-15 17:22:10 +08:00
def load_plugins(*plugin_dir: str) -> Set[Plugin]:
2020-10-18 15:04:45 +08:00
"""
:说明:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
导入目录下多个插件 ``_`` 开头的插件不会被导入
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:参数:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
- ``*plugin_dir: str``: 插件路径
2020-11-30 11:08:00 +08:00
2021-02-19 15:15:46 +08:00
:返回:
- ``Set[Plugin]``
"""
loaded_plugins = set()
manager = PluginManager(PLUGIN_NAMESPACE, search_path=plugin_dir)
for plugin_name in manager.list_plugins():
context: Context = copy_context()
result = context.run(_load_plugin, manager, plugin_name)
if result:
loaded_plugins.add(result)
return loaded_plugins
def load_all_plugins(module_path: Set[str],
plugin_dir: Set[str]) -> Set[Plugin]:
"""
:说明:
导入指定列表中的插件以及指定目录下多个插件 ``_`` 开头的插件不会被导入
:参数:
- ``module_path: Set[str]``: 指定插件集合
- ``plugin_dir: Set[str]``: 指定插件路径集合
2020-10-18 15:04:45 +08:00
:返回:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
- ``Set[Plugin]``
"""
2020-11-21 20:40:09 +08:00
2021-02-19 14:58:26 +08:00
def _load_plugin(plugin_name: str) -> Optional[Plugin]:
if plugin_name.startswith("_"):
return None
2020-11-21 20:40:09 +08:00
_tmp_matchers.set(set())
_export.set(Export())
2020-06-30 10:13:58 +08:00
2021-02-19 14:58:26 +08:00
if plugin_name in plugins:
2020-12-17 21:09:30 +08:00
return None
2020-08-24 17:59:36 +08:00
2020-08-15 17:22:10 +08:00
try:
2021-02-19 14:58:26 +08:00
module = manager.load_plugin(plugin_name)
2020-08-15 17:22:10 +08:00
2020-11-21 20:40:09 +08:00
for m in _tmp_matchers.get():
2021-02-19 14:58:26 +08:00
m.module = plugin_name
plugin = Plugin(plugin_name, module, _tmp_matchers.get(),
_export.get())
plugins[plugin_name] = plugin
logger.opt(
colors=True).info(f'Succeeded to import "<y>{plugin_name}</y>"')
2020-11-21 20:40:09 +08:00
return plugin
2020-08-15 17:22:10 +08:00
except Exception as e:
2020-08-27 13:27:42 +08:00
logger.opt(colors=True, exception=e).error(
2021-02-19 14:58:26 +08:00
f'<r><bg #f8bbd0>Failed to import "{plugin_name}"</bg #f8bbd0></r>'
)
2020-11-21 20:40:09 +08:00
return None
loaded_plugins = set()
2021-02-19 15:15:46 +08:00
manager = PluginManager(PLUGIN_NAMESPACE, module_path, plugin_dir)
2021-02-19 14:58:26 +08:00
for plugin_name in manager.list_plugins():
2020-11-21 20:40:09 +08:00
context: Context = copy_context()
2021-02-19 14:58:26 +08:00
result = context.run(_load_plugin, plugin_name)
2020-11-21 20:40:09 +08:00
if result:
loaded_plugins.add(result)
2020-08-15 17:22:10 +08:00
return loaded_plugins
2020-06-30 10:13:58 +08:00
def load_from_json(file_path: str, encoding: str = "utf-8") -> Set[Plugin]:
2021-02-24 17:56:43 +08:00
"""
:说明:
导入指定 json 文件中的 ``plugins`` 以及 ``plugin_dirs`` 下多个插件 ``_`` 开头的插件不会被导入
:参数:
- ``file_path: str``: 指定 json 文件路径
- ``encoding: str``: 指定 json 文件编码
:返回:
- ``Set[Plugin]``
"""
with open(file_path, "r", encoding=encoding) as f:
data = json.load(f)
plugins = data.get("plugins")
plugin_dirs = data.get("plugin_dirs")
assert isinstance(plugins, list), "plugins must be a list of plugin name"
assert isinstance(plugin_dirs,
list), "plugin_dirs must be a list of directories"
return load_all_plugins(set(plugins), set(plugin_dirs))
def load_from_toml(file_path: str, encoding: str = "utf-8") -> Set[Plugin]:
2021-02-24 17:56:43 +08:00
"""
:说明:
导入指定 toml 文件 ``[nonebot.plugins]`` 中的 ``plugins`` 以及 ``plugin_dirs`` 下多个插件
``_`` 开头的插件不会被导入
:参数:
- ``file_path: str``: 指定 toml 文件路径
- ``encoding: str``: 指定 toml 文件编码
:返回:
- ``Set[Plugin]``
"""
with open(file_path, "r", encoding=encoding) as f:
data = tomlkit.parse(f.read())
nonebot_data = data.get("nonebot", {}).get("plugins")
if not nonebot_data:
raise ValueError("Cannot find '[nonebot.plugins]' in given toml file!")
plugins = nonebot_data.get("plugins", [])
plugin_dirs = nonebot_data.get("plugin_dirs", [])
assert isinstance(plugins, list), "plugins must be a list of plugin name"
assert isinstance(plugin_dirs,
list), "plugin_dirs must be a list of directories"
return load_all_plugins(set(plugins), set(plugin_dirs))
2021-01-25 18:15:25 +08:00
def load_builtin_plugins(name: str = "echo") -> Optional[Plugin]:
2020-10-18 15:04:45 +08:00
"""
:说明:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
导入 NoneBot 内置插件
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:返回:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
- ``Plugin``
"""
2021-01-25 18:15:25 +08:00
return load_plugin(f"nonebot.plugins.{name}")
2020-11-21 18:33:35 +08:00
def get_plugin(name: str) -> Optional[Plugin]:
"""
:说明:
2020-11-30 11:08:00 +08:00
2020-11-21 18:33:35 +08:00
获取当前导入的某个插件
2020-11-30 11:08:00 +08:00
2020-11-21 18:33:35 +08:00
:参数:
2020-11-30 11:08:00 +08:00
2020-11-21 18:33:35 +08:00
* ``name: str``: 插件名 ``load_plugin`` 参数一致如果为 ``load_plugins`` 导入的插件则为文件()
2020-11-30 11:08:00 +08:00
2020-11-21 18:33:35 +08:00
:返回:
2020-11-30 11:08:00 +08:00
2020-11-21 18:33:35 +08:00
- ``Optional[Plugin]``
"""
return plugins.get(name)
2020-06-30 10:13:58 +08:00
def get_loaded_plugins() -> Set[Plugin]:
2020-10-18 15:04:45 +08:00
"""
:说明:
2020-11-30 11:08:00 +08:00
2020-11-21 18:33:35 +08:00
获取当前已导入的所有插件
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
:返回:
2020-11-30 11:08:00 +08:00
2020-10-18 15:04:45 +08:00
- ``Set[Plugin]``
"""
2020-06-30 10:13:58 +08:00
return set(plugins.values())
2020-11-21 20:40:09 +08:00
def export() -> Export:
2020-11-21 20:50:33 +08:00
"""
:说明:
2020-11-30 11:08:00 +08:00
2020-11-21 20:50:33 +08:00
获取插件的导出内容对象
2020-11-30 11:08:00 +08:00
2020-11-21 20:50:33 +08:00
:返回:
2020-11-30 11:08:00 +08:00
2020-11-21 20:50:33 +08:00
- ``Export``
"""
2020-11-21 20:40:09 +08:00
return _export.get()
def require(name: str) -> Optional[Export]:
2020-11-21 20:50:33 +08:00
"""
:说明:
2020-11-30 11:08:00 +08:00
2020-11-21 20:50:33 +08:00
获取一个插件的导出内容
2020-11-30 11:08:00 +08:00
2020-11-21 20:50:33 +08:00
:参数:
2020-11-30 11:08:00 +08:00
2020-11-21 20:50:33 +08:00
* ``name: str``: 插件名 ``load_plugin`` 参数一致如果为 ``load_plugins`` 导入的插件则为文件()
2020-11-30 11:08:00 +08:00
2020-11-21 20:50:33 +08:00
:返回:
2020-11-30 11:08:00 +08:00
2020-11-21 20:50:33 +08:00
- ``Optional[Export]``
"""
plugin = get_plugin(name) or load_plugin(name)
2020-11-21 20:40:09 +08:00
return plugin.export if plugin else None