From e52aa34f85ec4e5615faeb40451ebadc23ec4e6a Mon Sep 17 00:00:00 2001 From: Richard Chien Date: Mon, 25 Jun 2018 21:14:27 +0800 Subject: [PATCH] Restructure --- none/__init__.py | 10 +++++----- none/command.py | 16 ++++++++++++++-- none/expression.py | 18 ++++++++++++++++++ none/expressions/weather.py | 12 ++++++++++++ {plugins => none/plugins}/base.py | 0 none/plugins/weather.py | 21 +++++++++++++++++++++ plugins/weather.py | 20 -------------------- 7 files changed, 70 insertions(+), 27 deletions(-) create mode 100644 none/expression.py create mode 100644 none/expressions/weather.py rename {plugins => none/plugins}/base.py (100%) create mode 100644 none/plugins/weather.py delete mode 100644 plugins/weather.py diff --git a/none/__init__.py b/none/__init__.py index ddd91450..9c194f8e 100644 --- a/none/__init__.py +++ b/none/__init__.py @@ -55,14 +55,14 @@ _plugins = set() def load_plugins(): _plugins.clear() - root_dir = os.path.dirname(__path__[0]) - plugins_dir = os.path.join(root_dir, 'plugins') + none_dir = __path__[0] + plugins_dir = os.path.join(none_dir, 'plugins') saved_cwd = os.getcwd() - os.chdir(root_dir) + os.chdir(none_dir) for item in os.listdir(plugins_dir): path = os.path.join(plugins_dir, item) if os.path.isfile(path) and \ - (path.startswith('_') or not path.endswith('.py')): + (item.startswith('_') or not item.endswith('.py')): continue if os.path.isdir(path) and \ (path.startswith('_') or not os.path.exists( @@ -73,7 +73,7 @@ def load_plugins(): if not m: continue - mod_name = 'plugins.' + m.group(1) + mod_name = 'none.plugins.' + m.group(1) try: _plugins.add(importlib.import_module(mod_name)) logger.info('Succeeded to import "{}"'.format(mod_name)) diff --git a/none/command.py b/none/command.py index ec562d59..c433d4df 100644 --- a/none/command.py +++ b/none/command.py @@ -1,13 +1,16 @@ import re import asyncio from datetime import datetime -from typing import Tuple, Union, Callable, Iterable, Dict, Any, Optional, List +from typing import ( + Tuple, Union, Callable, Iterable, Dict, Any, Optional, List, Sequence +) from aiocqhttp import CQHttp, Error as CQHttpError from aiocqhttp.message import Message from . import permissions as perm from .helpers import context_source +from .expression import render # Key: str (one segment of command name) # Value: subtree or a leaf Command object @@ -160,7 +163,8 @@ class Session: return False return True - def require_arg(self, key: str, prompt: str, *, + def require_arg(self, key: str, prompt: str = None, *, + prompt_expr: Union[str, Sequence[str], Callable] = None, interactive: bool = True) -> Any: """ Get an argument with a given key. @@ -174,6 +178,7 @@ class Session: :param key: argument key :param prompt: prompt to ask the user + :param prompt_expr: prompt expression to ask the user :param interactive: should enter interactive mode while key missing :return: the argument value :raise FurtherInteractionNeeded: further interaction is needed @@ -184,6 +189,8 @@ class Session: self.current_key = key # ask the user for more information + if prompt_expr is not None: + prompt = render(prompt_expr, key=key) asyncio.ensure_future(self.send(prompt)) raise FurtherInteractionNeeded @@ -196,6 +203,11 @@ class Session: if not ignore_failure: raise + async def send_expr(self, + expr: Union[str, Sequence[str], Callable], + **kwargs): + return await self.send(render(expr, **kwargs)) + def _new_command_session(bot: CQHttp, ctx: Dict[str, Any]) -> Optional[Session]: diff --git a/none/expression.py b/none/expression.py new file mode 100644 index 00000000..2b7df1db --- /dev/null +++ b/none/expression.py @@ -0,0 +1,18 @@ +import random +from typing import Union, Sequence, Callable + +from aiocqhttp import message +from aiocqhttp.message import Message + + +def render(expr: Union[str, Sequence[str], Callable], *, escape_args=True, + **kwargs) -> Message: + if isinstance(expr, Callable): + expr = expr() + elif isinstance(expr, Sequence): + expr = random.choice(expr) + if escape_args: + for k, v in kwargs.items(): + if isinstance(v, str): + kwargs[k] = message.escape(v) + return expr.format(**kwargs) diff --git a/none/expressions/weather.py b/none/expressions/weather.py new file mode 100644 index 00000000..a89cd9b5 --- /dev/null +++ b/none/expressions/weather.py @@ -0,0 +1,12 @@ +WHICH_CITY = ( + '你想知道哪个城市的天气呢?', + '你要查询的城市是哪个呢?', + '你要查询哪个城市呢?', + '哪个城市呢?', + '请告诉我你要查询的城市~', +) + +REPORT = ( + '你查询了{city}的天气', + '{city}的天气是……', +) diff --git a/plugins/base.py b/none/plugins/base.py similarity index 100% rename from plugins/base.py rename to none/plugins/base.py diff --git a/none/plugins/weather.py b/none/plugins/weather.py new file mode 100644 index 00000000..bbb71f83 --- /dev/null +++ b/none/plugins/weather.py @@ -0,0 +1,21 @@ +import none +from none.command import Session +from none.expressions import weather as expr + + +@none.on_command(('weather', 'weather'), aliases=('天气', '天气预报')) +async def weather(session: Session): + city = session.require_arg('city', prompt_expr=expr.WHICH_CITY) + await session.send_expr(expr.REPORT, city=city) + + +@weather.args_parser +async def _(session: Session): + if session.current_key: + session.args[session.current_key] = session.current_arg.strip() + + +@none.on_command(('weather', 'suggestion'), + aliases=('生活指数', '生活建议', '生活提示')) +async def suggestion(session: Session): + await session.send('suggestion') diff --git a/plugins/weather.py b/plugins/weather.py deleted file mode 100644 index 92a281d4..00000000 --- a/plugins/weather.py +++ /dev/null @@ -1,20 +0,0 @@ -import none -from none.command import Session - - -@none.on_command(('weather', 'weather'), aliases=('天气',)) -async def weather(session: Session): - city = session.require_arg('city', prompt='你想知道哪个城市的天气呢?') - other = session.require_arg('other', prompt='其他信息?') - await session.send(f'你查询了{city}的天气,{other}') - - -@weather.args_parser -async def _(session: Session): - if session.current_key: - session.args[session.current_key] = session.current_arg.strip() - - -@none.on_command(('weather', 'suggestion'), aliases=('生活指数', '生活提示')) -async def suggestion(session: Session): - await session.send('suggestion')