nonebot2/nonebot/plugin.py

208 lines
6.9 KiB
Python
Raw Normal View History

2020-06-30 10:13:58 +08:00
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
2020-08-17 16:09:41 +08:00
import re
2020-08-24 17:59:36 +08:00
import sys
2020-08-15 17:22:10 +08:00
import pkgutil
2020-06-30 10:13:58 +08:00
import importlib
2020-08-24 17:59:36 +08:00
from importlib._bootstrap import _load
2020-06-30 10:13:58 +08:00
2020-07-05 20:39:34 +08:00
from nonebot.log import logger
from nonebot.matcher import Matcher
2020-08-20 17:15:05 +08:00
from nonebot.permission import Permission
2020-08-17 16:09:41 +08:00
from nonebot.rule import Rule, startswith, endswith, command, regex
from nonebot.typing import Set, Dict, Type, Tuple, Union, Optional, ModuleType, RuleChecker
2020-06-30 10:13:58 +08:00
plugins: Dict[str, "Plugin"] = {}
_tmp_matchers: Set[Type[Matcher]] = set()
class Plugin(object):
# TODO: store plugin informations
def __init__(self, module_path: str, module: ModuleType,
matchers: Set[Type[Matcher]]):
self.module_path = module_path
self.module = module
self.matchers = matchers
2020-08-20 17:15:05 +08:00
def on(rule: Union[Rule, RuleChecker] = Rule(),
permission: Permission = Permission(),
*,
handlers: Optional[list] = None,
temp: bool = False,
2020-08-20 17:15:05 +08:00
priority: int = 1,
block: bool = False,
state: Optional[dict] = None) -> Type[Matcher]:
2020-08-20 17:15:05 +08:00
matcher = Matcher.new("",
Rule() & rule,
permission,
temp=temp,
priority=priority,
block=block,
2020-08-20 17:15:05 +08:00
handlers=handlers,
default_state=state)
_tmp_matchers.add(matcher)
return matcher
2020-08-17 16:09:41 +08:00
def on_metaevent(rule: Union[Rule, RuleChecker] = Rule(),
2020-07-25 12:28:30 +08:00
*,
handlers: Optional[list] = None,
temp: bool = False,
2020-07-25 12:28:30 +08:00
priority: int = 1,
block: bool = False,
state: Optional[dict] = None) -> 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)
_tmp_matchers.add(matcher)
return matcher
2020-08-17 16:09:41 +08:00
def on_message(rule: Union[Rule, RuleChecker] = Rule(),
2020-08-20 17:15:05 +08:00
permission: Permission = Permission(),
2020-06-30 10:13:58 +08:00
*,
handlers: Optional[list] = None,
temp: bool = False,
2020-06-30 10:13:58 +08:00
priority: int = 1,
block: bool = True,
state: Optional[dict] = None) -> Type[Matcher]:
2020-08-20 17:15:05 +08:00
matcher = Matcher.new("message",
Rule() & rule,
2020-08-17 16:09:41 +08:00
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)
_tmp_matchers.add(matcher)
return matcher
2020-08-17 16:09:41 +08:00
def on_notice(rule: Union[Rule, RuleChecker] = Rule(),
2020-07-25 12:28:30 +08:00
*,
handlers: Optional[list] = None,
temp: bool = False,
2020-07-25 12:28:30 +08:00
priority: int = 1,
block: bool = False,
state: Optional[dict] = None) -> 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)
_tmp_matchers.add(matcher)
return matcher
2020-08-17 16:09:41 +08:00
def on_request(rule: Union[Rule, RuleChecker] = Rule(),
2020-07-25 12:28:30 +08:00
*,
handlers: Optional[list] = None,
temp: bool = False,
2020-07-25 12:28:30 +08:00
priority: int = 1,
block: bool = False,
state: Optional[dict] = None) -> 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)
_tmp_matchers.add(matcher)
return matcher
2020-08-17 16:09:41 +08:00
def on_startswith(msg: str,
rule: Optional[Union[Rule, RuleChecker]] = None,
2020-08-20 17:15:05 +08:00
permission: Permission = Permission(),
2020-08-17 16:09:41 +08:00
**kwargs) -> Type[Matcher]:
return on_message(startswith(msg) &
rule, permission, **kwargs) if rule else on_message(
startswith(msg), permission, **kwargs)
def on_endswith(msg: str,
rule: Optional[Union[Rule, RuleChecker]] = None,
2020-08-20 17:15:05 +08:00
permission: Permission = Permission(),
2020-08-17 16:09:41 +08:00
**kwargs) -> Type[Matcher]:
return on_message(endswith(msg) &
rule, permission, **kwargs) if rule else on_message(
startswith(msg), permission, **kwargs)
2020-08-23 20:01:58 +08:00
def on_command(cmd: Union[str, Tuple[str, ...]],
2020-08-17 16:09:41 +08:00
rule: Optional[Union[Rule, RuleChecker]] = None,
2020-08-20 17:15:05 +08:00
permission: Permission = Permission(),
2020-08-17 16:09:41 +08:00
**kwargs) -> Type[Matcher]:
2020-08-23 10:45:26 +08:00
if isinstance(cmd, str):
cmd = (cmd,)
2020-08-17 16:09:41 +08:00
return on_message(command(cmd) &
rule, permission, **kwargs) if rule else on_message(
command(cmd), permission, **kwargs)
def on_regex(pattern: str,
flags: Union[int, re.RegexFlag] = 0,
rule: Optional[Rule] = None,
2020-08-20 17:15:05 +08:00
permission: Permission = Permission(),
2020-08-17 16:09:41 +08:00
**kwargs) -> Type[Matcher]:
return on_message(regex(pattern, flags) &
2020-08-20 17:15:05 +08:00
rule, permission, **kwargs) if rule else on_message(
regex(pattern, flags), permission, **kwargs)
2020-06-30 10:13:58 +08:00
def load_plugin(module_path: str) -> Optional[Plugin]:
try:
_tmp_matchers.clear()
module = importlib.import_module(module_path)
plugin = Plugin(module_path, module, _tmp_matchers.copy())
plugins[module_path] = plugin
logger.info(f"Succeeded to import \"{module_path}\"")
return plugin
except Exception as e:
logger.error(f"Failed to import \"{module_path}\", error: {e}")
logger.exception(e)
return None
2020-08-15 17:22:10 +08:00
def load_plugins(*plugin_dir: str) -> Set[Plugin]:
loaded_plugins = set()
for module_info in pkgutil.iter_modules(plugin_dir):
_tmp_matchers.clear()
name = module_info.name
if name.startswith("_"):
2020-06-30 10:13:58 +08:00
continue
2020-08-24 17:59:36 +08:00
spec = module_info.module_finder.find_spec(name)
if spec.name in sys.modules:
continue
2020-08-15 17:22:10 +08:00
try:
2020-08-24 17:59:36 +08:00
module = _load(spec)
2020-08-15 17:22:10 +08:00
plugin = Plugin(name, module, _tmp_matchers.copy())
plugins[name] = plugin
loaded_plugins.add(plugin)
logger.info(f"Succeeded to import \"{name}\"")
except Exception as e:
logger.error(f"Failed to import \"{name}\", error: {e}")
logger.exception(e)
return loaded_plugins
2020-06-30 10:13:58 +08:00
def get_loaded_plugins() -> Set[Plugin]:
return set(plugins.values())