Implement command help system
This commit is contained in:
parent
5c8f6b02fd
commit
2f88dc28c6
|
@ -0,0 +1,31 @@
|
|||
:mod:`ModInfo` --- Module command help system
|
||||
=============================================
|
||||
|
||||
Implements global `help` and `helpindex` commands that print help information about all available modules. Modules must
|
||||
import and use a decorator from this module. For example:
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyircbot.modules.ModInfo import info
|
||||
|
||||
# ...
|
||||
|
||||
@info("help [command] show the manual for all or [commands]", cmds=["help"])
|
||||
@command("help")
|
||||
def cmd_help(self, msg, cmd):
|
||||
# ...
|
||||
|
||||
|
||||
The `info` decorator takes a mandatory string parameter describing the command. The second, optional, list parameter
|
||||
`cmds` is a list of short names thart are aliases for the function that aide in help lookup. In all cases, the cases,
|
||||
commands will be prefixed with the default command prefix (`from pyircbot.modulebase.command.prefix`).
|
||||
|
||||
|
||||
Class Reference
|
||||
---------------
|
||||
|
||||
.. automodule:: pyircbot.modules.ModInfo
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
|
@ -93,7 +93,6 @@ Client sending a message that the bot will relay
|
|||
|
||||
pyircbot_send default privmsg ["#clonebot", "asdf1234"]
|
||||
|
||||
"""
|
||||
|
||||
Example Programs
|
||||
----------------
|
||||
|
|
|
@ -251,9 +251,6 @@ class regex(hook):
|
|||
def cmd_foobar(self, matches, msg):
|
||||
print("Someone's message was exactly "foobar" ({}) in channel {}".format(msg.message, msg.args[0]))
|
||||
|
||||
This stores a list of IRC actions each function is tagged for in method.__tag_regexes. This attribute is scanned
|
||||
during module init and appropriate hooks are set up.
|
||||
|
||||
:param regexps: expressions to match for
|
||||
:type keywords: str
|
||||
:param allow_private: enable matching in private messages
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
from pyircbot.modulebase import ModuleBase, ModuleHook, MissingDependancyException, regex, command
|
||||
from pyircbot.modules.ModInfo import info
|
||||
import datetime
|
||||
import time
|
||||
import math
|
||||
|
@ -79,6 +80,7 @@ class Calc(ModuleBase):
|
|||
seconds = int(remaining - (minutes * 60))
|
||||
return "Please wait %s minute(s) and %s second(s)." % (minutes, seconds)
|
||||
|
||||
@info("quote [key[ =[ value]]] set or update facts", cmds=["quote"])
|
||||
@regex(r'(?:^\.?(?:calc|quote)(?:\s+?(?:([^=]+)(?:\s?(=)\s?(.+)?)?)?)?)', types=['PRIVMSG'])
|
||||
def cmd_calc(self, message, match):
|
||||
word, changeit, value = match.groups()
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
.. module::ModInfo
|
||||
:synopsis: Provides manpage-like info for commands
|
||||
"""
|
||||
|
||||
|
||||
from pyircbot.modulebase import ModuleBase, command
|
||||
|
||||
|
||||
class info(object):
|
||||
"""
|
||||
Decorator for tagging module methods with help text
|
||||
|
||||
.. code-block:: python
|
||||
from pyircbot.modules.ModInfo import info
|
||||
|
||||
...
|
||||
|
||||
@info("help [command] show the manual for all or [commands]", cmds=["help", "rtfm"])
|
||||
@command("help")
|
||||
def cmd_help(self, msg, cmd):
|
||||
...
|
||||
|
||||
:param docstring: command help formatted as above
|
||||
:type docstring: str
|
||||
:param cmds: enable command names or aliases this function implements, as a list of strings. E.g. if the "help"
|
||||
command has the alias "rtfm"
|
||||
:type cmds: list
|
||||
"""
|
||||
def __init__(self, docstring, cmds=None):
|
||||
self.docstring = docstring
|
||||
self.commands = cmds or []
|
||||
|
||||
def __call__(self, func):
|
||||
setattr(func, "irchelp", self.docstring)
|
||||
setattr(func, "irchelpc", self.commands)
|
||||
return func
|
||||
|
||||
|
||||
class ModInfo(ModuleBase):
|
||||
|
||||
@info("help [command] show the manual for all or [commands]", cmds=["help"])
|
||||
@command("help")
|
||||
def cmd_help(self, msg, cmd):
|
||||
"""
|
||||
Get help on a command
|
||||
"""
|
||||
if cmd.args:
|
||||
for modname, module, helptext, helpcommands in self.iter_modules():
|
||||
if cmd.args[0] in ["{}{}".format(command.prefix, i) for i in helpcommands]:
|
||||
self.bot.act_PRIVMSG(msg.args[0], "RTFM: {}: {}".format(cmd.args[0], helptext))
|
||||
else:
|
||||
for modname, module, helptext, helpcommands in self.iter_modules():
|
||||
self.bot.act_PRIVMSG(msg.args[0], "{}: {}{}".format(modname, command.prefix, helptext))
|
||||
|
||||
@command("helpindex")
|
||||
def cmd_helpindex(self, msg, cmd):
|
||||
"""
|
||||
Short index of commands
|
||||
"""
|
||||
commands = []
|
||||
for modname, module, helptext, helpcommands in self.iter_modules():
|
||||
commands += ["{}{}".format(command.prefix, i) for i in helpcommands]
|
||||
|
||||
self.bot.act_PRIVMSG(msg.args[0], "{}: commands: {}".format(msg.prefix.nick, ", ".join(commands)))
|
||||
|
||||
def iter_modules(self):
|
||||
"""
|
||||
Iterator that cycles through module methods that are tagged with help information. The iterator yields tuples
|
||||
of:
|
||||
|
||||
(module_name, module_object, helptext, command_list)
|
||||
"""
|
||||
for modname, module in self.bot.moduleInstances.items():
|
||||
for attr_name in dir(module):
|
||||
attr = getattr(module, attr_name)
|
||||
if callable(attr) and hasattr(attr, "irchelp"):
|
||||
yield (modname, module, getattr(attr, "irchelp"), getattr(attr, "irchelpc"), )
|
||||
raise StopIteration()
|
|
@ -7,7 +7,9 @@
|
|||
|
||||
"""
|
||||
|
||||
from pyircbot.modulebase import ModuleBase, ModuleHook
|
||||
from pyircbot.modules.ModInfo import info
|
||||
from pyircbot.modulebase import ModuleBase, command, hook
|
||||
from contextlib import closing
|
||||
import sqlite3
|
||||
import time
|
||||
|
||||
|
@ -15,7 +17,6 @@ import time
|
|||
class Seen(ModuleBase):
|
||||
def __init__(self, bot, moduleName):
|
||||
ModuleBase.__init__(self, bot, moduleName)
|
||||
self.hooks = [ModuleHook("PRIVMSG", self.lastSeen)]
|
||||
# if the database doesnt exist, it will be created
|
||||
sql = self.getSql()
|
||||
c = sql.cursor()
|
||||
|
@ -27,31 +28,32 @@ class Seen(ModuleBase):
|
|||
c.execute("CREATE TABLE `seen` (`nick` VARCHAR(32), `date` INTEGER, PRIMARY KEY(`nick`))")
|
||||
self.x = "asdf"
|
||||
|
||||
def lastSeen(self, args, prefix, trailing):
|
||||
@hook("PRIVMSG")
|
||||
def recordSeen(self, message, command):
|
||||
# using a message to update last seen, also, the .seen query
|
||||
prefixObj = self.bot.decodePrefix(prefix)
|
||||
nick = prefixObj.nick
|
||||
sql = self.getSql()
|
||||
c = sql.cursor()
|
||||
# update or add the user's row
|
||||
datest = str(time.time() + (int(self.config["add_hours"]) * 60 * 60))
|
||||
c.execute("REPLACE INTO `seen` (`nick`, `date`) VALUES (?, ?)", (nick.lower(), datest))
|
||||
# self.log.info("Seen: %s on %s" % (nick.lower(), datest))
|
||||
sql.commit()
|
||||
if trailing.startswith(".seen"):
|
||||
cmdargs = trailing.split(" ")
|
||||
sql = self.getSql()
|
||||
with closing(sql.cursor()) as c:
|
||||
# update or add the user's row
|
||||
c.execute("REPLACE INTO `seen` (`nick`, `date`) VALUES (?, ?)", (message.prefix.nick.lower(), datest))
|
||||
# self.log.info("Seen: %s on %s" % (nick.lower(), datest))
|
||||
sql.commit()
|
||||
|
||||
@info("seen <nick> print last time user was seen", cmds=["seen"])
|
||||
@command("seen", require_args=True)
|
||||
def lastSeen(self, message, command):
|
||||
sql = self.getSql()
|
||||
searchnic = command.args[0].lower()
|
||||
with closing(sql.cursor()) as c:
|
||||
# query the DB for the user
|
||||
if len(cmdargs) >= 2:
|
||||
searchnic = cmdargs[1].lower()
|
||||
c.execute("SELECT * FROM `seen` WHERE `nick`= ? ", [searchnic])
|
||||
rows = c.fetchall()
|
||||
if len(rows) == 1:
|
||||
self.bot.act_PRIVMSG(args[0], "I last saw %s on %s (%s)." %
|
||||
(cmdargs[1], time.strftime("%m/%d/%y at %I:%M %p",
|
||||
time.localtime(rows[0]['date'])), self.config["timezone"]))
|
||||
else:
|
||||
self.bot.act_PRIVMSG(args[0], "Sorry, I haven't seen %s!" % cmdargs[1])
|
||||
c.close()
|
||||
c.execute("SELECT * FROM `seen` WHERE `nick`= ? ", [searchnic])
|
||||
rows = c.fetchall()
|
||||
if len(rows) == 1:
|
||||
self.bot.act_PRIVMSG(message.args[0], "I last saw %s on %s (%s)." %
|
||||
(command.args[0], time.strftime("%m/%d/%y at %I:%M %p",
|
||||
time.localtime(rows[0]['date'])), self.config["timezone"]))
|
||||
else:
|
||||
self.bot.act_PRIVMSG(message.args[0], "Sorry, I haven't seen %s!" % command.args[0])
|
||||
|
||||
def getSql(self):
|
||||
# return a SQL reference to the database
|
||||
|
@ -66,9 +68,3 @@ class Seen(ModuleBase):
|
|||
for idx, col in enumerate(cursor.description):
|
||||
d[col[0]] = row[idx]
|
||||
return d
|
||||
|
||||
def test(self, arg):
|
||||
print("TEST: %s" % arg)
|
||||
print("self.x = %s" % self.x)
|
||||
return arg
|
||||
|
||||
|
|
|
@ -369,14 +369,14 @@ class PyIRCBot(object):
|
|||
argsStart = len(command)
|
||||
args = ""
|
||||
if argsStart > 0:
|
||||
args = message[argsStart + 1:]
|
||||
args = message[argsStart + 1:].strip()
|
||||
|
||||
if requireArgs and args.strip() == '':
|
||||
if requireArgs and args == '':
|
||||
return False
|
||||
|
||||
# Verified! Return the set.
|
||||
return ParsedCommand(command,
|
||||
args.split(" "),
|
||||
args.split(" ") if args else [],
|
||||
args,
|
||||
message)
|
||||
|
||||
|
|
Loading…
Reference in New Issue