|
- # -*- coding: utf-8 -*-
-
- """
- EarwigBot's IRC Front-end Component
-
- The IRC frontend runs on a normal IRC server and expects users to interact with
- it and give it commands. Commands are stored as "command classes", subclasses
- of BaseCommand in irc/base_command.py. All command classes are automatically
- imported by irc/command_handler.py if they are in irc/commands.
- """
-
- from re import findall
-
- from core import config
- from irc import command_handler
- from irc.classes import Connection, Data, BrokenSocketException
-
- connection = None
-
- def get_connection():
- """Return a new Connection() instance with information about our server
- connection, but don't actually connect yet."""
- cf = config.irc["frontend"]
- connection = Connection(cf["host"], cf["port"], cf["nick"], cf["ident"],
- cf["realname"])
- return connection
-
- def startup(conn):
- """Accept a single arg, a Connection() object, and set our global variable
- 'connection' to it. Load all command classes in irc/commands with
- command_handler, and then establish a connection with the IRC server."""
- global connection
- connection = conn
- command_handler.load_commands(connection)
- connection.connect()
-
- def main():
- """Main loop for the Frontend IRC Bot component. get_connection() and
- startup() should have already been called."""
- read_buffer = str()
-
- while 1:
- try:
- read_buffer = read_buffer + connection.get()
- except BrokenSocketException:
- print "Socket has broken on front-end; restarting bot..."
- return
-
- lines = read_buffer.split("\n")
- read_buffer = lines.pop()
-
- for line in lines: # handle a single message from IRC
- line = line.strip().split()
- data = Data() # new Data() instance to store info about this line
- data.line = line
-
- if line[1] == "JOIN":
- data.nick, data.ident, data.host = findall(
- ":(.*?)!(.*?)@(.*?)\Z", line[0])[0]
- data.chan = line[2][1:]
- command_handler.check("join", data) # check for 'join' hooks in
- # our commands
-
- if line[1] == "PRIVMSG":
- data.nick, data.ident, data.host = findall(
- ":(.*?)!(.*?)@(.*?)\Z", line[0])[0]
- data.msg = ' '.join(line[3:])[1:]
- data.chan = line[2]
-
- if data.chan == config.irc["frontend"]["nick"]:
- # this is a privmsg to us, so set 'chan' as the nick of the
- # sender, then check for private-only command hooks
- data.chan = data.nick
- command_handler.check("msg_private", data)
- else:
- # check for public-only command hooks
- command_handler.check("msg_public", data)
-
- # check for command hooks that apply to all messages
- command_handler.check("msg", data)
-
- # hardcode the !restart command (we can't restart from within
- # an ordinary command)
- if data.msg in ["!restart", ".restart"]:
- if data.host in config.irc["permissions"]["owners"]:
- print "Restarting bot per owner request..."
- return
-
- if line[0] == "PING": # if we are pinged, pong back to the server
- connection.send("PONG %s" % line[1])
-
- if line[1] == "376": # we've successfully connected to the network
- try: # if we're supposed to auth to nickserv, do that
- ns_username = config.irc["frontend"]["nickservUsername"]
- ns_password = config.irc["frontend"]["nickservPassword"]
- except KeyError:
- pass
- else:
- connection.say("NickServ", "IDENTIFY {0} {1}".format(
- ns_username, ns_password))
-
- # join all of our startup channels
- for chan in config.irc["frontend"]["channels"]:
- connection.join(chan)
|