🔧 change command and add builtin plugin

This commit is contained in:
yanyongyu 2020-08-29 21:59:36 +08:00
parent def5caedbc
commit f5b655ef71
6 changed files with 79 additions and 21 deletions

View File

@ -201,4 +201,6 @@ def run(host: Optional[str] = None,
get_driver().run(host, port, *args, **kwargs)
from nonebot.plugin import load_plugin, load_plugins, get_loaded_plugins
from nonebot.plugin import on_message, on_notice, on_request, on_metaevent
from nonebot.plugin import on_startswith, on_endswith, on_command, on_regex
from nonebot.plugin import load_plugin, load_plugins, load_builtin_plugins, get_loaded_plugins

View File

@ -10,8 +10,9 @@ from importlib._bootstrap import _load
from nonebot.log import logger
from nonebot.matcher import Matcher
from nonebot.permission import Permission
from nonebot.typing import Handler, RuleChecker
from nonebot.rule import Rule, startswith, endswith, command, regex
from nonebot.typing import Set, Dict, Type, Tuple, Union, Optional, ModuleType, RuleChecker
from nonebot.typing import Set, List, Dict, Type, Tuple, Union, Optional, ModuleType
plugins: Dict[str, "Plugin"] = {}
@ -20,10 +21,9 @@ _tmp_matchers: Set[Type[Matcher]] = set()
class Plugin(object):
# TODO: store plugin informations
def __init__(self, module_path: str, module: ModuleType,
def __init__(self, name: str, module: ModuleType,
matchers: Set[Type[Matcher]]):
self.module_path = module_path
self.name = name
self.module = module
self.matchers = matchers
@ -31,7 +31,7 @@ class Plugin(object):
def on(rule: Union[Rule, RuleChecker] = Rule(),
permission: Permission = Permission(),
*,
handlers: Optional[list] = None,
handlers: Optional[List[Handler]] = None,
temp: bool = False,
priority: int = 1,
block: bool = False,
@ -50,7 +50,7 @@ def on(rule: Union[Rule, RuleChecker] = Rule(),
def on_metaevent(rule: Union[Rule, RuleChecker] = Rule(),
*,
handlers: Optional[list] = None,
handlers: Optional[List[Handler]] = None,
temp: bool = False,
priority: int = 1,
block: bool = False,
@ -70,7 +70,7 @@ def on_metaevent(rule: Union[Rule, RuleChecker] = Rule(),
def on_message(rule: Union[Rule, RuleChecker] = Rule(),
permission: Permission = Permission(),
*,
handlers: Optional[list] = None,
handlers: Optional[List[Handler]] = None,
temp: bool = False,
priority: int = 1,
block: bool = True,
@ -89,7 +89,7 @@ def on_message(rule: Union[Rule, RuleChecker] = Rule(),
def on_notice(rule: Union[Rule, RuleChecker] = Rule(),
*,
handlers: Optional[list] = None,
handlers: Optional[List[Handler]] = None,
temp: bool = False,
priority: int = 1,
block: bool = False,
@ -108,7 +108,7 @@ def on_notice(rule: Union[Rule, RuleChecker] = Rule(),
def on_request(rule: Union[Rule, RuleChecker] = Rule(),
*,
handlers: Optional[list] = None,
handlers: Optional[List[Handler]] = None,
temp: bool = False,
priority: int = 1,
block: bool = False,
@ -149,9 +149,19 @@ def on_command(cmd: Union[str, Tuple[str, ...]],
**kwargs) -> Type[Matcher]:
if isinstance(cmd, str):
cmd = (cmd,)
return on_message(command(cmd) &
rule, permission, **kwargs) if rule else on_message(
command(cmd), permission, **kwargs)
async def _strip_cmd(bot, event, state: dict):
message = event.message
event.message = message.__class__(
str(message)[len(state["_prefix"]["raw_command"]):].strip())
handlers = kwargs.pop("handlers", [])
handlers.insert(0, _strip_cmd)
return on_message(
command(cmd) &
rule, permission, handlers=handlers, **kwargs) if rule else on_message(
command(cmd), permission, handlers=handlers, **kwargs)
def on_regex(pattern: str,
@ -167,12 +177,20 @@ def on_regex(pattern: str,
def load_plugin(module_path: str) -> Optional[Plugin]:
try:
_tmp_matchers.clear()
if module_path in plugins:
return plugins[module_path]
elif module_path in sys.modules:
logger.warning(
f"Module {module_path} has been loaded by other plugins! Ignored"
)
return
module = importlib.import_module(module_path)
for m in _tmp_matchers:
m.module = module_path
plugin = Plugin(module_path, module, _tmp_matchers.copy())
plugins[module_path] = plugin
logger.opt(colors=True).info(f'Succeeded to import "{module_path}"')
logger.opt(
colors=True).info(f'Succeeded to import "<y>{module_path}</y>"')
return plugin
except Exception as e:
logger.opt(colors=True, exception=e).error(
@ -189,7 +207,11 @@ def load_plugins(*plugin_dir: str) -> Set[Plugin]:
continue
spec = module_info.module_finder.find_spec(name)
if spec.name in sys.modules:
if spec.name in plugins:
continue
elif spec.name in sys.modules:
logger.warning(
f"Module {spec.name} has been loaded by other plugin! Ignored")
continue
try:
@ -207,5 +229,9 @@ def load_plugins(*plugin_dir: str) -> Set[Plugin]:
return loaded_plugins
def load_builtin_plugins():
return load_plugin("nonebot.plugins.base")
def get_loaded_plugins() -> Set[Plugin]:
return set(plugins.values())

10
nonebot/plugins/base.py Normal file
View File

@ -0,0 +1,10 @@
from nonebot.rule import to_me
from nonebot.plugin import on_command
from nonebot.typing import Bot, Event
say = on_command("say", to_me())
@say.handle()
async def repeat(bot: Bot, event: Event, state: dict):
await bot.send(message=event.message, event=event)

View File

@ -74,13 +74,21 @@ class TrieRule:
suffix = cls.suffix.longest_prefix(
message_r.data["text"].rstrip()[::-1])
state["_prefix"] = {prefix.key: prefix.value} if prefix else {}
state["_suffix"] = {suffix.key: suffix.value} if suffix else {}
state["_prefix"] = {
"raw_command": prefix.key,
"command": prefix.value
} if prefix else {}
state["_suffix"] = {
"raw_command": suffix.key,
"command": suffix.value
} if suffix else {}
return ({
prefix.key: prefix.value
"raw_command": prefix.key,
"command": prefix.value
} if prefix else {}, {
suffix.key: suffix.value
"raw_command": suffix.key,
"command": suffix.value
} if suffix else {})
@ -122,7 +130,7 @@ def command(command: Tuple[str, ...]) -> Rule:
TrieRule.add_prefix(f"{start}{sep.join(command)}", command)
async def _command(bot: Bot, event: Event, state: dict) -> bool:
return command in state["_prefix"].values()
return command == state["_prefix"]["command"]
return Rule(_command)

View File

@ -7,10 +7,22 @@ import sys
sys.path.insert(0, os.path.abspath(".."))
import nonebot
from nonebot.log import logger, default_format
# test custom log
logger.add("error.log",
rotation="00:00",
diagnose=False,
level="ERROR",
format=default_format)
nonebot.init()
app = nonebot.get_asgi()
# load builtin plugin
nonebot.load_plugin("nonebot.plugins.base")
# load local plugins
nonebot.load_plugins("test_plugins")
if __name__ == "__main__":

View File

@ -11,7 +11,7 @@ test_command = on_command("帮助", to_me())
@test_command.handle()
async def test_handler(bot: Bot, event: Event, state: dict):
args = str(event.message)[len(list(state["_prefix"].keys())[0]):].strip()
args = str(event.message).strip()
print("[!] Command:", state["_prefix"], "Args:", args)
if args:
state["help"] = args