Rework prefix-ignorer to retain a reference to the unstripped cmdname. Currently unworking.

This commit is contained in:
Griatch 2017-02-17 00:46:00 +01:00
parent fd3d6aee9a
commit dffbf9f8d6
2 changed files with 35 additions and 23 deletions

View file

@ -428,7 +428,7 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
""" """
@inlineCallbacks @inlineCallbacks
def _run_command(cmd, cmdname, args, raw_string): def _run_command(cmd, cmdname, raw_cmdname, args):
""" """
Helper function: This initializes and runs the Command Helper function: This initializes and runs the Command
instance once the parser has identified it as either a normal instance once the parser has identified it as either a normal
@ -437,8 +437,10 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
Args: Args:
cmd (Command): Command object cmd (Command): Command object
cmdname (str): Name of command cmdname (str): Name of command
args (str): Extra text entered after the identified command raw_cmdname (str): Name of Command, unaffected by eventual
raw_string (str): Full input string, only used for debugging. prefix-stripping (if no prefix-stripping, this is the same
as cmdname).
args (str): extra text entered after the identified command
Returns: Returns:
deferred (Deferred): this will fire with the return of the deferred (Deferred): this will fire with the return of the
@ -452,7 +454,9 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
try: try:
# Assign useful variables to the instance # Assign useful variables to the instance
cmd.caller = caller cmd.caller = caller
cmd.cmdstring = cmdname cmd.cmdname = cmdname
cmd.raw_cmdname = raw_cmdname
cmd.cmdstring = cmdname # deprecated
cmd.args = args cmd.args = args
cmd.cmdset = cmdset cmd.cmdset = cmdset
cmd.session = session cmd.session = session
@ -575,7 +579,7 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
if len(matches) == 1: if len(matches) == 1:
# We have a unique command match. But it may still be invalid. # We have a unique command match. But it may still be invalid.
match = matches[0] match = matches[0]
cmdname, args, cmd = match[0], match[1], match[2] cmdname, args, cmd, raw_cmdname = match[0], match[1], match[2], match[5]
if not matches: if not matches:
# No commands match our entered command # No commands match our entered command
@ -608,7 +612,7 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
raise ExecSystemCommand(cmd, sysarg) raise ExecSystemCommand(cmd, sysarg)
# A normal command. # A normal command.
ret = yield _run_command(cmd, cmdname, args, raw_string) ret = yield _run_command(cmd, cmdname, raw_cmdname, args)
returnValue(ret) returnValue(ret)
except ErrorReported as exc: except ErrorReported as exc:
@ -623,7 +627,7 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
sysarg = exc.sysarg sysarg = exc.sysarg
if syscmd: if syscmd:
ret = yield _run_command(syscmd, syscmd.key, sysarg, raw_string) ret = yield _run_command(syscmd, syscmd.key, syscmd, sysarg)
returnValue(ret) returnValue(ret)
elif sysarg: elif sysarg:
# return system arg # return system arg

View file

