[release] Update version to 0.9.6+ post release
[gpxe.git] / contrib / errcode / gpxebot.py
blobf975942f07f52012d5b60f7591b36bf5265fdaea
1 #!/usr/bin/env python
2 # Copyright (C) 2008 Stefan Hajnoczi <stefanha@gmail.com>.
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License as
6 # published by the Free Software Foundation; either version 2 of the
7 # License, or any later version.
9 # This program is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 import re
18 import socket
19 import errcode
21 HOST = 'irc.freenode.net'
22 PORT = 6667
23 NICK = 'gpxebot'
24 CHAN = '#etherboot'
25 NICKSERV_PASSWORD = None
26 IDENT = 'gpxebot'
27 REALNAME = 'gPXE bot'
29 ERRCODE_RE = re.compile(r'(errcode|Error)\s+((0x)?[0-9a-fA-F]{8})')
31 NO_ARGS = -1
33 handlers = {}
35 def nick_from_mask(mask):
36 return (mask.find('!') > -1 and mask.split('!', 1)[0]) or mask
38 def autojoin():
39 del handlers['376']
40 if NICKSERV_PASSWORD:
41 pmsg('nickserv', 'identify %s' % NICKSERV_PASSWORD)
42 if CHAN:
43 cmd('JOIN %s' % CHAN)
45 def ping(_, arg):
46 cmd('PONG %s' % arg)
48 def privmsg(_, target, msg):
49 if target == CHAN:
50 replyto = target
51 if msg.find(NICK) == -1:
52 return
53 elif target == NICK:
54 replyto = nick_from_mask(who)
55 m = ERRCODE_RE.search(msg)
56 if m:
57 try:
58 pmsg(replyto, str(errcode.Errcode(int(m.groups()[1], 16))))
59 except ValueError:
60 pass
61 if msg.find('help') > -1:
62 pmsg(replyto, 'I look up gPXE error codes. Message me like this:')
63 pmsg(replyto, 'errcode 0x12345678 OR Error 0x12345678')
65 def add_handler(command, handler, nargs):
66 handlers[command] = (handler, nargs)
68 def cmd(msg):
69 sock.sendall('%s\r\n' % msg)
71 def pmsg(target, msg):
72 cmd('PRIVMSG %s :%s' % (target, msg))
74 def dispatch(args):
75 command = args[0]
76 if command in handlers:
77 h = handlers[command]
78 if h[1] == NO_ARGS:
79 h[0]()
80 elif len(args) == h[1]:
81 h[0](*args)
83 def parse(line):
84 if line[0] == ':':
85 who, line = line.split(None, 1)
86 who = who[1:]
87 else:
88 who = None
89 args = []
90 while line and line[0] != ':' and line.find(' ') != -1:
91 fields = line.split(None, 1)
92 if len(fields) == 1:
93 fields.append(None)
94 arg, line = fields
95 args.append(arg)
96 if line:
97 if line[0] == ':':
98 args.append(line[1:])
99 else:
100 args.append(line)
101 return who, args
103 add_handler('376', autojoin, NO_ARGS)
104 add_handler('PING', ping, 2)
105 add_handler('PRIVMSG', privmsg, 3)
107 sock = socket.socket()
108 sock.connect((HOST, PORT))
109 cmd('NICK %s' % NICK)
110 cmd('USER %s none none :%s' % (IDENT, REALNAME))
112 rbuf = ''
113 while True:
114 r = sock.recv(4096)
115 if not r:
116 break
117 rbuf += r
119 while rbuf.find('\r\n') != -1:
120 line, rbuf = rbuf.split('\r\n', 1)
121 if not line:
122 continue
123 who, args = parse(line)
124 dispatch(args)