2020-10-18 15:04:45 +08:00
"""
插件
== ==
为 NoneBot 插件开发提供便携的定义函数 。
"""
2020-08-17 16:09:41 +08:00
import re
2021-02-24 17:48:08 +08:00
import json
2020-12-06 02:30:19 +08:00
from types import ModuleType
2020-08-29 22:32:40 +08:00
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
2021-02-24 17:48:08 +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
2020-12-20 11:59:23 +08:00
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
2020-08-29 22:32:40 +08:00
@dataclass ( eq = False )
2020-06-30 10:13:58 +08:00
class Plugin ( object ) :
2020-10-18 15:04:45 +08:00
""" 存储插件信息 """
2020-08-29 22:32:40 +08:00
name : str
2020-10-18 15:04:45 +08:00
"""
- * * 类型 * * : ` ` str ` `
- * * 说明 * * : 插件名称 , 使用 文件 / 文件夹 名称作为插件名
"""
2020-08-29 22:32:40 +08:00
module : ModuleType
2020-10-18 15:04:45 +08:00
"""
- * * 类型 * * : ` ` ModuleType ` `
- * * 说明 * * : 插件模块对象
"""
2020-08-29 22:32:40 +08:00
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 ,
2020-08-25 15:23:10 +08:00
temp : bool = False ,
2020-08-20 17:15:05 +08:00
priority : int = 1 ,
2020-08-21 14:24:32 +08:00
block : bool = False ,
2020-12-20 11:59:23 +08:00
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 ` ` : 是否阻止事件向更低优先级传递
2020-12-20 11:59:23 +08:00
* ` ` 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 ,
2020-08-21 14:24:32 +08:00
block = block ,
2020-08-20 17:15:05 +08:00
handlers = handlers ,
2020-12-20 11:59:23 +08:00
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
2020-12-20 11:59:23 +08:00
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 ` ` : 是否阻止事件向更低优先级传递
2020-12-20 11:59:23 +08:00
* ` ` 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 ,
2020-08-21 14:24:32 +08:00
block = block ,
2020-07-25 12:28:30 +08:00
handlers = handlers ,
2020-12-20 11:59:23 +08:00
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 ,
2020-08-25 15:23:10 +08:00
temp : bool = False ,
2020-06-30 10:13:58 +08:00
priority : int = 1 ,
2020-08-21 14:24:32 +08:00
block : bool = True ,
2020-12-20 11:59:23 +08:00
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 ` ` : 是否阻止事件向更低优先级传递
2020-12-20 11:59:23 +08:00
* ` ` 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 ,
2020-08-21 14:24:32 +08:00
block = block ,
2020-07-25 12:28:30 +08:00
handlers = handlers ,
2020-12-20 11:59:23 +08:00
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 ,
2020-08-25 15:23:10 +08:00
temp : bool = False ,
2020-07-25 12:28:30 +08:00
priority : int = 1 ,
2020-08-21 14:24:32 +08:00
block : bool = False ,
2020-12-20 11:59:23 +08:00
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 ` ` : 是否阻止事件向更低优先级传递
2020-12-20 11:59:23 +08:00
* ` ` 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 ,
2020-08-21 14:24:32 +08:00
block = block ,
2020-07-25 12:28:30 +08:00
handlers = handlers ,
2020-12-20 11:59:23 +08:00
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 ,
2020-08-25 15:23:10 +08:00
temp : bool = False ,
2020-07-25 12:28:30 +08:00
priority : int = 1 ,
2020-08-21 14:24:32 +08:00
block : bool = False ,
2020-12-20 11:59:23 +08:00
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 ` ` : 是否阻止事件向更低优先级传递
2020-12-20 11:59:23 +08:00
* ` ` 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 ,
2020-08-21 14:24:32 +08:00
block = block ,
2020-06-30 10:13:58 +08:00
handlers = handlers ,
2020-12-20 11:59:23 +08:00
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 ` ` : 是否阻止事件向更低优先级传递
2020-12-20 11:59:23 +08:00
* ` ` 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-30 16:26:04 +08:00
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 ` ` : 是否阻止事件向更低优先级传递
2020-12-20 11:59:23 +08:00
* ` ` 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-30 16:26:04 +08:00
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 ,
2020-10-30 16:26:04 +08:00
* * kwargs ) - > Type [ Matcher ] :
"""
: 说明 :
2020-11-30 11:08:00 +08:00
2020-10-30 16:26:04 +08:00
注册一个消息事件响应器 , 并且当消息纯文本部分包含关键词时响应 。
2020-11-30 11:08:00 +08:00
2020-10-30 16:26:04 +08:00
: 参数 :
2020-11-30 11:08:00 +08:00
2020-10-30 16:26:04 +08:00
* ` ` keywords : Set [ str ] ` ` : 关键词列表
2020-12-17 21:09:30 +08:00
* ` ` rule : Optional [ Union [ Rule , T_RuleChecker ] ] ` ` : 事件响应规则
2020-10-30 16:26:04 +08:00
* ` ` permission : Optional [ Permission ] ` ` : 事件响应权限
2020-12-17 21:09:30 +08:00
* ` ` handlers : Optional [ List [ T_Handler ] ] ` ` : 事件处理函数列表
2020-10-30 16:26:04 +08:00
* ` ` temp : bool ` ` : 是否为临时事件响应器 ( 仅执行一次 )
* ` ` priority : int ` ` : 事件响应器优先级
* ` ` block : bool ` ` : 是否阻止事件向更低优先级传递
2020-12-20 11:59:23 +08:00
* ` ` state : Optional [ T_State ] ` ` : 默认 state
* ` ` state_factory : Optional [ T_StateFactory ] ` ` : 默认 state 的工厂函数
2020-11-30 11:08:00 +08:00
2020-10-30 16:26:04 +08:00
: 返回 :
2020-11-30 11:08:00 +08:00
2020-10-30 16:26:04 +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 ` ` : 是否阻止事件向更低优先级传递
2020-12-20 11:59:23 +08:00
* ` ` 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-29 21:59:36 +08:00
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 )
2020-08-29 21:59:36 +08:00
handlers = kwargs . pop ( " handlers " , [ ] )
handlers . insert ( 0 , _strip_cmd )
2020-10-22 22:08:19 +08:00
commands = set ( [ cmd ] ) | ( aliases or set ( ) )
2020-10-30 16:26:04 +08:00
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 ,
rule : Optional [ Rule ] = None ,
* * 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 ` ` : 是否阻止事件向更低优先级传递
2020-12-20 11:59:23 +08:00
* ` ` 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-30 16:26:04 +08:00
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
2020-12-04 01:41:23 +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 ] ] ` ` : 事件响应规则
2020-12-04 01:41:23 +08:00
* ` ` permission : Optional [ Permission ] ` ` : 事件响应权限
2020-12-17 21:09:30 +08:00
* ` ` handlers : Optional [ List [ T_Handler ] ] ` ` : 事件处理函数列表
2020-12-04 01:41:23 +08:00
* ` ` temp : bool ` ` : 是否为临时事件响应器 ( 仅执行一次 )
* ` ` priority : int ` ` : 事件响应器优先级
* ` ` block : bool ` ` : 是否阻止事件向更低优先级传递
2020-12-20 11:59:23 +08:00
* ` ` state : Optional [ T_State ] ` ` : 默认 state
* ` ` state_factory : Optional [ T_StateFactory ] ` ` : 默认 state 的工厂函数
2020-12-04 01:41:23 +08:00
: 返回 :
- ` ` Type [ Matcher ] ` `
"""
final_kwargs = self . base_kwargs . copy ( )
final_kwargs . update ( kwargs )
2020-12-20 11:59:23 +08:00
matcher = on ( * * final_kwargs )
2020-12-04 01:41:23 +08:00
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 ] ] ` ` : 事件处理函数列表
2020-12-04 01:41:23 +08:00
* ` ` temp : bool ` ` : 是否为临时事件响应器 ( 仅执行一次 )
* ` ` priority : int ` ` : 事件响应器优先级
* ` ` block : bool ` ` : 是否阻止事件向更低优先级传递
2020-12-20 11:59:23 +08:00
* ` ` state : Optional [ T_State ] ` ` : 默认 state
* ` ` state_factory : Optional [ T_StateFactory ] ` ` : 默认 state 的工厂函数
2020-12-04 01:41:23 +08:00
: 返回 :
- ` ` 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 )
2020-12-20 11:59:23 +08:00
matcher = on_metaevent ( * * final_kwargs )
2020-12-04 01:41:23 +08:00
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 ] ] ` ` : 事件响应规则
2020-12-04 01:41:23 +08:00
* ` ` permission : Optional [ Permission ] ` ` : 事件响应权限
2020-12-17 21:09:30 +08:00
* ` ` handlers : Optional [ List [ T_Handler ] ] ` ` : 事件处理函数列表
2020-12-04 01:41:23 +08:00
* ` ` temp : bool ` ` : 是否为临时事件响应器 ( 仅执行一次 )
* ` ` priority : int ` ` : 事件响应器优先级
* ` ` block : bool ` ` : 是否阻止事件向更低优先级传递
2020-12-20 11:59:23 +08:00
* ` ` state : Optional [ T_State ] ` ` : 默认 state
* ` ` state_factory : Optional [ T_StateFactory ] ` ` : 默认 state 的工厂函数
2020-12-04 01:41:23 +08:00
: 返回 :
- ` ` 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 )
2020-12-20 11:59:23 +08:00
matcher = on_message ( * * final_kwargs )
2020-12-04 01:41:23 +08:00
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 ] ] ` ` : 事件处理函数列表
2020-12-04 01:41:23 +08:00
* ` ` temp : bool ` ` : 是否为临时事件响应器 ( 仅执行一次 )
* ` ` priority : int ` ` : 事件响应器优先级
* ` ` block : bool ` ` : 是否阻止事件向更低优先级传递
2020-12-20 11:59:23 +08:00
* ` ` state : Optional [ T_State ] ` ` : 默认 state
* ` ` state_factory : Optional [ T_StateFactory ] ` ` : 默认 state 的工厂函数
2020-12-04 01:41:23 +08:00
: 返回 :
- ` ` 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 )
2020-12-20 11:59:23 +08:00
matcher = on_notice ( * * final_kwargs )
2020-12-04 01:41:23 +08:00
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 ] ] ` ` : 事件处理函数列表
2020-12-04 01:41:23 +08:00
* ` ` temp : bool ` ` : 是否为临时事件响应器 ( 仅执行一次 )
* ` ` priority : int ` ` : 事件响应器优先级
* ` ` block : bool ` ` : 是否阻止事件向更低优先级传递
2020-12-20 11:59:23 +08:00
* ` ` state : Optional [ T_State ] ` ` : 默认 state
* ` ` state_factory : Optional [ T_StateFactory ] ` ` : 默认 state 的工厂函数
2020-12-04 01:41:23 +08:00
: 返回 :
- ` ` 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 )
2020-12-20 11:59:23 +08:00
matcher = on_request ( * * final_kwargs )
2020-12-04 01:41:23 +08:00
self . matchers . append ( matcher )
return matcher
2021-02-05 11:49:12 +08:00
def on_startswith ( self , msg : str , * * kwargs ) - > Type [ Matcher ] :
2020-12-04 01:41:23 +08:00
"""
: 说明 :
注册一个消息事件响应器 , 并且当消息的 * * 文本部分 * * 以指定内容开头时响应 。
: 参数 :
* ` ` msg : str ` ` : 指定消息开头内容
2020-12-17 21:09:30 +08:00
* ` ` rule : Optional [ Union [ Rule , T_RuleChecker ] ] ` ` : 事件响应规则
2020-12-04 01:41:23 +08:00
* ` ` permission : Optional [ Permission ] ` ` : 事件响应权限
2020-12-17 21:09:30 +08:00
* ` ` handlers : Optional [ List [ T_Handler ] ] ` ` : 事件处理函数列表
2020-12-04 01:41:23 +08:00
* ` ` temp : bool ` ` : 是否为临时事件响应器 ( 仅执行一次 )
* ` ` priority : int ` ` : 事件响应器优先级
* ` ` block : bool ` ` : 是否阻止事件向更低优先级传递
2020-12-20 11:59:23 +08:00
* ` ` state : Optional [ T_State ] ` ` : 默认 state
* ` ` state_factory : Optional [ T_StateFactory ] ` ` : 默认 state 的工厂函数
2020-12-04 01:41:23 +08:00
: 返回 :
- ` ` 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
2020-12-04 01:41:23 +08:00
2021-02-05 11:49:12 +08:00
def on_endswith ( self , msg : str , * * kwargs ) - > Type [ Matcher ] :
2020-12-04 01:41:23 +08:00
"""
: 说明 :
注册一个消息事件响应器 , 并且当消息的 * * 文本部分 * * 以指定内容结尾时响应 。
: 参数 :
* ` ` msg : str ` ` : 指定消息结尾内容
2020-12-17 21:09:30 +08:00
* ` ` rule : Optional [ Union [ Rule , T_RuleChecker ] ] ` ` : 事件响应规则
2020-12-04 01:41:23 +08:00
* ` ` permission : Optional [ Permission ] ` ` : 事件响应权限
2020-12-17 21:09:30 +08:00
* ` ` handlers : Optional [ List [ T_Handler ] ] ` ` : 事件处理函数列表
2020-12-04 01:41:23 +08:00
* ` ` temp : bool ` ` : 是否为临时事件响应器 ( 仅执行一次 )
* ` ` priority : int ` ` : 事件响应器优先级
* ` ` block : bool ` ` : 是否阻止事件向更低优先级传递
2020-12-20 11:59:23 +08:00
* ` ` state : Optional [ T_State ] ` ` : 默认 state
* ` ` state_factory : Optional [ T_StateFactory ] ` ` : 默认 state 的工厂函数
2020-12-04 01:41:23 +08:00
: 返回 :
- ` ` 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
2020-12-04 01:41:23 +08:00
2021-02-05 11:49:12 +08:00
def on_keyword ( self , keywords : Set [ str ] , * * kwargs ) - > Type [ Matcher ] :
2020-12-04 01:41:23 +08:00
"""
: 说明 :
注册一个消息事件响应器 , 并且当消息纯文本部分包含关键词时响应 。
: 参数 :
* ` ` keywords : Set [ str ] ` ` : 关键词列表
2020-12-17 21:09:30 +08:00
* ` ` rule : Optional [ Union [ Rule , T_RuleChecker ] ] ` ` : 事件响应规则
2020-12-04 01:41:23 +08:00
* ` ` permission : Optional [ Permission ] ` ` : 事件响应权限
2020-12-17 21:09:30 +08:00
* ` ` handlers : Optional [ List [ T_Handler ] ] ` ` : 事件处理函数列表
2020-12-04 01:41:23 +08:00
* ` ` temp : bool ` ` : 是否为临时事件响应器 ( 仅执行一次 )
* ` ` priority : int ` ` : 事件响应器优先级
* ` ` block : bool ` ` : 是否阻止事件向更低优先级传递
2020-12-20 11:59:23 +08:00
* ` ` state : Optional [ T_State ] ` ` : 默认 state
* ` ` state_factory : Optional [ T_StateFactory ] ` ` : 默认 state 的工厂函数
2020-12-04 01:41:23 +08:00
: 返回 :
- ` ` 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
2020-12-04 01:41:23 +08:00
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 ] ] ` ` : 事件响应规则
2020-12-04 01:41:23 +08:00
* ` ` permission : Optional [ Permission ] ` ` : 事件响应权限
2020-12-17 21:09:30 +08:00
* ` ` handlers : Optional [ List [ T_Handler ] ] ` ` : 事件处理函数列表
2020-12-04 01:41:23 +08:00
* ` ` temp : bool ` ` : 是否为临时事件响应器 ( 仅执行一次 )
* ` ` priority : int ` ` : 事件响应器优先级
* ` ` block : bool ` ` : 是否阻止事件向更低优先级传递
2020-12-20 11:59:23 +08:00
* ` ` state : Optional [ T_State ] ` ` : 默认 state
* ` ` state_factory : Optional [ T_StateFactory ] ` ` : 默认 state 的工厂函数
2020-12-04 01:41:23 +08:00
: 返回 :
- ` ` 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
2020-12-04 01:41:23 +08:00
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
2020-12-04 01:41:23 +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 ] ] ` ` : 事件响应规则
2020-12-04 01:41:23 +08:00
* ` ` permission : Optional [ Permission ] ` ` : 事件响应权限
2020-12-17 21:09:30 +08:00
* ` ` handlers : Optional [ List [ T_Handler ] ] ` ` : 事件处理函数列表
2020-12-04 01:41:23 +08:00
* ` ` temp : bool ` ` : 是否为临时事件响应器 ( 仅执行一次 )
* ` ` priority : int ` ` : 事件响应器优先级
* ` ` block : bool ` ` : 是否阻止事件向更低优先级传递
2020-12-20 11:59:23 +08:00
* ` ` state : Optional [ T_State ] ` ` : 默认 state
* ` ` state_factory : Optional [ T_StateFactory ] ` ` : 默认 state 的工厂函数
2020-12-04 01:41:23 +08:00
: 返回 :
- ` ` 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
2020-12-04 01:41:23 +08:00
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
2021-02-24 17:48:08 +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 ] ` `
"""
2021-02-24 17:48:08 +08:00
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 ] ` `
"""
2021-02-24 17:48:08 +08:00
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-08-29 21:59:36 +08:00
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 ] ` `
"""
2020-12-13 12:19:01 +08:00
plugin = get_plugin ( name ) or load_plugin ( name )
2020-11-21 20:40:09 +08:00
return plugin . export if plugin else None