1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
#!/usr/bin/env python
import os
from ircasy import asybot
from asyncore import loop
from translate_colors import translate_colors
import shlex
from re import split, search, match
config_filename = './config.py'
from getconf import make_getconf
getconf = make_getconf(config_filename)
import logging,logging.handlers
log = logging.getLogger('asybot')
hdlr = logging.handlers.SysLogHandler(facility=logging.handlers.SysLogHandler.LOG_DAEMON)
formatter = logging.Formatter( '%(filename)s: %(levelname)s: %(message)s')
hdlr.setFormatter(formatter)
log.addHandler(hdlr)
logging.basicConfig(level = logging.DEBUG if getconf('debug') else logging.INFO)
class Reaktor(asybot):
def __init__(self):
asybot.__init__(self, getconf('irc_server'), getconf('irc_port'), getconf('irc_nickname'), getconf('irc_channels'), hammer_interval=getconf('irc_hammer_interval'), alarm_timeout=getconf('irc_alarm_timeout'), kill_timeout=getconf('irc_kill_timeout'))
def on_privmsg(self, prefix, command, params, rest):
for command in getconf('commands'):
y = match(command['pattern'], rest)
if y:
self.execute_command(command, y, prefix, params)
break
def execute_command(self, command, match, prefix, target):
from os.path import realpath, dirname, join
from subprocess import Popen as popen, PIPE
from time import time
#TODO: allow only commands below ./commands/
exe = join(dirname(realpath(dirname(__file__))), command['argv'][0])
myargv = [exe] + command['argv'][1:]
if match.groupdict().get('args',None):
myargv += shlex.split(match.groupdict()['args'])
env = {}
env['_from'] = prefix.split('!', 1)[0]
env['config_filename'] = os.path.abspath(config_filename)
start = time()
try:
p = popen(myargv, bufsize=1, stdout=PIPE, stderr=PIPE, env=env)
except (OSError, Exception) as error:
self.ME(target, 'brain damaged')
log.error('OSError@%s: %s' % (myargv, error))
return
pid = p.pid
for line in iter(p.stdout.readline, ''.encode()):
try:
self.PRIVMSG(target, translate_colors(line.decode()))
except Exception as error:
log.error('no send: %s' % error)
log.debug('%s stdout: %s' % (pid, line))
p.wait()
elapsed = time() - start
code = p.returncode
log.info('command: %s -> %s in %d seconds' % (myargv, code, elapsed))
[log.debug('%s stderr: %s' % (pid, x)) for x in p.stderr.readlines()]
if code != 0:
self.ME(target, 'mimimi')
if __name__ == "__main__":
Reaktor()
loop()
|