More cleanup of irc bot code, including having it cleanly disconnect from irc channel when destroyed.

This commit is contained in:
Griatch 2014-02-27 01:11:00 +01:00
parent 7bde8afe66
commit f126d30b36
3 changed files with 62 additions and 18 deletions

View file

@ -764,6 +764,8 @@ class CmdIRC2Chan(MuxCommand):
Usage:
@irc2chan[/switches] <evennia_channel> = <ircnetwork> <port> <#irchannel> <botname>
@irc2chan/list
@irc2chan/delete botname|dbid
Switches:
/disconnect - this will delete the bot and remove the irc connection
@ -799,7 +801,7 @@ class CmdIRC2Chan(MuxCommand):
ircbots = [bot.typeclass for bot in PlayerDB.objects.filter(db_is_bot=True)]
if ircbots:
from src.utils.evtable import EvTable
table = EvTable("{wdbid{n", "{wbotname{n", "{wev-channel{n", "{wirc-channel{n", border="cells")
table = EvTable("{wdbid{n", "{wbotname{n", "{wev-channel{n", "{wirc-channel{n", border="cells", maxwidth=78)
for ircbot in ircbots:
ircinfo = "%s (%s:%s)" % (ircbot.db.irc_channel, ircbot.db.irc_network, ircbot.db.irc_port)
table.add_row(ircbot.id, ircbot.db.irc_botname, ircbot.db.ev_channel, ircinfo)
@ -808,6 +810,21 @@ class CmdIRC2Chan(MuxCommand):
self.msg("No irc bots found.")
return
if('disconnect' in self.switches or 'remove' in self.switches or
'delete' in self.switches):
botname = "ircbot-%s" % self.lhs
matches = PlayerDB.objects.filter(db_is_bot=True, db_key=botname)
if not matches:
# try dbref match
matches = PlayerDB.objects.filter(db_is_bot=True, id=self.args.lstrip("#"))
if matches:
matches[0].delete()
self.msg("IRC connection destroyed.")
else:
self.msg("IRC connection/bot could not be removed, does it exist?")
return
if not self.args or not self.rhs:
string = "Usage: @irc2chan[/switches] <evennia_channel> = <ircnetwork> <port> <#irchannel> <botname>"
self.msg(string)
@ -826,16 +843,6 @@ class CmdIRC2Chan(MuxCommand):
botname = "ircbot-%s" % irc_botname
if('disconnect' in self.switches or 'remove' in self.switches or
'delete' in self.switches):
matches = PlayerDB.objects.filter(db_is_bot=True, db_key=botname)
if matches:
matches[0].delete()
self.msg("IRC connection destroyed.")
else:
self.msg("IRC connection/bot could not be removed, does it exist?")
return
# create a new bot
bot = PlayerDB.objects.filter(username__iexact=botname)
if bot:

View file

