Newer
Older
src / python / mybot / BotInstance.py
#!/bin/python

# BotInstance
#
# (c) 2006 Andreas Jaggi <andreas.jaggi@waterwave.ch>

import re, os, copy, random
from IRCClient import IRCClient, LogAllMixin
import BotManager

class BotInstance(LogAllMixin, IRCClient):
	def __init__(self, manager = None, server = "irc.freenode.net", port = 6667, nick = "saf02oitgawsg", channel = "#asdf", id = 0):

		print "Spawning bot for: %s:%s %s on %s" % (server, port, nick, channel)

		if manager == None:
				manager = BotManager.BotManager()
		self.manager = manager
		self.channel = channel
		self.observedChannels = []

		IRCClient.__init__(self, server, port)
		self.connect(nick, nick)
		self.join(channel)

		self.answer = "Um, Richard, I didn't see the question."
		self.autojoin = 0
		self.tojoin = []
		self.next = None
		self.id = id
		self.nick = nick
		self.port = port
		self.joinct = 0
		self.server = server
		self.finished = 0
		self.nickre = re.compile(nick)

		self.availableChannels = []

	def requestChannelList(self):
		self.send("LIST")

	def join(self, channel, key = None):
		if channel not in self.observedChannels:
			IRCClient.join(self, channel, key)

			self.observedChannels.append(channel)
			self.manager.observedChannelsUpdated(self)

	def handle_say(self, source, to, message):
		#print "----(%s->%s): %s" % (source, to, message)

		sourcenick = source.split("!")[0]

		if message == "Shane":
			self.say(self.channel, self.answer)
		elif message == "AutoJoinEnable":
			self.autojoin = 1
			#self.say(self.channel, "Enabled AutoJoin")
		elif message == "AutoJoinDisable":
			self.autojoin = 0
			#self.say(self.channel, "Disabled AutoJoin")
		elif message == "PrintChannels":
			for x in self.observedChannels:
				self.say(self.channel, x)
		elif message == "DoList":
			self.send("LIST")
			#self.say(self.channel, "Doing list")
		elif message == "WorkOnJoin":
			#self.say(self.channel, "Working on join")
			self.WorkOnJoin()
		elif message.split(' ')[0] == 'Inject':
			newchannel = message.split(' ')[1]
			#self.say(self.channel, "Injecting %s" % newchannel)
			self.addChannel(newchannel)
		elif message.split(' ')[0] == 'NNS':
			self.server = message.split(' ')[1]
			#self.say(self.channel, "NNS %s" % self.server)
			self.spanNext()
		elif self.nickre.match(message):
			self.readFuzzyText(message)
			if to != self.nick:
				self.say(to, self.answer)
			else:
				self.say(sourcenick, self.answer)
		else:
			self.readFuzzyText(message)

	def readFuzzyText(self, message):
		if len(message) > 0:
			newtokens = set(message.split(" "))
			oldtokens = set(self.answer.split(" "))
			nexttokens = list(newtokens.union(oldtokens))
			random.shuffle(nexttokens)
			a = random.randint(0, (len(nexttokens)-1)/2)
			b = random.randint(a, len(nexttokens)-1)
			self.answer = ' '.join(nexttokens[a:b])

	def addChannel(self, channel):
		if channel not in self.tojoin:
			if channel not in self.observedChannels:
				self.tojoin.append(channel)
				random.shuffle(self.tojoin)

	def WorkOnJoin(self):
		if self.tojoin and self.autojoin and not self.finished:
			for x in range(0, min(5, len(self.tojoin))):
				channel = self.tojoin.pop()
				#self.say(self.channel, "Joining %s" % channel)
				self.join(channel)
			#self.say(self.channel, "%s remaining" % len(self.tojoin))

	def handle_incoming(self, line):
		LogAllMixin.handle_incoming(self, line)

		self.joinct = self.joinct+1
		if self.joinct > 200:
			self.joinct = 0
			self.WorkOnJoin()

	def handle_reply(self, prefix, code, params):
		print "reply: %s" % code
		if code == 322:
			# reply to a LIST command
			newchannel = params.split(' ')[1]
			if newchannel not in self.availableChannels:
				self.availableChannels.append(newchannel)
				self.manager.availableChannelsUpdated(self)

			self.addChannel(newchannel)
		if code == 405:
			self.spanNext()
			self.finished = 1

	def spanNext(self):
		newid = random.randint(int(self.id), int(self.id)**2+10)
		self.next = BotInstance(self.manager, self.server, self.port, "%s%s%s" % (self.nick, self.id, newid), self.channel, "%s%s" % (self.id, newid))
		self.autojoin = 0
		self.next.autojoin = 1
		self.next.tojoin = copy.deepcopy(self.tojoin)
		self.tojoin = []
		self.next.start()

	def handle_notice(self, source, to, message):
		print "notice: (%s->%s): %s" % (source, to, message)

	def handle_command(self, prefix, command, params):
		print "command: %s" % command

if __name__ == "__main__":
	bot = BotInstance()
	bot.start()
	bot.tjoin()