diff options
Diffstat (limited to 'IRC')
| -rwxr-xr-x | IRC/asybot.py | 169 | ||||
| -rwxr-xr-x | IRC/bot.py | 34 | ||||
| -rwxr-xr-x | IRC/bot2.py | 130 | ||||
| -rw-r--r-- | IRC/content | 1 | ||||
| -rwxr-xr-x | IRC/index | 2 | ||||
| -rwxr-xr-x | IRC/install | 28 | 
6 files changed, 170 insertions, 194 deletions
| diff --git a/IRC/asybot.py b/IRC/asybot.py new file mode 100755 index 0000000..6e9df1d --- /dev/null +++ b/IRC/asybot.py @@ -0,0 +1,169 @@ +#! /usr/bin/env python +# +# //Reaktor/IRC/asybot.py +# + +from __future__ import print_function + +def is_executable(x): +  import os +  return os.path.exists(x) and os.access(x, os.X_OK) + +from asynchat import async_chat as asychat +from asyncore import loop +from socket import AF_INET, SOCK_STREAM +from signal import SIGALRM, signal, alarm +from datetime import datetime as date, timedelta +from sys import exit +from re import split, search +class asybot(asychat): +  def __init__(self, server, port, nickname, targets, **kwargs): +    asychat.__init__(self) +    self.server = server +    self.port = port +    self.nickname = nickname +    self.targets = targets +    self.username = kwargs['username'] if 'username' in kwargs else nickname +    self.hostname = kwargs['hostname'] if 'hostname' in kwargs else nickname +    self.ircname = kwargs['ircname'] if 'ircname' in kwargs else nickname +    self.realname = kwargs['realname'] if 'realname' in kwargs else nickname +    self.data = '' +    self.set_terminator('\r\n') +    self.create_socket(AF_INET, SOCK_STREAM) +    self.connect((self.server, self.port)) +    self.alarm_timeout = 300 +    self.kill_timeout = 360 +    self.last_activity = date.now() +    signal(SIGALRM, lambda signum, frame: self.alarm_handler()) +    alarm(self.alarm_timeout) +    loop() + +  def alarm_handler(self): +    delta = date.now() - self.last_activity +    if delta > timedelta(seconds=self.kill_timeout): +      print('kill alarm %s' % delta) +      exit() +    else: +      print('alarm %s' % delta) +      self.push('PING :asybot') +      alarm(self.alarm_timeout) + +  def collect_incoming_data(self, data): +    self.data += data + +  def found_terminator(self): +    print('< %s' % self.data) +    self.last_activity = date.now() + +    message = self.data +    self.data = '' + +    _, prefix, command, params, rest, _ = \ +        split('^(?::(\S+)\s)?(\S+)((?:\s[^:]\S*)*)(?:\s:(.*))?$', message) +    params = params.split(' ')[1:] +    #print([prefix, command, params, rest]) + +    if command == 'PING': +      self.push('PONG :%s' % rest) + +    elif command == 'PRIVMSG': +      self.on_privmsg(prefix, command, params, rest) + +    # reset alarm +    alarm(self.alarm_timeout) + +  def push(self, message): +    print('> %s' % message) +    asychat.push(self, message + self.get_terminator()) + +  def handle_connect(self): +    self.push('NICK %s' % self.nickname) +    self.push('USER %s %s %s :%s' % +        (self.username, self.hostname, self.server, self.realname)) +    self.push('JOIN %s' % ','.join(self.targets)) + +  def on_privmsg(self, prefix, command, params, rest): +    def PRIVMSG(text): +      self.push('PRIVMSG %s :%s' % (','.join(params), text)) + +    def ME(text): +      PRIVMSG('ACTION ' + text + '') + +    _from = prefix.split('!', 1)[0] + +    try: +      _, _handle, _command, _argument, _ = split( +          '^(\w+|\*):\s*(\w+)(?:\s+(.*))?$', rest) +    except ValueError, error: +      if search(self.nickname, rest): +        PRIVMSG('I\'m so famous') +      return # ignore + +    if _handle == self.nickname or _handle == '*': + +      from os.path import realpath, dirname, join +      from subprocess import Popen as popen, PIPE + +      Reaktor_dir = dirname(realpath(dirname(__file__))) +      public_commands = join(Reaktor_dir, 'public_commands') +      command = join(public_commands, _command) + +      if is_executable(command): + +        env = {} +        if _argument != None: +          env['argument'] = _argument + +        try: +          p = popen([command], stdin=PIPE, stdout=PIPE, stderr=PIPE, env=env) +        except OSError, error: +          ME('is made of stupid') +          print('OSError@%s: %s' % (command, error)) +          return + +        stdout, stderr = [ x[:len(x)-1] for x in +            [ x.split('\n') for x in p.communicate()]] +        code = p.returncode +        pid = p.pid + +        print('command: %s -> %s' % (command, code)) +        [print('%s stdout: %s' % (pid, x)) for x in stdout] +        [print('%s stderr: %s' % (pid, x)) for x in stderr] + +        if code == 0: +          [PRIVMSG(x) for x in stdout] +          [PRIVMSG(x) for x in stderr] +        else: +          ME('mimimi') + +      else: +        if _handle != '*': +          PRIVMSG(_from + ': you are made of stupid') + +# retrieve the value of a [singleton] variable from a tinc.conf(5)-like file +def getconf1(x, path): +  from re import findall +  pattern = '(?:^|\n)\s*' + x + '\s*=\s*(.*\w)\s*(?:\n|$)' +  y = findall(pattern, open(path, 'r').read()) +  if len(y) < 1: +    raise AttributeError("len(getconf1('%s', '%s') < 1)" % (x, path)) +  if len(y) > 1: +    y = ' '.join(y) +    raise AttributeError("len(getconf1('%s', '%s') > 1)\n  ====>  %s" +        % (x, path, y)) +  return y[0] + +if __name__ == "__main__": +  from os import environ as env +  name = getconf1('Name', '/etc/tinc/retiolum/tinc.conf') +  hostname = '%s.retiolum' % name +  nick = str(env.get('nick', name)) +  host = str(env.get('host', 'supernode')) +  port = int(env.get('port', 6667)) +  target = str(env.get('target', '#retiolum')) +  print('====> irc://%s@%s:%s/%s' % (nick, host, port, target)) + +  from getpass import getuser +  asybot(host, port, nick, [target], username=getuser(), +      ircname='//Reaktor running at %s' % hostname, +      hostname=hostname) diff --git a/IRC/bot.py b/IRC/bot.py deleted file mode 100755 index af974f4..0000000 --- a/IRC/bot.py +++ /dev/null @@ -1,34 +0,0 @@ -#! /usr/bin/env python2 - -from irclib import IRC, ServerConnectionError, is_channel -from sys import exit -from os import environ as env - -host = str(env.get('host', 'irc.freenode.org')) -port = int(env.get('port', 6667)) -nick = str(env.get('nick', 'crabspasm')) -channel = str(env.get('channel', '#tincspasm')) -print '====> irc://%s@%s:%s/%s' % (nick, host, port, channel) - -irc = IRC() -try: -  client = irc.server().connect(host, port, nick) -except ServerConnectionError, error: -  print error -  exit - -def on_connect(connection, event): -  connection.join(channel) -  print 'Es passiert...' - -def on_join(connection, event): -  connection.privmsg(channel, 'lol') - -def on_disconnect(connection, event): -  exit - -client.add_global_handler('welcome', on_connect) -client.add_global_handler('join', on_join) -client.add_global_handler('disconnect', on_disconnect) - -irc.process_forever() diff --git a/IRC/bot2.py b/IRC/bot2.py deleted file mode 100755 index 326dd8f..0000000 --- a/IRC/bot2.py +++ /dev/null @@ -1,130 +0,0 @@ -#! /usr/bin/env python -# -# //Reaktor/IRC/bot2.py -# - -from __future__ import print_function -from irclib import SimpleIRCClient, ServerConnectionError, is_channel -from sys import exit -from os import environ as env -import re - -class IRCBot(SimpleIRCClient): -  def __init__(self, target): -    SimpleIRCClient.__init__(self) -    self.target = target - -  def on_pubmsg(self, connection, event): - -    def PRIVMSG(target, text): -      self.connection.privmsg(target, text) - -    def ME(target, text): -      PRIVMSG(target, 'ACTION ' + text + '') - -    def is_executable(x): -      import os -      return os.path.exists(x) and os.access(x, os.X_OK) - -    _nickname = connection.get_nickname() -    _source = event.source() -    _from = _source.split('!', 1)[0] -    _target = event.target() - -    try: -      _, _handle, _command, _argument, _ = re.split( -          '^(\w+|\*):\s*(\w+)(?:\s+(.*))?$', event.arguments()[0]) -    except ValueError, error: -      if re.search(_nickname, event.arguments()[0]): -        PRIVMSG(self.target, 'I\'m so famous') -      return # ignore - -    if _handle == _nickname or _handle == '*': - -      from os.path import realpath, dirname, join -      from subprocess import Popen as popen, PIPE - -      Reaktor_dir = dirname(realpath(dirname(__file__))) -      public_commands = join(Reaktor_dir, 'public_commands') -      command = join(public_commands, _command) - -      if is_executable(command): - -        env = {} -        if _argument != None: -          env['argument'] = _argument - -        try: -          p = popen([command], stdin=PIPE, stdout=PIPE, stderr=PIPE, env=env) -        except OSError, error: -          ME(self.target, 'is made of stupid') -          print('OSError@%s: %s' % (command, error)) -          return - -        stdout, stderr = [ x[:len(x)-1] for x in -            [ x.split('\n') for x in p.communicate()]] -        code = p.returncode -        pid = p.pid - -        print('command: %s -> %s' % (command, code)) -        [print('%s stdout: %s' % (pid, x)) for x in stdout] -        [print('%s stderr: %s' % (pid, x)) for x in stderr] - -        if code == 0: -          [PRIVMSG(self.target, x) for x in stdout] -          [PRIVMSG(_source, x) for x in stderr] -        else: -          ME(self.target, 'mimimi') - -      else: -        if _handle != '*': -          PRIVMSG(self.target, _from + ': you are made of stupid') - -  def on_welcome(self, connection, event): -    print('I\'m welcome! :D joining to %s now...' % (self.target)) -    if is_channel(self.target): -      connection.join(self.target) -    else: -      self.connection.privmsg(self.target, 'lol') -      self.connection.quit('Pong timeout: 423 seconds') - -  def on_join(self, connection, event): -    print('Es passiert in %s' % (self.target)) - -  def on_disconnect(self, connection, event): -    # TODO reconnect -    exit(0) - -# retrieve the value of a [singleton] variable from a tinc.conf(5)-like file -def getconf1(x, path): -  from re import findall -  pattern = '(?:^|\n)\s*' + x + '\s*=\s*(.*\w)\s*(?:\n|$)' -  y = findall(pattern, open(path, 'r').read()) -  if len(y) < 1: -    raise AttributeError("len(getconf1('%s', '%s') < 1)" % (x, path)) -  if len(y) > 1: -    y = ' '.join(y) -    raise AttributeError("len(getconf1('%s', '%s') > 1)\n  ====>  %s" -        % (x, path, y)) -  return y[0] - -def main(): -  name = getconf1('Name', '/etc/tinc/retiolum/tinc.conf') -  nick = str(env.get('nick', name)) -  host = str(env.get('host', 'supernode')) -  port = int(env.get('port', 6667)) -  target = str(env.get('target', '#retiolum')) -  print('====> irc://%s@%s:%s/%s' % (nick, host, port, target)) - -  client = IRCBot(target) -  try: -    from getpass import getuser -    client.connect(host, port, nick, username=getuser(), -        ircname='//Reaktor running at %s.retiolum' % (name)) -  except ServerConnectionError, error: -    print(error) -    exit(1) -  client.start() - -if __name__ == "__main__": -  main() diff --git a/IRC/content b/IRC/content deleted file mode 100644 index e029237..0000000 --- a/IRC/content +++ /dev/null @@ -1 +0,0 @@ -python-irclib-0.4.6/ircbot.py @@ -6,4 +6,4 @@ cd $(dirname $(readlink -f $0))/..  IRC/install -exec python IRC/bot2.py "$@" +exec python IRC/asybot.py "$@" diff --git a/IRC/install b/IRC/install deleted file mode 100755 index d5f7a8c..0000000 --- a/IRC/install +++ /dev/null @@ -1,28 +0,0 @@ -#! /bin/sh -set -xeuf - -# cd //Reaktor/IRC -cd $(dirname $(readlink -f $0)) - -# install irclib.py -{ -  PV=0.4.6 -  PN=python-irclib -  P=$PN-$PV -  tarball=$P.tar.gz -  URL=http://downloads.sourceforge.net/$PN/$tarball -  SHA1SUM=c6271e44293ed51c21af0f44ce106667d3006e6f - -  file=irclib.py - -  if ! echo "$SHA1SUM  $file" | sha1sum -c; then -    temp=`mktemp` -    trap "rm -f $temp" EXIT INT - -    echo $P/$file > $temp -    curl -LfsS $URL | tar --strip-components=1 -zxT $temp -  fi -  echo "$SHA1SUM  $file" | sha1sum -c -} - - | 
