support spec arg "context" (e.g. private only), marked exported as private

This commit is contained in:
jesopo 2020-01-25 23:57:27 +00:00
parent 6a3702577f
commit 1a8a4ac9d4
2 changed files with 36 additions and 12 deletions

View file

@ -4,14 +4,18 @@ from src import IRCBot, ModuleManager, utils
class Module(ModuleManager.BaseModule): class Module(ModuleManager.BaseModule):
def _get_help(self, hook): def _get_help(self, hook):
return hook.get_kwarg("help", None) or hook.docstring.description return hook.get_kwarg("help", None) or hook.docstring.description
def _get_usage(self, hook, command, command_prefix=""): def _get_usage(self, hook, is_channel, command, command_prefix=""):
command = "%s%s" % (command_prefix, command) command = "%s%s" % (command_prefix, command)
spec = hook.get_kwargs("spec") spec = hook.get_kwargs("spec")
usages_kwarg = hook.get_kwargs("usage") usages_kwarg = hook.get_kwargs("usage")
if spec: if spec:
usages = [utils.parse.argument_spec_human(s) for s in spec] if is_channel:
context = utils.parse.SpecArgumentContext.CHANNEL
else:
context = utils.parse.SpecArgumentContext.PRIVATE
usages = [utils.parse.argument_spec_human(s, context) for s in spec]
elif usage: elif usage:
usages = usages_kwarg usages = usages_kwarg
@ -36,7 +40,8 @@ class Module(ModuleManager.BaseModule):
if hook == None: if hook == None:
raise utils.EventError("Unknown command '%s'" % command) raise utils.EventError("Unknown command '%s'" % command)
help = self._get_help(hook) help = self._get_help(hook)
usage = self._get_usage(hook, command, event["command_prefix"]) usage = self._get_usage(hook, event["is_channel"], command,
event["command_prefix"])
out = help out = help
if usage: if usage:

View file

@ -1,4 +1,4 @@
import decimal, io, typing import decimal, enum, io, typing
from . import datetime, errors from . import datetime, errors
COMMENT_TYPES = ["#", "//"] COMMENT_TYPES = ["#", "//"]
@ -156,7 +156,14 @@ def format_token_replace(s: str, vars: typing.Dict[str, str],
s = s[:i] + vars[token.replace(sigil, "", 1)] + s[i+len(token):] s = s[:i] + vars[token.replace(sigil, "", 1)] + s[i+len(token):]
return s return s
class SpecArgumentContext(enum.IntFlag):
CHANNEL = 1
PRIVATE = 2
ALL = 3
class SpecArgumentType(object): class SpecArgumentType(object):
context = SpecArgumentContext.ALL
def __init__(self, type_name: str, name: typing.Optional[str], exported: str): def __init__(self, type_name: str, name: typing.Optional[str], exported: str):
self.type = type_name self.type = type_name
self._name = name self._name = name
@ -195,6 +202,9 @@ class SpecArgumentTypeTime(SpecArgumentType):
def error(self) -> typing.Optional[str]: def error(self) -> typing.Optional[str]:
return "Invalid timeframe" return "Invalid timeframe"
class SpecArgumentPrivateType(SpecArgumentType):
context = SpecArgumentContext.PRIVATE
SPEC_ARGUMENT_TYPES = { SPEC_ARGUMENT_TYPES = {
"word": SpecArgumentTypeWord, "word": SpecArgumentTypeWord,
"wordlower": SpecArgumentTypeWordLower, "wordlower": SpecArgumentTypeWordLower,
@ -228,20 +238,29 @@ def argument_spec(spec: str) -> typing.List[SpecArgument]:
argument_type_class = SpecArgumentType argument_type_class = SpecArgumentType
if argument_type in SPEC_ARGUMENT_TYPES: if argument_type in SPEC_ARGUMENT_TYPES:
argument_type_class = SPEC_ARGUMENT_TYPES[argument_type] argument_type_class = SPEC_ARGUMENT_TYPES[argument_type]
elif exported:
argument_type_class = SpecArgumentPrivateType
argument_types.append(argument_type_class(argument_type, argument_types.append(argument_type_class(argument_type,
argument_type_name, exported)) argument_type_name, exported))
out.append(SpecArgument(optional, argument_types)) out.append(SpecArgument(optional, argument_types))
return out return out
def argument_spec_human(spec: typing.List[SpecArgument]) -> str: def argument_spec_human(spec: typing.List[SpecArgument],
context: SpecArgumentContext=SpecArgumentContext.ALL) -> str:
out: typing.List[str] = [] out: typing.List[str] = []
for spec_argument in spec: for spec_argument in spec:
names = [t.name() or t.type for t in spec_argument.types] names: typing.List[str] = []
names = list(filter(None, names)) for argument_type in spec_argument.types:
if not (context&argument_type.context) == 0:
name = argument_type.name() or argument_type.type
if name:
names.append(name)
if spec_argument.optional: if names:
format = "[%s]" if spec_argument.optional:
else: format = "[%s]"
format = "<%s>" else:
out.append(format % "|".join(names)) format = "<%s>"
out.append(format % "|".join(names))
return " ".join(out) return " ".join(out)