Add more commands

This commit is contained in:
Joscha 2016-05-23 16:33:18 +02:00
parent 400da9c053
commit 80bfb26362
2 changed files with 184 additions and 34 deletions

View file

@ -1,8 +1,8 @@
from . import callbacks
import time import time
from . import room from . import callbacks
from . import exceptions from . import exceptions
from . import room
class Bot(): class Bot():
""" """
@ -24,6 +24,10 @@ class Bot():
self.manager = manager self.manager = manager
# modify/customize this in your __init__() function (or anywhere else you want, for that matter)
self.bot_description = ("This bot complies with the botrulez™ (https://github.com/jedevc/botrulez),\n"
"plus a few extra commands.")
self.helptexts = {} self.helptexts = {}
self.detailed_helptexts = {} self.detailed_helptexts = {}
@ -31,23 +35,49 @@ class Bot():
self.room.add_callback("message", self.on_message) self.room.add_callback("message", self.on_message)
self.commands = callbacks.Callbacks() self.commands = callbacks.Callbacks()
#self.commands.add("create", create_command)
#self.commands.add("kill", kill_command)
#self.commands.add("send", send_command)
#self.commands.add("uptime", uptime_command)
self.add_command("help", self.help_command, "Shows help information about the bot.", self.add_command("create", self.create_command, "Create a new bot of this bot's type.", # possibly add option to set nick?
("!create @bot [ <room> [ --pw=<password> ] ]\n"
"--pw : the room's password\n\n"
"Create a bot in the room specified, or the current room if no room\n"
"is specified. If the target room is passworded, you can use the\n"
"--pw option to set a password for the bot to use."))
self.add_command("help", self.help_command, "Show help information about the bot.",
("!help @bot [ -s | <command> ]\n" ("!help @bot [ -s | <command> ]\n"
"-s : general syntax help\n\n" "-s : general syntax help\n\n"
"Shows detailed help for a command if you specify a command name.\n" "Shows detailed help for a command if you specify a command name.\n"
"Shows a list of commands and short description if no arguments are given.")) "Shows a list of commands and short description if no arguments are given."))
self.add_command("kill", self.kill_command, "Kill (stop) the bot.",
("!kill @bot [ -r ]\n"
"-r : restart the bot (will change the id)\n\n"
"The bot disconnects from the room and stops."))
self.add_command("ping", self.ping_command, "Replies 'Pong!'.", self.add_command("ping", self.ping_command, "Replies 'Pong!'.",
("!ping @bot\n\n" ("!ping @bot\n\n"
"This command was originally used to help distinguish bots from\n" "This command was originally used to help distinguish bots from\n"
"people. Since the Great UI Change, this is no longer necessary as\n" "people. Since the Great UI Change, this is no longer necessary as\n"
"bots and people are displayed separately.")) "bots and people are displayed separately."))
self.add_command("restart", self.restart_command, "Restart the bot (shorthand for !kill -r).",
("!restart @bot\n\n"
"Restart the bot.\n"
"Short for !kill @bot -r"))
self.add_command("send", self.send_command, "Send the bot to another room.",
("!send @bot <room> [ --pw=<password> ]\n"
"--pw : the room's password\n\n"
"Sends this bot to the room specified. If the target room is passworded,\n"
"you can use the --pw option to set a password for the bot to use."))
self.add_command("uptime", self.uptime_command, "Show bot uptime since last (re-)start.",
("!uptime @bot [ -i ]\n"
"-i : show more detailed information\n\n"
"Shows the bot's uptime since the last start or restart.\n"
"Shows additional information (i.e. id) if the -i flag is set."))
self.add_command("show", self.show_command, detailed_helptext="You've found a hidden command! :)") self.add_command("show", self.show_command, detailed_helptext="You've found a hidden command! :)")
self.room.launch() self.room.launch()
@ -98,7 +128,7 @@ class Bot():
if not self.commands.exists(command): if not self.commands.exists(command):
return return
if not name == self.room.session.mentionable(): if not name == self.mentionable():
return return
if bot_id is not None: # id specified if bot_id is not None: # id specified
@ -108,8 +138,8 @@ class Bot():
return return
else: # no id specified else: # no id specified
bots = self.manager.get_similar(self.get_room(), name) bots = self.manager.get_similar(self.roomname(), name)
if self.manager.get_id(self) == min(bots): if self.manager.get_id(self) == min(bots): # only one bot should display the messages
if len(bots) > 1: if len(bots) > 1:
msg = ("There are multiple bots with that name in this room. To select one,\n" msg = ("There are multiple bots with that name in this room. To select one,\n"
"please specify its id (from the list below) as follows:\n" "please specify its id (from the list below) as follows:\n"
@ -117,41 +147,39 @@ class Bot():
for bot_id in sorted(bots): for bot_id in sorted(bots):
bot = bots[bot_id] bot = bots[bot_id]
msg += "\n{} - @{} ({})".format(bot_id, bot.get_nick(), bot.creation_info()) msg += "\n{} - @{} ({})".format(bot_id, bot.nick(), bot.creation_info())
self.room.send_message(msg, parent=message.id) self.room.send_message(msg, parent=message.id)
else: # name is unique else: # name is unique
self.commands.call(command, message, arguments, flags, options) self.commands.call(command, message, arguments, flags, options)
def get_room(self): def roomname(self):
""" """
get_room() -> roomname roomname() -> roomname
The room the bot is connected to. The room the bot is connected to.
""" """
return self.room.room return self.room.room
def get_mentionable_nick(self): def nick(self):
""" """
get_mentionable_nick() -> nick nick() -> nick
The The bot's nick in a mentionable format. The bot's full nick.
""" """
if self.room.session: return self.room.nick
return self.room.session.mentionable()
def get_nick(self): def mentionable(self):
""" """
get_nick() -> nick mentionable() -> nick
The bot's nick. The bot's nick in a mentionable format.
""" """
if self.room.session: return self.room.mentionable()
return self.room.session.name
def creation_info(self): def creation_info(self):
""" """
@ -161,7 +189,7 @@ class Bot():
""" """
ftime = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(self.start_time)) ftime = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(self.start_time))
info = "created at {}".format(ftime) info = "created {}".format(ftime)
if self.created_by: if self.created_by:
info += " by @{}".format(self.created_by) info += " by @{}".format(self.created_by)
@ -171,6 +199,32 @@ class Bot():
return info return info
def uptime(self):
"""
uptime() -> str
Formatted uptime
"""
delta = int(time.time() - self.start_time)
uptime = ""
if delta >= 24*60*60:
uptime +="{}d ".format(delta//24*60*60)
delta %= 24*60*60
if delta >= 60*60:
uptime += "{}h ".format(delta//60*60)
delta %= 60*60
if delta >= 60:
uptime += "{}m ".format(delta//60)
delta %= 60
uptime += "{}s".format(delta)
return uptime
def parse_command(self, message): def parse_command(self, message):
""" """
parse_command(message_content) -> command, bot_id, name, argpart parse_command(message_content) -> command, bot_id, name, argpart
@ -326,6 +380,37 @@ class Bot():
# ----- COMMANDS ----- # ----- COMMANDS -----
def create_command(self, message, arguments, flags, options):
"""
create_command(message, *arguments, flags, options) -> None
Create a new bot.
"""
if not arguments:
room = self.roomname()
else:
room = arguments[0]
if room[:1] == "&":
room = room[1:]
if "pw" in options and options["pw"] is not True:
password = options["pw"]
else:
password = None
try:
bot = self.manager.create(room, password=password)
except exceptions.CreateBotException:
self.room.send_message("Bot could not be created.", parent=message.id)
else:
bot.created_in = self.roomname()
bot.created_by = message.mentionable()
self.room.send_message("Created @{} in &{}.".format(bot.mentionable(), room),
parent=message.id)
def help_command(self, message, arguments, flags, options): def help_command(self, message, arguments, flags, options):
""" """
help_command(message, *arguments, flags, options) -> None help_command(message, *arguments, flags, options) -> None
@ -333,10 +418,7 @@ class Bot():
Show help about the bot. Show help about the bot.
""" """
if "s" in flags: # detailed syntax help if arguments: # detailed help for one command
msg = "SYNTAX HELP PLACEHOLDER"
elif arguments: # detailed help for one command
command = arguments[0] command = arguments[0]
if command[:1] == "!": if command[:1] == "!":
command = command[1:] command = command[1:]
@ -348,20 +430,39 @@ class Bot():
if command in self.helptexts: if command in self.helptexts:
msg += "\n\n" + self.helptexts[command] msg += "\n\n" + self.helptexts[command]
elif "s" in flags: # detailed syntax help
msg = "SYNTAX HELP PLACEHOLDER"
else: # just list all commands else: # just list all commands
msg = "This bot supports the following commands:\n" msg = self.bot_description
msg += "\n\nThis bot supports the following commands:"
for command in sorted(self.helptexts): for command in sorted(self.helptexts):
helptext = self.helptexts[command] helptext = self.helptexts[command]
msg += "\n!{} - {}".format(command, helptext) msg += "\n!{} - {}".format(command, helptext)
msg += ("\n\nFor detailed help on the command syntax, try:\n" msg += ("\n\nFor help on the command syntax, try: !help @{0} -s\n"
"!help @{0} -s\n" "For detailed help on a command, try: !help {0} <command>")
"For detailed help on a command, try:\n" msg = msg.format(self.mentionable())
"!help {0} <command>").format(self.get_mentionable_nick())
self.room.send_message(msg, parent=message.id) self.room.send_message(msg, parent=message.id)
def kill_command(self, message, arguments, flags, options):
"""
kill_command(message, *arguments, flags, options) -> None
stop the bot.
"""
if "r" in flags:
bot = self.manager.create(self.roomname())
bot.created_by = self.created_by
bot.created_in = self.created_in
self.room.send_message("/me exits.", message.id)
self.manager.remove(self.manager.get_id(self))
def ping_command(self, message, arguments, flags, options): def ping_command(self, message, arguments, flags, options):
""" """
ping_command(message, *arguments, flags, options) -> None ping_command(message, *arguments, flags, options) -> None
@ -371,6 +472,40 @@ class Bot():
self.room.send_message("Pong!", parent=message.id) self.room.send_message("Pong!", parent=message.id)
def restart_command(self, message, arguments, flags, options):
"""
restart_command(message, *arguments, flags, options) -> None
Restart the bot (shorthand for !kill @bot -r).
"""
self.commands.call("kill", message, [], "r", {})
def send_command(self, message, arguments, flags, options):
"""
_command(message, *arguments, flags, options) -> None
Send this bot to another room.
"""
if not arguments:
return
else:
room = arguments[0]
if room[:1] == "&":
room = room[1:]
if "pw" in options and options["pw"] is not True:
password = options["pw"]
else:
password = None
self.room.send_message("/me moves to &{}.".format(room), parent=message.id)
self.room.change(room, password=password)
self.room.launch()
def show_command(self, message, arguments, flags, options): def show_command(self, message, arguments, flags, options):
""" """
show_command(message, arguments, flags, options) -> None show_command(message, arguments, flags, options) -> None
@ -380,3 +515,18 @@ class Bot():
msg = "arguments: {}\nflags: {}\noptions: {}".format(arguments, repr(flags), options) msg = "arguments: {}\nflags: {}\noptions: {}".format(arguments, repr(flags), options)
self.room.send_message(msg, parent=message.id) self.room.send_message(msg, parent=message.id)
def uptime_command(self, message, arguments, flags, options):
"""
uptime_command(message, arguments, flags, options) -> None
Show uptime and other info.
"""
msg = "uptime: {}".format(self.uptime())
if "i" in flags:
msg += "\nid: {}".format(self.manager.get_id(self))
msg += "\n{}".format(self.creation_info())
self.room.send_message(msg, message.id)

View file

@ -82,4 +82,4 @@ class BotManager():
""" """
return {bot_id: bot for bot_id, bot in self.bots.items() return {bot_id: bot for bot_id, bot in self.bots.items()
if bot.get_room() == room and bot.get_mentionable_nick() == nick} if bot.roomname() == room and bot.mentionable() == nick}