diff options
Diffstat (limited to 'python-tornado/Pubnub.py')
| -rw-r--r-- | python-tornado/Pubnub.py | 709 | 
1 files changed, 0 insertions, 709 deletions
| diff --git a/python-tornado/Pubnub.py b/python-tornado/Pubnub.py deleted file mode 100644 index 89c0d97..0000000 --- a/python-tornado/Pubnub.py +++ /dev/null @@ -1,709 +0,0 @@ -## www.pubnub.com - PubNub Real-time push service in the cloud.  -# coding=utf8 - -## PubNub Real-time Push APIs and Notifications Framework -## Copyright (c) 2010 Stephen Blum -## http://www.pubnub.com/ - -## ----------------------------------- -## PubNub 3.3.5 Real-time Push Cloud API -## ----------------------------------- - - -from Crypto.Cipher import AES -from Crypto.Hash import MD5 -from base64 import encodestring, decodestring  -import hashlib -import hmac - -class PubnubCrypto() : -    """ -    #** -    #* PubnubCrypto -    #* -    #** - -    ## Initiate Class -    pc = PubnubCrypto - -    """ -    -    def pad( self, msg, block_size=16 ): -        """ -        #** -        #* pad -        #* -        #* pad the text to be encrypted -        #* appends a padding character to the end of the String -        #* until the string has block_size length -        #* @return msg with padding. -        #** -        """ -        padding = block_size - (len(msg) % block_size) -        return msg + chr(padding)*padding -        -    def depad( self, msg ): -        """ -        #** -        #* depad -        #* -        #* depad the decryptet message" -        #* @return msg without padding. -        #** -        """ -        return msg[0:-ord(msg[-1])] - -    def getSecret( self, key ): -        """ -        #** -        #* getSecret -        #* -        #* hases the key to MD5 -        #* @return key in MD5 format -        #** -        """ -        return hashlib.sha256(key).hexdigest() - -    def encrypt( self, key, msg ): -        """ -        #** -        #* encrypt -        #* -        #* encrypts the message -        #* @return message in encrypted format -        #** -        """ -        secret = self.getSecret(key) -        Initial16bytes='0123456789012345' -        cipher = AES.new(secret[0:32],AES.MODE_CBC,Initial16bytes) -        enc = encodestring(cipher.encrypt(self.pad(msg))) -        return enc -    def decrypt( self, key, msg ): -        """ -        #** -        #* decrypt -        #* -        #* decrypts the message -        #* @return message in decryped format -        #** -        """ -        secret = self.getSecret(key) -        Initial16bytes='0123456789012345' -        cipher = AES.new(secret[0:32],AES.MODE_CBC,Initial16bytes) -        return self.depad((cipher.decrypt(decodestring(msg)))) - - -try: import json -except ImportError: import simplejson as json - -import time -import hashlib -import urllib2 -import uuid  - -class PubnubBase(object): -    def __init__( -        self, -        publish_key, -        subscribe_key, -        secret_key = False, -        cipher_key = False, -        ssl_on = False, -        origin = 'pubsub.pubnub.com', -        UUID = None -    ) : -        """ -        #** -        #* Pubnub -        #* -        #* Init the Pubnub Client API -        #* -        #* @param string publish_key required key to send messages. -        #* @param string subscribe_key required key to receive messages. -        #* @param string secret_key optional key to sign messages. -        #* @param boolean ssl required for 2048 bit encrypted messages. -        #* @param string origin PUBNUB Server Origin. -        #* @param string pres_uuid optional identifier for presence (auto-generated if not supplied) -        #** - -        ## Initiat Class -        pubnub = Pubnub( 'PUBLISH-KEY', 'SUBSCRIBE-KEY', 'SECRET-KEY', False ) - -        """ -        self.origin        = origin -        self.limit         = 1800 -        self.publish_key   = publish_key -        self.subscribe_key = subscribe_key -        self.secret_key    = secret_key -        self.cipher_key    = cipher_key -        self.ssl           = ssl_on -        self.pc            = PubnubCrypto() - -        if self.ssl : -            self.origin = 'https://' + self.origin -        else : -            self.origin = 'http://'  + self.origin -         -        self.uuid = UUID or str(uuid.uuid4()) -         -        if not isinstance(self.uuid, basestring): -            raise AttributeError("pres_uuid must be a string") - -    def sign(self, channel, message): -        ## Sign Message -        if self.secret_key: -            signature = hashlib.md5('/'.join([ -                self.publish_key, -                self.subscribe_key, -                self.secret_key, -                channel, -                message -            ])).hexdigest() -        else: -            signature = '0' -        return signature - -    def encrypt(self, message): -        if self.cipher_key: -            message = json.dumps(self.pc.encrypt(self.cipher_key, json.dumps(message)).replace('\n','')) -        else : -            message = json.dumps(message) - -        return message; - -    def decrypt(self, message): -        if self.cipher_key: -            message = self.pc.decrypt(self.cipher_key, message) - -        return message - - -    def publish( self, args ) : -        """ -        #** -        #* Publish -        #* -        #* Send a message to a channel. -        #* -        #* @param array args with channel and message. -        #* @return array success information. -        #** - -        ## Publish Example -        info = pubnub.publish({ -            'channel' : 'hello_world', -            'message' : { -                'some_text' : 'Hello my World' -            } -        }) -        print(info) - -        """ -        ## Fail if bad input. -        if not (args['channel'] and args['message']) : -            return [ 0, 'Missing Channel or Message' ] - -        ## Capture User Input -        channel = str(args['channel']) - -        ## Capture Callback -        if args.has_key('callback') : -            callback = args['callback'] -        else : -            callback = None  - -        #message = json.dumps(args['message'], separators=(',',':')) -        message = self.encrypt(args['message']) - -        signature = self.sign(channel, message) - -        ## Send Message -        return self._request({"urlcomponents": [ -            'publish', -            self.publish_key, -            self.subscribe_key, -            signature, -            channel, -            '0', -            message -        ]}, callback) -     -    def presence( self, args ) : -        """ -        #** -        #* presence -        #* -        #* This is BLOCKING. -        #* Listen for presence events on a channel. -        #* -        #* @param array args with channel and callback. -        #* @return false on fail, array on success. -        #** - -        ## Presence Example -        def pres_event(message) : -            print(message) -            return True - -        pubnub.presence({ -            'channel'  : 'hello_world', -            'callback' : receive  -        }) -        """ - -        ## Fail if missing channel -        if not 'channel' in args : -            raise Exception('Missing Channel.') -            return False - -        ## Fail if missing callback -        if not 'callback' in args : -            raise Exception('Missing Callback.') -            return False - -        ## Capture User Input -        channel   = str(args['channel']) -        callback  = args['callback'] -        subscribe_key = args.get('subscribe_key') or self.subscribe_key -         -        return self.subscribe({'channel': channel+'-pnpres', 'subscribe_key':subscribe_key, 'callback': callback}) -     -     -    def here_now( self, args ) : -        """ -        #** -        #* Here Now -        #* -        #* Load current occupancy from a channel. -        #* -        #* @param array args with 'channel'. -        #* @return mixed false on fail, array on success. -        #* - -        ## Presence Example -        here_now = pubnub.here_now({ -            'channel' : 'hello_world', -        }) -        print(here_now['occupancy']) -        print(here_now['uuids']) - -        """ -        channel = str(args['channel']) - -        ## Capture Callback -        if args.has_key('callback') : -            callback = args['callback'] -        else : -            callback = None -         -        ## Fail if bad input. -        if not channel : -            raise Exception('Missing Channel') -            return False -         -        ## Get Presence Here Now -        return self._request({"urlcomponents": [ -            'v2','presence', -            'sub_key', self.subscribe_key, -            'channel', channel -        ]}, callback); -         -         -    def history( self, args ) : -        """ -        #** -        #* History -        #* -        #* Load history from a channel. -        #* -        #* @param array args with 'channel' and 'limit'. -        #* @return mixed false on fail, array on success. -        #* - -        ## History Example -        history = pubnub.history({ -            'channel' : 'hello_world', -            'limit'   : 1 -        }) -        print(history) - -        """ -        ## Capture User Input -        limit   = args.has_key('limit') and int(args['limit']) or 10 -        channel = str(args['channel']) - -        ## Fail if bad input. -        if not channel : -            raise Exception('Missing Channel') -            return False - -        ## Capture Callback -        if args.has_key('callback') : -            callback = args['callback'] -        else : -            callback = None - -        ## Get History -        return self._request({ "urlcomponents" : [ -            'history', -            self.subscribe_key, -            channel, -            '0', -            str(limit) -        ] }, callback); - -    def detailedHistory(self, args) : -        """ -        #** -        #* Detailed History -        #* -        #* Load Detailed history from a channel. -        #* -        #* @param array args with 'channel', optional: 'start', 'end', 'reverse', 'count' -        #* @return mixed false on fail, array on success. -        #* - -        ## History Example -        history = pubnub.detailedHistory({ -            'channel' : 'hello_world', -            'count'   : 5 -        }) -        print(history) - -        """ -        ## Capture User Input -        channel = str(args['channel']) - -        params = dict()  -        count = 100     -         -        if args.has_key('count'): -            count = int(args['count']) - -        params['count'] = str(count)     -         -        if args.has_key('reverse'): -            params['reverse'] = str(args['reverse']).lower() - -        if args.has_key('start'): -            params['start'] = str(args['start']) - -        if args.has_key('end'): -            params['end'] = str(args['end']) - -        ## Fail if bad input. -        if not channel : -            raise Exception('Missing Channel') -            return False - -        ## Capture Callback -        if args.has_key('callback') : -            callback = args['callback'] -        else : -            callback = None  - -        ## Get History -        return self._request({ 'urlcomponents' : [ -            'v2', -            'history', -            'sub-key', -            self.subscribe_key, -            'channel', -            channel, -        ],'urlparams' : params }, callback=callback); - -    def time(self, args = None) : -        """ -        #** -        #* Time -        #* -        #* Timestamp from PubNub Cloud. -        #* -        #* @return int timestamp. -        #* - -        ## PubNub Server Time Example -        timestamp = pubnub.time() -        print(timestamp) - -        """ -        ## Capture Callback -        if args and args.has_key('callback') : -            callback = args['callback'] -        else : -            callback = None  -        time = self._request({'urlcomponents' : [ -            'time', -            '0' -        ]}, callback) -        if time != None: -            return time[0] - - -    def _encode( self, request ) : -        return [ -            "".join([ ' ~`!@#$%^&*()+=[]\\{}|;\':",./<>?'.find(ch) > -1 and -                hex(ord(ch)).replace( '0x', '%' ).upper() or -                ch for ch in list(bit) -            ]) for bit in request] -     -    def getUrl(self,request): -        ## Build URL -        url = self.origin + '/' + "/".join([ -            "".join([ ' ~`!@#$%^&*()+=[]\\{}|;\':",./<>?'.find(ch) > -1 and -                hex(ord(ch)).replace( '0x', '%' ).upper() or -                ch for ch in list(bit) -            ]) for bit in request["urlcomponents"]]) -        if (request.has_key("urlparams")): -            url = url + '?' + "&".join([ x + "=" + y  for x,y in request["urlparams"].iteritems()]) -        return url - - -try: -    from hashlib import sha256 -    digestmod = sha256 -except ImportError: -    import Crypto.Hash.SHA256 as digestmod -    sha256 = digestmod.new -import hmac - -class PubnubCoreAsync(PubnubBase): - -    def start(self): pass  -    def stop(self):  pass -    def timeout( self, delay, callback ): -        pass - -    def __init__( -        self, -        publish_key, -        subscribe_key, -        secret_key = False, -        cipher_key = False, -        ssl_on = False, -        origin = 'pubsub.pubnub.com', -        uuid = None -    ) : -        """ -        #** -        #* Pubnub -        #* -        #* Init the Pubnub Client API -        #* -        #* @param string publish_key required key to send messages. -        #* @param string subscribe_key required key to receive messages. -        #* @param string secret_key required key to sign messages. -        #* @param boolean ssl required for 2048 bit encrypted messages. -        #* @param string origin PUBNUB Server Origin. -        #** - -        ## Initiat Class -        pubnub = Pubnub( 'PUBLISH-KEY', 'SUBSCRIBE-KEY', 'SECRET-KEY', False ) - -        """ -        super(PubnubCoreAsync, self).__init__( -            publish_key=publish_key, -            subscribe_key=subscribe_key, -            secret_key=secret_key, -            cipher_key=cipher_key, -            ssl_on=ssl_on, -            origin=origin, -            UUID=uuid -        )         - -        self.subscriptions = {} -        self.timetoken     = 0 -        self.version       = '3.3.4' -        self.accept_encoding = 'gzip' - -    def subscribe( self, args ) : -        """ -        #** -        #* Subscribe -        #* -        #* This is NON-BLOCKING. -        #* Listen for a message on a channel. -        #* -        #* @param array args with channel and message. -        #* @return false on fail, array on success. -        #** - -        ## Subscribe Example -        def receive(message) : -            print(message) -            return True - -        ## On Connect Callback -        def connected() : -            pubnub.publish({ -                'channel' : 'hello_world', -                'message' : { 'some_var' : 'text' } -            }) - -        ## Subscribe -        pubnub.subscribe({ -            'channel'  : 'hello_world', -            'connect'  : connected, -            'callback' : receive -        }) - -        """ -        ## Fail if missing channel -        if not 'channel' in args : -            return 'Missing Channel.' - -        ## Fail if missing callback -        if not 'callback' in args : -            return 'Missing Callback.' - -        ## Capture User Input -        channel   = str(args['channel']) -        callback  = args['callback'] -        connectcb = args['connect'] - -        if 'errorback' in args: -            errorback = args['errorback'] -        else: -            errorback = lambda x: x - -        ## New Channel? -        if not (channel in self.subscriptions) : -            self.subscriptions[channel] = { -                'first'     : False, -                'connected' : False, -            } - -        ## Ensure Single Connection -        if self.subscriptions[channel]['connected'] : -            return "Already Connected" - -        self.subscriptions[channel]['connected'] = 1 -        ## SUBSCRIPTION RECURSION  -        def _subscribe(): -            ## STOP CONNECTION? -            if not self.subscriptions[channel]['connected']: -                return -           -            def sub_callback(response): -                if not self.subscriptions[channel]['first'] : -                    self.subscriptions[channel]['first'] = True -                    connectcb() - -                ## STOP CONNECTION? -                if not self.subscriptions[channel]['connected']: -                    return - - - -                ## PROBLEM? -                if not response: -                    def time_callback(_time): -                        if not _time: -                            self.timeout( 1, _subscribe ) -                            return errorback("Lost Network Connection") -                        else: -                            self.timeout( 1, _subscribe) - -                    ## ENSURE CONNECTED (Call Time Function) -                    return self.time({ 'callback' : time_callback }) - -                self.timetoken = response[1] -                _subscribe() - -                pc = PubnubCrypto() -                out = [] -                for message in response[0]: -                     callback(self.decrypt(message)) - -            ## CONNECT TO PUBNUB SUBSCRIBE SERVERS -            try: -                self._request( { "urlcomponents" : [ -                    'subscribe', -                    self.subscribe_key, -                    channel, -                    '0', -                    str(self.timetoken) -                ], "urlparams" : {"uuid":self.uuid} }, sub_callback ) -            except : -                self.timeout( 1, _subscribe) -                return - -        ## BEGIN SUBSCRIPTION (LISTEN FOR MESSAGES) -        _subscribe() -    def unsubscribe( self, args ): -        channel = str(args['channel']) -        if not (channel in self.subscriptions): -            return False - -        ## DISCONNECT -        self.subscriptions[channel]['connected'] = 0 -        self.subscriptions[channel]['timetoken'] = 0 -        self.subscriptions[channel]['first']     = False - - -import tornado.httpclient - -try: -    from hashlib import sha256 -    digestmod = sha256 -except ImportError: -    import Crypto.Hash.SHA256 as digestmod -    sha256 = digestmod.new - -import hmac -import tornado.ioloop -from tornado.stack_context import ExceptionStackContext - -ioloop = tornado.ioloop.IOLoop.instance() - -class Pubnub(PubnubCoreAsync): - -    def stop(self): ioloop.stop() -    def start(self): ioloop.start() -    def timeout( self, delay, callback): -        ioloop.add_timeout( time.time()+float(delay), callback ) -         -    def __init__( -        self, -        publish_key, -        subscribe_key, -        secret_key = False, -        cipher_key = False, -        ssl_on = False, -        origin = 'pubsub.pubnub.com' -    ) : -        super(Pubnub, self).__init__( -            publish_key=publish_key, -            subscribe_key=subscribe_key, -            secret_key=secret_key, -            cipher_key=cipher_key, -            ssl_on=ssl_on, -            origin=origin, -        )         -        self.headers = {} -        self.headers['User-Agent'] = 'Python-Tornado' -        self.headers['Accept-Encoding'] = self.accept_encoding -        self.headers['V'] = self.version -        self.http = tornado.httpclient.AsyncHTTPClient(max_clients=1000) - -    def _request( self, request, callback ) : -        url = self.getUrl(request) -        ## Send Request Expecting JSON Response -        #print self.headers - -        request = tornado.httpclient.HTTPRequest( url, 'GET', self.headers, connect_timeout=10, request_timeout=310 ) - -        def responseCallback(response): -            def handle_exc(*args): -                return True -            if response.error is not None: -                with ExceptionStackContext(handle_exc): -                    response.rethrow() -            elif callback: -                callback(eval(response._get_body())) -         -        self.http.fetch( -            request, -            callback=responseCallback, -        ) - | 
