output.append(('PRIVMSG', (replyto, '%s %s' % (name.ljust(max_width), cmd.__doc__))))
return output
output = do_help(commands)
- if utils.nick_from_mask(who) in op_members:
+ if who.is_op():
output.extend(do_help(op_commands))
return output
commands['help'] = help_command
'''Send a chat message (privmsg #etherboot Hello all!)'''
if len(words) < 3:
return
- return ('PRIVMSG', (words[1], ' '.join(words[2:])))
+ return 'PRIVMSG', (words[1], ' '.join(words[2:]))
op_commands['privmsg'] = privmsg_command
def restart_command(who, target, replyto, words):
return
command = words[0].lower()
- if utils.nick_from_mask(who) in op_members and command in op_commands:
+ if who.is_op() and command in op_commands:
return op_commands[command](who, target, replyto, words)
if command in commands:
return commands[command](who, target, replyto, words)
NO_ARGS = -1
handlers = {}
-restart = False
+
+class Who(object):
+ def __init__(self, mask, is_identified=False):
+ self.mask = mask
+ self.nick = mask.split('!', 1)[0]
+ self.is_identified = is_identified
+
+ def is_op(self):
+ return self.is_identified and self.nick in cmds.op_members
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)
+ print 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 = Who(mask, is_identified)
+
+ utils.do_log(cmds.logs, target, who.nick, msg)
words = msg.split()
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)
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)
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)
# 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])
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(Who(config.NICK, True), config.NICK, config.NICK, words)) or restart
cmdfifo.close()