create dispatcher class; redefine processors as threads
[electrum-server.git] / irc.py
1 ####################################################################
2
3 import threading, socket, traceback, time
4
5 def random_string(N):
6     import random, string
7     return ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(N))
8
9 from processor import Processor
10
11 class ServerProcessor(Processor):
12
13     def __init__(self, config):
14         Processor.__init__(self)
15         self.daemon = True
16         self.peers = {}
17         self.banner = config.get('server','banner')
18         self.host = config.get('server','host')
19         self.nick = config.get('server','ircname')
20         self.irc = config.get('server','irc') == 'yes'
21
22     def get_peers(self):
23         return self.peers.values()
24
25     def run(self):
26         if not self.irc: 
27             return
28         NICK = 'E_'+random_string(10)
29         while not self.shared.stopped():
30             try:
31                 s = socket.socket()
32                 s.connect(('irc.freenode.net', 6667))
33                 s.send('USER electrum 0 * :'+self.host+' '+self.nick+'\n')
34                 s.send('NICK '+NICK+'\n')
35                 s.send('JOIN #electrum\n')
36                 sf = s.makefile('r', 0)
37                 t = 0
38                 while not self.shared.stopped():
39                     line = sf.readline()
40                     line = line.rstrip('\r\n')
41                     line = line.split()
42                     if line[0]=='PING': 
43                         s.send('PONG '+line[1]+'\n')
44                     elif '353' in line: # answer to /names
45                         k = line.index('353')
46                         for item in line[k+1:]:
47                             if item[0:2] == 'E_':
48                                 s.send('WHO %s\n'%item)
49                     elif '352' in line: # answer to /who
50                         # warning: this is a horrible hack which apparently works
51                         k = line.index('352')
52                         ip = line[k+4]
53                         ip = socket.gethostbyname(ip)
54                         name = line[k+6]
55                         host = line[k+9]
56                         self.peers[name] = (ip,host)
57                     if time.time() - t > 5*60:
58                         self.push_response({'method':'server.peers', 'result':[self.get_peers()]})
59                         s.send('NAMES #electrum\n')
60                         t = time.time()
61                         self.peers = {}
62             except:
63                 traceback.print_exc(file=sys.stdout)
64             finally:
65                 sf.close()
66                 s.close()
67
68
69
70     def process(self, request):
71         method = request['method']
72
73         result = ''
74         if method == 'server.banner':
75             result = self.banner.replace('\\n','\n')
76         elif method == 'server.peers.subscribe':
77             result = self.get_peers()
78         else:
79             print "unknown method", request
80
81         if result!='':
82             response = { 'id':request['id'], 'method':method, 'params':request['params'], 'result':result }
83             self.push_response(response)
84
85
86