Renamed: modules -> backends
[electrum-server.git] / backends / irc / __init__.py
1 import threading, socket, traceback, time, sys
2
3 def random_string(N):
4     import random, string
5     return ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(N))
6
7 from processor import Processor
8
9 class ServerProcessor(Processor):
10
11     def __init__(self, config):
12         Processor.__init__(self)
13         self.daemon = True
14         self.peers = {}
15         self.banner = config.get('server','banner')
16         self.host = config.get('server','host')
17         self.password = config.get('server','password')
18
19         self.native_port = config.get('server','native_port')
20         self.stratum_tcp_port = config.get('server','stratum_tcp_port')
21         self.stratum_http_port = config.get('server','stratum_http_port')
22
23         self.irc = config.get('server', 'irc') == 'yes'
24         self.nick = config.get('server', 'irc_nick') 
25         if not self.nick: self.nick = random_string(10)
26
27
28     def get_peers(self):
29         return self.peers.values()
30
31
32     def getname(self):
33         s = ''
34         if self.native_port:
35             s+= 'n' + self.native_port + ' '
36         if self.stratum_tcp_port:
37             s += 't' + self.stratum_tcp_port + ' ' 
38         if self.stratum_http_port:
39             s += 'h' + self.stratum_http_port + ' '
40         return s
41
42
43     def run(self):
44         if not self.irc: 
45             return
46
47         ircname = self.getname()
48
49         while not self.shared.stopped():
50             try:
51                 s = socket.socket()
52                 s.connect(('irc.freenode.net', 6667))
53                 s.send('USER electrum 0 * :' + self.host + ' ' + ircname + '\n')
54                 s.send('NICK E_' + self.nick + '\n')
55                 s.send('JOIN #electrum\n')
56                 sf = s.makefile('r', 0)
57                 t = 0
58                 while not self.shared.stopped():
59                     line = sf.readline()
60                     line = line.rstrip('\r\n')
61                     line = line.split()
62                     if line[0]=='PING': 
63                         s.send('PONG '+line[1]+'\n')
64                     elif '353' in line: # answer to /names
65                         k = line.index('353')
66                         for item in line[k+1:]:
67                             if item[0:2] == 'E_':
68                                 s.send('WHO %s\n'%item)
69                     elif '352' in line: # answer to /who
70                         # warning: this is a horrible hack which apparently works
71                         k = line.index('352')
72                         ip = line[k+4]
73                         ip = socket.gethostbyname(ip)
74                         name = line[k+6]
75                         host = line[k+9]
76                         ports  = line[k+10:]
77                         self.peers[name] = (ip, host, ports)
78                     if time.time() - t > 5*60:
79                         self.push_response({'method':'server.peers', 'result':[self.get_peers()]})
80                         s.send('NAMES #electrum\n')
81                         t = time.time()
82                         self.peers = {}
83             except:
84                 traceback.print_exc(file=sys.stdout)
85             finally:
86                 sf.close()
87                 s.close()
88
89
90
91     def process(self, request):
92         method = request['method']
93         params = request['params']
94         result = None
95
96         if method == 'server.banner':
97             result = self.banner.replace('\\n','\n')
98
99         elif method == 'server.peers.subscribe':
100             result = self.get_peers()
101
102         elif method == 'server.version':
103             pass
104
105         elif method == 'server.stop':
106             print "stopping..."
107             try:
108                 password = request['params'][0]
109             except:
110                 password = None
111             if password == self.password:
112                 self.shared.stop()
113                 result = 'ok'
114         else:
115             print "unknown method", request
116
117         if result!='':
118             response = { 'id':request['id'], 'method':method, 'params':params, 'result':result }
119             self.push_response(response)
120