Allow looser lspci command syntax
[people/stefanha/gpxebot.git] / gpxebot.py
index 20098c3..bc3f122 100755 (executable)
@@ -27,47 +27,57 @@ import utils
 NO_ARGS = -1
 
 handlers = {}
-restart  = False
 
 def autojoin():
     del handlers['376']
-    do_response(cmds.readrc_command())
+
+    # Receive '+' or '-' indicator with every message showing whether the
+    # sender is identified to nick services.  Only identified users may be bot
+    # operators.
+    cmd('CAPAB IDENTIFY-MSG')
+
+    return do_response(cmds.readrc_command())
 
 def ping(_, arg):
     cmd('PONG %s' % arg)
+    return False
 
 def do_response(response):
-    global restart
-
     # it should be in the format (command, args) 
     # or [(command, args), (command, args)...]
     # args is a tuple
     if not response:
-        return
+        return False
     if isinstance(response, list):
-        [do_response(r) for r in response]
-        return
+        return any(do_response(r) for r in response)
     (command, args) = response
     if command == 'PRIVMSG':
         pmsg(*args)
     elif command == 'CMD':
         cmd(*args)
-    elif command == 'RESTART':
-        restart = True
+    return command == 'RESTART'
 
 def privmsg(_, target, msg):
-    utils.do_log(cmds.logs, target, who, msg)
+    # Establish identify of sender from CAPAB IDENTIFY-MSG info
+    is_identified = msg.startswith('+')
+    if msg.startswith('-') or msg.startswith('+'):
+        msg = msg[1:]
+    who = cmds.Who(mask, is_identified)
+
+    utils.do_log(cmds.logs, target, who.nick, msg)
 
     words = msg.split()
+    if not words:
+        return False
     if target.startswith('#'):
         replyto = target
         if not config.NICK in words[0]:
-            return
+            return False
         words.pop(0)
     elif target == config.NICK:
-        replyto = utils.nick_from_mask(who)
+        replyto = who.nick
 
-    do_response(cmds.do_command(who, target, replyto, words))
+    return do_response(cmds.do_command(who, target, replyto, words))
 
 def add_handler(command, handler, nargs):
     handlers[command] = (handler, nargs)
@@ -77,24 +87,26 @@ def cmd(msg):
     sock.sendall('%s\r\n' % msg)
 
 def pmsg(target, msg):
-    utils.do_log(cmds.logs, target, config.NICK, msg)
-    cmd('PRIVMSG %s :%s' % (target, msg))
+    if target:
+        utils.do_log(cmds.logs, target, config.NICK, 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]()
+            return h[0]()
         elif len(args) == h[1]:
-            h[0](*args)
+            return h[0](*args)
+    return False
 
 def parse(line):
     if line[0] == ':':
-        who, line = line.split(None, 1)
-        who = who[1:]
+        mask, line = line[1:].split(None, 1)
     else:
-        who = None
+        mask = None
+
     args = []
     while line and line[0] != ':':
         fields = line.split(None, 1)
@@ -103,11 +115,9 @@ def parse(line):
         arg, line = fields
         args.append(arg)
     if line:
-        if line[0] == ':':
-            args.append(line[1:])
-        else:
-            args.append(line)
-    return who, args
+        args.append(line[1:])
+
+    return mask, args
 
 add_handler('376', autojoin, NO_ARGS)
 add_handler('PING', ping, 2)
@@ -136,6 +146,7 @@ except OSError:
 # read/write will not block on Linux.
 cmdfifo = open(config.FIFO, 'r+')
 
+restart = False
 sockbuf = ''
 while not restart:
     rlist, _, xlist = select.select([sock, cmdfifo], [], [sock])
@@ -146,17 +157,17 @@ while not restart:
             break
         sockbuf += r
 
-        while sockbuf.find('\r\n') != -1:
+        while '\r\n' in sockbuf:
             line, sockbuf = sockbuf.split('\r\n', 1)
             if not line:
                 continue
             utils.dbg('READ ' + line)
-            who, args = parse(line)
-            dispatch(args)
+            mask, args = parse(line)
+            restart = dispatch(args)
 
     if cmdfifo in rlist:
         words = cmdfifo.readline().strip().split()
-        do_response(cmds.do_command(config.NICK, config.NICK, config.NICK, words))
+        restart = do_response(cmds.do_command(cmds.Who(config.NICK, True), config.NICK, config.NICK, words)) or restart
 
 cmdfifo.close()