firebot/contrib/procbot.py

75 lines
1.9 KiB
Python
Executable File

#! /usr/bin/env python
import os
import irc
import async_proc
class Runner(async_proc.process_dispatcher):
def __init__(self, cmdline, outfunc):
f = os.popen('%s 2>&1' % (cmdline), 'r')
self.outfunc = outfunc
self.linebuf = ""
async_proc.process_dispatcher.__init__(self, f)
def handle_read(self):
self.linebuf += self.recv(4098)
def handle_close(self):
ret = self.close()
if self.linebuf:
self.outfunc(self.linebuf, ret)
def esc(arg):
"Shell-escape an argument"
return "'" + arg.replace("'", "'\\''") + "'"
def lesc(args):
"Shell-escape a list of arguments"
return [esc(arg) for arg in args]
class ProcBot(irc.Bot):
maxlines = 5
def proc_cb(self, pfx, sender, forum, linebuf, ret):
if not pfx:
pfx = ""
lines = []
for line in linebuf.split('\n'):
line = line.strip()
if line:
lines.append("%s%s" % (pfx, line))
if ret and not lines:
lines = ["%sThat generates an error (%d)." % (pfx, ret)]
if len(lines) > self.maxlines:
forum.msg("%sToo many lines, sending privately" % pfx)
self.despool(sender, lines)
else:
self.despool(forum, lines)
if __name__ == '__main__':
import bindingsbot
import re
class LsBot(ProcBot, bindingsbot.BindingsBot):
bindings = bindingsbot.BindingsBot.bindings
def ls(self, sender, forum, addl, match):
r = Runner('ls', lambda linebuf, ret: self.proc_cb("ls: ",
sender, forum,
linebuf, ret))
bindings.append((re.compile(r"^ls", re.IGNORECASE),
ls))
p = LsBot(('irc.woozle.org', 6667),
'procbot',
'hi asl',
["#ch"])
irc.run_forever()