Newer
Older
src / python / mybot / BotInstance.py
@Andreas Jaggi Andreas Jaggi on 4 Jun 2006 3 KB Changes:
#!/bin/python

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

import re, os, copy, random, datetime
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"):

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

		if manager == None:
				manager = BotManager.BotManager()
		self.manager = manager
		self.server = server
		self.channel = channel
		self.nickname = nick
		self.port = port
		self.observedChannels = []
		self.availableChannels = []
		self.nickre = re.compile(nick)

		self.answer = "Um, Richard, I didn't see the question."
		self.queries = []
		self.results = {}
		self.queriesre = {}

		self.channelLimitReached = 0
		self.nextInstance = None

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

		self.start();

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

	def join(self, channel, key = None):
		if channel not in self.observedChannels:
			if self.channelLimitReached:
				self.nextInstance.join(channel, key)
			else:
				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 == "PrintChannels":
			for x in self.observedChannels:
				self.say(self.channel, x)
		elif message == "DoList":
			self.send("LIST")
		elif message.split(' ')[0] == 'JoinChannel':
			self.join(message.split(' ')[1])
		elif self.nickre.match(message):
			self.readFuzzyText(message)
			if to != self.nickname:
				self.say(to, self.answer)
			else:
				self.say(sourcenick, self.answer)
		else:
			self.readFuzzyText(message)

		for query in self.queries:
			queryre = self.queriesre.setdefault(query, re.compile(query))

			if queryre.match(message) or queryre.match(source) or queryre.match(to):
				if not self.results.has_key(query):
					self.results[query] = []
				self.results[query].append((datetime.date.today().ctime(), self.server, self.channel, source, to, message))
				self.manager.resultsUpdated(self)

	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 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)

		if code == 323:
			# end of LIST command
			self.availableChannels.sort()
			self.observedChannels.sort()
			self.manager.availableChannelsUpdated(self)

		if code == 405:
			# "You can't join that many channels"
			channelname = params.split(' ')[1]

			print "recieved channel: %s" % channelname

			if not self.channelLimitReached:
				self.channelLimitReached = 1

				newnick = self.manager.genNick()
				self.nextInstance = BotInstance(self.manager, self.server, self.port, newnick, self.channel)

			self.nextInstance.join(channelname)

	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.tjoin()