From 8ae248738eaee6b6777d74676d060a8675e0937a Mon Sep 17 00:00:00 2001 From: yanyongyu Date: Sat, 11 Apr 2020 14:56:39 +0800 Subject: [PATCH] add more manage func --- nonebot/message.py | 29 +++++++++--- nonebot/natural_language.py | 17 +++---- nonebot/plugin.py | 92 +++++++++++++++++++++++++++++++++---- 3 files changed, 116 insertions(+), 22 deletions(-) diff --git a/nonebot/message.py b/nonebot/message.py index a5898925..fbfd8b52 100644 --- a/nonebot/message.py +++ b/nonebot/message.py @@ -19,6 +19,19 @@ def message_preprocessor(func: Callable) -> Callable: return func +class CanceledException(Exception): + """ + Raised by message_preprocessor indicating that + the bot should ignore the message + """ + + def __init__(self, reason): + """ + :param reason: reason to ignore the message + """ + self.reason = reason + + async def handle_message(bot: NoneBot, event: CQEvent) -> None: _log_message(event) @@ -26,17 +39,21 @@ async def handle_message(bot: NoneBot, event: CQEvent) -> None: if not event.message: event.message.append(MessageSegment.text('')) # type: ignore + raw_to_me = event.get('to_me', False) + _check_at_me(bot, event) + _check_calling_me_nickname(bot, event) + event['to_me'] = raw_to_me or event['to_me'] + coros = [] plugin_manager = PluginManager() for preprocessor in _message_preprocessors: coros.append(preprocessor(bot, event, plugin_manager)) if coros: - await asyncio.wait(coros) - - raw_to_me = event.get('to_me', False) - _check_at_me(bot, event) - _check_calling_me_nickname(bot, event) - event['to_me'] = raw_to_me or event['to_me'] + try: + await asyncio.gather(*coros) + except CanceledException: + logger.info(f'Message {event["message_id"]} is ignored') + return while True: try: diff --git a/nonebot/natural_language.py b/nonebot/natural_language.py index 5b168bd4..268217ff 100644 --- a/nonebot/natural_language.py +++ b/nonebot/natural_language.py @@ -61,10 +61,11 @@ class NLPManager: return False @classmethod - def switch_processor_global(cls, - processor: NLProcessor, - state: Optional[bool] = None) -> Optional[bool]: - """Remove or add a processor + def switch_nlprocessor_global(cls, + processor: NLProcessor, + state: Optional[bool] = None + ) -> Optional[bool]: + """Remove or add a natural language processor globally Args: processor (NLProcessor): Processor object @@ -79,10 +80,10 @@ class NLPManager: cls._nl_processors.add(processor) return False - def switch_processor(self, - processor: NLProcessor, - state: Optional[bool] = None) -> Optional[bool]: - """Remove or add processor + def switch_nlprocessor(self, + processor: NLProcessor, + state: Optional[bool] = None) -> Optional[bool]: + """Remove or add a natural language processor Args: processor (NLProcessor): Processor to remove diff --git a/nonebot/plugin.py b/nonebot/plugin.py index 09ce4046..986adc7e 100644 --- a/nonebot/plugin.py +++ b/nonebot/plugin.py @@ -74,7 +74,56 @@ class PluginManager: for command in plugin.commands: CommandManager.switch_command_global(command.name, state) for nl_processor in plugin.nl_processors: - NLPManager.switch_processor_global(nl_processor, state) + NLPManager.switch_nlprocessor_global(nl_processor, state) + for event_handler in plugin.event_handlers: + for event in event_handler.events: + if event_handler.func in _bus._subscribers[event] and not state: + _bus.unsubscribe(event, event_handler.func) + elif event_handler.func not in _bus._subscribers[event] and state != False: + _bus.subscribe(event, event_handler.func) + + @classmethod + def switch_command_global(cls, name: str, state: Optional[bool] = None) -> None: + """Change plugin command state globally or simply switch it if `state` is None + + Args: + name (str): Plugin name + state (Optional[bool]): State to change to. Defaults to None. + """ + plugin = cls.get_plugin(name) + if not plugin: + warnings.warn(f"Plugin {name} not found") + return + for command in plugin.commands: + CommandManager.switch_command_global(command.name, state) + + @classmethod + def switch_nlprocessor_global(cls, name: str, state: Optional[bool] = None) -> None: + """Change plugin nlprocessor state globally or simply switch it if `state` is None + + Args: + name (str): Plugin name + state (Optional[bool]): State to change to. Defaults to None. + """ + plugin = cls.get_plugin(name) + if not plugin: + warnings.warn(f"Plugin {name} not found") + return + for processor in plugin.nl_processors: + NLPManager.switch_nlprocessor_global(processor, state) + + @classmethod + def switch_eventhandler_global(cls, name: str, state: Optional[bool] = None) -> None: + """Change plugin event handler state globally or simply switch it if `state` is None + + Args: + name (str): Plugin name + state (Optional[bool]): State to change to. Defaults to None. + """ + plugin = cls.get_plugin(name) + if not plugin: + warnings.warn(f"Plugin {name} not found") + return for event_handler in plugin.event_handlers: for event in event_handler.events: if event_handler.func in _bus._subscribers[event] and not state: @@ -85,6 +134,11 @@ class PluginManager: def switch_plugin(self, name: str, state: Optional[bool] = None) -> None: """Change plugin state or simply switch it if `state` is None + Tips: + This method will only change the state of the plugin's + commands and natural language processors since change + state of the event handler partially is meaningless. + Args: name (str): Plugin name state (Optional[bool]): State to change to. Defaults to None. @@ -96,13 +150,35 @@ class PluginManager: for command in plugin.commands: self.cmd_manager.switch_command(command.name, state) for nl_processor in plugin.nl_processors: - self.nlp_manager.switch_processor(nl_processor, state) - # for event_handler in plugin.event_handlers: - # for event in event_handler.events: - # if event_handler.func in _bus._subscribers[event] and not state: - # _bus.unsubscribe(event, event_handler.func) - # elif event_handler.func not in _bus._subscribers[event] and state != False: - # _bus.subscribe(event, event_handler.func) + self.nlp_manager.switch_nlprocessor(nl_processor, state) + + def switch_command(self, name: str, state: Optional[bool] = None) -> None: + """Change plugin command state or simply switch it if `state` is None + + Args: + name (str): Plugin name + state (Optional[bool]): State to change to. Defaults to None. + """ + plugin = self.get_plugin(name) + if not plugin: + warnings.warn(f"Plugin {name} not found") + return + for command in plugin.commands: + self.cmd_manager.switch_command(command.name, state) + + def switch_nlprocessor(self, name: str, state: Optional[bool] = None) -> None: + """Change plugin nlprocessor state or simply switch it if `state` is None + + Args: + name (str): Plugin name + state (Optional[bool]): State to change to. Defaults to None. + """ + plugin = self.get_plugin(name) + if not plugin: + warnings.warn(f"Plugin {name} not found") + return + for processor in plugin.nl_processors: + self.nlp_manager.switch_nlprocessor(processor, state) def load_plugin(module_name: str) -> Optional[Plugin]: