Check command keywords using keyword help (passed in @hook)
This commit is contained in:
parent
70b52d5567
commit
ea9829b341
|
@ -61,6 +61,8 @@ def reload():
|
|||
import nemubot.exception
|
||||
imp.reload(nemubot.exception)
|
||||
|
||||
nemubot.exception.reload()
|
||||
|
||||
import nemubot.hooks
|
||||
imp.reload(nemubot.hooks)
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ class Bot(threading.Thread):
|
|||
if s == "in_Command" and (h.name is not None or h.regexp is not None) and h.is_matching(msg.args[0][1:]):
|
||||
if h.help_usage:
|
||||
lp = ["\x03\x02%s%s\x03\x02: %s" % (msg.args[0], (" " + k if k is not None else ""), h.help_usage[k]) for k in h.help_usage]
|
||||
jp = ["\x03\x02@%s\x03\x02: %s" % (k, h.keywords[k]) for k in h.keywords]
|
||||
jp = h.keywords.help()
|
||||
return res.append_message(lp + ([". Moreover, you can provides some optional parameters: "] + jp if len(jp) else []), title="Usage for command %s from module %s" % (msg.args[0], module))
|
||||
elif h.help:
|
||||
return res.append_message("Command %s from module %s: %s" % (msg.args[0], module, h.help))
|
||||
|
|
|
@ -32,3 +32,10 @@ class IMException(Exception):
|
|||
from nemubot.message import Text
|
||||
return Text(*self.args,
|
||||
server=msg.server, to=msg.to_response)
|
||||
|
||||
|
||||
def reload():
|
||||
import imp
|
||||
|
||||
import nemubot.exception.Keyword
|
||||
imp.reload(nemubot.exception.printer.IRC)
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
# Nemubot is a smart and modulable IM bot.
|
||||
# Copyright (C) 2012-2015 Mercier Pierre-Olivier
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from nemubot.exception import IMException
|
||||
|
||||
|
||||
class KeywordException(IMException):
|
||||
|
||||
def __init__(self, message):
|
||||
super(KeywordException, self).__init__(message)
|
|
@ -38,5 +38,9 @@ def reload():
|
|||
imp.reload(nemubot.hooks.message)
|
||||
Message = nemubot.hooks.message.Message
|
||||
|
||||
import nemubot.hooks.keywords
|
||||
imp.reload(nemubot.hooks.keywords)
|
||||
nemubot.hooks.keywords.reload()
|
||||
|
||||
import nemubot.hooks.manager
|
||||
imp.reload(nemubot.hooks.manager)
|
||||
|
|
|
@ -50,8 +50,12 @@ class Abstract:
|
|||
self.end_call = end_call
|
||||
|
||||
|
||||
def check(self, data1):
|
||||
return True
|
||||
|
||||
|
||||
def match(self, data1, server):
|
||||
return NotImplemented
|
||||
return True
|
||||
|
||||
|
||||
def run(self, data1, *args):
|
||||
|
@ -60,8 +64,11 @@ class Abstract:
|
|||
from nemubot.exception import IMException
|
||||
self.times -= 1
|
||||
|
||||
ret = None
|
||||
|
||||
try:
|
||||
ret = call_game(self.call, data1, self.data, *args)
|
||||
if self.check(data1):
|
||||
ret = call_game(self.call, data1, self.data, *args)
|
||||
except IMException as e:
|
||||
ret = e.fill_response(data1)
|
||||
finally:
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
# Nemubot is a smart and modulable IM bot.
|
||||
# Copyright (C) 2012-2015 Mercier Pierre-Olivier
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from nemubot.exception.keyword import KeywordException
|
||||
from nemubot.hooks.keywords.abstract import Abstract
|
||||
|
||||
|
||||
class NoKeyword(Abstract):
|
||||
|
||||
def check(self, mkw):
|
||||
if len(mkw):
|
||||
raise KeywordException("This command doesn't take any keyword arguments.")
|
||||
return super().check(mkw)
|
||||
|
||||
|
||||
def reload():
|
||||
import imp
|
||||
|
||||
import nemubot.hooks.keywords.abstract
|
||||
imp.reload(nemubot.hooks.keywords.abstract)
|
||||
|
||||
import nemubot.hooks.keywords.dict
|
||||
imp.reload(nemubot.hooks.keywords.dict)
|
|
@ -0,0 +1,35 @@
|
|||
# Nemubot is a smart and modulable IM bot.
|
||||
# Copyright (C) 2012-2015 Mercier Pierre-Olivier
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
class Abstract:
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def check(self, mkw):
|
||||
"""Check that all given message keywords are valid
|
||||
|
||||
Argument:
|
||||
mkw -- dictionnary of keywords present in the message
|
||||
"""
|
||||
|
||||
assert type(mkw) is dict, mkw
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def help(self):
|
||||
return ""
|
|
@ -0,0 +1,59 @@
|
|||
# Nemubot is a smart and modulable IM bot.
|
||||
# Copyright (C) 2012-2015 Mercier Pierre-Olivier
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from nemubot.exception.keyword import KeywordException
|
||||
from nemubot.hooks.keywords.abstract import Abstract
|
||||
from nemubot.tools.human import guess
|
||||
|
||||
|
||||
class Dict(Abstract):
|
||||
|
||||
|
||||
def __init__(self, d):
|
||||
super().__init__()
|
||||
self.d = d
|
||||
|
||||
|
||||
@property
|
||||
def chk_noarg(self):
|
||||
if not hasattr(self, "_cache_chk_noarg"):
|
||||
self._cache_chk_noarg = [k for k in self.d if "=" not in k]
|
||||
return self._cache_chk_noarg
|
||||
|
||||
|
||||
@property
|
||||
def chk_args(self):
|
||||
if not hasattr(self, "_cache_chk_args"):
|
||||
self._cache_chk_args = [k.split("=", 1)[0] for k in self.d if "=" in k]
|
||||
return self._cache_chk_args
|
||||
|
||||
|
||||
def check(self, mkw):
|
||||
for k in mkw:
|
||||
if (mkw[k] and k not in self.chk_args) or (not mkw[k] and k not in self.chk_noarg):
|
||||
if mkw[k] and k in self.chk_noarg:
|
||||
raise KeywordException("Keyword %s doesn't take value." % k)
|
||||
elif not mkw[k] and k in self.chk_args:
|
||||
raise KeywordException("Keyword %s requires a value." % k)
|
||||
else:
|
||||
ch = [c for c in guess(k, self.d)]
|
||||
raise KeywordException("Unknown keyword %s." % k + (" Did you mean: " + ", ".join(ch) + "?" if len(ch) else ""))
|
||||
|
||||
return super().check(mkw)
|
||||
|
||||
|
||||
def help(self):
|
||||
return ["\x03\x02@%s\x03\x02: %s" % (k, self.d[k]) for k in self.d]
|
|
@ -17,6 +17,9 @@
|
|||
import re
|
||||
|
||||
from nemubot.hooks.abstract import Abstract
|
||||
from nemubot.hooks.keywords import NoKeyword
|
||||
from nemubot.hooks.keywords.abstract import Abstract as AbstractKeywords
|
||||
from nemubot.hooks.keywords.dict import Dict as DictKeywords
|
||||
import nemubot.message
|
||||
|
||||
|
||||
|
@ -25,16 +28,19 @@ class Message(Abstract):
|
|||
"""Class storing hook information, specialized for a generic Message"""
|
||||
|
||||
def __init__(self, call, name=None, regexp=None, channels=list(),
|
||||
server=None, help=None, help_usage=dict(), keywords=dict(),
|
||||
server=None, help=None, help_usage=dict(), keywords=NoKeyword(),
|
||||
**kargs):
|
||||
|
||||
Abstract.__init__(self, call=call, **kargs)
|
||||
|
||||
if isinstance(keywords, dict):
|
||||
keywords = DictKeywords(keywords)
|
||||
|
||||
assert regexp is None or type(regexp) is str, regexp
|
||||
assert channels is None or type(channels) is list, channels
|
||||
assert server is None or type(server) is str, server
|
||||
assert type(help_usage) is dict, help_usage
|
||||
assert type(keywords) is dict, keywords
|
||||
assert isinstance(keywords, AbstractKeywords), keywords
|
||||
|
||||
self.name = str(name) if name is not None else None
|
||||
self.regexp = regexp
|
||||
|
@ -53,6 +59,10 @@ class Message(Abstract):
|
|||
)
|
||||
|
||||
|
||||
def check(self, msg):
|
||||
return not hasattr(msg, "kwargs") or self.keywords.check(msg.kwargs)
|
||||
|
||||
|
||||
def match(self, msg, server=None):
|
||||
if not isinstance(msg, nemubot.message.abstract.Abstract):
|
||||
return True
|
||||
|
|
Loading…
Reference in New Issue