aboutsummaryrefslogtreecommitdiffstats
path: root/IRC/bot2.py
blob: 0279c0f604e79d5b501d210bc443b2de2c8223e1 (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
#! /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 == '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):

        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:
        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()