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
RevLine 
[48]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#
[60]11# Last Update: 2010.06.22
[48]12#
13#####################################################################
14
15import os, sys
16import simplejson as json
17
18from twisted.internet import reactor, protocol, defer
[50]19from twisted.protocols import basic
[48]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
[53]35THINKGEAR_DELIMITER = '\r'
[50]36
[62]37ENABLE_THINKGEAR_AUTHORIZATION = configuration.ENABLE_THINKGEAR_AUTHORIZATION
[48]38AUTHORIZATION_REQUEST = configuration.THINKGEAR_AUTHORIZATION_REQUEST
39
[50]40THINKGEAR_PARAMETERS = {"enableRawOutput": False, "format": "Json"}
41#THINKGEAR_PARAMETERS = {"enableRawOutput": True, "format": "Json"}
[56]42#THINKGEAR_PARAMETERS = configuration.FLASH_POLICY_FILE_REQUEST
[49]43
[48]44#####################################################################
45# Classes
46#####################################################################
47
[62]48class puzzlebox_brainstorms_client_thinkgear:
[49]49       
50        def __init__(self, log, \
[57]51                          server_host=SERVER_HOST, \
52                          server_port=SERVER_PORT, \
53                          DEBUG=DEBUG):
[49]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
[50]61
[57]62                self.is_authorized = True
63               
64
[50]65        ##################################################################
[57]66
67        def authorize_and_send_parameters(self,\
68                                          thinkgear_parameters, \
69                                          authorization_request):
70
71                if self.DEBUG:
[60]72                        print "--> [ThinkGear Client] Sending Authorization Request:",
[57]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
[50]90               
[57]91        ##################################################################
92
93        def send_parameters(self, \
94                         parameters, \
95                         authentication=None, \
96                         max_connection_attempts=MAX_CONNECTION_ATTEMPTS):
[50]97               
[57]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)
[50]105               
[57]106                reactor.connectTCP(self.server_host, self.server_port, self.factory)
107
108                return self.factory.replyDefer
109
110
[49]111        ##################################################################
[48]112
[57]113        def send_parameters_and_print_response(self, parameters):
114
[49]115                if self.DEBUG:
[57]116                        print "----> [ThinkGear Client] Sending:",
117                        print parameters
[49]118
[57]119                       
120                d = self.send_parameters(parameters)
[55]121                d.addCallback(self.print_response)
[57]122
123
[49]124        ##################################################################
[57]125
[49]126        def print_response(self, response):
127               
128                if self.DEBUG:
[57]129                        print "--> [ThinkGear Client] Server Response:",
[49]130                        print response
[50]131               
[49]132
[50]133#####################################################################
134# ThinkGear Client Protocol class
135#####################################################################
136
137class puzzlebox_brainstorms_client_thinkgear_protocol( \
138        basic.LineReceiver):
139
[53]140        delimiter = THINKGEAR_DELIMITER
[49]141       
[51]142        def __init__(self):
143               
144                self.DEBUG = DEBUG
145
[50]146       
147        ##################################################################
148       
[52]149        def connectionMade(self):
[57]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
[52]174               
[57]175                self.sendLine(packet)
[52]176               
[53]177##              self.factory.noReply = reactor.callLater(NO_REPLY_WAIT, self.noReply)
[50]178       
179       
180        ##################################################################
181       
[52]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"
[57]189
190
[50]191        ##################################################################
[49]192
[57]193        def lineReceived(self, line):
[50]194
[57]195                # Ignore blank lines
196                if not line:
197                        return
[50]198
[57]199                try:
200                        data = json.loads(line)
201                except Exception, e:
[62]202                        if self.DEBUG:
[53]203                                print "Partial data received (or error:",
204                                print e
205                                print ")."
[50]206
[53]207                                print "line:",
208                                print line
[62]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)
[53]214                               
[57]215                else:
[50]216
[57]217                        if (type(data) == type({})):
[51]218
[57]219                                self.factory.process_response(data)
220##                              self.factory.replyDefer.callback(data)
[53]221
[57]222                        else:
223                                if self.DEBUG:
224                                        print "data:",
225                                        print data
[53]226
[57]227
228        ##################################################################
229
230        def connectionLost(self, reason):
231
[53]232                if self.DEBUG > 1:
233                        print "Connection lost:",
234                        print reason
235
[54]236
237        ##################################################################
238
239        def connectionDone(self, reason):
240
241                if self.DEBUG > 1:
242                        print "Connection done:",
243                        print reason
244
[53]245       
[48]246#####################################################################
[50]247# ThinkGear Client Factory class
248#####################################################################
249
[62]250class puzzlebox_brainstorms_client_thinkgear_factory(protocol.ClientFactory):
[50]251       
252        def __init__(self, log, \
[57]253                     parameters, \
254                     authentication, \
255                     server_host=SERVER_HOST, \
256                     server_port=SERVER_PORT, \
257                     max_connection_attempts=MAX_CONNECTION_ATTEMPTS, \
258                     DEBUG=DEBUG):
[50]259               
260                self.log = log
261                self.DEBUG = DEBUG
262                self.server_host = server_host
263                self.server_port = server_port
[57]264                self.parameters = parameters
265                self.authentication = authentication
[50]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
[57]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
[62]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
[50]332#####################################################################
[48]333# Main
334#####################################################################
335
336if __name__ == '__main__':
337       
[60]338        #log = puzzlebox_logger.puzzlebox_logger(logfile='client_thinkgear')
[48]339        log = None
340       
[57]341        authorization_request = AUTHORIZATION_REQUEST
[50]342        thinkgear_parameters = THINKGEAR_PARAMETERS
[48]343       
[49]344        thinkgear_client = puzzlebox_brainstorms_client_thinkgear( \
[48]345                    log, \
346                    server_host=SERVER_HOST, \
347                    server_port=SERVER_PORT, \
348                    DEBUG=DEBUG)
[49]349
350
[62]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)
[49]357
[62]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
[48]367        reactor.run()
368
Note: See TracBrowser for help on using the repository browser.