source: remote_control/puzzlebox_brainstorms_client_thinkgear.py @ 62

Last change on this file since 62 was 62, checked in by sc, 11 years ago

client_thinkgear:

  • no longer inherits from puzzlebox_brainstorms_client
  • authorization can be enabled/disabled via configuration file
  • automatically attempts to reset connection parameters to JSON if response is not recognized

configuration:

  • thinkgear authorization enable/disble support

thinkgear_emulator_server_setup.py:

  • initial checkin
File size: 9.6 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#
4# Puzzlebox - Brainstorms - Client - ThinkGear Connector
5#
6# Copyright Puzzlebox Productions, LLC (2010)
7#
8# This code is released under the GNU Pulic License (GPL) version 2
9# For more information please refer to http://www.gnu.org/copyleft/gpl.html
10#
11# Last Update: 2010.06.22
12#
13#####################################################################
14
15import os, sys
16import simplejson as json
17
18from twisted.internet import reactor, protocol, defer
19from twisted.protocols import basic
20
21import puzzlebox_brainstorms_configuration as configuration
22
23#####################################################################
24# Globals
25#####################################################################
26
27DEBUG = 1
28
29SERVER_HOST = configuration.THINKGEAR_SERVER_HOST
30SERVER_PORT = configuration.THINKGEAR_SERVER_PORT
31
32MAX_CONNECTION_ATTEMPTS = configuration.MAX_CONNECTION_ATTEMPTS
33NO_REPLY_WAIT = configuration.NO_REPLY_WAIT
34
35THINKGEAR_DELIMITER = '\r'
36
37ENABLE_THINKGEAR_AUTHORIZATION = configuration.ENABLE_THINKGEAR_AUTHORIZATION
38AUTHORIZATION_REQUEST = configuration.THINKGEAR_AUTHORIZATION_REQUEST
39
40THINKGEAR_PARAMETERS = {"enableRawOutput": False, "format": "Json"}
41#THINKGEAR_PARAMETERS = {"enableRawOutput": True, "format": "Json"}
42#THINKGEAR_PARAMETERS = configuration.FLASH_POLICY_FILE_REQUEST
43
44#####################################################################
45# Classes
46#####################################################################
47
48class puzzlebox_brainstorms_client_thinkgear:
49       
50        def __init__(self, log, \
51                          server_host=SERVER_HOST, \
52                          server_port=SERVER_PORT, \
53                          DEBUG=DEBUG):
54               
55                self.log = log
56                self.DEBUG=DEBUG
57               
58                self.server_host = server_host
59                self.server_port = server_port
60                self.max_connection_attempts = MAX_CONNECTION_ATTEMPTS
61
62                self.is_authorized = True
63               
64
65        ##################################################################
66
67        def authorize_and_send_parameters(self,\
68                                          thinkgear_parameters, \
69                                          authorization_request):
70
71                if self.DEBUG:
72                        print "--> [ThinkGear Client] Sending Authorization Request:",
73                        print authorization_request
74
75                       
76                d = self.send_parameters(thinkgear_parameters, authorization_request)
77                d.addCallback(self.update_authorization)
78
79
80        ##################################################################
81
82        def update_authorization(self, authorization):
83
84                if self.DEBUG:
85                        print "--> [ThinkGear Client] Authorization:",
86                        print authorization
87                       
88                self.is_authorized = authorization
89
90               
91        ##################################################################
92
93        def send_parameters(self, \
94                         parameters, \
95                         authentication=None, \
96                         max_connection_attempts=MAX_CONNECTION_ATTEMPTS):
97               
98                self.factory = puzzlebox_brainstorms_client_thinkgear_factory(self.log, \
99                             parameters, \
100                             authentication, \
101                             self.server_host, \
102                             self.server_port, \
103                             max_connection_attempts, \
104                             self.DEBUG)
105               
106                reactor.connectTCP(self.server_host, self.server_port, self.factory)
107
108                return self.factory.replyDefer
109
110
111        ##################################################################
112
113        def send_parameters_and_print_response(self, parameters):
114
115                if self.DEBUG:
116                        print "----> [ThinkGear Client] Sending:",
117                        print parameters
118
119                       
120                d = self.send_parameters(parameters)
121                d.addCallback(self.print_response)
122
123
124        ##################################################################
125
126        def print_response(self, response):
127               
128                if self.DEBUG:
129                        print "--> [ThinkGear Client] Server Response:",
130                        print response
131               
132
133#####################################################################
134# ThinkGear Client Protocol class
135#####################################################################
136
137class puzzlebox_brainstorms_client_thinkgear_protocol( \
138        basic.LineReceiver):
139
140        delimiter = THINKGEAR_DELIMITER
141       
142        def __init__(self):
143               
144                self.DEBUG = DEBUG
145
146       
147        ##################################################################
148       
149        def connectionMade(self):
150
151                if self.DEBUG:
152                        print "----> [ThinkGear Client] Connected to %s:%i" % \
153                              (self.factory.server_host, \
154                               self.factory.server_port)
155
156
157                if (self.factory.authentication != None):
158                        self.send_data(self.factory.authentication)
159
160                else:
161                        self.send_data(self.factory.parameters)
162
163
164        ##################################################################
165
166        def send_data(self, data):
167
168                packet = json.dumps(data)
169
170                if self.DEBUG:
171                        print "----> [ThinkGear Client] Sending:",
172                        print packet
173
174               
175                self.sendLine(packet)
176               
177##              self.factory.noReply = reactor.callLater(NO_REPLY_WAIT, self.noReply)
178       
179       
180        ##################################################################
181       
182        def noReply(self):
183               
184                try:
185                        self.factory.replyDefer.callback('NO_REPLY')
186                except:
187                        if self.DEBUG:
188                                print "noReply failed to call callback"
189
190
191        ##################################################################
192
193        def lineReceived(self, line):
194
195                # Ignore blank lines
196                if not line:
197                        return
198
199                try:
200                        data = json.loads(line)
201                except Exception, e:
202                        if self.DEBUG:
203                                print "Partial data received (or error:",
204                                print e
205                                print ")."
206
207                                print "line:",
208                                print line
209
210                                # We've received back an unrecognized response
211                                # so we'll attempt to reset the server's
212                                # parameters for JSON communication
213                                self.send_data(self.factory.parameters)
214                               
215                else:
216
217                        if (type(data) == type({})):
218
219                                self.factory.process_response(data)
220##                              self.factory.replyDefer.callback(data)
221
222                        else:
223                                if self.DEBUG:
224                                        print "data:",
225                                        print data
226
227
228        ##################################################################
229
230        def connectionLost(self, reason):
231
232                if self.DEBUG > 1:
233                        print "Connection lost:",
234                        print reason
235
236
237        ##################################################################
238
239        def connectionDone(self, reason):
240
241                if self.DEBUG > 1:
242                        print "Connection done:",
243                        print reason
244
245       
246#####################################################################
247# ThinkGear Client Factory class
248#####################################################################
249
250class puzzlebox_brainstorms_client_thinkgear_factory(protocol.ClientFactory):
251       
252        def __init__(self, log, \
253                     parameters, \
254                     authentication, \
255                     server_host=SERVER_HOST, \
256                     server_port=SERVER_PORT, \
257                     max_connection_attempts=MAX_CONNECTION_ATTEMPTS, \
258                     DEBUG=DEBUG):
259               
260                self.log = log
261                self.DEBUG = DEBUG
262                self.server_host = server_host
263                self.server_port = server_port
264                self.parameters = parameters
265                self.authentication = authentication
266               
267                self.max_connection_attempts = max_connection_attempts
268                self.connection_attempt = 1
269               
270                self.protocol = \
271                   puzzlebox_brainstorms_client_thinkgear_protocol
272               
273                self.replyDefer = defer.Deferred()
274
275
276        ##################################################################
277
278        def process_response(self, response):
279
280                if self.DEBUG:
281                        if (('rawEeg' not in response.keys()) or \
282                            (self.DEBUG > 1)):
283                                print "<-- [ThinkGear Client] Received:",
284                                print response
285
286
287                if response.has_key('isAuthorized'):
288
289                        if (response['isAuthorized'] == True):
290                                self.replyDefer.callback(True)
291                        else:
292                                self.replyDefer.callback(False)
293
294
295        ##################################################################
296       
297        def clientConnectionFailed(self, connector, reason):
298               
299                if self.DEBUG:
300                        print "Client failed to connect to remote component at %s:%i" % \
301                           (self.server_host, self.server_port)
302               
303                reply = 'FAILED_TO_CONNECT'
304               
305                self.connection_attempt = self.connection_attempt + 1
306               
307                if ((self.max_connection_attempts == None) or \
308                         (self.connection_attempt <= self.max_connection_attempts)):
309                       
310                        # If connection failed retry after one second
311                        reactor.callLater(1, connector.connect)
312               
313                else:
314                        if self.DEBUG:
315                                print "Maximum connection retries reached, aborting"
316                       
317                       
318                        self.replyDefer.callback(reply)
319       
320       
321        ##################################################################
322       
323        def clientConnectionLost(self, connector, reason):
324               
325                # Losing Connection is expected after data exchange is complete
326                try:
327                        self.replyDefer.callback(reason)
328                except:
329                        pass
330
331
332#####################################################################
333# Main
334#####################################################################
335
336if __name__ == '__main__':
337       
338        #log = puzzlebox_logger.puzzlebox_logger(logfile='client_thinkgear')
339        log = None
340       
341        authorization_request = AUTHORIZATION_REQUEST
342        thinkgear_parameters = THINKGEAR_PARAMETERS
343       
344        thinkgear_client = puzzlebox_brainstorms_client_thinkgear( \
345                    log, \
346                    server_host=SERVER_HOST, \
347                    server_port=SERVER_PORT, \
348                    DEBUG=DEBUG)
349
350
351        if ENABLE_THINKGEAR_AUTHORIZATION:
352                # Use ThinkGear authentication
353                reactor.callWhenRunning( \
354                        thinkgear_client.authorize_and_send_parameters, \
355                        thinkgear_parameters, \
356                        authorization_request)
357
358        else:   
359                # Do not use ThinkGear authentication
360                authorization_request = None
361                reactor.callWhenRunning( \
362                        thinkgear_client.send_parameters, \
363                        thinkgear_parameters, \
364                        authorization_request)
365
366
367        reactor.run()
368
Note: See TracBrowser for help on using the repository browser.