move callbacks to the network class
[electrum-nvc.git] / lib / network.py
1 import interface
2 from blockchain import Blockchain
3 import threading, time, Queue, os, sys, shutil
4 from util import user_dir, appdata_dir, print_error
5 from bitcoin import *
6
7
8 class Network(threading.Thread):
9
10     def __init__(self, config):
11         threading.Thread.__init__(self)
12         self.daemon = True
13         self.config = config
14         self.lock = threading.Lock()
15         self.blockchain = Blockchain(config)
16         self.interfaces = {}
17         self.queue = Queue.Queue()
18         self.default_server = self.config.get('server')
19         self.servers_list = interface.filter_protocol(interface.DEFAULT_SERVERS,'s')
20         self.callbacks = {}
21
22
23     def register_callback(self, event, callback):
24         with self.lock:
25             if not self.callbacks.get(event):
26                 self.callbacks[event] = []
27             self.callbacks[event].append(callback)
28
29
30     def trigger_callback(self, event):
31         with self.lock:
32             callbacks = self.callbacks.get(event,[])[:]
33         if callbacks:
34             [callback() for callback in callbacks]
35
36
37     def start_interfaces(self):
38
39         for server in self.servers_list:
40             self.interfaces[server] = interface.Interface({'server':server})
41
42         for i in self.interfaces.values():
43             i.network = self # fixme
44             i.start(self.queue)
45
46         if self.default_server:
47             self.interface = interface.Interface({'server':self.default_server})
48             self.interface.network = self # fixme
49             self.interface.start(self.queue)
50         else:
51             self.interface = self.interfaces[0]
52
53
54     def start(self, wait=False):
55
56         self.start_interfaces()
57         threading.Thread.__init__(self)
58         if wait:
59             self.interface.connect_event.wait()
60             return self.interface.is_connected
61
62
63
64     def run(self):
65         self.blockchain.start()
66
67         with self.lock:
68             self.running = True
69
70         while self.is_running():
71             i = self.queue.get()
72
73             if i.is_connected:
74                 i.register_channel('verifier', self.blockchain.queue)
75                 i.register_channel('get_header')
76                 i.send([ ('blockchain.headers.subscribe',[])], 'verifier')
77                 if i == self.interface:
78                     i.send([('server.banner',[])])
79                     i.send([('server.peers.subscribe',[])])
80             else:
81                 self.interfaces.pop(i.server)
82                 if i == self.interface:
83                     if self.default_server is None:
84                         print_msg("Using random server...")
85                         server = random.choice( self.servers_list )
86                         self.interface = interface.Interface({'server':self.default_server})
87                     else:
88                         #i.trigger_callback('disconnected')
89                         pass
90
91     def on_peers(self, resut):
92         pass
93
94     def on_banner(self, result):
95         pass
96
97     def stop(self):
98         with self.lock: self.running = False
99
100     def is_running(self):
101         with self.lock: return self.running
102
103
104     def resend_subscriptions(self):
105         for channel, messages in self.subscriptions.items():
106             if messages:
107                 self.send(messages, channel)
108
109
110     def auto_cycle(self):
111         if not self.is_connected and self.config.get('auto_cycle'):
112             print_msg("Using random server...")
113             servers = filter_protocol(DEFAULT_SERVERS, 's')
114             while servers:
115                 server = random.choice( servers )
116                 servers.remove(server)
117                 print server
118                 self.config.set_key('server', server, False)
119                 self.init_with_server(self.config)
120                 if self.is_connected: break
121
122             if not self.is_connected:
123                 print 'no server available'
124                 self.connect_event.set() # to finish start
125                 self.server = 'ecdsa.org:50001:t'
126                 self.proxy = None
127                 return
128
129
130
131
132 if __name__ == "__main__":
133     import simple_config
134     config = simple_config.SimpleConfig({'verbose':True})
135     network = Network(config)
136     network.start()
137
138     while 1:
139         time.sleep(1)
140
141
142