diff options
Diffstat (limited to 'contrib/errcode/gpxebot.py')
-rwxr-xr-x | contrib/errcode/gpxebot.py | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/contrib/errcode/gpxebot.py b/contrib/errcode/gpxebot.py new file mode 100755 index 00000000..4fb2ce1e --- /dev/null +++ b/contrib/errcode/gpxebot.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python +# Copyright (C) 2008 Stefan Hajnoczi <stefanha@gmail.com>. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +import re +import socket +import errcode + +HOST = 'irc.freenode.net' +PORT = 6667 +NICK = 'gpxebot' +CHAN = '#etherboot' +NICKSERV_PASSWORD = None +IDENT = 'gpxebot' +REALNAME = 'gPXE bot' + +ERRCODE_RE = re.compile(r'(errcode|Error)\s+((0x)?[0-9a-fA-F]{8})') + +NO_ARGS = -1 + +handlers = {} + +def nick_from_mask(mask): + return (mask.find('!') > -1 and mask.split('!', 1)[0]) or mask + +def autojoin(): + del handlers['376'] + if NICKSERV_PASSWORD: + pmsg('nickserv', 'identify %s' % NICKSERV_PASSWORD) + if CHAN: + cmd('JOIN %s' % CHAN) + +def ping(_, arg): + cmd('PONG %s' % arg) + +def privmsg(_, target, msg): + if target == CHAN: + replyto = target + if msg.find(NICK) == -1: + return + elif target == NICK: + replyto = nick_from_mask(who) + m = ERRCODE_RE.search(msg) + if m: + try: + pmsg(replyto, str(errcode.Errcode(int(m.groups()[1], 16)))) + except ValueError: + pass + if msg.find('help') > -1: + pmsg(replyto, 'I look up gPXE error codes. Message me like this:') + pmsg(replyto, 'errcode 0x12345678 OR Error 0x12345678') + +def add_handler(command, handler, nargs): + handlers[command] = (handler, nargs) + +def cmd(msg): + sock.sendall('%s\r\n' % msg) + +def pmsg(target, msg): + cmd('PRIVMSG %s :%s' % (target, msg)) + +def dispatch(args): + command = args[0] + if command in handlers: + h = handlers[command] + if h[1] == NO_ARGS: + h[0]() + elif len(args) == h[1]: + h[0](*args) + +def parse(line): + if line[0] == ':': + who, line = line.split(None, 1) + who = who[1:] + else: + who = None + args = [] + while line and line[0] != ':' and line.find(' ') != -1: + arg, line = line.split(None, 1) + args.append(arg) + if line: + if line[0] == ':': + args.append(line[1:]) + else: + args.append(line) + return who, args + +add_handler('376', autojoin, NO_ARGS) +add_handler('PING', ping, 2) +add_handler('PRIVMSG', privmsg, 3) + +sock = socket.socket() +sock.connect((HOST, PORT)) +cmd('NICK %s' % NICK) +cmd('USER %s none none :%s' % (IDENT, REALNAME)) + +rbuf = '' +while True: + r = sock.recv(4096) + if not r: + break + rbuf += r + + while rbuf.find('\r\n') != -1: + line, rbuf = rbuf.split('\r\n', 1) + if not line: + continue + who, args = parse(line) + dispatch(args) |