@ -34,6 +34,7 @@ class IRCBot(irc.IRCClient, Session):
the game as a full session.
"""
self.join(self.channel)
self.stopping = False
self.factory.bot = self
self.init_session("ircbot", self.network, self.factory.sessionhandler)
# we link back to our bot and log in
@ -43,6 +44,15 @@ class IRCBot(irc.IRCClient, Session):
logger.log_infomsg("IRC bot '%s' connected to %s at %s:%s." % (self.nickname, self.channel,
self.network, self.port))
def disconnect(self, reason=None):
"""
Called by sessionhandler to disconnect this protocol
"""
print "irc disconnect called!"
self.sessionhandler.disconnect(self)
self.stopping = True
self.transport.loseConnection()
def privmsg(self, user, channel, msg):
"A message was sent to channel"
if not msg.startswith('***'):
@ -99,6 +109,13 @@ class IRCBotFactory(protocol.ReconnectingClientFactory):
"Tracks reconnections for debugging"
logger.log_infomsg("(re)connecting to %s" % self.channel)
def clientConnectionFailed(self, connector, reason):
self.retry(connector)
def clientConnectionLost(self, connector, reason):
if not self.bot.stopping:
self.retry(connector)
def start(self):
"Connect session to sessionhandler"
service = internet.TCPClient(self.network, self.port, self)

View file

@ -75,6 +75,7 @@ ANSI-coloured string types.
#from textwrap import wrap
from textwrap import TextWrapper
from copy import deepcopy, copy
from src.utils.utils import to_unicode
from src.utils.ansi import ANSIString
def make_iter(obj):
@ -86,7 +87,7 @@ def _to_ansi(obj, regexable=False):
if hasattr(obj, "__iter__"):
return [_to_ansi(o) for o in obj]
else:
return ANSIString(unicode(obj), regexable=regexable)
return ANSIString(to_unicode(obj), regexable=regexable)
_unicode = unicode
@ -644,6 +645,15 @@ class EvTable(object):
corners. Default is 1.
corner_char - character to use in corners when border is
active.
corner_top_left - character to use in upper left corner of table
(defaults to corner_char)
corner_top_right
corner_bottom_left
corner_bottom_right
pretty_corners - (default True): use custom characters to make
the table corners look "rounded". Uses UTF-8
characters.
header_line_char - characters to use for underlining
the header row (default is '~')
Requires border to be active.
@ -707,6 +717,11 @@ class EvTable(object):
# border settings are passed into Cell as well (so kwargs.get and not pop)
self.border_width = kwargs.get("border_width", 1)
self.corner_char = kwargs.get("corner_char", "+")
pcorners = kwargs.pop("pretty_corners", False)
self.corner_top_left = _to_ansi(kwargs.pop("corner_top_left", '.' if pcorners else self.corner_char))
self.corner_top_right = _to_ansi(kwargs.pop("corner_top_right", '.' if pcorners else self.corner_char))
self.corner_bottom_left = _to_ansi(kwargs.pop("corner_bottom_left", '`' if pcorners else self.corner_char))
self.corner_bottom_right = _to_ansi(kwargs.pop("corner_bottom_right", '´' if pcorners else self.corner_char))
self.width = kwargs.pop("width", None)
self.height = kwargs.pop("height", None)
@ -747,13 +762,13 @@ class EvTable(object):
def corners(ret):
"Handle corners of table"
if ix == 0 and iy == 0:
ret["corner_top_left"] = cchar
ret["corner_top_left"] = self.corner_top_left
if ix == nx and iy == 0:
ret["corner_top_right"] = cchar
ret["corner_top_right"] = self.corner_top_right
if ix == 0 and iy == ny:
ret["corner_bottom_left"] = cchar
ret["corner_bottom_left"] = self.corner_bottom_left
if ix == nx and iy == ny:
ret["corner_bottom_right"] = cchar
ret["corner_bottom_right"] = self.corner_bottom_right
return ret
def left_edge(ret):
@ -976,7 +991,7 @@ class EvTable(object):
cell_data = [cell.get() for cell in cell_row]
cell_height = min(len(lines) for lines in cell_data)
for iline in range(cell_height):
yield "".join(celldata[iline] for celldata in cell_data)
yield "".join(_to_ansi(celldata[iline] for celldata in cell_data))
def add_header(self, *args, **kwargs):
"""
@ -1094,6 +1109,11 @@ class EvTable(object):
self.corner_char = kwargs.get("corner_char", self.corner_char)
self.header_line_char = kwargs.get("header_line_char", self.header_line_char)
self.corner_top_left = _to_ansi(kwargs.pop("corner_top_left", self.corner_top_leftorner_char))
self.corner_top_right = _to_ansi(kwargs.pop("corner_top_right", self.corner_char))
self.corner_bottom_left = _to_ansi(kwargs.pop("corner_bottom_left", self.corner_char))
self.corner_bottom_right = _to_ansi(kwargs.pop("corner_bottom_right", self.corner_char))
self.options.update(kwargs)
self._balance()
@ -1105,5 +1125,5 @@ class EvTable(object):
def __str__(self):
"print table"
return "\n".join([line for line in self._generate_lines()])
return to_unicode("\n".join([line for line in self._generate_lines()]))