@ -47,7 +47,7 @@ def cmdparser(raw_string, cmdset, caller, match_index=None):
""" """
def create_match(cmdname, string, cmdobj): def create_match(cmdname, string, cmdobj, raw_cmdname):
""" """
Builds a command match by splitting the incoming string and Builds a command match by splitting the incoming string and
evaluating the quality of the match. evaluating the quality of the match.
@ -56,38 +56,44 @@ def cmdparser(raw_string, cmdset, caller, match_index=None):
cmdname (str): Name of command to check for. cmdname (str): Name of command to check for.
string (str): The string to match against. string (str): The string to match against.
cmdobj (str): The full Command instance. cmdobj (str): The full Command instance.
raw_cmdname (str, optional): If CMD_IGNORE_PREFIX is set and the cmdname starts with
one of the prefixes to ignore, this contains the raw, unstripped cmdname,
otherwise it is None.
Returns: Returns:
match (tuple): This is on the form (cmdname, args, cmdobj, cmdlen, mratio), where match (tuple): This is on the form (cmdname, args, cmdobj, cmdlen, mratio, raw_cmdname), where
`cmdname` is the command's name and `args` the rest of the incoming string, `cmdname` is the command's name and `args` the rest of the incoming string,
without said command name. `cmdobj` is the Command instance, the cmdlen is without said command name. `cmdobj` is the Command instance, the cmdlen is
the same as len(cmdname) and mratio is a measure of how big a part of the the same as len(cmdname) and mratio is a measure of how big a part of the
full input string the cmdname takes up - an exact match would be 1.0. full input string the cmdname takes up - an exact match would be 1.0. Finally,
the `raw_cmdname` is the cmdname unmodified by eventual prefix-stripping.
""" """
cmdlen, strlen = len(unicode(cmdname)), len(unicode(string)) cmdlen, strlen = len(unicode(cmdname)), len(unicode(string))
mratio = 1 - (strlen - cmdlen) / (1.0 * strlen) mratio = 1 - (strlen - cmdlen) / (1.0 * strlen)
args = string[cmdlen:] args = string[cmdlen:]
return (cmdname, args, cmdobj, cmdlen, mratio) return (cmdname, args, cmdobj, cmdlen, mratio, raw_cmdname)
def build_matches(raw_string, include_prefixes=False): def build_matches(raw_string, include_prefixes=False):
l_raw_string = raw_string.lower() l_raw_string = raw_string.lower()
matches = [] matches = []
try: try:
if include_prefixes: if include_prefixes:
# use the cmdname as-is
for cmd in cmdset: for cmd in cmdset:
matches.extend([create_match(cmdname, raw_string, cmd) matches.extend([create_match(cmdname, raw_string, cmd, cmdname)
for cmdname in [cmd.key] + cmd.aliases for cmdname in [cmd.key] + cmd.aliases
if cmdname and l_raw_string.startswith(cmdname.lower()) if cmdname and l_raw_string.startswith(cmdname.lower())
and (not cmd.arg_regex or and (not cmd.arg_regex or
cmd.arg_regex.match(l_raw_string[len(cmdname):]))]) cmd.arg_regex.match(l_raw_string[len(cmdname):]))])
else: else:
# strip prefixes set in settings
for cmd in cmdset: for cmd in cmdset:
for cmdname in [cmd.key] + cmd.aliases: for raw_cmdname in [cmd.key] + cmd.aliases:
cmdname = cmdname.lstrip(_CMD_IGNORE_PREFIXES) if len(cmdname) > 1 else cmdname cmdname = raw_cmdname.lstrip(_CMD_IGNORE_PREFIXES) if len(raw_cmdname) > 1 else raw_cmdname
if cmdname and l_raw_string.startswith(cmdname.lower()) and \ if cmdname and l_raw_string.startswith(cmdname.lower()) and \
(not cmd.arg_regex or cmd.arg_regex.match(l_raw_string[len(cmdname):])): (not cmd.arg_regex or cmd.arg_regex.match(l_raw_string[len(cmdname):])):
matches.append(create_match(cmdname, raw_string, cmd)) matches.append(create_match(cmdname, raw_string, cmd, raw_cmdname))
except Exception: except Exception:
log_trace("cmdhandler error. raw_input:%s" % raw_string) log_trace("cmdhandler error. raw_input:%s" % raw_string)
return matches return matches
@ -107,7 +113,7 @@ def cmdparser(raw_string, cmdset, caller, match_index=None):
if not raw_string: if not raw_string:
return [] return []
# find mathces # find mathces, first using the full name
matches = build_matches(raw_string, include_prefixes=True) matches = build_matches(raw_string, include_prefixes=True)
if not matches: if not matches:
# try to match a number 1-cmdname, 2-cmdname etc # try to match a number 1-cmdname, 2-cmdname etc
@ -116,13 +122,15 @@ def cmdparser(raw_string, cmdset, caller, match_index=None):
return cmdparser(new_raw_string, cmdset, caller, match_index=int(mindex)) return cmdparser(new_raw_string, cmdset, caller, match_index=int(mindex))
elif _CMD_IGNORE_PREFIXES: elif _CMD_IGNORE_PREFIXES:
# still no match. Try to strip prefixes # still no match. Try to strip prefixes
raw_string = raw_string.lstrip(_CMD_IGNORE_PREFIXES) if len(raw_string) > 1 else raw_string new_raw_string = raw_string.lstrip(_CMD_IGNORE_PREFIXES) if len(raw_string) > 1 else raw_string
matches = build_matches(raw_string, include_prefixes=False) if len(new_raw_string) < len(raw_string):
if not matches: raw_string = new_raw_string
# try to match a number 1-cmdname, 2-cmdname etc matches = build_matches(raw_string, include_prefixes=False)
mindex, new_raw_string = try_num_prefixes(raw_string) if not matches:
if mindex is not None: # try to match a number 1-cmdname, 2-cmdname etc
return cmdparser(new_raw_string, cmdset, caller, match_index=int(mindex)) mindex, new_raw_string = try_num_prefixes(raw_string)
if mindex is not None:
return cmdparser(new_raw_string, cmdset, caller, match_index=int(mindex))
# only select command matches we are actually allowed to call. # only select command matches we are actually allowed to call.
matches = [match for match in matches if match[2].access(caller, 'cmd')] matches = [match for match in matches if match[2].access(caller, 'cmd')]