Archived
1
0
Fork 0
This repository has been archived on 2024-04-26. You can view files and clone it, but cannot push or open issues or pull requests.
akari-bot/core/parser/command.py

76 lines
3 KiB
Python
Raw Normal View History

2021-07-19 16:12:29 +00:00
import re
2022-08-15 09:54:24 +00:00
import copy
2021-07-18 16:17:09 +00:00
import shlex
2021-10-24 10:55:45 +00:00
import traceback
2022-08-07 17:56:38 +00:00
from typing import Union, Dict
2021-08-07 07:56:48 +00:00
2022-08-07 17:56:38 +00:00
from core.elements import Command, MessageSession
2022-08-10 09:10:35 +00:00
from core.exceptions import InvalidCommandFormatError
2022-08-08 09:10:35 +00:00
from .args import parse_argv, Template, templates_to_str, DescPattern
from ..logger import Logger
2021-10-15 17:36:22 +00:00
2021-07-19 16:12:29 +00:00
2021-07-18 16:17:09 +00:00
class CommandParser:
2022-08-07 17:56:38 +00:00
def __init__(self, args: Command, command_prefixes: list,
bind_prefix=None,
2021-11-19 16:33:53 +00:00
msg: MessageSession = None):
2022-08-23 04:53:34 +00:00
args = copy.deepcopy(args)
self.command_prefixes = command_prefixes
self.bind_prefix = bind_prefix
2021-10-24 10:55:45 +00:00
self.origin_template = args
2021-11-19 16:33:53 +00:00
self.msg: Union[MessageSession, None] = msg
2022-01-27 13:16:53 +00:00
self.options_desc = []
2022-08-07 17:56:38 +00:00
help_docs = {}
for match in (args.match_list.set if self.msg is None else args.match_list.get(self.msg.target.targetFrom)):
if match.help_doc:
for m in match.help_doc:
help_docs[m] = {'priority': match.priority, 'meta': match}
2021-10-15 17:36:22 +00:00
else:
2022-08-07 17:56:38 +00:00
help_docs[''] = {'priority': match.priority, 'meta': match}
if match.options_desc is not None:
for m in match.options_desc:
self.options_desc.append(f'{m} {match.options_desc[m]}')
2022-08-23 04:53:34 +00:00
self.args: Dict[Union[Template, ''], dict] = help_docs
2021-07-19 16:12:29 +00:00
2021-07-26 12:43:51 +00:00
def return_formatted_help_doc(self) -> str:
2022-08-06 13:39:24 +00:00
if not self.args:
2021-10-15 17:36:22 +00:00
return '(此模块没有帮助信息)'
2022-08-07 17:56:38 +00:00
lst = []
format_args = templates_to_str([args for args in self.args if args != ''], with_desc=True)
for x in format_args:
x = f'{self.command_prefixes[0]}{self.bind_prefix} {x}'
lst.append(x)
args = '\n'.join(y for y in lst)
2022-01-27 13:16:53 +00:00
if self.options_desc:
args += '\n参数:\n' + '\n'.join(self.options_desc)
2021-07-19 16:12:29 +00:00
return args
2021-07-18 16:17:09 +00:00
def parse(self, command):
2021-10-24 10:55:45 +00:00
if self.args is None:
2021-09-10 18:05:27 +00:00
return None
2021-10-24 10:55:45 +00:00
command = re.sub(r'[“”]', '"', command)
2021-09-04 13:27:23 +00:00
try:
split_command = shlex.split(command)
except ValueError:
split_command = command.split(' ')
Logger.debug(split_command)
2021-07-19 16:12:29 +00:00
try:
2021-10-24 10:55:45 +00:00
if not isinstance(self.origin_template, Command):
if len(split_command) == 1:
2022-08-06 13:39:24 +00:00
return None, None
2021-10-24 10:55:45 +00:00
else:
if len(split_command) == 1:
2022-08-06 13:39:24 +00:00
if '' in self.args:
return self.args['']['meta'], None
2022-08-08 09:10:35 +00:00
for arg in self.args:
if len(arg.args) == 1 and isinstance(arg.args[0], DescPattern):
return self.args[arg]['meta'], None
2021-10-24 10:55:45 +00:00
raise InvalidCommandFormatError
else:
2022-08-07 17:56:38 +00:00
base_match = parse_argv(split_command[1:], [args for args in self.args if args != ''])
2022-08-06 13:39:24 +00:00
return self.args[base_match.original_template]['meta'], base_match.args
2021-10-24 10:55:45 +00:00
except InvalidCommandFormatError:
2021-10-24 10:55:45 +00:00
traceback.print_exc()
2021-07-19 16:12:29 +00:00
raise InvalidCommandFormatError