2022-08-15 09:54:24 +00:00
|
|
|
import copy
|
2022-08-30 12:49:01 +00:00
|
|
|
import re
|
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-10 09:10:35 +00:00
|
|
|
from core.exceptions import InvalidCommandFormatError
|
2023-03-04 08:51:56 +00:00
|
|
|
from core.types import MessageSession, Module
|
2023-03-04 10:17:07 +00:00
|
|
|
from core.utils.i18n import Locale
|
2022-08-08 09:10:35 +00:00
|
|
|
from .args import parse_argv, Template, templates_to_str, DescPattern
|
2022-08-05 18:12:44 +00:00
|
|
|
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:
|
2023-03-04 08:51:56 +00:00
|
|
|
def __init__(self, args: Module, command_prefixes: list,
|
2022-07-18 12:34:00 +00:00
|
|
|
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)
|
2022-07-18 12:34:00 +00:00
|
|
|
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 = []
|
2023-03-04 10:17:07 +00:00
|
|
|
self.lang = self.msg.locale if self.msg is not None else Locale('zh_cn')
|
2022-08-07 17:56:38 +00:00
|
|
|
help_docs = {}
|
2023-03-04 08:51:56 +00:00
|
|
|
for match in (args.command_list.set if self.msg is None else args.command_list.get(self.msg.target.targetFrom)):
|
2022-08-07 17:56:38 +00:00
|
|
|
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:
|
2023-03-04 08:51:56 +00:00
|
|
|
desc = match.options_desc[m]
|
|
|
|
if locale_str := re.findall(r'\{(.*)}', desc):
|
|
|
|
for l in locale_str:
|
2023-03-14 10:14:05 +00:00
|
|
|
desc = desc.replace(f'{{{l}}}', self.lang.t(l, fallback_failed_prompt=False))
|
2023-03-04 08:51:56 +00:00
|
|
|
self.options_desc.append(f'{m} {desc}')
|
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:
|
2023-03-04 08:51:56 +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:
|
2023-03-01 09:10:45 +00:00
|
|
|
if locale_str := re.findall(r'\{(.*)}', x):
|
|
|
|
for l in locale_str:
|
2023-03-14 10:14:05 +00:00
|
|
|
x = x.replace(f'{{{l}}}', self.lang.t(l, fallback_failed_prompt=False))
|
2022-08-07 17:56:38 +00:00
|
|
|
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:
|
2023-03-08 11:40:16 +00:00
|
|
|
options_desc = self.options_desc.copy()
|
|
|
|
options_desc_localed = []
|
|
|
|
for x in options_desc:
|
|
|
|
if locale_str := re.findall(r'\{(.*)}', x):
|
|
|
|
for l in locale_str:
|
2023-03-14 10:14:05 +00:00
|
|
|
x = x.replace(f'{{{l}}}', self.lang.t(l, fallback_failed_prompt=False))
|
2023-03-08 11:40:16 +00:00
|
|
|
options_desc_localed.append(x)
|
|
|
|
args += f'\n{self.lang.t("core.help.options")}\n' + '\n'.join(options_desc_localed)
|
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(' ')
|
2022-08-05 18:12:44 +00:00
|
|
|
Logger.debug(split_command)
|
2021-07-19 16:12:29 +00:00
|
|
|
try:
|
2023-03-04 08:51:56 +00:00
|
|
|
if not self.origin_template.command_list.set:
|
2021-10-24 10:55:45 +00:00
|
|
|
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
|
|
|
|
2022-08-05 18:12:44 +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
|