summaryrefslogtreecommitdiffstats
path: root/Reaktor/IRC/bot2.py
blob: a4a8bf33d3cba8042d3aca41a4bff392d09b3c8b (plain)
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#! /usr/bin/env python
#
# //Reaktor/IRC
#
# export host and port to connect to a specific IRC server
# defaults to supernode and 6667
#
# export nick to use a specific nickname
# defaults to Name in /etc/tinc/retiolum/tinc.conf
#
# export target to join a specific channel
# defaults to #retiolum
#
# Example usage (in your local krebs repository):
# host=irc.freenode.org nick=$HOSTNAME target=#tincspasm Reaktor/IRC/index
#

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:
      PRIVMSG(self.target, 'I\'m so famous')
      return # ignore

    if _handle == _nickname or _handle == 'ALL':

      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):
        try:
          p = popen([command], stdin=PIPE, stdout=PIPE, stderr=PIPE)
        except OSError, error:
          ME(self.target, 'I am made of stupid')
          print('OSError@%s: %s' % (argv, 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, _from + ': ' + x) for x in stdout]
          [PRIVMSG(_source, x) for x in stderr]
        else:
          ME(self.target, 'mimimi')

      else:
        ME(self.target, 'believes that ' + _from + ' is 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()