mirror of
https://github.com/nonebot/nonebot2.git
synced 2024-11-24 09:05:04 +08:00
Update
This commit is contained in:
parent
844ade5c31
commit
492fed9b50
@ -17,7 +17,7 @@ default_handler.setFormatter(logging.Formatter(
|
|||||||
logger.addHandler(default_handler)
|
logger.addHandler(default_handler)
|
||||||
|
|
||||||
from .plugin import handle_message, handle_notice, handle_request
|
from .plugin import handle_message, handle_notice, handle_request
|
||||||
from .command import on_command
|
from .command import on_command, call_command
|
||||||
|
|
||||||
|
|
||||||
def create_bot(config_object: Any = None):
|
def create_bot(config_object: Any = None):
|
||||||
|
129
none/command.py
129
none/command.py
@ -19,60 +19,74 @@ _aliases = {}
|
|||||||
_sessions = {}
|
_sessions = {}
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: session 保存为一个栈,命令可以调用命令,进入新的 session,命令执行完毕,
|
||||||
|
# 中间没有抛出异常(标志进入交互模式的异常),则从栈中 pop
|
||||||
|
|
||||||
|
|
||||||
class Command:
|
class Command:
|
||||||
__slots__ = ('name', 'func', 'permission')
|
__slots__ = ('name', 'func', 'permission', 'args_parser')
|
||||||
|
|
||||||
def __init__(self, name: Tuple[str], func: Callable, permission: int):
|
def __init__(self, name: Tuple[str], func: Callable, permission: int):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.func = func
|
self.func = func
|
||||||
self.permission = permission
|
self.permission = permission
|
||||||
|
self.args_parser = None
|
||||||
|
|
||||||
async def run(self, bot, session) -> bool:
|
async def run(self, bot, session, *,
|
||||||
permission = 0
|
permission: int = None) -> bool:
|
||||||
ctx = session.ctx
|
if permission is None:
|
||||||
if ctx['user_id'] in bot.config.SUPERUSERS:
|
permission = await calculate_permission(bot, session.ctx)
|
||||||
permission |= perm.IS_SUPERUSER
|
|
||||||
if ctx['message_type'] == 'private':
|
|
||||||
if ctx['sub_type'] == 'friend':
|
|
||||||
permission |= perm.IS_PRIVATE_FRIEND
|
|
||||||
elif ctx['sub_type'] == 'group':
|
|
||||||
permission |= perm.IS_PRIVATE_GROUP
|
|
||||||
elif ctx['sub_type'] == 'discuss':
|
|
||||||
permission |= perm.IS_PRIVATE_DISCUSS
|
|
||||||
elif ctx['sub_type'] == 'other':
|
|
||||||
permission |= perm.IS_PRIVATE_OTHER
|
|
||||||
elif ctx['message_type'] == 'group':
|
|
||||||
permission |= perm.IS_GROUP_MEMBER
|
|
||||||
if not ctx['anonymous']:
|
|
||||||
try:
|
|
||||||
member_info = await bot.get_group_member_info(**ctx)
|
|
||||||
if member_info:
|
|
||||||
if member_info['role'] == 'owner':
|
|
||||||
permission |= perm.IS_GROUP_OWNER
|
|
||||||
elif member_info['role'] == 'admin':
|
|
||||||
permission |= perm.IS_GROUP_ADMIN
|
|
||||||
except CQHttpError:
|
|
||||||
pass
|
|
||||||
elif ctx['message_type'] == 'discuss':
|
|
||||||
permission |= perm.IS_DISCUSS
|
|
||||||
|
|
||||||
if isinstance(self.func, Callable) and permission & self.permission:
|
if isinstance(self.func, Callable) and permission & self.permission:
|
||||||
|
if isinstance(self.args_parser, Callable):
|
||||||
|
self.args_parser(session)
|
||||||
await self.func(bot, session)
|
await self.func(bot, session)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def _find_command(name: Tuple[str]) -> Optional[Command]:
|
async def calculate_permission(bot: CQHttp, ctx: Dict[str, Any]) -> int:
|
||||||
if not name:
|
permission = 0
|
||||||
|
if ctx['user_id'] in bot.config.SUPERUSERS:
|
||||||
|
permission |= perm.IS_SUPERUSER
|
||||||
|
if ctx['message_type'] == 'private':
|
||||||
|
if ctx['sub_type'] == 'friend':
|
||||||
|
permission |= perm.IS_PRIVATE_FRIEND
|
||||||
|
elif ctx['sub_type'] == 'group':
|
||||||
|
permission |= perm.IS_PRIVATE_GROUP
|
||||||
|
elif ctx['sub_type'] == 'discuss':
|
||||||
|
permission |= perm.IS_PRIVATE_DISCUSS
|
||||||
|
elif ctx['sub_type'] == 'other':
|
||||||
|
permission |= perm.IS_PRIVATE_OTHER
|
||||||
|
elif ctx['message_type'] == 'group':
|
||||||
|
permission |= perm.IS_GROUP_MEMBER
|
||||||
|
if not ctx['anonymous']:
|
||||||
|
try:
|
||||||
|
member_info = await bot.get_group_member_info(**ctx)
|
||||||
|
if member_info:
|
||||||
|
if member_info['role'] == 'owner':
|
||||||
|
permission |= perm.IS_GROUP_OWNER
|
||||||
|
elif member_info['role'] == 'admin':
|
||||||
|
permission |= perm.IS_GROUP_ADMIN
|
||||||
|
except CQHttpError:
|
||||||
|
pass
|
||||||
|
elif ctx['message_type'] == 'discuss':
|
||||||
|
permission |= perm.IS_DISCUSS
|
||||||
|
return permission
|
||||||
|
|
||||||
|
|
||||||
|
def _find_command(name: Union[str, Tuple[str]]) -> Optional[Command]:
|
||||||
|
cmd_name = name if isinstance(name, tuple) else (name,)
|
||||||
|
|
||||||
|
if not cmd_name:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
cmd_tree = _registry
|
cmd_tree = _registry
|
||||||
for part in name[:-1]:
|
for part in cmd_name[:-1]:
|
||||||
if part not in cmd_tree:
|
if part not in cmd_tree:
|
||||||
return None
|
return None
|
||||||
cmd_tree = cmd_tree[part]
|
cmd_tree = cmd_tree[part]
|
||||||
|
|
||||||
return cmd_tree.get(name[-1])
|
return cmd_tree.get(cmd_name[-1])
|
||||||
|
|
||||||
|
|
||||||
class Session:
|
class Session:
|
||||||
@ -80,15 +94,16 @@ class Session:
|
|||||||
'current_key', 'current_arg', 'current_arg_text',
|
'current_key', 'current_arg', 'current_arg_text',
|
||||||
'images', 'args', 'last_interaction')
|
'images', 'args', 'last_interaction')
|
||||||
|
|
||||||
def __init__(self, cmd: Command, ctx: Dict[str, Any],
|
def __init__(self, cmd: Command, ctx: Dict[str, Any], *,
|
||||||
current_arg: str = ''):
|
current_arg: str = '', args: Dict[str, Any] = None):
|
||||||
self.cmd = cmd
|
self.cmd = cmd
|
||||||
self.ctx = ctx
|
self.ctx = ctx
|
||||||
self.current_key = None
|
self.current_key = None
|
||||||
self.current_arg = current_arg
|
self.current_arg = current_arg
|
||||||
self.current_arg_text = Message(current_arg).extract_plain_text()
|
self.current_arg_text = Message(current_arg).extract_plain_text()
|
||||||
self.images = []
|
self.images = [s.data['url'] for s in ctx['message']
|
||||||
self.args = {}
|
if s.type == 'image' and 'url' in s.data]
|
||||||
|
self.args = args or {}
|
||||||
self.last_interaction = None
|
self.last_interaction = None
|
||||||
|
|
||||||
def require_arg(self, key: str, prompt: str = '', *,
|
def require_arg(self, key: str, prompt: str = '', *,
|
||||||
@ -137,9 +152,8 @@ async def handle_command(bot: CQHttp, ctx: Dict[str, Any]) -> bool:
|
|||||||
if not cmd:
|
if not cmd:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
session = Session(cmd=cmd, ctx=ctx, current_arg=''.join(cmd_remained))
|
session = Session(cmd, ctx, current_arg=''.join(cmd_remained))
|
||||||
session.images = [s.data['url'] for s in ctx['message']
|
# TODO: 插入 session
|
||||||
if s.type == 'image' and 'url' in s.data]
|
|
||||||
return await cmd.run(bot, session)
|
return await cmd.run(bot, session)
|
||||||
|
|
||||||
|
|
||||||
@ -156,13 +170,40 @@ def on_command(name: Union[str, Tuple[str]], aliases: Iterable = (),
|
|||||||
for parent_key in cmd_name[:-1]:
|
for parent_key in cmd_name[:-1]:
|
||||||
current_parent[parent_key] = {}
|
current_parent[parent_key] = {}
|
||||||
current_parent = current_parent[parent_key]
|
current_parent = current_parent[parent_key]
|
||||||
current_parent[cmd_name[-1]] = Command(
|
cmd = Command(name=cmd_name, func=func, permission=permission)
|
||||||
name=cmd_name, func=func, permission=permission)
|
current_parent[cmd_name[-1]] = cmd
|
||||||
for alias in aliases:
|
for alias in aliases:
|
||||||
_aliases[alias] = cmd_name
|
_aliases[alias] = cmd_name
|
||||||
|
|
||||||
# TODO: 给 func 添加一个 argparser 装饰器,用于注册它的参数解析器
|
def args_parser(parser_func: Callable):
|
||||||
|
cmd.args_parser = parser_func
|
||||||
|
return parser_func
|
||||||
|
|
||||||
|
func.args_parser = args_parser
|
||||||
return func
|
return func
|
||||||
|
|
||||||
return deco
|
return deco
|
||||||
|
|
||||||
|
|
||||||
|
async def call_command(name: Union[str, Tuple[str]],
|
||||||
|
bot: CQHttp, ctx: Dict[str, Any], **kwargs) -> bool:
|
||||||
|
"""
|
||||||
|
Call a command internally.
|
||||||
|
|
||||||
|
There is no permission restriction on this function,
|
||||||
|
which means any command can be called from any other command.
|
||||||
|
Unexpected users should be handled by the caller command's permission
|
||||||
|
option.
|
||||||
|
|
||||||
|
:param name: command name (str or tuple of str)
|
||||||
|
:param bot: CQHttp instance
|
||||||
|
:param ctx: event context
|
||||||
|
:param kwargs: other keyword args that will be passed to Session()
|
||||||
|
:return: the command is successfully called
|
||||||
|
"""
|
||||||
|
cmd = _find_command(name)
|
||||||
|
if cmd:
|
||||||
|
session = Session(cmd, ctx, **kwargs)
|
||||||
|
# TODO: 插入 session
|
||||||
|
return await cmd.run(bot, session, permission=perm.IS_SUPERUSER)
|
||||||
|
return False
|
||||||
|
@ -11,6 +11,7 @@ GROUP = 0x0F00
|
|||||||
SUPERUSER = 0xF000
|
SUPERUSER = 0xF000
|
||||||
EVERYONE = 0xFFFF
|
EVERYONE = 0xFFFF
|
||||||
|
|
||||||
|
IS_NOBODY = 0x0000
|
||||||
IS_PRIVATE_FRIEND = PRIVATE_FRIEND
|
IS_PRIVATE_FRIEND = PRIVATE_FRIEND
|
||||||
IS_PRIVATE_GROUP = PRIVATE_GROUP
|
IS_PRIVATE_GROUP = PRIVATE_GROUP
|
||||||
IS_PRIVATE_DISCUSS = PRIVATE_DISCUSS
|
IS_PRIVATE_DISCUSS = PRIVATE_DISCUSS
|
||||||
|
15
plugins/weather.py
Normal file
15
plugins/weather.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import none
|
||||||
|
from none.command import Session
|
||||||
|
from none.helpers import send
|
||||||
|
|
||||||
|
|
||||||
|
@none.on_command('weather', aliases=('天气',))
|
||||||
|
async def weather(bot, session: Session):
|
||||||
|
city = session.require_arg('city', prompt='你想知道哪个城市的天气呢?')
|
||||||
|
await send(bot, session.ctx, f'你查询了{city}的天气')
|
||||||
|
|
||||||
|
|
||||||
|
@weather.args_parser
|
||||||
|
def _(session: Session):
|
||||||
|
if session.current_key:
|
||||||
|
session.args[session.current_key] = session.current_arg.strip()
|
Loading…
Reference in New Issue
Block a user