from twisted.internet import reactor, task, defer, protocol
from twisted.python import log
from twisted.words.protocols import irc
from twisted.web.client import getPage
from twisted.application import internet, service
HOST, PORT = 'irc.rizon.net', 6667
nickname = ''
channels = [""]
eng = engine.Eng()
nickname = nickname
for channel in self.factory.channels:
def extract_nicks(self, msg):
def say(self, msg, target):
#def say(self, msg, channel)
# Obviously, called when a PRIVMSG is received.
def privmsg(self, user, channel, message):
message = message.decode("utf8").strip()
msg = eng.administrate(message, nickname, user)
msg = msg.encode("utf8")
def _send_message(self, msg, target, nick=None):
msg = '%s, %s' % (nick, msg)
def _show_error(self, failure):
def command_ping(self, rest):
def command_saylater(self, rest):
when, sep, msg = rest.partition(' ')
when = int(when)
d = defer.Deferred()
# A small example of how to defer the reply from a command. callLater
# will callback the Deferred with the reply after so many seconds.
reactor.callLater(when, d.callback, msg)
# Returning the Deferred here means that it'll be returned from
# maybeDeferred in privmsg.
def command_title(self, url):
d = getPage(url)
# Another example of using Deferreds. twisted.web.client.getPage returns
# a Deferred which is called back when the URL requested has been
# downloaded. We add a callback to the chain which will parse the page
# and extract only the title. If we just returned the deferred instead,
# the function would still work, but the reply would be the entire
# contents of the page.
# After that, we add a callback that will extract the title
# from the parsed tree lxml returns
def _parse_pagetitle(self, page_contents, url):
# Parses the page into a tree of elements:
pagetree = lxml.html.fromstring(page_contents)
# Extracts the title text from the lxml document using xpath
title = u' '.join(pagetree.xpath('//title/text()')).strip()
# Since lxml gives you unicode and unicode data must be encoded
# to send over the wire, we have to encode the title. Sadly IRC predates
# unicode, so there's no formal way of specifying the encoding of data
# transmitted over IRC. UTF-8 is our best bet, and what most people use.
title = title.encode('utf-8')
# Since we're returning this value from a callback, it will be passed in
# to the next callback in the chain (self._send_message).
return '%s -- "%s"' % (url, title)
protocol = MyFirstIRCProtocol
channels = channels
if __name__ == '__main__':
# This runs the program in the foreground. We tell the reactor to connect
# over TCP using a given factory, and once the reactor is started, it will
# open that connection.
reactor.connectTCP(HOST, PORT, MyFirstIRCFactory())
# Since we're running in the foreground anyway, show what's happening by
# logging to stdout.
# And this starts the reactor running. This call blocks until everything is
# done, because this runs the whole twisted mainloop.
# This runs the program in the background. __name__ is __builtin__ when you use
# twistd -y on a python module.
elif __name__ == '__builtin__':
# Create a new application to which we can attach our services. twistd wants
# an application object, which is how it knows what services should be
# running. This simplifies startup and shutdown.
application = service.Application('MyFirstIRCBot')
# twisted.application.internet.TCPClient is how to make a TCP client service
# which we can attach to the application.
ircService = internet.TCPClient(HOST, PORT, MyFirstIRCFactory())
# twistd -y looks for a global variable in this module named 'application'.
# Since there is one now, and it's all set up, there's nothing left to do.