From 80edcffbfe140a6d19c65deca24e1ba1c0f49b99 Mon Sep 17 00:00:00 2001 From: Devendra Date: Mon, 24 Mar 2014 19:17:48 +0530 Subject: support for python3 --- common/PubnubBase.py | 27 ++++++++++----------- python/Pubnub.py | 38 ++++++++++++++---------------- python/examples/here-now-example.py | 4 ++-- python/examples/history-example.py | 1 + python/examples/publish-example.py | 3 +++ python/examples/subscribe-example.py | 5 ++-- python/tests/detailed-history-unit-test.py | 24 +++++++++---------- python/tests/unit-test.py | 3 ++- python/unassembled/Platform.py | 11 ++++----- 9 files changed, 59 insertions(+), 57 deletions(-) diff --git a/common/PubnubBase.py b/common/PubnubBase.py index 5856921..b8817c1 100644 --- a/common/PubnubBase.py +++ b/common/PubnubBase.py @@ -3,7 +3,6 @@ except ImportError: import simplejson as json import time import hashlib -import urllib2 import uuid class PubnubBase(object): @@ -51,7 +50,7 @@ class PubnubBase(object): self.uuid = UUID or str(uuid.uuid4()) - if not isinstance(self.uuid, basestring): + if not isinstance(self.uuid, str): raise AttributeError("pres_uuid must be a string") def sign(self, channel, message): @@ -112,7 +111,7 @@ class PubnubBase(object): channel = str(args['channel']) ## Capture Callback - if args.has_key('callback') : + if 'callback' in args : callback = args['callback'] else : callback = None @@ -196,7 +195,7 @@ class PubnubBase(object): channel = str(args['channel']) ## Capture Callback - if args.has_key('callback') : + if 'callback' in args : callback = args['callback'] else : callback = None @@ -234,7 +233,7 @@ class PubnubBase(object): """ ## Capture User Input - limit = args.has_key('limit') and int(args['limit']) or 10 + limit = 'limit' in args and int(args['limit']) or 10 channel = str(args['channel']) ## Fail if bad input. @@ -243,7 +242,7 @@ class PubnubBase(object): return False ## Capture Callback - if args.has_key('callback') : + if 'callback' in args : callback = args['callback'] else : callback = None @@ -282,18 +281,18 @@ class PubnubBase(object): params = dict() count = 100 - if args.has_key('count'): + if 'count' in args: count = int(args['count']) params['count'] = str(count) - if args.has_key('reverse'): + if 'reverse' in args: params['reverse'] = str(args['reverse']).lower() - if args.has_key('start'): + if 'start' in args: params['start'] = str(args['start']) - if args.has_key('end'): + if 'end' in args: params['end'] = str(args['end']) ## Fail if bad input. @@ -302,7 +301,7 @@ class PubnubBase(object): return False ## Capture Callback - if args.has_key('callback') : + if 'callback' in args : callback = args['callback'] else : callback = None @@ -333,7 +332,7 @@ class PubnubBase(object): """ ## Capture Callback - if args and args.has_key('callback') : + if args and 'callback' in args : callback = args['callback'] else : callback = None @@ -359,6 +358,6 @@ class PubnubBase(object): 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()]) + if ("urlparams" in request): + url = url + '?' + "&".join([ x + "=" + y for x,y in request["urlparams"].items()]) return url diff --git a/python/Pubnub.py b/python/Pubnub.py index 59a38af..5dd4c7d 100644 --- a/python/Pubnub.py +++ b/python/Pubnub.py @@ -98,7 +98,6 @@ except ImportError: import simplejson as json import time import hashlib -import urllib2 import uuid class PubnubBase(object): @@ -146,7 +145,7 @@ class PubnubBase(object): self.uuid = UUID or str(uuid.uuid4()) - if not isinstance(self.uuid, basestring): + if not isinstance(self.uuid, str): raise AttributeError("pres_uuid must be a string") def sign(self, channel, message): @@ -207,7 +206,7 @@ class PubnubBase(object): channel = str(args['channel']) ## Capture Callback - if args.has_key('callback') : + if 'callback' in args : callback = args['callback'] else : callback = None @@ -291,7 +290,7 @@ class PubnubBase(object): channel = str(args['channel']) ## Capture Callback - if args.has_key('callback') : + if 'callback' in args : callback = args['callback'] else : callback = None @@ -329,7 +328,7 @@ class PubnubBase(object): """ ## Capture User Input - limit = args.has_key('limit') and int(args['limit']) or 10 + limit = 'limit' in args and int(args['limit']) or 10 channel = str(args['channel']) ## Fail if bad input. @@ -338,7 +337,7 @@ class PubnubBase(object): return False ## Capture Callback - if args.has_key('callback') : + if 'callback' in args : callback = args['callback'] else : callback = None @@ -377,18 +376,18 @@ class PubnubBase(object): params = dict() count = 100 - if args.has_key('count'): + if 'count' in args: count = int(args['count']) params['count'] = str(count) - if args.has_key('reverse'): + if 'reverse' in args: params['reverse'] = str(args['reverse']).lower() - if args.has_key('start'): + if 'start' in args: params['start'] = str(args['start']) - if args.has_key('end'): + if 'end' in args: params['end'] = str(args['end']) ## Fail if bad input. @@ -397,7 +396,7 @@ class PubnubBase(object): return False ## Capture Callback - if args.has_key('callback') : + if 'callback' in args : callback = args['callback'] else : callback = None @@ -428,7 +427,7 @@ class PubnubBase(object): """ ## Capture Callback - if args and args.has_key('callback') : + if args and 'callback' in args : callback = args['callback'] else : callback = None @@ -454,8 +453,8 @@ class PubnubBase(object): 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()]) + if ("urlparams" in request): + url = url + '?' + "&".join([ x + "=" + y for x,y in request["urlparams"].items()]) return url @@ -576,6 +575,7 @@ class PubnubCore(PubnubBase): return True +import urllib3 class Pubnub(PubnubCore): def __init__( @@ -596,7 +596,8 @@ class Pubnub(PubnubCore): ssl_on = ssl_on, origin = origin, uuid = pres_uuid - ) + ) + self.http = urllib3.PoolManager(timeout=310) def _request( self, request, callback = None ) : ## Build URL @@ -604,11 +605,8 @@ class Pubnub(PubnubCore): ## Send Request Expecting JSONP Response try: - try: usock = urllib2.urlopen( url, None, 310 ) - except TypeError: usock = urllib2.urlopen( url, None ) - response = usock.read() - usock.close() - resp_json = json.loads(response) + response = self.http.request('GET', url) + resp_json = json.loads(response.data.decode("utf-8")) except: return None diff --git a/python/examples/here-now-example.py b/python/examples/here-now-example.py index d2ca9bd..b9f0b02 100644 --- a/python/examples/here-now-example.py +++ b/python/examples/here-now-example.py @@ -11,7 +11,7 @@ import sys sys.path.append('../') -from twisted.internet import reactor +sys.path.append('./') from Pubnub import Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' @@ -28,7 +28,7 @@ pubnub = Pubnub( publish_key=publish_key, subscribe_key=subscribe_key, crazy = 'hello_world' def print_cb(message): - print message + print(message) pubnub.here_now( { 'channel' : crazy, diff --git a/python/examples/history-example.py b/python/examples/history-example.py index c7c9547..bf78c7d 100755 --- a/python/examples/history-example.py +++ b/python/examples/history-example.py @@ -1,5 +1,6 @@ import sys sys.path.append('../') +sys.path.append('./') from Pubnub import Pubnub ## Initiat Class diff --git a/python/examples/publish-example.py b/python/examples/publish-example.py index c97034b..55f19ea 100755 --- a/python/examples/publish-example.py +++ b/python/examples/publish-example.py @@ -1,3 +1,6 @@ +import sys +sys.path.append('.') +sys.path.append('..') from Pubnub import Pubnub ## Initiate Class diff --git a/python/examples/subscribe-example.py b/python/examples/subscribe-example.py index 14a43d9..a67a08f 100755 --- a/python/examples/subscribe-example.py +++ b/python/examples/subscribe-example.py @@ -1,5 +1,6 @@ import sys -sys.path.append('../') +sys.path.append('..') +sys.path.append('.') import threading import time import random @@ -59,7 +60,7 @@ publish() print("waiting for subscribes and presence") pres_thread.join() -print pubnub.here_now({'channel':channel}) +print(pubnub.here_now({'channel':channel})) sub_thread.join() diff --git a/python/tests/detailed-history-unit-test.py b/python/tests/detailed-history-unit-test.py index 31bdef8..b1500b4 100755 --- a/python/tests/detailed-history-unit-test.py +++ b/python/tests/detailed-history-unit-test.py @@ -14,7 +14,7 @@ sys.path.append('.') sys.path.append('..') sys.path.append('../common') from Pubnub import Pubnub -import unittest2 as unittest +import unittest as unittest publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' @@ -37,7 +37,7 @@ class TestDetailedHistory(unittest.TestCase): @classmethod def publish_msg(cls, start, end, offset): - print 'Publishing messages' + print('Publishing messages') inputs = [] for i in range(start + offset, end + offset): message = str(i) + " " + crazy @@ -47,19 +47,19 @@ class TestDetailedHistory(unittest.TestCase): }) t = pubnub.time() inputs.append({'timestamp': t, 'message': message}) - print 'Message # ', i, ' published' + print(('Message # ' + i + ' published')) return inputs @classmethod - def setUpClass(cls): - print 'Setting up context for Detailed History tests. Please wait ...' - cls.starttime = pubnub.time() - cls.inputs = cls.inputs + cls.publish_msg(0, cls.total_msg / 2, 0) - cls.midtime = pubnub.time() - cls.inputs = cls.inputs + cls.publish_msg( - 0, cls.total_msg / 2, cls.total_msg / 2) - cls.endtime = pubnub.time() - print 'Context setup for Detailed History tests. Now running tests' + def setUpClass(c): + print('Setting up context for Detailed History tests. Please wait ...') + c.starttime = pubnub.time() + c.inputs = c.inputs + c.publish_msg(0, c.total_msg / 2, 0) + c.midtime = pubnub.time() + c.inputs = c.inputs + c.publish_msg( + 0, c.total_msg / 2, c.total_msg / 2) + c.endtime = pubnub.time() + print('Context setup for Detailed History tests. Now running tests') def test_begin_to_end_count(self): count = 5 diff --git a/python/tests/unit-test.py b/python/tests/unit-test.py index 1737ace..762959e 100755 --- a/python/tests/unit-test.py +++ b/python/tests/unit-test.py @@ -53,8 +53,9 @@ history = pubnub.history({ 'channel' : crazy, 'limit' : 1 }) + test( - history[0].encode('utf-8') == crazy, + history[0] == crazy, 'History Message: ' + history[0] ) test( len(history) == 1, 'History Message Count' ) diff --git a/python/unassembled/Platform.py b/python/unassembled/Platform.py index f598a98..627a350 100644 --- a/python/unassembled/Platform.py +++ b/python/unassembled/Platform.py @@ -1,3 +1,4 @@ +import urllib3 class Pubnub(PubnubCore): def __init__( @@ -18,7 +19,8 @@ class Pubnub(PubnubCore): ssl_on = ssl_on, origin = origin, uuid = pres_uuid - ) + ) + self.http = urllib3.PoolManager(timeout=310) def _request( self, request, callback = None ) : ## Build URL @@ -26,11 +28,8 @@ class Pubnub(PubnubCore): ## Send Request Expecting JSONP Response try: - try: usock = urllib2.urlopen( url, None, 310 ) - except TypeError: usock = urllib2.urlopen( url, None ) - response = usock.read() - usock.close() - resp_json = json.loads(response) + response = self.http.request('GET', url) + resp_json = json.loads(response.data.decode("utf-8")) except: return None -- cgit v1.2.3 From b8d1dd86a0d8c4261d4f3765f3ca227d7b555c84 Mon Sep 17 00:00:00 2001 From: Devendra Date: Tue, 25 Mar 2014 10:50:39 +0530 Subject: fixing encryption, and changing from urllib3 to urllib --- common/PubnubCrypto.py | 9 ++++----- python/Pubnub.py | 21 ++++++++++----------- python/examples/publish-example.py | 32 +++++++++++++++++++++++++++++--- python/unassembled/Platform.py | 12 ++++++------ 4 files changed, 49 insertions(+), 25 deletions(-) diff --git a/common/PubnubCrypto.py b/common/PubnubCrypto.py index df7cb8d..1f5fc8d 100644 --- a/common/PubnubCrypto.py +++ b/common/PubnubCrypto.py @@ -28,7 +28,7 @@ class PubnubCrypto() : #** """ padding = block_size - (len(msg) % block_size) - return msg + chr(padding)*padding + return msg + (chr(padding)*padding).encode('utf-8') def depad( self, msg ): """ @@ -50,7 +50,7 @@ class PubnubCrypto() : #* @return key in MD5 format #** """ - return hashlib.sha256(key).hexdigest() + return hashlib.sha256(key.encode("utf-8")).hexdigest() def encrypt( self, key, msg ): """ @@ -64,8 +64,7 @@ class PubnubCrypto() : 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 + return encodestring(cipher.encrypt(self.pad(msg.encode('utf-8')))).decode('utf-8') def decrypt( self, key, msg ): """ #** @@ -78,4 +77,4 @@ class PubnubCrypto() : secret = self.getSecret(key) Initial16bytes='0123456789012345' cipher = AES.new(secret[0:32],AES.MODE_CBC,Initial16bytes) - return self.depad((cipher.decrypt(decodestring(msg)))) + return (cipher.decrypt(decodestring(msg.encode('utf-8')))).decode('utf-8') diff --git a/python/Pubnub.py b/python/Pubnub.py index 5dd4c7d..aa7068b 100644 --- a/python/Pubnub.py +++ b/python/Pubnub.py @@ -40,7 +40,7 @@ class PubnubCrypto() : #** """ padding = block_size - (len(msg) % block_size) - return msg + chr(padding)*padding + return msg + (chr(padding)*padding).encode('utf-8') def depad( self, msg ): """ @@ -62,7 +62,7 @@ class PubnubCrypto() : #* @return key in MD5 format #** """ - return hashlib.sha256(key).hexdigest() + return hashlib.sha256(key.encode("utf-8")).hexdigest() def encrypt( self, key, msg ): """ @@ -76,8 +76,7 @@ class PubnubCrypto() : 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 + return encodestring(cipher.encrypt(self.pad(msg.encode('utf-8')))).decode('utf-8') def decrypt( self, key, msg ): """ #** @@ -90,7 +89,7 @@ class PubnubCrypto() : secret = self.getSecret(key) Initial16bytes='0123456789012345' cipher = AES.new(secret[0:32],AES.MODE_CBC,Initial16bytes) - return self.depad((cipher.decrypt(decodestring(msg)))) + return (cipher.decrypt(decodestring(msg.encode('utf-8')))).decode('utf-8') try: import json @@ -575,7 +574,8 @@ class PubnubCore(PubnubBase): return True -import urllib3 + +import urllib.request class Pubnub(PubnubCore): def __init__( @@ -597,17 +597,16 @@ class Pubnub(PubnubCore): origin = origin, uuid = pres_uuid ) - self.http = urllib3.PoolManager(timeout=310) def _request( self, request, callback = None ) : ## Build URL url = self.getUrl(request) - + print(url) ## Send Request Expecting JSONP Response try: - response = self.http.request('GET', url) - resp_json = json.loads(response.data.decode("utf-8")) - except: + response = urllib.request.urlopen(url,timeout=310) + resp_json = json.loads(response.read().decode("utf-8")) + except Exception as e: return None if (callback): diff --git a/python/examples/publish-example.py b/python/examples/publish-example.py index 55f19ea..31ae198 100755 --- a/python/examples/publish-example.py +++ b/python/examples/publish-example.py @@ -4,14 +4,40 @@ sys.path.append('..') from Pubnub import Pubnub ## Initiate Class -pubnub = Pubnub( publish_key='demo', subscribe_key='demo', ssl_on=False ) +pubnub = Pubnub( publish_key='demo', subscribe_key='demo', cipher_key='enigma', ssl_on=False ) +#pubnub = Pubnub( publish_key='demo', subscribe_key='demo', ssl_on=False ) ## Publish Example info = pubnub.publish({ - 'channel' : 'hello_world', + 'channel' : 'abcd', 'message' : { - 'some_text' : 'Hello my World' + 'iam' : 'object' } }) print(info) +info = pubnub.publish({ + 'channel' : 'abcd', + 'message' : "hi I am string" +}) +print(info) + +info = pubnub.publish({ + 'channel' : 'abcd', + 'message' : 1234 +}) +print(info) + +info = pubnub.publish({ + 'channel' : 'abcd', + 'message' : "1234" +}) +print(info) + +info = pubnub.publish({ + 'channel' : 'abcd', + 'message' : [ + 'i' , 'am', 'array' + ] +}) +print(info) diff --git a/python/unassembled/Platform.py b/python/unassembled/Platform.py index 627a350..55ec449 100644 --- a/python/unassembled/Platform.py +++ b/python/unassembled/Platform.py @@ -1,4 +1,5 @@ -import urllib3 + +import urllib.request class Pubnub(PubnubCore): def __init__( @@ -20,17 +21,16 @@ class Pubnub(PubnubCore): origin = origin, uuid = pres_uuid ) - self.http = urllib3.PoolManager(timeout=310) def _request( self, request, callback = None ) : ## Build URL url = self.getUrl(request) - + print(url) ## Send Request Expecting JSONP Response try: - response = self.http.request('GET', url) - resp_json = json.loads(response.data.decode("utf-8")) - except: + response = urllib.request.urlopen(url,timeout=310) + resp_json = json.loads(response.read().decode("utf-8")) + except Exception as e: return None if (callback): -- cgit v1.2.3 From 9ac3ccf6283772b404a0c80945e3cdf3406ac5bf Mon Sep 17 00:00:00 2001 From: Devendra Date: Tue, 25 Mar 2014 11:47:03 +0530 Subject: making version 2 and version 3 work same time --- common/PubnubBase.py | 13 +++- common/PubnubCrypto.py | 79 +++++++++++++++++++++- python/Pubnub.py | 148 +++++++++++++++++++++++++++++++++++++---- python/unassembled/Platform.py | 34 ++++++++-- 4 files changed, 253 insertions(+), 21 deletions(-) diff --git a/common/PubnubBase.py b/common/PubnubBase.py index b8817c1..4c5b422 100644 --- a/common/PubnubBase.py +++ b/common/PubnubBase.py @@ -3,7 +3,8 @@ except ImportError: import simplejson as json import time import hashlib -import uuid +import uuid +import sys class PubnubBase(object): def __init__( @@ -41,7 +42,7 @@ class PubnubBase(object): 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 @@ -49,6 +50,14 @@ class PubnubBase(object): self.origin = 'http://' + self.origin self.uuid = UUID or str(uuid.uuid4()) + + if type(sys.version_info) is tuple: + self.python_version = 2 + self.pc = PubnubCrypto2() + else: + self.python_version = 3 + self.pc = PubnubCrypto3() + if not isinstance(self.uuid, str): raise AttributeError("pres_uuid must be a string") diff --git a/common/PubnubCrypto.py b/common/PubnubCrypto.py index 1f5fc8d..3489216 100644 --- a/common/PubnubCrypto.py +++ b/common/PubnubCrypto.py @@ -4,7 +4,84 @@ from base64 import encodestring, decodestring import hashlib import hmac -class PubnubCrypto() : +class PubnubCrypto2() : + """ + #** + #* 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)))) + + +class PubnubCrypto3() : """ #** #* PubnubCrypto diff --git a/python/Pubnub.py b/python/Pubnub.py index aa7068b..91f67ad 100644 --- a/python/Pubnub.py +++ b/python/Pubnub.py @@ -16,7 +16,84 @@ from base64 import encodestring, decodestring import hashlib import hmac -class PubnubCrypto() : +class PubnubCrypto2() : + """ + #** + #* 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)))) + + +class PubnubCrypto3() : """ #** #* PubnubCrypto @@ -97,7 +174,8 @@ except ImportError: import simplejson as json import time import hashlib -import uuid +import uuid +import sys class PubnubBase(object): def __init__( @@ -128,14 +206,14 @@ class PubnubBase(object): 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() + 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 + if self.ssl : self.origin = 'https://' + self.origin @@ -143,6 +221,14 @@ class PubnubBase(object): self.origin = 'http://' + self.origin self.uuid = UUID or str(uuid.uuid4()) + + if type(sys.version_info) is tuple: + self.python_version = 2 + self.pc = PubnubCrypto2() + else: + self.python_version = 3 + self.pc = PubnubCrypto3() + if not isinstance(self.uuid, str): raise AttributeError("pres_uuid must be a string") @@ -574,8 +660,10 @@ class PubnubCore(PubnubBase): return True - -import urllib.request +try: + import urllib.request +except: + import urllib2 class Pubnub(PubnubCore): def __init__( @@ -597,19 +685,51 @@ class Pubnub(PubnubCore): origin = origin, uuid = pres_uuid ) + if self.python_version == 2: + self._request = self._request2 + else: + self._request = self._request3 - def _request( self, request, callback = None ) : + def _request2( self, request, callback = None ) : + ## Build URL + url = self.getUrl(request) + + ## Send Request Expecting JSONP Response + try: + try: usock = urllib2.urlopen( url, None, 310 ) + except TypeError: usock = urllib2.urlopen( url, None ) + response = usock.read() + usock.close() + resp_json = json.loads(response) + except: + return None + + if (callback): + callback(resp_json) + else: + return resp_json + + + def _request3( self, request, callback = None ) : ## Build URL url = self.getUrl(request) - print(url) ## Send Request Expecting JSONP Response try: response = urllib.request.urlopen(url,timeout=310) resp_json = json.loads(response.read().decode("utf-8")) except Exception as e: + print(e) return None if (callback): callback(resp_json) else: return resp_json + + ''' + def _request(self, request, callback = None): + if self.python_version == 2: + return self._request2(request,callback) + else: + return self._request3(request, callback) + ''' diff --git a/python/unassembled/Platform.py b/python/unassembled/Platform.py index 55ec449..c60690f 100644 --- a/python/unassembled/Platform.py +++ b/python/unassembled/Platform.py @@ -1,5 +1,7 @@ - -import urllib.request +try: + import urllib.request +except: + import urllib2 class Pubnub(PubnubCore): def __init__( @@ -21,16 +23,40 @@ class Pubnub(PubnubCore): origin = origin, uuid = pres_uuid ) + if self.python_version == 2: + self._request = self._request2 + else: + self._request = self._request3 + + def _request2( self, request, callback = None ) : + ## Build URL + url = self.getUrl(request) + + ## Send Request Expecting JSONP Response + try: + try: usock = urllib2.urlopen( url, None, 310 ) + except TypeError: usock = urllib2.urlopen( url, None ) + response = usock.read() + usock.close() + resp_json = json.loads(response) + except: + return None + + if (callback): + callback(resp_json) + else: + return resp_json + - def _request( self, request, callback = None ) : + def _request3( self, request, callback = None ) : ## Build URL url = self.getUrl(request) - print(url) ## Send Request Expecting JSONP Response try: response = urllib.request.urlopen(url,timeout=310) resp_json = json.loads(response.read().decode("utf-8")) except Exception as e: + print(e) return None if (callback): -- cgit v1.2.3 From 765ee5db6fc39d77e55dcf4fe97fb96da2f46d30 Mon Sep 17 00:00:00 2001 From: Devendra Date: Wed, 2 Apr 2014 02:44:29 +0530 Subject: multiplexing support --- common/PubnubBase.py | 12 +- common/PubnubCore.py | 4 +- common/PubnubCoreAsync.py | 171 +++++++++++------ python-tornado/Pubnub.py | 329 +++++++++++++++++++++++++-------- python-tornado/unassembled/Platform.py | 28 ++- python-twisted/Pubnub.py | 329 +++++++++++++++++++++++++-------- python-twisted/unassembled/Platform.py | 28 ++- python/Makefile | 2 +- python/Pubnub.py | 326 +++++++++++++++++++++++++------- python/unassembled/Platform.py | 82 +++++++- 10 files changed, 1002 insertions(+), 309 deletions(-) diff --git a/common/PubnubBase.py b/common/PubnubBase.py index 4c5b422..d287be3 100644 --- a/common/PubnubBase.py +++ b/common/PubnubBase.py @@ -90,6 +90,14 @@ class PubnubBase(object): return message + def _return_wrapped_callback(self, callback=None): + def _new_format_callback(response): + if 'payload' in response: + if (callback != None): callback({'message' : response['message'], 'payload' : response['payload']}) + else: + if (callback != None):callback(response) + if (callback != None): return _new_format_callback + def publish( self, args ) : """ @@ -139,7 +147,7 @@ class PubnubBase(object): channel, '0', message - ]}, callback) + ]'urlparams' : {'auth' : self.auth_key}}, self._return_wrapped_callback(callback)) def presence( self, args ) : """ @@ -179,7 +187,7 @@ class PubnubBase(object): 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}) + return self.subscribe({'channel': channel+'-pnpres', 'subscribe_key':subscribe_key, 'callback': self._return_wrapped_callback(callback)}) def here_now( self, args ) : diff --git a/common/PubnubCore.py b/common/PubnubCore.py index dcfd319..3ed3a68 100644 --- a/common/PubnubCore.py +++ b/common/PubnubCore.py @@ -1,4 +1,4 @@ -class PubnubCore(PubnubBase): +class PubnubCore(PubnubCoreAsync): def __init__( self, publish_key, @@ -44,7 +44,7 @@ class PubnubCore(PubnubBase): - def subscribe( self, args ) : + def subscribe_sync( self, args ) : """ #** #* Subscribe diff --git a/common/PubnubCoreAsync.py b/common/PubnubCoreAsync.py index a7fbb7d..0038243 100644 --- a/common/PubnubCoreAsync.py +++ b/common/PubnubCoreAsync.py @@ -10,8 +10,6 @@ class PubnubCoreAsync(PubnubBase): def start(self): pass def stop(self): pass - def timeout( self, delay, callback ): - pass def __init__( self, @@ -54,8 +52,23 @@ class PubnubCoreAsync(PubnubBase): self.timetoken = 0 self.version = '3.3.4' self.accept_encoding = 'gzip' - - def subscribe( self, args ) : + self.SUB_RECEIVER = None + self._connect = None + + def get_channel_list(self, channels): + channel = '' + first = True + for ch in channels: + if not channels[ch]['subscribed']: + continue + if not first: + channel += ',' + else: + first = False + channel += ch + return channel + + def subscribe( self, args=None, sync=False ) : """ #** #* Subscribe @@ -87,94 +100,140 @@ class PubnubCoreAsync(PubnubBase): }) """ - ## Fail if missing channel - if not 'channel' in args : - return 'Missing Channel.' - ## Fail if missing callback - if not 'callback' in args : - return 'Missing Callback.' + if sync is True and self.susbcribe_sync is not None: + self.susbcribe_sync(args) + return + + def _invoke(func,msg=None): + if func is not None: + if msg is not None: + func(msg) + else: + func() + + def _invoke_connect(): + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + if chobj['connected'] is False: + chobj['connected'] = True + _invoke(chobj['connect']) + + def _invoke_error(err=None): + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + _invoke(chobj.error,err) + - ## Capture User Input - channel = str(args['channel']) - callback = args['callback'] - connectcb = args['connect'] + if callback is None: + _invoke(error, "Callback Missing") + return + + if channel is None: + _invoke(error, "Channel Missing") + return + + def _get_channel(): + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + if chobj['subscribed'] is True: + return chobj - if 'errorback' in args: - errorback = args['errorback'] - else: - errorback = lambda x: x ## New Channel? - if not (channel in self.subscriptions) : + if not channel in self.subscriptions: self.subscriptions[channel] = { - 'first' : False, - 'connected' : False, + 'name' : channel, + 'first' : False, + 'connected' : False, + 'subscribed' : True, + 'callback' : callback, + 'connect' : connect, + 'disconnect' : disconnect, + 'reconnect' : reconnect } - ## Ensure Single Connection + ## return if already connected to channel if self.subscriptions[channel]['connected'] : - return "Already Connected" + _invoke(error, "Already Connected") + return + - self.subscriptions[channel]['connected'] = 1 ## SUBSCRIPTION RECURSION - def _subscribe(): - ## STOP CONNECTION? - if not self.subscriptions[channel]['connected']: - return + def _connect(): + self._reset_offline() + def sub_callback(response): - if not self.subscriptions[channel]['first'] : - self.subscriptions[channel]['first'] = True - connectcb() + print response + ## ERROR ? + if not response or error in response: + _invoke_error() - ## STOP CONNECTION? - if not self.subscriptions[channel]['connected']: - return + _invoke_connect() + self.timetoken = response[1] - ## 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) + if len(response) > 2: + channel_list = response[2].split(',') + response_list = response[0] + for ch in enumerate(channel_list): + if ch[1] in self.subscriptions: + chobj = self.subscriptions[ch[1]] + _invoke(chobj['callback'],self.decrypt(response_list[ch[0]])) + else: + response_list = response[0] + chobj = _get_channel() + for r in response_list: + if chobj: + _invoke(chobj['callback'], self.decrypt(r)) - ## ENSURE CONNECTED (Call Time Function) - return self.time({ 'callback' : time_callback }) - self.timetoken = response[1] - _subscribe() + _connect() + - pc = PubnubCrypto() - out = [] - for message in response[0]: - callback(self.decrypt(message)) + channel_list = self.get_channel_list(self.subscriptions) + print channel_list ## CONNECT TO PUBNUB SUBSCRIBE SERVERS try: - self._request( { "urlcomponents" : [ + self.SUB_RECEIVER = self._request( { "urlcomponents" : [ 'subscribe', self.subscribe_key, - channel, + channel_list, '0', str(self.timetoken) - ], "urlparams" : {"uuid":self.uuid} }, sub_callback ) - except : - self.timeout( 1, _subscribe) + ], "urlparams" : {"uuid":self.uuid} }, sub_callback, single=True ) + except Exception as e: + self.timeout( 1, _connect) return + self._connect = _connect + + ## BEGIN SUBSCRIPTION (LISTEN FOR MESSAGES) - _subscribe() + _connect() + + def _reset_offline(self): + if self.SUB_RECEIVER is not None: + self.SUB_RECEIVER() + self.SUB_RECEIVER = None + + def CONNECT(self): + self._reset_offline() + self._connect() + + def unsubscribe( self, args ): + #print(args['channel']) channel = str(args['channel']) if not (channel in self.subscriptions): return False ## DISCONNECT self.subscriptions[channel]['connected'] = 0 + self.subscriptions[channel]['subscribed'] = False self.subscriptions[channel]['timetoken'] = 0 self.subscriptions[channel]['first'] = False + self.CONNECT() diff --git a/python-tornado/Pubnub.py b/python-tornado/Pubnub.py index 89c0d97..ee66619 100644 --- a/python-tornado/Pubnub.py +++ b/python-tornado/Pubnub.py @@ -16,7 +16,7 @@ from base64 import encodestring, decodestring import hashlib import hmac -class PubnubCrypto() : +class PubnubCrypto2() : """ #** #* PubnubCrypto @@ -93,13 +93,89 @@ class PubnubCrypto() : return self.depad((cipher.decrypt(decodestring(msg)))) +class PubnubCrypto3() : + """ + #** + #* 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).encode('utf-8') + + 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.encode("utf-8")).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) + return encodestring(cipher.encrypt(self.pad(msg.encode('utf-8')))).decode('utf-8') + 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 (cipher.decrypt(decodestring(msg.encode('utf-8')))).decode('utf-8') + + try: import json except ImportError: import simplejson as json import time import hashlib -import urllib2 -import uuid +import uuid +import sys class PubnubBase(object): def __init__( @@ -137,7 +213,7 @@ class PubnubBase(object): 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 @@ -145,8 +221,16 @@ class PubnubBase(object): self.origin = 'http://' + self.origin self.uuid = UUID or str(uuid.uuid4()) + + if type(sys.version_info) is tuple: + self.python_version = 2 + self.pc = PubnubCrypto2() + else: + self.python_version = 3 + self.pc = PubnubCrypto3() + - if not isinstance(self.uuid, basestring): + if not isinstance(self.uuid, str): raise AttributeError("pres_uuid must be a string") def sign(self, channel, message): @@ -177,6 +261,14 @@ class PubnubBase(object): return message + def _return_wrapped_callback(self, callback=None): + def _new_format_callback(response): + if 'payload' in response: + if (callback != None): callback({'message' : response['message'], 'payload' : response['payload']}) + else: + if (callback != None):callback(response) + if (callback != None): return _new_format_callback + def publish( self, args ) : """ @@ -207,7 +299,7 @@ class PubnubBase(object): channel = str(args['channel']) ## Capture Callback - if args.has_key('callback') : + if 'callback' in args : callback = args['callback'] else : callback = None @@ -226,7 +318,7 @@ class PubnubBase(object): channel, '0', message - ]}, callback) + ]'urlparams' : {'auth' : self.auth_key}}, self._return_wrapped_callback(callback)) def presence( self, args ) : """ @@ -266,7 +358,7 @@ class PubnubBase(object): 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}) + return self.subscribe({'channel': channel+'-pnpres', 'subscribe_key':subscribe_key, 'callback': self._return_wrapped_callback(callback)}) def here_now( self, args ) : @@ -291,7 +383,7 @@ class PubnubBase(object): channel = str(args['channel']) ## Capture Callback - if args.has_key('callback') : + if 'callback' in args : callback = args['callback'] else : callback = None @@ -329,7 +421,7 @@ class PubnubBase(object): """ ## Capture User Input - limit = args.has_key('limit') and int(args['limit']) or 10 + limit = 'limit' in args and int(args['limit']) or 10 channel = str(args['channel']) ## Fail if bad input. @@ -338,7 +430,7 @@ class PubnubBase(object): return False ## Capture Callback - if args.has_key('callback') : + if 'callback' in args : callback = args['callback'] else : callback = None @@ -377,18 +469,18 @@ class PubnubBase(object): params = dict() count = 100 - if args.has_key('count'): + if 'count' in args: count = int(args['count']) params['count'] = str(count) - if args.has_key('reverse'): + if 'reverse' in args: params['reverse'] = str(args['reverse']).lower() - if args.has_key('start'): + if 'start' in args: params['start'] = str(args['start']) - if args.has_key('end'): + if 'end' in args: params['end'] = str(args['end']) ## Fail if bad input. @@ -397,7 +489,7 @@ class PubnubBase(object): return False ## Capture Callback - if args.has_key('callback') : + if 'callback' in args : callback = args['callback'] else : callback = None @@ -428,7 +520,7 @@ class PubnubBase(object): """ ## Capture Callback - if args and args.has_key('callback') : + if args and 'callback' in args : callback = args['callback'] else : callback = None @@ -454,8 +546,8 @@ class PubnubBase(object): 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()]) + if ("urlparams" in request): + url = url + '?' + "&".join([ x + "=" + y for x,y in request["urlparams"].items()]) return url @@ -471,8 +563,6 @@ class PubnubCoreAsync(PubnubBase): def start(self): pass def stop(self): pass - def timeout( self, delay, callback ): - pass def __init__( self, @@ -515,8 +605,23 @@ class PubnubCoreAsync(PubnubBase): self.timetoken = 0 self.version = '3.3.4' self.accept_encoding = 'gzip' - - def subscribe( self, args ) : + self.SUB_RECEIVER = None + self._connect = None + + def get_channel_list(self, channels): + channel = '' + first = True + for ch in channels: + if not channels[ch]['subscribed']: + continue + if not first: + channel += ',' + else: + first = False + channel += ch + return channel + + def subscribe( self, args=None, sync=False ) : """ #** #* Subscribe @@ -548,97 +653,143 @@ class PubnubCoreAsync(PubnubBase): }) """ - ## Fail if missing channel - if not 'channel' in args : - return 'Missing Channel.' - ## Fail if missing callback - if not 'callback' in args : - return 'Missing Callback.' + if sync is True and self.susbcribe_sync is not None: + self.susbcribe_sync(args) + return - ## Capture User Input - channel = str(args['channel']) - callback = args['callback'] - connectcb = args['connect'] + def _invoke(func,msg=None): + if func is not None: + if msg is not None: + func(msg) + else: + func() + + def _invoke_connect(): + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + if chobj['connected'] is False: + chobj['connected'] = True + _invoke(chobj['connect']) + + def _invoke_error(err=None): + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + _invoke(chobj.error,err) + + + if callback is None: + _invoke(error, "Callback Missing") + return + + if channel is None: + _invoke(error, "Channel Missing") + return + + def _get_channel(): + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + if chobj['subscribed'] is True: + return chobj - if 'errorback' in args: - errorback = args['errorback'] - else: - errorback = lambda x: x ## New Channel? - if not (channel in self.subscriptions) : + if not channel in self.subscriptions: self.subscriptions[channel] = { - 'first' : False, - 'connected' : False, + 'name' : channel, + 'first' : False, + 'connected' : False, + 'subscribed' : True, + 'callback' : callback, + 'connect' : connect, + 'disconnect' : disconnect, + 'reconnect' : reconnect } - ## Ensure Single Connection + ## return if already connected to channel if self.subscriptions[channel]['connected'] : - return "Already Connected" + _invoke(error, "Already Connected") + return + - self.subscriptions[channel]['connected'] = 1 ## SUBSCRIPTION RECURSION - def _subscribe(): - ## STOP CONNECTION? - if not self.subscriptions[channel]['connected']: - return + def _connect(): + self._reset_offline() + def sub_callback(response): - if not self.subscriptions[channel]['first'] : - self.subscriptions[channel]['first'] = True - connectcb() + print response + ## ERROR ? + if not response or error in response: + _invoke_error() - ## STOP CONNECTION? - if not self.subscriptions[channel]['connected']: - return + _invoke_connect() + self.timetoken = response[1] - ## 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) + if len(response) > 2: + channel_list = response[2].split(',') + response_list = response[0] + for ch in enumerate(channel_list): + if ch[1] in self.subscriptions: + chobj = self.subscriptions[ch[1]] + _invoke(chobj['callback'],self.decrypt(response_list[ch[0]])) + else: + response_list = response[0] + chobj = _get_channel() + for r in response_list: + if chobj: + _invoke(chobj['callback'], self.decrypt(r)) - ## ENSURE CONNECTED (Call Time Function) - return self.time({ 'callback' : time_callback }) - self.timetoken = response[1] - _subscribe() + _connect() + - pc = PubnubCrypto() - out = [] - for message in response[0]: - callback(self.decrypt(message)) + channel_list = self.get_channel_list(self.subscriptions) + print channel_list ## CONNECT TO PUBNUB SUBSCRIBE SERVERS try: - self._request( { "urlcomponents" : [ + self.SUB_RECEIVER = self._request( { "urlcomponents" : [ 'subscribe', self.subscribe_key, - channel, + channel_list, '0', str(self.timetoken) - ], "urlparams" : {"uuid":self.uuid} }, sub_callback ) - except : - self.timeout( 1, _subscribe) + ], "urlparams" : {"uuid":self.uuid} }, sub_callback, single=True ) + except Exception as e: + self.timeout( 1, _connect) return + self._connect = _connect + + ## BEGIN SUBSCRIPTION (LISTEN FOR MESSAGES) - _subscribe() + _connect() + + def _reset_offline(self): + if self.SUB_RECEIVER is not None: + self.SUB_RECEIVER() + self.SUB_RECEIVER = None + + def CONNECT(self): + self._reset_offline() + self._connect() + + def unsubscribe( self, args ): + #print(args['channel']) channel = str(args['channel']) if not (channel in self.subscriptions): return False ## DISCONNECT self.subscriptions[channel]['connected'] = 0 + self.subscriptions[channel]['subscribed'] = False self.subscriptions[channel]['timetoken'] = 0 self.subscriptions[channel]['first'] = False + self.CONNECT() import tornado.httpclient @@ -685,15 +836,24 @@ class Pubnub(PubnubCoreAsync): self.headers['Accept-Encoding'] = self.accept_encoding self.headers['V'] = self.version self.http = tornado.httpclient.AsyncHTTPClient(max_clients=1000) + self.id = None - def _request( self, request, callback ) : + def _request( self, request, callback, single=False ) : 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 ) + if single is True: + id = time.time() + self.id = id def responseCallback(response): + if single is True: + if not id == self.id: + return None + + body = response._get_body() + if body is None: + return + def handle_exc(*args): return True if response.error is not None: @@ -701,9 +861,14 @@ class Pubnub(PubnubCoreAsync): response.rethrow() elif callback: callback(eval(response._get_body())) - + self.http.fetch( - request, - callback=responseCallback, + request=request, + callback=responseCallback ) + def abort(): + pass + + return abort + diff --git a/python-tornado/unassembled/Platform.py b/python-tornado/unassembled/Platform.py index 62d3a26..f98befb 100644 --- a/python-tornado/unassembled/Platform.py +++ b/python-tornado/unassembled/Platform.py @@ -42,15 +42,24 @@ class Pubnub(PubnubCoreAsync): self.headers['Accept-Encoding'] = self.accept_encoding self.headers['V'] = self.version self.http = tornado.httpclient.AsyncHTTPClient(max_clients=1000) + self.id = None - def _request( self, request, callback ) : + def _request( self, request, callback, single=False ) : 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 ) + if single is True: + id = time.time() + self.id = id def responseCallback(response): + if single is True: + if not id == self.id: + return None + + body = response._get_body() + if body is None: + return + def handle_exc(*args): return True if response.error is not None: @@ -58,9 +67,14 @@ class Pubnub(PubnubCoreAsync): response.rethrow() elif callback: callback(eval(response._get_body())) - + self.http.fetch( - request, - callback=responseCallback, + request=request, + callback=responseCallback ) + def abort(): + pass + + return abort + diff --git a/python-twisted/Pubnub.py b/python-twisted/Pubnub.py index 66534b5..3bc2d35 100644 --- a/python-twisted/Pubnub.py +++ b/python-twisted/Pubnub.py @@ -16,7 +16,7 @@ from base64 import encodestring, decodestring import hashlib import hmac -class PubnubCrypto() : +class PubnubCrypto2() : """ #** #* PubnubCrypto @@ -93,13 +93,89 @@ class PubnubCrypto() : return self.depad((cipher.decrypt(decodestring(msg)))) +class PubnubCrypto3() : + """ + #** + #* 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).encode('utf-8') + + 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.encode("utf-8")).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) + return encodestring(cipher.encrypt(self.pad(msg.encode('utf-8')))).decode('utf-8') + 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 (cipher.decrypt(decodestring(msg.encode('utf-8')))).decode('utf-8') + + try: import json except ImportError: import simplejson as json import time import hashlib -import urllib2 -import uuid +import uuid +import sys class PubnubBase(object): def __init__( @@ -137,7 +213,7 @@ class PubnubBase(object): 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 @@ -145,8 +221,16 @@ class PubnubBase(object): self.origin = 'http://' + self.origin self.uuid = UUID or str(uuid.uuid4()) + + if type(sys.version_info) is tuple: + self.python_version = 2 + self.pc = PubnubCrypto2() + else: + self.python_version = 3 + self.pc = PubnubCrypto3() + - if not isinstance(self.uuid, basestring): + if not isinstance(self.uuid, str): raise AttributeError("pres_uuid must be a string") def sign(self, channel, message): @@ -177,6 +261,14 @@ class PubnubBase(object): return message + def _return_wrapped_callback(self, callback=None): + def _new_format_callback(response): + if 'payload' in response: + if (callback != None): callback({'message' : response['message'], 'payload' : response['payload']}) + else: + if (callback != None):callback(response) + if (callback != None): return _new_format_callback + def publish( self, args ) : """ @@ -207,7 +299,7 @@ class PubnubBase(object): channel = str(args['channel']) ## Capture Callback - if args.has_key('callback') : + if 'callback' in args : callback = args['callback'] else : callback = None @@ -226,7 +318,7 @@ class PubnubBase(object): channel, '0', message - ]}, callback) + ]'urlparams' : {'auth' : self.auth_key}}, self._return_wrapped_callback(callback)) def presence( self, args ) : """ @@ -266,7 +358,7 @@ class PubnubBase(object): 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}) + return self.subscribe({'channel': channel+'-pnpres', 'subscribe_key':subscribe_key, 'callback': self._return_wrapped_callback(callback)}) def here_now( self, args ) : @@ -291,7 +383,7 @@ class PubnubBase(object): channel = str(args['channel']) ## Capture Callback - if args.has_key('callback') : + if 'callback' in args : callback = args['callback'] else : callback = None @@ -329,7 +421,7 @@ class PubnubBase(object): """ ## Capture User Input - limit = args.has_key('limit') and int(args['limit']) or 10 + limit = 'limit' in args and int(args['limit']) or 10 channel = str(args['channel']) ## Fail if bad input. @@ -338,7 +430,7 @@ class PubnubBase(object): return False ## Capture Callback - if args.has_key('callback') : + if 'callback' in args : callback = args['callback'] else : callback = None @@ -377,18 +469,18 @@ class PubnubBase(object): params = dict() count = 100 - if args.has_key('count'): + if 'count' in args: count = int(args['count']) params['count'] = str(count) - if args.has_key('reverse'): + if 'reverse' in args: params['reverse'] = str(args['reverse']).lower() - if args.has_key('start'): + if 'start' in args: params['start'] = str(args['start']) - if args.has_key('end'): + if 'end' in args: params['end'] = str(args['end']) ## Fail if bad input. @@ -397,7 +489,7 @@ class PubnubBase(object): return False ## Capture Callback - if args.has_key('callback') : + if 'callback' in args : callback = args['callback'] else : callback = None @@ -428,7 +520,7 @@ class PubnubBase(object): """ ## Capture Callback - if args and args.has_key('callback') : + if args and 'callback' in args : callback = args['callback'] else : callback = None @@ -454,8 +546,8 @@ class PubnubBase(object): 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()]) + if ("urlparams" in request): + url = url + '?' + "&".join([ x + "=" + y for x,y in request["urlparams"].items()]) return url @@ -471,8 +563,6 @@ class PubnubCoreAsync(PubnubBase): def start(self): pass def stop(self): pass - def timeout( self, delay, callback ): - pass def __init__( self, @@ -515,8 +605,23 @@ class PubnubCoreAsync(PubnubBase): self.timetoken = 0 self.version = '3.3.4' self.accept_encoding = 'gzip' - - def subscribe( self, args ) : + self.SUB_RECEIVER = None + self._connect = None + + def get_channel_list(self, channels): + channel = '' + first = True + for ch in channels: + if not channels[ch]['subscribed']: + continue + if not first: + channel += ',' + else: + first = False + channel += ch + return channel + + def subscribe( self, args=None, sync=False ) : """ #** #* Subscribe @@ -548,97 +653,143 @@ class PubnubCoreAsync(PubnubBase): }) """ - ## Fail if missing channel - if not 'channel' in args : - return 'Missing Channel.' - ## Fail if missing callback - if not 'callback' in args : - return 'Missing Callback.' + if sync is True and self.susbcribe_sync is not None: + self.susbcribe_sync(args) + return - ## Capture User Input - channel = str(args['channel']) - callback = args['callback'] - connectcb = args['connect'] + def _invoke(func,msg=None): + if func is not None: + if msg is not None: + func(msg) + else: + func() + + def _invoke_connect(): + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + if chobj['connected'] is False: + chobj['connected'] = True + _invoke(chobj['connect']) + + def _invoke_error(err=None): + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + _invoke(chobj.error,err) + + + if callback is None: + _invoke(error, "Callback Missing") + return + + if channel is None: + _invoke(error, "Channel Missing") + return + + def _get_channel(): + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + if chobj['subscribed'] is True: + return chobj - if 'errorback' in args: - errorback = args['errorback'] - else: - errorback = lambda x: x ## New Channel? - if not (channel in self.subscriptions) : + if not channel in self.subscriptions: self.subscriptions[channel] = { - 'first' : False, - 'connected' : False, + 'name' : channel, + 'first' : False, + 'connected' : False, + 'subscribed' : True, + 'callback' : callback, + 'connect' : connect, + 'disconnect' : disconnect, + 'reconnect' : reconnect } - ## Ensure Single Connection + ## return if already connected to channel if self.subscriptions[channel]['connected'] : - return "Already Connected" + _invoke(error, "Already Connected") + return + - self.subscriptions[channel]['connected'] = 1 ## SUBSCRIPTION RECURSION - def _subscribe(): - ## STOP CONNECTION? - if not self.subscriptions[channel]['connected']: - return + def _connect(): + self._reset_offline() + def sub_callback(response): - if not self.subscriptions[channel]['first'] : - self.subscriptions[channel]['first'] = True - connectcb() + print response + ## ERROR ? + if not response or error in response: + _invoke_error() - ## STOP CONNECTION? - if not self.subscriptions[channel]['connected']: - return + _invoke_connect() + self.timetoken = response[1] - ## 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) + if len(response) > 2: + channel_list = response[2].split(',') + response_list = response[0] + for ch in enumerate(channel_list): + if ch[1] in self.subscriptions: + chobj = self.subscriptions[ch[1]] + _invoke(chobj['callback'],self.decrypt(response_list[ch[0]])) + else: + response_list = response[0] + chobj = _get_channel() + for r in response_list: + if chobj: + _invoke(chobj['callback'], self.decrypt(r)) - ## ENSURE CONNECTED (Call Time Function) - return self.time({ 'callback' : time_callback }) - self.timetoken = response[1] - _subscribe() + _connect() + - pc = PubnubCrypto() - out = [] - for message in response[0]: - callback(self.decrypt(message)) + channel_list = self.get_channel_list(self.subscriptions) + print channel_list ## CONNECT TO PUBNUB SUBSCRIBE SERVERS try: - self._request( { "urlcomponents" : [ + self.SUB_RECEIVER = self._request( { "urlcomponents" : [ 'subscribe', self.subscribe_key, - channel, + channel_list, '0', str(self.timetoken) - ], "urlparams" : {"uuid":self.uuid} }, sub_callback ) - except : - self.timeout( 1, _subscribe) + ], "urlparams" : {"uuid":self.uuid} }, sub_callback, single=True ) + except Exception as e: + self.timeout( 1, _connect) return + self._connect = _connect + + ## BEGIN SUBSCRIPTION (LISTEN FOR MESSAGES) - _subscribe() + _connect() + + def _reset_offline(self): + if self.SUB_RECEIVER is not None: + self.SUB_RECEIVER() + self.SUB_RECEIVER = None + + def CONNECT(self): + self._reset_offline() + self._connect() + + def unsubscribe( self, args ): + #print(args['channel']) channel = str(args['channel']) if not (channel in self.subscriptions): return False ## DISCONNECT self.subscriptions[channel]['connected'] = 0 + self.subscriptions[channel]['subscribed'] = False self.subscriptions[channel]['timetoken'] = 0 self.subscriptions[channel]['first'] = False + self.CONNECT() from twisted.web.client import getPage @@ -650,10 +801,14 @@ from twisted.web.client import HTTPConnectionPool from twisted.web.http_headers import Headers from twisted.internet.ssl import ClientContextFactory from twisted.internet.task import LoopingCall +import twisted +from hashlib import sha256 +import time pnconn_pool = HTTPConnectionPool(reactor, persistent=True) -pnconn_pool.maxPersistentPerHost = 100 +pnconn_pool.maxPersistentPerHost = 100000 pnconn_pool.cachedConnectionTimeout = 310 +pnconn_pool.retryAutomatically = True class Pubnub(PubnubCoreAsync): @@ -684,7 +839,7 @@ class Pubnub(PubnubCoreAsync): #self.headers['Accept-Encoding'] = [self.accept_encoding] self.headers['V'] = [self.version] - def _request( self, request, callback ) : + def _request( self, request, callback, single=False ) : global pnconn_pool ## Build URL @@ -696,24 +851,42 @@ class Pubnub(PubnubCoreAsync): ]) for bit in request]) ''' url = self.getUrl(request) + agent = ContentDecoderAgent(RedirectAgent(Agent( reactor, contextFactory = WebClientContextFactory(), pool = self.ssl and None or pnconn_pool )), [('gzip', GzipDecoder)]) + request = agent.request( 'GET', url, Headers(self.headers), None ) + if single is True: + id = time.time() + self.id = id + def received(response): finished = Deferred() response.deliverBody(PubNubResponse(finished)) return finished def complete(data): - callback(eval(data)) + if single is True: + if not id == self.id: + return None + try: + callback(eval(data)) + except Exception as e: + pass + #need error handling here + + def abort(): + pass request.addCallback(received) request.addBoth(complete) + return abort + class WebClientContextFactory(ClientContextFactory): def getContext(self, hostname, port): return ClientContextFactory.getContext(self) diff --git a/python-twisted/unassembled/Platform.py b/python-twisted/unassembled/Platform.py index 7318703..3b84b30 100644 --- a/python-twisted/unassembled/Platform.py +++ b/python-twisted/unassembled/Platform.py @@ -7,10 +7,14 @@ from twisted.web.client import HTTPConnectionPool from twisted.web.http_headers import Headers from twisted.internet.ssl import ClientContextFactory from twisted.internet.task import LoopingCall +import twisted +from hashlib import sha256 +import time pnconn_pool = HTTPConnectionPool(reactor, persistent=True) -pnconn_pool.maxPersistentPerHost = 100 +pnconn_pool.maxPersistentPerHost = 100000 pnconn_pool.cachedConnectionTimeout = 310 +pnconn_pool.retryAutomatically = True class Pubnub(PubnubCoreAsync): @@ -41,7 +45,7 @@ class Pubnub(PubnubCoreAsync): #self.headers['Accept-Encoding'] = [self.accept_encoding] self.headers['V'] = [self.version] - def _request( self, request, callback ) : + def _request( self, request, callback, single=False ) : global pnconn_pool ## Build URL @@ -53,24 +57,42 @@ class Pubnub(PubnubCoreAsync): ]) for bit in request]) ''' url = self.getUrl(request) + agent = ContentDecoderAgent(RedirectAgent(Agent( reactor, contextFactory = WebClientContextFactory(), pool = self.ssl and None or pnconn_pool )), [('gzip', GzipDecoder)]) + request = agent.request( 'GET', url, Headers(self.headers), None ) + if single is True: + id = time.time() + self.id = id + def received(response): finished = Deferred() response.deliverBody(PubNubResponse(finished)) return finished def complete(data): - callback(eval(data)) + if single is True: + if not id == self.id: + return None + try: + callback(eval(data)) + except Exception as e: + pass + #need error handling here + + def abort(): + pass request.addCallback(received) request.addBoth(complete) + return abort + class WebClientContextFactory(ClientContextFactory): def getContext(self, hostname, port): return ClientContextFactory.getContext(self) diff --git a/python/Makefile b/python/Makefile index 5eb9e2f..b693cf8 100644 --- a/python/Makefile +++ b/python/Makefile @@ -12,7 +12,7 @@ build: echo "\n" >> ./Pubnub.py cat ../common/PubnubBase.py >> ./Pubnub.py echo "\n" >> ./Pubnub.py - cat ../common/PubnubCore.py >> ./Pubnub.py + cat ../common/PubnubCoreAsync.py >> ./Pubnub.py echo "\n" >> ./Pubnub.py cat ./unassembled/Platform.py >> ./Pubnub.py find -name "Pubnub*py" | xargs sed -i "s/PubNub\ [0-9]\.[0-9]\.[0-9]/PubNub\ $(VERSION)/g" diff --git a/python/Pubnub.py b/python/Pubnub.py index 91f67ad..a449c2d 100644 --- a/python/Pubnub.py +++ b/python/Pubnub.py @@ -206,13 +206,13 @@ class PubnubBase(object): 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.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 if self.ssl : @@ -261,6 +261,14 @@ class PubnubBase(object): return message + def _return_wrapped_callback(self, callback=None): + def _new_format_callback(response): + if 'payload' in response: + if (callback != None): callback({'message' : response['message'], 'payload' : response['payload']}) + else: + if (callback != None):callback(response) + if (callback != None): return _new_format_callback + def publish( self, args ) : """ @@ -310,7 +318,7 @@ class PubnubBase(object): channel, '0', message - ]}, callback) + ]'urlparams' : {'auth' : self.auth_key}}, self._return_wrapped_callback(callback)) def presence( self, args ) : """ @@ -350,7 +358,7 @@ class PubnubBase(object): 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}) + return self.subscribe({'channel': channel+'-pnpres', 'subscribe_key':subscribe_key, 'callback': self._return_wrapped_callback(callback)}) def here_now( self, args ) : @@ -543,7 +551,19 @@ class PubnubBase(object): return url -class PubnubCore(PubnubBase): +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 __init__( self, publish_key, @@ -562,17 +582,16 @@ class PubnubCore(PubnubBase): #* #* @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 string secret_key required 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 ) """ - super(PubnubCore, self).__init__( + super(PubnubCoreAsync, self).__init__( publish_key=publish_key, subscribe_key=subscribe_key, secret_key=secret_key, @@ -584,20 +603,33 @@ class PubnubCore(PubnubBase): self.subscriptions = {} self.timetoken = 0 - self.version = '3.4' + self.version = '3.3.4' self.accept_encoding = 'gzip' + self.SUB_RECEIVER = None + self._connect = None + def get_channel_list(self, channels): + channel = '' + first = True + for ch in channels: + if not channels[ch]['subscribed']: + continue + if not first: + channel += ',' + else: + first = False + channel += ch + return channel - - def subscribe( self, args ) : + def subscribe( self, args=None, sync=False ) : """ #** #* Subscribe #* - #* This is BLOCKING. + #* This is NON-BLOCKING. #* Listen for a message on a channel. #* - #* @param array args with channel and callback. + #* @param array args with channel and message. #* @return false on fail, array on success. #** @@ -606,58 +638,158 @@ class PubnubCore(PubnubBase): print(message) return True + ## On Connect Callback + def connected() : + pubnub.publish({ + 'channel' : 'hello_world', + 'message' : { 'some_var' : 'text' } + }) + + ## Subscribe pubnub.subscribe({ 'channel' : 'hello_world', - 'callback' : receive + 'connect' : connected, + 'callback' : receive }) """ - ## Fail if missing channel - if not 'channel' in args : - raise Exception('Missing Channel.') - return False + if sync is True and self.susbcribe_sync is not None: + self.susbcribe_sync(args) + return + + def _invoke(func,msg=None): + if func is not None: + if msg is not None: + func(msg) + else: + func() + + def _invoke_connect(): + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + if chobj['connected'] is False: + chobj['connected'] = True + _invoke(chobj['connect']) + + def _invoke_error(err=None): + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + _invoke(chobj.error,err) + + + if callback is None: + _invoke(error, "Callback Missing") + return + + if channel is None: + _invoke(error, "Channel Missing") + return + + def _get_channel(): + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + if chobj['subscribed'] is True: + return chobj + + + ## New Channel? + if not channel in self.subscriptions: + self.subscriptions[channel] = { + 'name' : channel, + 'first' : False, + 'connected' : False, + 'subscribed' : True, + 'callback' : callback, + 'connect' : connect, + 'disconnect' : disconnect, + 'reconnect' : reconnect + } - ## Fail if missing callback - if not 'callback' in args : - raise Exception('Missing Callback.') - return False + ## return if already connected to channel + if self.subscriptions[channel]['connected'] : + _invoke(error, "Already Connected") + return + - ## Capture User Input - channel = str(args['channel']) - callback = args['callback'] - subscribe_key = args.get('subscribe_key') or self.subscribe_key + ## SUBSCRIPTION RECURSION + def _connect(): + + self._reset_offline() + + def sub_callback(response): + print response + ## ERROR ? + if not response or error in response: + _invoke_error() + + _invoke_connect() + + + self.timetoken = response[1] - ## Begin Subscribe - while True : + if len(response) > 2: + channel_list = response[2].split(',') + response_list = response[0] + for ch in enumerate(channel_list): + if ch[1] in self.subscriptions: + chobj = self.subscriptions[ch[1]] + _invoke(chobj['callback'],self.decrypt(response_list[ch[0]])) + else: + response_list = response[0] + chobj = _get_channel() + for r in response_list: + if chobj: + _invoke(chobj['callback'], self.decrypt(r)) - timetoken = 'timetoken' in args and args['timetoken'] or 0 - try : - ## Wait for Message - response = self._request({"urlcomponents" : [ + + _connect() + + + + channel_list = self.get_channel_list(self.subscriptions) + print channel_list + ## CONNECT TO PUBNUB SUBSCRIBE SERVERS + try: + self.SUB_RECEIVER = self._request( { "urlcomponents" : [ 'subscribe', - subscribe_key, - channel, + self.subscribe_key, + channel_list, '0', - str(timetoken) - ],"urlparams" : {"uuid" : self.uuid }}) + str(self.timetoken) + ], "urlparams" : {"uuid":self.uuid} }, sub_callback, single=True ) + except Exception as e: + self.timeout( 1, _connect) + return + + self._connect = _connect - messages = response[0] - args['timetoken'] = response[1] - ## If it was a timeout - if not len(messages) : - continue + ## BEGIN SUBSCRIPTION (LISTEN FOR MESSAGES) + _connect() - ## Run user Callback and Reconnect if user permits. - for message in messages : - if not callback(self.decrypt(message)) : - return + def _reset_offline(self): + if self.SUB_RECEIVER is not None: + self.SUB_RECEIVER() + self.SUB_RECEIVER = None - except Exception: - time.sleep(1) + def CONNECT(self): + self._reset_offline() + self._connect() + + + def unsubscribe( self, args ): + #print(args['channel']) + channel = str(args['channel']) + if not (channel in self.subscriptions): + return False - return True + ## DISCONNECT + self.subscriptions[channel]['connected'] = 0 + self.subscriptions[channel]['subscribed'] = False + self.subscriptions[channel]['timetoken'] = 0 + self.subscriptions[channel]['first'] = False + self.CONNECT() try: @@ -665,6 +797,34 @@ try: except: import urllib2 +import threading +import json +import time + +current_req_id = -1 + +class HTTPClient: + def __init__(self, url, callback, id=None): + self.url = url + self.id = id + self.callback = callback + self.stop = False + + def cancel(self): + self.stop = True + self.callback = None + + def run(self): + global current_req_id + data = urllib2.urlopen(self.url, timeout=310).read() + if self.stop is True: + return + if self.id is not None and current_req_id != self.id: + return + if self.callback is not None: + self.callback(json.loads(data)) + + class Pubnub(PubnubCore): def __init__( self, @@ -690,7 +850,33 @@ class Pubnub(PubnubCore): else: self._request = self._request3 - def _request2( self, request, callback = None ) : + def timeout(self, interval, func): + def cb(): + time.sleep(interval) + func() + thread = threading.Thread(target=cb) + thread.start() + + def _request2_async( self, request, callback, single=False ) : + global current_req_id + ## Build URL + url = self.getUrl(request) + if single is True: + id = time.time() + client = HTTPClient(url, callback, id) + current_req_id = id + else: + client = HTTPClient(url, callback) + + thread = threading.Thread(target=client.run) + thread.start() + def abort(): + client.cancel(); + return abort + + + def _request2_sync( self, request) : + ## Build URL url = self.getUrl(request) @@ -704,13 +890,18 @@ class Pubnub(PubnubCore): except: return None - if (callback): - callback(resp_json) - else: return resp_json - def _request3( self, request, callback = None ) : + def _request2(self, request, callback=None, single=False): + if callback is None: + return self._request2_sync(request,single=single) + else: + self._request2_async(request, callback, single=single) + + + + def _request3_sync( self, request) : ## Build URL url = self.getUrl(request) ## Send Request Expecting JSONP Response @@ -718,18 +909,15 @@ class Pubnub(PubnubCore): response = urllib.request.urlopen(url,timeout=310) resp_json = json.loads(response.read().decode("utf-8")) except Exception as e: - print(e) return None - if (callback): - callback(resp_json) - else: - return resp_json + return resp_json - ''' - def _request(self, request, callback = None): - if self.python_version == 2: - return self._request2(request,callback) + def _request3_async( self, request, callback, single=False ) : + pass + + def _request3(self, request, callback=None, single=False): + if callback is None: + return self._request3_sync(request,single=single) else: - return self._request3(request, callback) - ''' + self._request3_async(request, callback, single=single) diff --git a/python/unassembled/Platform.py b/python/unassembled/Platform.py index c60690f..f0f9327 100644 --- a/python/unassembled/Platform.py +++ b/python/unassembled/Platform.py @@ -3,6 +3,34 @@ try: except: import urllib2 +import threading +import json +import time + +current_req_id = -1 + +class HTTPClient: + def __init__(self, url, callback, id=None): + self.url = url + self.id = id + self.callback = callback + self.stop = False + + def cancel(self): + self.stop = True + self.callback = None + + def run(self): + global current_req_id + data = urllib2.urlopen(self.url, timeout=310).read() + if self.stop is True: + return + if self.id is not None and current_req_id != self.id: + return + if self.callback is not None: + self.callback(json.loads(data)) + + class Pubnub(PubnubCore): def __init__( self, @@ -28,7 +56,33 @@ class Pubnub(PubnubCore): else: self._request = self._request3 - def _request2( self, request, callback = None ) : + def timeout(self, interval, func): + def cb(): + time.sleep(interval) + func() + thread = threading.Thread(target=cb) + thread.start() + + def _request2_async( self, request, callback, single=False ) : + global current_req_id + ## Build URL + url = self.getUrl(request) + if single is True: + id = time.time() + client = HTTPClient(url, callback, id) + current_req_id = id + else: + client = HTTPClient(url, callback) + + thread = threading.Thread(target=client.run) + thread.start() + def abort(): + client.cancel(); + return abort + + + def _request2_sync( self, request) : + ## Build URL url = self.getUrl(request) @@ -42,13 +96,18 @@ class Pubnub(PubnubCore): except: return None - if (callback): - callback(resp_json) - else: return resp_json - def _request3( self, request, callback = None ) : + def _request2(self, request, callback=None, single=False): + if callback is None: + return self._request2_sync(request,single=single) + else: + self._request2_async(request, callback, single=single) + + + + def _request3_sync( self, request) : ## Build URL url = self.getUrl(request) ## Send Request Expecting JSONP Response @@ -56,10 +115,15 @@ class Pubnub(PubnubCore): response = urllib.request.urlopen(url,timeout=310) resp_json = json.loads(response.read().decode("utf-8")) except Exception as e: - print(e) return None - if (callback): - callback(resp_json) + return resp_json + + def _request3_async( self, request, callback, single=False ) : + pass + + def _request3(self, request, callback=None, single=False): + if callback is None: + return self._request3_sync(request,single=single) else: - return resp_json + self._request3_async(request, callback, single=single) -- cgit v1.2.3 From 99096b8c11b9a541f6350639e8735495cf90091c Mon Sep 17 00:00:00 2001 From: Devendra Date: Fri, 11 Apr 2014 14:49:43 +0530 Subject: v1 MX and async code for python, twisted, tornado --- common/PubnubBase.py | 96 ++++++++++- common/PubnubCore.py | 2 + common/PubnubCoreAsync.py | 149 +++++++++++------ python-tornado/Pubnub.py | 246 ++++++++++++++++++++++------ python-tornado/tests/subscribe-test.py | 148 +++++++++++++++++ python-tornado/unassembled/Platform.py | 1 + python-twisted/Pubnub.py | 246 ++++++++++++++++++++++------ python-twisted/tests/subscribe-test.py | 148 +++++++++++++++++ python-twisted/unassembled/Platform.py | 1 + python/Pubnub.py | 286 ++++++++++++++++++++++++++------- python/tests/subscribe-test.py | 148 +++++++++++++++++ python/unassembled/Platform.py | 41 +++-- 12 files changed, 1290 insertions(+), 222 deletions(-) create mode 100755 python-tornado/tests/subscribe-test.py create mode 100755 python-twisted/tests/subscribe-test.py create mode 100755 python/tests/subscribe-test.py diff --git a/common/PubnubBase.py b/common/PubnubBase.py index d287be3..ac41e0e 100644 --- a/common/PubnubBase.py +++ b/common/PubnubBase.py @@ -5,6 +5,14 @@ import time import hashlib import uuid import sys +from urllib import quote + +from base64 import urlsafe_b64encode +from hashlib import sha256 +from urllib import quote +from urllib import urlopen + +import hmac class PubnubBase(object): def __init__( @@ -13,6 +21,7 @@ class PubnubBase(object): subscribe_key, secret_key = False, cipher_key = False, + auth_key = None, ssl_on = False, origin = 'pubsub.pubnub.com', UUID = None @@ -42,6 +51,7 @@ class PubnubBase(object): self.secret_key = secret_key self.cipher_key = cipher_key self.ssl = ssl_on + self.auth_key = auth_key if self.ssl : @@ -76,6 +86,86 @@ class PubnubBase(object): signature = '0' return signature + def _pam_sign( self, msg ): + """Calculate a signature by secret key and message.""" + + return urlsafe_b64encode(hmac.new( + self.secret_key.encode("utf-8"), + msg.encode("utf-8"), + sha256 + ).digest()) + + def _pam_auth( self, query , apicode=0, callback=None): + """Issue an authenticated request.""" + + if 'timestamp' not in query: + query['timestamp'] = int(time.time()) + + ## Global Grant? + if 'auth' in query and not query['auth']: + del query['auth'] + + if 'channel' in query and not query['channel']: + del query['channel'] + + params = "&".join([ + x + "=" + quote( + str(query[x]), safe="" + ) for x in sorted(query) + ]) + sign_input = "{subkey}\n{pubkey}\n{apitype}\n{params}".format( + subkey=self.subscribe_key, + pubkey=self.publish_key, + apitype="audit" if (apicode) else "grant", + params=params + ) + + signature = self._pam_sign(sign_input) + + ''' + url = ("https://pubsub.pubnub.com/v1/auth/{apitype}/sub-key/".format(apitype="audit" if (apicode) else "grant") + + self.subscribe_key + "?" + + params + "&signature=" + + quote(signature, safe="")) + ''' + + return self._request({"urlcomponents": [ + 'v1', 'auth', "audit" if (apicode) else "grant" , + 'sub-key', + self.subscribe_key + ], 'urlparams' : {'auth' : self.auth_key, 'signature' : signature}}, + self._return_wrapped_callback(callback)) + + def grant( self, channel, authkey=False, read=True, write=True, ttl=5, callback=None): + """Grant Access on a Channel.""" + + return self._pam_auth({ + "channel" : channel, + "auth" : authkey, + "r" : read and 1 or 0, + "w" : write and 1 or 0, + "ttl" : ttl + }, callback=callback) + + def revoke( self, channel, authkey=False, read=False, write=False, ttl=1, callback=None): + """Revoke Access on a Channel.""" + + return self._pam_auth({ + "channel" : channel, + "auth" : authkey, + "r" : read and 1 or 0, + "w" : write and 1 or 0, + "ttl" : ttl + }, callback=callback) + + def audit(self, channel=False, authkey=False, callback=None): + return self._pam_auth({ + "channel" : channel, + "auth" : authkey + },1, callback=callback) + + + def encrypt(self, message): if self.cipher_key: message = json.dumps(self.pc.encrypt(self.cipher_key, json.dumps(message)).replace('\n','')) @@ -147,7 +237,7 @@ class PubnubBase(object): channel, '0', message - ]'urlparams' : {'auth' : self.auth_key}}, self._return_wrapped_callback(callback)) + ], 'urlparams' : {'auth' : self.auth_key}}, self._return_wrapped_callback(callback)) def presence( self, args ) : """ @@ -349,7 +439,7 @@ class PubnubBase(object): """ ## Capture Callback - if args and 'callback' in args : + if args and 'callback' in args: callback = args['callback'] else : callback = None @@ -376,5 +466,5 @@ class PubnubBase(object): ch for ch in list(bit) ]) for bit in request["urlcomponents"]]) if ("urlparams" in request): - url = url + '?' + "&".join([ x + "=" + y for x,y in request["urlparams"].items()]) + url = url + '?' + "&".join([ x + "=" + str(y) for x,y in request["urlparams"].items()]) return url diff --git a/common/PubnubCore.py b/common/PubnubCore.py index 3ed3a68..7fb67d6 100644 --- a/common/PubnubCore.py +++ b/common/PubnubCore.py @@ -5,6 +5,7 @@ class PubnubCore(PubnubCoreAsync): subscribe_key, secret_key = False, cipher_key = False, + auth_key = None, ssl_on = False, origin = 'pubsub.pubnub.com', uuid = None @@ -32,6 +33,7 @@ class PubnubCore(PubnubCoreAsync): subscribe_key=subscribe_key, secret_key=secret_key, cipher_key=cipher_key, + auth_key=auth_key, ssl_on=ssl_on, origin=origin, UUID=uuid diff --git a/common/PubnubCoreAsync.py b/common/PubnubCoreAsync.py index 0038243..4251d47 100644 --- a/common/PubnubCoreAsync.py +++ b/common/PubnubCoreAsync.py @@ -5,6 +5,9 @@ except ImportError: import Crypto.Hash.SHA256 as digestmod sha256 = digestmod.new import hmac +import threading +from threading import current_thread +import threading class PubnubCoreAsync(PubnubBase): @@ -17,6 +20,7 @@ class PubnubCoreAsync(PubnubBase): subscribe_key, secret_key = False, cipher_key = False, + auth_key = None, ssl_on = False, origin = 'pubsub.pubnub.com', uuid = None @@ -43,6 +47,7 @@ class PubnubCoreAsync(PubnubBase): subscribe_key=subscribe_key, secret_key=secret_key, cipher_key=cipher_key, + auth_key=auth_key, ssl_on=ssl_on, origin=origin, UUID=uuid @@ -50,22 +55,36 @@ class PubnubCoreAsync(PubnubBase): self.subscriptions = {} self.timetoken = 0 + self.last_timetoken = 0 self.version = '3.3.4' self.accept_encoding = 'gzip' self.SUB_RECEIVER = None self._connect = None + self._tt_lock = threading.RLock() def get_channel_list(self, channels): channel = '' first = True - for ch in channels: - if not channels[ch]['subscribed']: - continue - if not first: - channel += ',' - else: - first = False - channel += ch + if self._channel_list_lock: + with self._channel_list_lock: + for ch in channels: + if not channels[ch]['subscribed']: + continue + if not first: + channel += ',' + else: + first = False + channel += ch + else: + for ch in channels: + if not channels[ch]['subscribed']: + continue + if not first: + channel += ',' + else: + first = False + channel += ch + return channel def subscribe( self, args=None, sync=False ) : @@ -100,6 +119,26 @@ class PubnubCoreAsync(PubnubBase): }) """ + if args is None: + _invoke(error, "Arguments Missing") + return + channel = args['channel'] if 'channel' in args else None + callback = args['callback'] if 'callback' in args else None + connect = args['connect'] if 'connect' in args else None + disconnect = args['disconnect'] if 'disconnect' in args else None + reconnect = args['reconnect'] if 'reconnect' in args else None + error = args['error'] if 'error' in args else None + + with self._tt_lock: + self.last_timetoken = self.timetoken if self.timetoken != 0 else self.last_timetoken + self.timetoken = 0 + + if channel is None: + _invoke(error, "Channel Missing") + return + if callback is None: + _invoke(error, "Callback Missing") + return if sync is True and self.susbcribe_sync is not None: self.susbcribe_sync(args) @@ -113,18 +152,20 @@ class PubnubCoreAsync(PubnubBase): func() def _invoke_connect(): - for ch in self.subscriptions: - chobj = self.subscriptions[ch] - if chobj['connected'] is False: - chobj['connected'] = True - _invoke(chobj['connect']) + if self._channel_list_lock: + with self._channel_list_lock: + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + if chobj['connected'] is False: + chobj['connected'] = True + _invoke(chobj['connect'],chobj['name']) def _invoke_error(err=None): for ch in self.subscriptions: chobj = self.subscriptions[ch] _invoke(chobj.error,err) - + ''' if callback is None: _invoke(error, "Callback Missing") return @@ -132,6 +173,7 @@ class PubnubCoreAsync(PubnubBase): if channel is None: _invoke(error, "Channel Missing") return + ''' def _get_channel(): for ch in self.subscriptions: @@ -142,22 +184,36 @@ class PubnubCoreAsync(PubnubBase): ## New Channel? if not channel in self.subscriptions: - self.subscriptions[channel] = { - 'name' : channel, - 'first' : False, - 'connected' : False, - 'subscribed' : True, - 'callback' : callback, - 'connect' : connect, - 'disconnect' : disconnect, - 'reconnect' : reconnect - } + if self._channel_list_lock: + with self._channel_list_lock: + self.subscriptions[channel] = { + 'name' : channel, + 'first' : False, + 'connected' : False, + 'subscribed' : True, + 'callback' : callback, + 'connect' : connect, + 'disconnect' : disconnect, + 'reconnect' : reconnect + } + else: + self.subscriptions[channel] = { + 'name' : channel, + 'first' : False, + 'connected' : False, + 'subscribed' : True, + 'callback' : callback, + 'connect' : connect, + 'disconnect' : disconnect, + 'reconnect' : reconnect + } ## return if already connected to channel - if self.subscriptions[channel]['connected'] : + if channel in self.subscriptions and 'connected' in self.subscriptions[channel] and self.subscriptions[channel]['connected'] is True: _invoke(error, "Already Connected") return + ## SUBSCRIPTION RECURSION def _connect(): @@ -165,37 +221,37 @@ class PubnubCoreAsync(PubnubBase): self._reset_offline() def sub_callback(response): - print response ## ERROR ? if not response or error in response: _invoke_error() _invoke_connect() - - self.timetoken = response[1] - - if len(response) > 2: - channel_list = response[2].split(',') - response_list = response[0] - for ch in enumerate(channel_list): - if ch[1] in self.subscriptions: - chobj = self.subscriptions[ch[1]] - _invoke(chobj['callback'],self.decrypt(response_list[ch[0]])) - else: - response_list = response[0] - chobj = _get_channel() - for r in response_list: - if chobj: - _invoke(chobj['callback'], self.decrypt(r)) - - - _connect() + with self._tt_lock: + #print 'A tt : ', self.timetoken , ' last tt : ' , self.last_timetoken + self.timetoken = self.last_timetoken if self.timetoken == 0 and self.last_timetoken != 0 else response[1] + #print 'B tt : ', self.timetoken , ' last tt : ' , self.last_timetoken + if len(response) > 2: + channel_list = response[2].split(',') + response_list = response[0] + for ch in enumerate(channel_list): + if ch[1] in self.subscriptions: + chobj = self.subscriptions[ch[1]] + _invoke(chobj['callback'],self.decrypt(response_list[ch[0]])) + else: + response_list = response[0] + chobj = _get_channel() + for r in response_list: + if chobj: + _invoke(chobj['callback'], self.decrypt(r)) + + #with self._tt_lock: + # self.timetoken = self.last_timetoken if self.timetoken == 0 and self.last_timetoken != 0 else response[1] + _connect() channel_list = self.get_channel_list(self.subscriptions) - print channel_list ## CONNECT TO PUBNUB SUBSCRIBE SERVERS try: self.SUB_RECEIVER = self._request( { "urlcomponents" : [ @@ -206,6 +262,7 @@ class PubnubCoreAsync(PubnubBase): str(self.timetoken) ], "urlparams" : {"uuid":self.uuid} }, sub_callback, single=True ) except Exception as e: + print e self.timeout( 1, _connect) return diff --git a/python-tornado/Pubnub.py b/python-tornado/Pubnub.py index ee66619..61f7c3d 100644 --- a/python-tornado/Pubnub.py +++ b/python-tornado/Pubnub.py @@ -176,6 +176,14 @@ import time import hashlib import uuid import sys +from urllib import quote + +from base64 import urlsafe_b64encode +from hashlib import sha256 +from urllib import quote +from urllib import urlopen + +import hmac class PubnubBase(object): def __init__( @@ -184,6 +192,7 @@ class PubnubBase(object): subscribe_key, secret_key = False, cipher_key = False, + auth_key = None, ssl_on = False, origin = 'pubsub.pubnub.com', UUID = None @@ -213,6 +222,7 @@ class PubnubBase(object): self.secret_key = secret_key self.cipher_key = cipher_key self.ssl = ssl_on + self.auth_key = auth_key if self.ssl : @@ -247,6 +257,86 @@ class PubnubBase(object): signature = '0' return signature + def _pam_sign( self, msg ): + """Calculate a signature by secret key and message.""" + + return urlsafe_b64encode(hmac.new( + self.secret_key.encode("utf-8"), + msg.encode("utf-8"), + sha256 + ).digest()) + + def _pam_auth( self, query , apicode=0, callback=None): + """Issue an authenticated request.""" + + if 'timestamp' not in query: + query['timestamp'] = int(time.time()) + + ## Global Grant? + if 'auth' in query and not query['auth']: + del query['auth'] + + if 'channel' in query and not query['channel']: + del query['channel'] + + params = "&".join([ + x + "=" + quote( + str(query[x]), safe="" + ) for x in sorted(query) + ]) + sign_input = "{subkey}\n{pubkey}\n{apitype}\n{params}".format( + subkey=self.subscribe_key, + pubkey=self.publish_key, + apitype="audit" if (apicode) else "grant", + params=params + ) + + signature = self._pam_sign(sign_input) + + ''' + url = ("https://pubsub.pubnub.com/v1/auth/{apitype}/sub-key/".format(apitype="audit" if (apicode) else "grant") + + self.subscribe_key + "?" + + params + "&signature=" + + quote(signature, safe="")) + ''' + + return self._request({"urlcomponents": [ + 'v1', 'auth', "audit" if (apicode) else "grant" , + 'sub-key', + self.subscribe_key + ], 'urlparams' : {'auth' : self.auth_key, 'signature' : signature}}, + self._return_wrapped_callback(callback)) + + def grant( self, channel, authkey=False, read=True, write=True, ttl=5, callback=None): + """Grant Access on a Channel.""" + + return self._pam_auth({ + "channel" : channel, + "auth" : authkey, + "r" : read and 1 or 0, + "w" : write and 1 or 0, + "ttl" : ttl + }, callback=callback) + + def revoke( self, channel, authkey=False, read=False, write=False, ttl=1, callback=None): + """Revoke Access on a Channel.""" + + return self._pam_auth({ + "channel" : channel, + "auth" : authkey, + "r" : read and 1 or 0, + "w" : write and 1 or 0, + "ttl" : ttl + }, callback=callback) + + def audit(self, channel=False, authkey=False, callback=None): + return self._pam_auth({ + "channel" : channel, + "auth" : authkey + },1, callback=callback) + + + def encrypt(self, message): if self.cipher_key: message = json.dumps(self.pc.encrypt(self.cipher_key, json.dumps(message)).replace('\n','')) @@ -318,7 +408,7 @@ class PubnubBase(object): channel, '0', message - ]'urlparams' : {'auth' : self.auth_key}}, self._return_wrapped_callback(callback)) + ], 'urlparams' : {'auth' : self.auth_key}}, self._return_wrapped_callback(callback)) def presence( self, args ) : """ @@ -520,7 +610,7 @@ class PubnubBase(object): """ ## Capture Callback - if args and 'callback' in args : + if args and 'callback' in args: callback = args['callback'] else : callback = None @@ -547,7 +637,7 @@ class PubnubBase(object): ch for ch in list(bit) ]) for bit in request["urlcomponents"]]) if ("urlparams" in request): - url = url + '?' + "&".join([ x + "=" + y for x,y in request["urlparams"].items()]) + url = url + '?' + "&".join([ x + "=" + str(y) for x,y in request["urlparams"].items()]) return url @@ -558,6 +648,9 @@ except ImportError: import Crypto.Hash.SHA256 as digestmod sha256 = digestmod.new import hmac +import threading +from threading import current_thread +import threading class PubnubCoreAsync(PubnubBase): @@ -570,6 +663,7 @@ class PubnubCoreAsync(PubnubBase): subscribe_key, secret_key = False, cipher_key = False, + auth_key = None, ssl_on = False, origin = 'pubsub.pubnub.com', uuid = None @@ -596,6 +690,7 @@ class PubnubCoreAsync(PubnubBase): subscribe_key=subscribe_key, secret_key=secret_key, cipher_key=cipher_key, + auth_key=auth_key, ssl_on=ssl_on, origin=origin, UUID=uuid @@ -603,22 +698,36 @@ class PubnubCoreAsync(PubnubBase): self.subscriptions = {} self.timetoken = 0 + self.last_timetoken = 0 self.version = '3.3.4' self.accept_encoding = 'gzip' self.SUB_RECEIVER = None self._connect = None + self._tt_lock = threading.RLock() def get_channel_list(self, channels): channel = '' first = True - for ch in channels: - if not channels[ch]['subscribed']: - continue - if not first: - channel += ',' - else: - first = False - channel += ch + if self._channel_list_lock: + with self._channel_list_lock: + for ch in channels: + if not channels[ch]['subscribed']: + continue + if not first: + channel += ',' + else: + first = False + channel += ch + else: + for ch in channels: + if not channels[ch]['subscribed']: + continue + if not first: + channel += ',' + else: + first = False + channel += ch + return channel def subscribe( self, args=None, sync=False ) : @@ -653,6 +762,26 @@ class PubnubCoreAsync(PubnubBase): }) """ + if args is None: + _invoke(error, "Arguments Missing") + return + channel = args['channel'] if 'channel' in args else None + callback = args['callback'] if 'callback' in args else None + connect = args['connect'] if 'connect' in args else None + disconnect = args['disconnect'] if 'disconnect' in args else None + reconnect = args['reconnect'] if 'reconnect' in args else None + error = args['error'] if 'error' in args else None + + with self._tt_lock: + self.last_timetoken = self.timetoken if self.timetoken != 0 else self.last_timetoken + self.timetoken = 0 + + if channel is None: + _invoke(error, "Channel Missing") + return + if callback is None: + _invoke(error, "Callback Missing") + return if sync is True and self.susbcribe_sync is not None: self.susbcribe_sync(args) @@ -666,18 +795,20 @@ class PubnubCoreAsync(PubnubBase): func() def _invoke_connect(): - for ch in self.subscriptions: - chobj = self.subscriptions[ch] - if chobj['connected'] is False: - chobj['connected'] = True - _invoke(chobj['connect']) + if self._channel_list_lock: + with self._channel_list_lock: + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + if chobj['connected'] is False: + chobj['connected'] = True + _invoke(chobj['connect'],chobj['name']) def _invoke_error(err=None): for ch in self.subscriptions: chobj = self.subscriptions[ch] _invoke(chobj.error,err) - + ''' if callback is None: _invoke(error, "Callback Missing") return @@ -685,6 +816,7 @@ class PubnubCoreAsync(PubnubBase): if channel is None: _invoke(error, "Channel Missing") return + ''' def _get_channel(): for ch in self.subscriptions: @@ -695,22 +827,36 @@ class PubnubCoreAsync(PubnubBase): ## New Channel? if not channel in self.subscriptions: - self.subscriptions[channel] = { - 'name' : channel, - 'first' : False, - 'connected' : False, - 'subscribed' : True, - 'callback' : callback, - 'connect' : connect, - 'disconnect' : disconnect, - 'reconnect' : reconnect - } + if self._channel_list_lock: + with self._channel_list_lock: + self.subscriptions[channel] = { + 'name' : channel, + 'first' : False, + 'connected' : False, + 'subscribed' : True, + 'callback' : callback, + 'connect' : connect, + 'disconnect' : disconnect, + 'reconnect' : reconnect + } + else: + self.subscriptions[channel] = { + 'name' : channel, + 'first' : False, + 'connected' : False, + 'subscribed' : True, + 'callback' : callback, + 'connect' : connect, + 'disconnect' : disconnect, + 'reconnect' : reconnect + } ## return if already connected to channel - if self.subscriptions[channel]['connected'] : + if channel in self.subscriptions and 'connected' in self.subscriptions[channel] and self.subscriptions[channel]['connected'] is True: _invoke(error, "Already Connected") return + ## SUBSCRIPTION RECURSION def _connect(): @@ -718,37 +864,37 @@ class PubnubCoreAsync(PubnubBase): self._reset_offline() def sub_callback(response): - print response ## ERROR ? if not response or error in response: _invoke_error() _invoke_connect() - - self.timetoken = response[1] - - if len(response) > 2: - channel_list = response[2].split(',') - response_list = response[0] - for ch in enumerate(channel_list): - if ch[1] in self.subscriptions: - chobj = self.subscriptions[ch[1]] - _invoke(chobj['callback'],self.decrypt(response_list[ch[0]])) - else: - response_list = response[0] - chobj = _get_channel() - for r in response_list: - if chobj: - _invoke(chobj['callback'], self.decrypt(r)) - - - _connect() + with self._tt_lock: + #print 'A tt : ', self.timetoken , ' last tt : ' , self.last_timetoken + self.timetoken = self.last_timetoken if self.timetoken == 0 and self.last_timetoken != 0 else response[1] + #print 'B tt : ', self.timetoken , ' last tt : ' , self.last_timetoken + if len(response) > 2: + channel_list = response[2].split(',') + response_list = response[0] + for ch in enumerate(channel_list): + if ch[1] in self.subscriptions: + chobj = self.subscriptions[ch[1]] + _invoke(chobj['callback'],self.decrypt(response_list[ch[0]])) + else: + response_list = response[0] + chobj = _get_channel() + for r in response_list: + if chobj: + _invoke(chobj['callback'], self.decrypt(r)) + + #with self._tt_lock: + # self.timetoken = self.last_timetoken if self.timetoken == 0 and self.last_timetoken != 0 else response[1] + _connect() channel_list = self.get_channel_list(self.subscriptions) - print channel_list ## CONNECT TO PUBNUB SUBSCRIBE SERVERS try: self.SUB_RECEIVER = self._request( { "urlcomponents" : [ @@ -759,6 +905,7 @@ class PubnubCoreAsync(PubnubBase): str(self.timetoken) ], "urlparams" : {"uuid":self.uuid} }, sub_callback, single=True ) except Exception as e: + print e self.timeout( 1, _connect) return @@ -837,6 +984,7 @@ class Pubnub(PubnubCoreAsync): self.headers['V'] = self.version self.http = tornado.httpclient.AsyncHTTPClient(max_clients=1000) self.id = None + self._channel_list_lock = None def _request( self, request, callback, single=False ) : url = self.getUrl(request) diff --git a/python-tornado/tests/subscribe-test.py b/python-tornado/tests/subscribe-test.py new file mode 100755 index 0000000..0d4c65e --- /dev/null +++ b/python-tornado/tests/subscribe-test.py @@ -0,0 +1,148 @@ +## 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.1 Real-time Push Cloud API +## ----------------------------------- + +import sys +sys.path.append('../') +import datetime +from Pubnub import Pubnub +from functools import partial +from threading import current_thread +import threading +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or None +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False + +## ----------------------------------------------------------------------- +## Initiate Pubnub State +## ----------------------------------------------------------------------- +#pubnub = Pubnub( publish_key, subscribe_key, secret_key, cipher_key, ssl_on ) +pubnub = Pubnub( publish_key, subscribe_key, secret_key, ssl_on ) +crazy = 'hello_world' + +current = -1 + +errors = 0 +received = 0 + +## ----------------------------------------------------------------------- +## Subscribe Example +## ----------------------------------------------------------------------- +def message_received(message): + print message + +def check_received(message): + global current + global errors + global received + print message + print current + if message <= current: + print 'ERROR' + #sys.exit() + errors += 1 + else: + received += 1 + print 'active thread count : ', threading.activeCount() + print 'errors = ' , errors + print current_thread().getName(), ' , ', 'received = ', received + + if received != message: + print '********** MISSED **************** ', message - received + current = message + + +def connected_test(ch) : + print 'Connected' , ch + +def connected(ch) : + pass + + +''' +pubnub.subscribe({ + 'channel' : 'abcd1', + 'connect' : connected, + 'callback' : message_received +}) +''' +def cb1(): + pubnub.subscribe({ + 'channel' : 'efgh1', + 'connect' : connected, + 'callback' : message_received + }) + +def cb2(): + pubnub.subscribe({ + 'channel' : 'dsm-test', + 'connect' : connected_test, + 'callback' : check_received + }) + +def cb3(): + pubnub.unsubscribe({'channel' : 'efgh1'}) + +def cb4(): + pubnub.unsubscribe({'channel' : 'abcd1'}) + +def subscribe(channel): + pubnub.subscribe({ + 'channel' : channel, + 'connect' : connected, + 'callback' : message_received + }) + + +print threading.activeCount() + + +pubnub.timeout(15,cb1) + +pubnub.timeout(30,cb2) + + +pubnub.timeout(45,cb3) + +pubnub.timeout(60,cb4) + +#''' +for x in range(1,1000): + #print x + def y(t): + subscribe('channel-' + str(t)) + + def z(t): + pubnub.unsubscribe({'channel' : 'channel-' + str(t)}) + + pubnub.timeout(x + 5, partial(y,x)) + pubnub.timeout(x + 25, partial(z, x)) + x += 10 +#''' + +''' +for x in range(1,1000): + def cb(r): print r , ' : ', threading.activeCount() + def y(t): + pubnub.publish({ + 'message' : t, + 'callback' : cb, + 'channel' : 'dsm-test' + }) + + + pubnub.timeout(x + 1, partial(y,x)) + x += 1 +''' + + +pubnub.start() diff --git a/python-tornado/unassembled/Platform.py b/python-tornado/unassembled/Platform.py index f98befb..501993e 100644 --- a/python-tornado/unassembled/Platform.py +++ b/python-tornado/unassembled/Platform.py @@ -43,6 +43,7 @@ class Pubnub(PubnubCoreAsync): self.headers['V'] = self.version self.http = tornado.httpclient.AsyncHTTPClient(max_clients=1000) self.id = None + self._channel_list_lock = None def _request( self, request, callback, single=False ) : url = self.getUrl(request) diff --git a/python-twisted/Pubnub.py b/python-twisted/Pubnub.py index 3bc2d35..7171efe 100644 --- a/python-twisted/Pubnub.py +++ b/python-twisted/Pubnub.py @@ -176,6 +176,14 @@ import time import hashlib import uuid import sys +from urllib import quote + +from base64 import urlsafe_b64encode +from hashlib import sha256 +from urllib import quote +from urllib import urlopen + +import hmac class PubnubBase(object): def __init__( @@ -184,6 +192,7 @@ class PubnubBase(object): subscribe_key, secret_key = False, cipher_key = False, + auth_key = None, ssl_on = False, origin = 'pubsub.pubnub.com', UUID = None @@ -213,6 +222,7 @@ class PubnubBase(object): self.secret_key = secret_key self.cipher_key = cipher_key self.ssl = ssl_on + self.auth_key = auth_key if self.ssl : @@ -247,6 +257,86 @@ class PubnubBase(object): signature = '0' return signature + def _pam_sign( self, msg ): + """Calculate a signature by secret key and message.""" + + return urlsafe_b64encode(hmac.new( + self.secret_key.encode("utf-8"), + msg.encode("utf-8"), + sha256 + ).digest()) + + def _pam_auth( self, query , apicode=0, callback=None): + """Issue an authenticated request.""" + + if 'timestamp' not in query: + query['timestamp'] = int(time.time()) + + ## Global Grant? + if 'auth' in query and not query['auth']: + del query['auth'] + + if 'channel' in query and not query['channel']: + del query['channel'] + + params = "&".join([ + x + "=" + quote( + str(query[x]), safe="" + ) for x in sorted(query) + ]) + sign_input = "{subkey}\n{pubkey}\n{apitype}\n{params}".format( + subkey=self.subscribe_key, + pubkey=self.publish_key, + apitype="audit" if (apicode) else "grant", + params=params + ) + + signature = self._pam_sign(sign_input) + + ''' + url = ("https://pubsub.pubnub.com/v1/auth/{apitype}/sub-key/".format(apitype="audit" if (apicode) else "grant") + + self.subscribe_key + "?" + + params + "&signature=" + + quote(signature, safe="")) + ''' + + return self._request({"urlcomponents": [ + 'v1', 'auth', "audit" if (apicode) else "grant" , + 'sub-key', + self.subscribe_key + ], 'urlparams' : {'auth' : self.auth_key, 'signature' : signature}}, + self._return_wrapped_callback(callback)) + + def grant( self, channel, authkey=False, read=True, write=True, ttl=5, callback=None): + """Grant Access on a Channel.""" + + return self._pam_auth({ + "channel" : channel, + "auth" : authkey, + "r" : read and 1 or 0, + "w" : write and 1 or 0, + "ttl" : ttl + }, callback=callback) + + def revoke( self, channel, authkey=False, read=False, write=False, ttl=1, callback=None): + """Revoke Access on a Channel.""" + + return self._pam_auth({ + "channel" : channel, + "auth" : authkey, + "r" : read and 1 or 0, + "w" : write and 1 or 0, + "ttl" : ttl + }, callback=callback) + + def audit(self, channel=False, authkey=False, callback=None): + return self._pam_auth({ + "channel" : channel, + "auth" : authkey + },1, callback=callback) + + + def encrypt(self, message): if self.cipher_key: message = json.dumps(self.pc.encrypt(self.cipher_key, json.dumps(message)).replace('\n','')) @@ -318,7 +408,7 @@ class PubnubBase(object): channel, '0', message - ]'urlparams' : {'auth' : self.auth_key}}, self._return_wrapped_callback(callback)) + ], 'urlparams' : {'auth' : self.auth_key}}, self._return_wrapped_callback(callback)) def presence( self, args ) : """ @@ -520,7 +610,7 @@ class PubnubBase(object): """ ## Capture Callback - if args and 'callback' in args : + if args and 'callback' in args: callback = args['callback'] else : callback = None @@ -547,7 +637,7 @@ class PubnubBase(object): ch for ch in list(bit) ]) for bit in request["urlcomponents"]]) if ("urlparams" in request): - url = url + '?' + "&".join([ x + "=" + y for x,y in request["urlparams"].items()]) + url = url + '?' + "&".join([ x + "=" + str(y) for x,y in request["urlparams"].items()]) return url @@ -558,6 +648,9 @@ except ImportError: import Crypto.Hash.SHA256 as digestmod sha256 = digestmod.new import hmac +import threading +from threading import current_thread +import threading class PubnubCoreAsync(PubnubBase): @@ -570,6 +663,7 @@ class PubnubCoreAsync(PubnubBase): subscribe_key, secret_key = False, cipher_key = False, + auth_key = None, ssl_on = False, origin = 'pubsub.pubnub.com', uuid = None @@ -596,6 +690,7 @@ class PubnubCoreAsync(PubnubBase): subscribe_key=subscribe_key, secret_key=secret_key, cipher_key=cipher_key, + auth_key=auth_key, ssl_on=ssl_on, origin=origin, UUID=uuid @@ -603,22 +698,36 @@ class PubnubCoreAsync(PubnubBase): self.subscriptions = {} self.timetoken = 0 + self.last_timetoken = 0 self.version = '3.3.4' self.accept_encoding = 'gzip' self.SUB_RECEIVER = None self._connect = None + self._tt_lock = threading.RLock() def get_channel_list(self, channels): channel = '' first = True - for ch in channels: - if not channels[ch]['subscribed']: - continue - if not first: - channel += ',' - else: - first = False - channel += ch + if self._channel_list_lock: + with self._channel_list_lock: + for ch in channels: + if not channels[ch]['subscribed']: + continue + if not first: + channel += ',' + else: + first = False + channel += ch + else: + for ch in channels: + if not channels[ch]['subscribed']: + continue + if not first: + channel += ',' + else: + first = False + channel += ch + return channel def subscribe( self, args=None, sync=False ) : @@ -653,6 +762,26 @@ class PubnubCoreAsync(PubnubBase): }) """ + if args is None: + _invoke(error, "Arguments Missing") + return + channel = args['channel'] if 'channel' in args else None + callback = args['callback'] if 'callback' in args else None + connect = args['connect'] if 'connect' in args else None + disconnect = args['disconnect'] if 'disconnect' in args else None + reconnect = args['reconnect'] if 'reconnect' in args else None + error = args['error'] if 'error' in args else None + + with self._tt_lock: + self.last_timetoken = self.timetoken if self.timetoken != 0 else self.last_timetoken + self.timetoken = 0 + + if channel is None: + _invoke(error, "Channel Missing") + return + if callback is None: + _invoke(error, "Callback Missing") + return if sync is True and self.susbcribe_sync is not None: self.susbcribe_sync(args) @@ -666,18 +795,20 @@ class PubnubCoreAsync(PubnubBase): func() def _invoke_connect(): - for ch in self.subscriptions: - chobj = self.subscriptions[ch] - if chobj['connected'] is False: - chobj['connected'] = True - _invoke(chobj['connect']) + if self._channel_list_lock: + with self._channel_list_lock: + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + if chobj['connected'] is False: + chobj['connected'] = True + _invoke(chobj['connect'],chobj['name']) def _invoke_error(err=None): for ch in self.subscriptions: chobj = self.subscriptions[ch] _invoke(chobj.error,err) - + ''' if callback is None: _invoke(error, "Callback Missing") return @@ -685,6 +816,7 @@ class PubnubCoreAsync(PubnubBase): if channel is None: _invoke(error, "Channel Missing") return + ''' def _get_channel(): for ch in self.subscriptions: @@ -695,22 +827,36 @@ class PubnubCoreAsync(PubnubBase): ## New Channel? if not channel in self.subscriptions: - self.subscriptions[channel] = { - 'name' : channel, - 'first' : False, - 'connected' : False, - 'subscribed' : True, - 'callback' : callback, - 'connect' : connect, - 'disconnect' : disconnect, - 'reconnect' : reconnect - } + if self._channel_list_lock: + with self._channel_list_lock: + self.subscriptions[channel] = { + 'name' : channel, + 'first' : False, + 'connected' : False, + 'subscribed' : True, + 'callback' : callback, + 'connect' : connect, + 'disconnect' : disconnect, + 'reconnect' : reconnect + } + else: + self.subscriptions[channel] = { + 'name' : channel, + 'first' : False, + 'connected' : False, + 'subscribed' : True, + 'callback' : callback, + 'connect' : connect, + 'disconnect' : disconnect, + 'reconnect' : reconnect + } ## return if already connected to channel - if self.subscriptions[channel]['connected'] : + if channel in self.subscriptions and 'connected' in self.subscriptions[channel] and self.subscriptions[channel]['connected'] is True: _invoke(error, "Already Connected") return + ## SUBSCRIPTION RECURSION def _connect(): @@ -718,37 +864,37 @@ class PubnubCoreAsync(PubnubBase): self._reset_offline() def sub_callback(response): - print response ## ERROR ? if not response or error in response: _invoke_error() _invoke_connect() - - self.timetoken = response[1] - - if len(response) > 2: - channel_list = response[2].split(',') - response_list = response[0] - for ch in enumerate(channel_list): - if ch[1] in self.subscriptions: - chobj = self.subscriptions[ch[1]] - _invoke(chobj['callback'],self.decrypt(response_list[ch[0]])) - else: - response_list = response[0] - chobj = _get_channel() - for r in response_list: - if chobj: - _invoke(chobj['callback'], self.decrypt(r)) - - - _connect() + with self._tt_lock: + #print 'A tt : ', self.timetoken , ' last tt : ' , self.last_timetoken + self.timetoken = self.last_timetoken if self.timetoken == 0 and self.last_timetoken != 0 else response[1] + #print 'B tt : ', self.timetoken , ' last tt : ' , self.last_timetoken + if len(response) > 2: + channel_list = response[2].split(',') + response_list = response[0] + for ch in enumerate(channel_list): + if ch[1] in self.subscriptions: + chobj = self.subscriptions[ch[1]] + _invoke(chobj['callback'],self.decrypt(response_list[ch[0]])) + else: + response_list = response[0] + chobj = _get_channel() + for r in response_list: + if chobj: + _invoke(chobj['callback'], self.decrypt(r)) + + #with self._tt_lock: + # self.timetoken = self.last_timetoken if self.timetoken == 0 and self.last_timetoken != 0 else response[1] + _connect() channel_list = self.get_channel_list(self.subscriptions) - print channel_list ## CONNECT TO PUBNUB SUBSCRIBE SERVERS try: self.SUB_RECEIVER = self._request( { "urlcomponents" : [ @@ -759,6 +905,7 @@ class PubnubCoreAsync(PubnubBase): str(self.timetoken) ], "urlparams" : {"uuid":self.uuid} }, sub_callback, single=True ) except Exception as e: + print e self.timeout( 1, _connect) return @@ -838,6 +985,7 @@ class Pubnub(PubnubCoreAsync): self.headers['User-Agent'] = ['Python-Twisted'] #self.headers['Accept-Encoding'] = [self.accept_encoding] self.headers['V'] = [self.version] + self._channel_list_lock = None def _request( self, request, callback, single=False ) : global pnconn_pool diff --git a/python-twisted/tests/subscribe-test.py b/python-twisted/tests/subscribe-test.py new file mode 100755 index 0000000..0d4c65e --- /dev/null +++ b/python-twisted/tests/subscribe-test.py @@ -0,0 +1,148 @@ +## 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.1 Real-time Push Cloud API +## ----------------------------------- + +import sys +sys.path.append('../') +import datetime +from Pubnub import Pubnub +from functools import partial +from threading import current_thread +import threading +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or None +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False + +## ----------------------------------------------------------------------- +## Initiate Pubnub State +## ----------------------------------------------------------------------- +#pubnub = Pubnub( publish_key, subscribe_key, secret_key, cipher_key, ssl_on ) +pubnub = Pubnub( publish_key, subscribe_key, secret_key, ssl_on ) +crazy = 'hello_world' + +current = -1 + +errors = 0 +received = 0 + +## ----------------------------------------------------------------------- +## Subscribe Example +## ----------------------------------------------------------------------- +def message_received(message): + print message + +def check_received(message): + global current + global errors + global received + print message + print current + if message <= current: + print 'ERROR' + #sys.exit() + errors += 1 + else: + received += 1 + print 'active thread count : ', threading.activeCount() + print 'errors = ' , errors + print current_thread().getName(), ' , ', 'received = ', received + + if received != message: + print '********** MISSED **************** ', message - received + current = message + + +def connected_test(ch) : + print 'Connected' , ch + +def connected(ch) : + pass + + +''' +pubnub.subscribe({ + 'channel' : 'abcd1', + 'connect' : connected, + 'callback' : message_received +}) +''' +def cb1(): + pubnub.subscribe({ + 'channel' : 'efgh1', + 'connect' : connected, + 'callback' : message_received + }) + +def cb2(): + pubnub.subscribe({ + 'channel' : 'dsm-test', + 'connect' : connected_test, + 'callback' : check_received + }) + +def cb3(): + pubnub.unsubscribe({'channel' : 'efgh1'}) + +def cb4(): + pubnub.unsubscribe({'channel' : 'abcd1'}) + +def subscribe(channel): + pubnub.subscribe({ + 'channel' : channel, + 'connect' : connected, + 'callback' : message_received + }) + + +print threading.activeCount() + + +pubnub.timeout(15,cb1) + +pubnub.timeout(30,cb2) + + +pubnub.timeout(45,cb3) + +pubnub.timeout(60,cb4) + +#''' +for x in range(1,1000): + #print x + def y(t): + subscribe('channel-' + str(t)) + + def z(t): + pubnub.unsubscribe({'channel' : 'channel-' + str(t)}) + + pubnub.timeout(x + 5, partial(y,x)) + pubnub.timeout(x + 25, partial(z, x)) + x += 10 +#''' + +''' +for x in range(1,1000): + def cb(r): print r , ' : ', threading.activeCount() + def y(t): + pubnub.publish({ + 'message' : t, + 'callback' : cb, + 'channel' : 'dsm-test' + }) + + + pubnub.timeout(x + 1, partial(y,x)) + x += 1 +''' + + +pubnub.start() diff --git a/python-twisted/unassembled/Platform.py b/python-twisted/unassembled/Platform.py index 3b84b30..5268446 100644 --- a/python-twisted/unassembled/Platform.py +++ b/python-twisted/unassembled/Platform.py @@ -44,6 +44,7 @@ class Pubnub(PubnubCoreAsync): self.headers['User-Agent'] = ['Python-Twisted'] #self.headers['Accept-Encoding'] = [self.accept_encoding] self.headers['V'] = [self.version] + self._channel_list_lock = None def _request( self, request, callback, single=False ) : global pnconn_pool diff --git a/python/Pubnub.py b/python/Pubnub.py index a449c2d..f3c518c 100644 --- a/python/Pubnub.py +++ b/python/Pubnub.py @@ -176,6 +176,14 @@ import time import hashlib import uuid import sys +from urllib import quote + +from base64 import urlsafe_b64encode +from hashlib import sha256 +from urllib import quote +from urllib import urlopen + +import hmac class PubnubBase(object): def __init__( @@ -184,6 +192,7 @@ class PubnubBase(object): subscribe_key, secret_key = False, cipher_key = False, + auth_key = None, ssl_on = False, origin = 'pubsub.pubnub.com', UUID = None @@ -213,6 +222,7 @@ class PubnubBase(object): self.secret_key = secret_key self.cipher_key = cipher_key self.ssl = ssl_on + self.auth_key = auth_key if self.ssl : @@ -247,6 +257,86 @@ class PubnubBase(object): signature = '0' return signature + def _pam_sign( self, msg ): + """Calculate a signature by secret key and message.""" + + return urlsafe_b64encode(hmac.new( + self.secret_key.encode("utf-8"), + msg.encode("utf-8"), + sha256 + ).digest()) + + def _pam_auth( self, query , apicode=0, callback=None): + """Issue an authenticated request.""" + + if 'timestamp' not in query: + query['timestamp'] = int(time.time()) + + ## Global Grant? + if 'auth' in query and not query['auth']: + del query['auth'] + + if 'channel' in query and not query['channel']: + del query['channel'] + + params = "&".join([ + x + "=" + quote( + str(query[x]), safe="" + ) for x in sorted(query) + ]) + sign_input = "{subkey}\n{pubkey}\n{apitype}\n{params}".format( + subkey=self.subscribe_key, + pubkey=self.publish_key, + apitype="audit" if (apicode) else "grant", + params=params + ) + + signature = self._pam_sign(sign_input) + + ''' + url = ("https://pubsub.pubnub.com/v1/auth/{apitype}/sub-key/".format(apitype="audit" if (apicode) else "grant") + + self.subscribe_key + "?" + + params + "&signature=" + + quote(signature, safe="")) + ''' + + return self._request({"urlcomponents": [ + 'v1', 'auth', "audit" if (apicode) else "grant" , + 'sub-key', + self.subscribe_key + ], 'urlparams' : {'auth' : self.auth_key, 'signature' : signature}}, + self._return_wrapped_callback(callback)) + + def grant( self, channel, authkey=False, read=True, write=True, ttl=5, callback=None): + """Grant Access on a Channel.""" + + return self._pam_auth({ + "channel" : channel, + "auth" : authkey, + "r" : read and 1 or 0, + "w" : write and 1 or 0, + "ttl" : ttl + }, callback=callback) + + def revoke( self, channel, authkey=False, read=False, write=False, ttl=1, callback=None): + """Revoke Access on a Channel.""" + + return self._pam_auth({ + "channel" : channel, + "auth" : authkey, + "r" : read and 1 or 0, + "w" : write and 1 or 0, + "ttl" : ttl + }, callback=callback) + + def audit(self, channel=False, authkey=False, callback=None): + return self._pam_auth({ + "channel" : channel, + "auth" : authkey + },1, callback=callback) + + + def encrypt(self, message): if self.cipher_key: message = json.dumps(self.pc.encrypt(self.cipher_key, json.dumps(message)).replace('\n','')) @@ -318,7 +408,7 @@ class PubnubBase(object): channel, '0', message - ]'urlparams' : {'auth' : self.auth_key}}, self._return_wrapped_callback(callback)) + ], 'urlparams' : {'auth' : self.auth_key}}, self._return_wrapped_callback(callback)) def presence( self, args ) : """ @@ -520,7 +610,7 @@ class PubnubBase(object): """ ## Capture Callback - if args and 'callback' in args : + if args and 'callback' in args: callback = args['callback'] else : callback = None @@ -547,7 +637,7 @@ class PubnubBase(object): ch for ch in list(bit) ]) for bit in request["urlcomponents"]]) if ("urlparams" in request): - url = url + '?' + "&".join([ x + "=" + y for x,y in request["urlparams"].items()]) + url = url + '?' + "&".join([ x + "=" + str(y) for x,y in request["urlparams"].items()]) return url @@ -558,6 +648,9 @@ except ImportError: import Crypto.Hash.SHA256 as digestmod sha256 = digestmod.new import hmac +import threading +from threading import current_thread +import threading class PubnubCoreAsync(PubnubBase): @@ -570,6 +663,7 @@ class PubnubCoreAsync(PubnubBase): subscribe_key, secret_key = False, cipher_key = False, + auth_key = None, ssl_on = False, origin = 'pubsub.pubnub.com', uuid = None @@ -596,6 +690,7 @@ class PubnubCoreAsync(PubnubBase): subscribe_key=subscribe_key, secret_key=secret_key, cipher_key=cipher_key, + auth_key=auth_key, ssl_on=ssl_on, origin=origin, UUID=uuid @@ -603,22 +698,36 @@ class PubnubCoreAsync(PubnubBase): self.subscriptions = {} self.timetoken = 0 + self.last_timetoken = 0 self.version = '3.3.4' self.accept_encoding = 'gzip' self.SUB_RECEIVER = None self._connect = None + self._tt_lock = threading.RLock() def get_channel_list(self, channels): channel = '' first = True - for ch in channels: - if not channels[ch]['subscribed']: - continue - if not first: - channel += ',' - else: - first = False - channel += ch + if self._channel_list_lock: + with self._channel_list_lock: + for ch in channels: + if not channels[ch]['subscribed']: + continue + if not first: + channel += ',' + else: + first = False + channel += ch + else: + for ch in channels: + if not channels[ch]['subscribed']: + continue + if not first: + channel += ',' + else: + first = False + channel += ch + return channel def subscribe( self, args=None, sync=False ) : @@ -653,6 +762,26 @@ class PubnubCoreAsync(PubnubBase): }) """ + if args is None: + _invoke(error, "Arguments Missing") + return + channel = args['channel'] if 'channel' in args else None + callback = args['callback'] if 'callback' in args else None + connect = args['connect'] if 'connect' in args else None + disconnect = args['disconnect'] if 'disconnect' in args else None + reconnect = args['reconnect'] if 'reconnect' in args else None + error = args['error'] if 'error' in args else None + + with self._tt_lock: + self.last_timetoken = self.timetoken if self.timetoken != 0 else self.last_timetoken + self.timetoken = 0 + + if channel is None: + _invoke(error, "Channel Missing") + return + if callback is None: + _invoke(error, "Callback Missing") + return if sync is True and self.susbcribe_sync is not None: self.susbcribe_sync(args) @@ -666,18 +795,20 @@ class PubnubCoreAsync(PubnubBase): func() def _invoke_connect(): - for ch in self.subscriptions: - chobj = self.subscriptions[ch] - if chobj['connected'] is False: - chobj['connected'] = True - _invoke(chobj['connect']) + if self._channel_list_lock: + with self._channel_list_lock: + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + if chobj['connected'] is False: + chobj['connected'] = True + _invoke(chobj['connect'],chobj['name']) def _invoke_error(err=None): for ch in self.subscriptions: chobj = self.subscriptions[ch] _invoke(chobj.error,err) - + ''' if callback is None: _invoke(error, "Callback Missing") return @@ -685,6 +816,7 @@ class PubnubCoreAsync(PubnubBase): if channel is None: _invoke(error, "Channel Missing") return + ''' def _get_channel(): for ch in self.subscriptions: @@ -695,22 +827,36 @@ class PubnubCoreAsync(PubnubBase): ## New Channel? if not channel in self.subscriptions: - self.subscriptions[channel] = { - 'name' : channel, - 'first' : False, - 'connected' : False, - 'subscribed' : True, - 'callback' : callback, - 'connect' : connect, - 'disconnect' : disconnect, - 'reconnect' : reconnect - } + if self._channel_list_lock: + with self._channel_list_lock: + self.subscriptions[channel] = { + 'name' : channel, + 'first' : False, + 'connected' : False, + 'subscribed' : True, + 'callback' : callback, + 'connect' : connect, + 'disconnect' : disconnect, + 'reconnect' : reconnect + } + else: + self.subscriptions[channel] = { + 'name' : channel, + 'first' : False, + 'connected' : False, + 'subscribed' : True, + 'callback' : callback, + 'connect' : connect, + 'disconnect' : disconnect, + 'reconnect' : reconnect + } ## return if already connected to channel - if self.subscriptions[channel]['connected'] : + if channel in self.subscriptions and 'connected' in self.subscriptions[channel] and self.subscriptions[channel]['connected'] is True: _invoke(error, "Already Connected") return + ## SUBSCRIPTION RECURSION def _connect(): @@ -718,37 +864,37 @@ class PubnubCoreAsync(PubnubBase): self._reset_offline() def sub_callback(response): - print response ## ERROR ? if not response or error in response: _invoke_error() _invoke_connect() - - self.timetoken = response[1] - - if len(response) > 2: - channel_list = response[2].split(',') - response_list = response[0] - for ch in enumerate(channel_list): - if ch[1] in self.subscriptions: - chobj = self.subscriptions[ch[1]] - _invoke(chobj['callback'],self.decrypt(response_list[ch[0]])) - else: - response_list = response[0] - chobj = _get_channel() - for r in response_list: - if chobj: - _invoke(chobj['callback'], self.decrypt(r)) - - - _connect() + with self._tt_lock: + #print 'A tt : ', self.timetoken , ' last tt : ' , self.last_timetoken + self.timetoken = self.last_timetoken if self.timetoken == 0 and self.last_timetoken != 0 else response[1] + #print 'B tt : ', self.timetoken , ' last tt : ' , self.last_timetoken + if len(response) > 2: + channel_list = response[2].split(',') + response_list = response[0] + for ch in enumerate(channel_list): + if ch[1] in self.subscriptions: + chobj = self.subscriptions[ch[1]] + _invoke(chobj['callback'],self.decrypt(response_list[ch[0]])) + else: + response_list = response[0] + chobj = _get_channel() + for r in response_list: + if chobj: + _invoke(chobj['callback'], self.decrypt(r)) + + #with self._tt_lock: + # self.timetoken = self.last_timetoken if self.timetoken == 0 and self.last_timetoken != 0 else response[1] + _connect() channel_list = self.get_channel_list(self.subscriptions) - print channel_list ## CONNECT TO PUBNUB SUBSCRIBE SERVERS try: self.SUB_RECEIVER = self._request( { "urlcomponents" : [ @@ -759,6 +905,7 @@ class PubnubCoreAsync(PubnubBase): str(self.timetoken) ], "urlparams" : {"uuid":self.uuid} }, sub_callback, single=True ) except Exception as e: + print e self.timeout( 1, _connect) return @@ -800,8 +947,11 @@ except: import threading import json import time +import threading +from threading import current_thread -current_req_id = -1 +latest_sub_callback_lock = threading.RLock() +latest_sub_callback = {'id' : None, 'callback' : None} class HTTPClient: def __init__(self, url, callback, id=None): @@ -815,23 +965,32 @@ class HTTPClient: self.callback = None def run(self): - global current_req_id data = urllib2.urlopen(self.url, timeout=310).read() if self.stop is True: return - if self.id is not None and current_req_id != self.id: - return - if self.callback is not None: + if self.callback is None: + global latest_sub_callback + global latest_sub_callback_lock + with latest_sub_callback_lock: + if latest_sub_callback['id'] != self.id: + return + else: + print(data) + if latest_sub_callback['callback'] is not None: + latest_sub_callback['id'] = 0 + latest_sub_callback['callback'](json.loads(data)) + else: self.callback(json.loads(data)) -class Pubnub(PubnubCore): +class Pubnub(PubnubCoreAsync): def __init__( self, publish_key, subscribe_key, secret_key = False, cipher_key = False, + auth_key = None, ssl_on = False, origin = 'pubsub.pubnub.com', pres_uuid = None @@ -841,6 +1000,7 @@ class Pubnub(PubnubCore): subscribe_key = subscribe_key, secret_key = secret_key, cipher_key = cipher_key, + auth_key = auth_key, ssl_on = ssl_on, origin = origin, uuid = pres_uuid @@ -849,6 +1009,7 @@ class Pubnub(PubnubCore): self._request = self._request2 else: self._request = self._request3 + self._channel_list_lock = threading.RLock() def timeout(self, interval, func): def cb(): @@ -858,13 +1019,14 @@ class Pubnub(PubnubCore): thread.start() def _request2_async( self, request, callback, single=False ) : - global current_req_id ## Build URL url = self.getUrl(request) if single is True: id = time.time() - client = HTTPClient(url, callback, id) - current_req_id = id + client = HTTPClient(url, None, id) + with latest_sub_callback_lock: + latest_sub_callback['id'] = id + latest_sub_callback['callback'] = callback else: client = HTTPClient(url, callback) @@ -879,7 +1041,6 @@ class Pubnub(PubnubCore): ## Build URL url = self.getUrl(request) - ## Send Request Expecting JSONP Response try: try: usock = urllib2.urlopen( url, None, 310 ) @@ -887,15 +1048,16 @@ class Pubnub(PubnubCore): response = usock.read() usock.close() resp_json = json.loads(response) - except: + except Exception as e: + print e return None - return resp_json + return resp_json def _request2(self, request, callback=None, single=False): if callback is None: - return self._request2_sync(request,single=single) + return self._request2_sync(request) else: self._request2_async(request, callback, single=single) diff --git a/python/tests/subscribe-test.py b/python/tests/subscribe-test.py new file mode 100755 index 0000000..0d4c65e --- /dev/null +++ b/python/tests/subscribe-test.py @@ -0,0 +1,148 @@ +## 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.1 Real-time Push Cloud API +## ----------------------------------- + +import sys +sys.path.append('../') +import datetime +from Pubnub import Pubnub +from functools import partial +from threading import current_thread +import threading +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or None +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False + +## ----------------------------------------------------------------------- +## Initiate Pubnub State +## ----------------------------------------------------------------------- +#pubnub = Pubnub( publish_key, subscribe_key, secret_key, cipher_key, ssl_on ) +pubnub = Pubnub( publish_key, subscribe_key, secret_key, ssl_on ) +crazy = 'hello_world' + +current = -1 + +errors = 0 +received = 0 + +## ----------------------------------------------------------------------- +## Subscribe Example +## ----------------------------------------------------------------------- +def message_received(message): + print message + +def check_received(message): + global current + global errors + global received + print message + print current + if message <= current: + print 'ERROR' + #sys.exit() + errors += 1 + else: + received += 1 + print 'active thread count : ', threading.activeCount() + print 'errors = ' , errors + print current_thread().getName(), ' , ', 'received = ', received + + if received != message: + print '********** MISSED **************** ', message - received + current = message + + +def connected_test(ch) : + print 'Connected' , ch + +def connected(ch) : + pass + + +''' +pubnub.subscribe({ + 'channel' : 'abcd1', + 'connect' : connected, + 'callback' : message_received +}) +''' +def cb1(): + pubnub.subscribe({ + 'channel' : 'efgh1', + 'connect' : connected, + 'callback' : message_received + }) + +def cb2(): + pubnub.subscribe({ + 'channel' : 'dsm-test', + 'connect' : connected_test, + 'callback' : check_received + }) + +def cb3(): + pubnub.unsubscribe({'channel' : 'efgh1'}) + +def cb4(): + pubnub.unsubscribe({'channel' : 'abcd1'}) + +def subscribe(channel): + pubnub.subscribe({ + 'channel' : channel, + 'connect' : connected, + 'callback' : message_received + }) + + +print threading.activeCount() + + +pubnub.timeout(15,cb1) + +pubnub.timeout(30,cb2) + + +pubnub.timeout(45,cb3) + +pubnub.timeout(60,cb4) + +#''' +for x in range(1,1000): + #print x + def y(t): + subscribe('channel-' + str(t)) + + def z(t): + pubnub.unsubscribe({'channel' : 'channel-' + str(t)}) + + pubnub.timeout(x + 5, partial(y,x)) + pubnub.timeout(x + 25, partial(z, x)) + x += 10 +#''' + +''' +for x in range(1,1000): + def cb(r): print r , ' : ', threading.activeCount() + def y(t): + pubnub.publish({ + 'message' : t, + 'callback' : cb, + 'channel' : 'dsm-test' + }) + + + pubnub.timeout(x + 1, partial(y,x)) + x += 1 +''' + + +pubnub.start() diff --git a/python/unassembled/Platform.py b/python/unassembled/Platform.py index f0f9327..22893f8 100644 --- a/python/unassembled/Platform.py +++ b/python/unassembled/Platform.py @@ -6,8 +6,11 @@ except: import threading import json import time +import threading +from threading import current_thread -current_req_id = -1 +latest_sub_callback_lock = threading.RLock() +latest_sub_callback = {'id' : None, 'callback' : None} class HTTPClient: def __init__(self, url, callback, id=None): @@ -21,23 +24,32 @@ class HTTPClient: self.callback = None def run(self): - global current_req_id data = urllib2.urlopen(self.url, timeout=310).read() if self.stop is True: return - if self.id is not None and current_req_id != self.id: - return - if self.callback is not None: + if self.callback is None: + global latest_sub_callback + global latest_sub_callback_lock + with latest_sub_callback_lock: + if latest_sub_callback['id'] != self.id: + return + else: + print(data) + if latest_sub_callback['callback'] is not None: + latest_sub_callback['id'] = 0 + latest_sub_callback['callback'](json.loads(data)) + else: self.callback(json.loads(data)) -class Pubnub(PubnubCore): +class Pubnub(PubnubCoreAsync): def __init__( self, publish_key, subscribe_key, secret_key = False, cipher_key = False, + auth_key = None, ssl_on = False, origin = 'pubsub.pubnub.com', pres_uuid = None @@ -47,6 +59,7 @@ class Pubnub(PubnubCore): subscribe_key = subscribe_key, secret_key = secret_key, cipher_key = cipher_key, + auth_key = auth_key, ssl_on = ssl_on, origin = origin, uuid = pres_uuid @@ -55,6 +68,7 @@ class Pubnub(PubnubCore): self._request = self._request2 else: self._request = self._request3 + self._channel_list_lock = threading.RLock() def timeout(self, interval, func): def cb(): @@ -64,13 +78,14 @@ class Pubnub(PubnubCore): thread.start() def _request2_async( self, request, callback, single=False ) : - global current_req_id ## Build URL url = self.getUrl(request) if single is True: id = time.time() - client = HTTPClient(url, callback, id) - current_req_id = id + client = HTTPClient(url, None, id) + with latest_sub_callback_lock: + latest_sub_callback['id'] = id + latest_sub_callback['callback'] = callback else: client = HTTPClient(url, callback) @@ -85,7 +100,6 @@ class Pubnub(PubnubCore): ## Build URL url = self.getUrl(request) - ## Send Request Expecting JSONP Response try: try: usock = urllib2.urlopen( url, None, 310 ) @@ -93,15 +107,16 @@ class Pubnub(PubnubCore): response = usock.read() usock.close() resp_json = json.loads(response) - except: + except Exception as e: + print e return None - return resp_json + return resp_json def _request2(self, request, callback=None, single=False): if callback is None: - return self._request2_sync(request,single=single) + return self._request2_sync(request) else: self._request2_async(request, callback, single=single) -- cgit v1.2.3 From 150ae1566d813acbb773839e919db2c0f467931c Mon Sep 17 00:00:00 2001 From: Devendra Date: Wed, 16 Apr 2014 00:00:40 +0530 Subject: adding code to support async and pam client capabilities with python v2 and v3 --- common/PubnubBase.py | 133 ++++------ common/PubnubCoreAsync.py | 125 +++++----- python-tornado/Pubnub.py | 286 ++++++++++------------ python-tornado/examples/publish-example.py | 35 +-- python-tornado/tests/subscribe-test.py | 19 +- python-tornado/unassembled/Platform.py | 28 ++- python-twisted/Pubnub.py | 325 +++++++++++++------------ python-twisted/examples/publish-example.py | 27 ++- python-twisted/unassembled/Platform.py | 67 ++++- python/Pubnub.py | 376 +++++++++++++++-------------- python/examples/publish-example.py | 87 ++++--- python/tests/subscribe-test.py | 19 +- python/unassembled/Platform.py | 120 ++++++--- 13 files changed, 875 insertions(+), 772 deletions(-) diff --git a/common/PubnubBase.py b/common/PubnubBase.py index ac41e0e..98c68eb 100644 --- a/common/PubnubBase.py +++ b/common/PubnubBase.py @@ -5,12 +5,13 @@ import time import hashlib import uuid import sys -from urllib import quote + +try: from urllib.parse import quote +except: from urllib2 import quote from base64 import urlsafe_b64encode from hashlib import sha256 -from urllib import quote -from urllib import urlopen + import hmac @@ -62,12 +63,11 @@ class PubnubBase(object): self.uuid = UUID or str(uuid.uuid4()) if type(sys.version_info) is tuple: - self.python_version = 2 - self.pc = PubnubCrypto2() + self.python_version = 2 + self.pc = PubnubCrypto2() else: self.python_version = 3 self.pc = PubnubCrypto3() - if not isinstance(self.uuid, str): raise AttributeError("pres_uuid must be a string") @@ -186,7 +186,10 @@ class PubnubBase(object): if (callback != None): callback({'message' : response['message'], 'payload' : response['payload']}) else: if (callback != None):callback(response) - if (callback != None): return _new_format_callback + if (callback != None): + return _new_format_callback + else: + return None def publish( self, args ) : @@ -221,23 +224,28 @@ class PubnubBase(object): if 'callback' in args : callback = args['callback'] else : - callback = None + callback = None + + if 'error' in args : + error = args['error'] + else : + error = None - #message = json.dumps(args['message'], separators=(',',':')) message = self.encrypt(args['message']) - signature = self.sign(channel, message) + #signature = self.sign(channel, message) ## Send Message return self._request({"urlcomponents": [ 'publish', self.publish_key, self.subscribe_key, - signature, + '0', channel, '0', message - ], 'urlparams' : {'auth' : self.auth_key}}, self._return_wrapped_callback(callback)) + ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) def presence( self, args ) : """ @@ -301,12 +309,10 @@ class PubnubBase(object): """ channel = str(args['channel']) - ## Capture Callback - if 'callback' in args : - callback = args['callback'] - else : - callback = None - + + callback = args['callback'] if 'callback' in args else None + error = args['error'] if 'error' in args else None + ## Fail if bad input. if not channel : raise Exception('Missing Channel') @@ -317,59 +323,16 @@ class PubnubBase(object): 'v2','presence', 'sub_key', self.subscribe_key, 'channel', channel - ]}, callback); - - - def history( self, args ) : + ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) + + 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 = 'limit' in args 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 'callback' in args : - 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. #* @@ -385,34 +348,21 @@ class PubnubBase(object): ## Capture User Input channel = str(args['channel']) - params = dict() - count = 100 - - if 'count' in args: - count = int(args['count']) - - params['count'] = str(count) - - if 'reverse' in args: - params['reverse'] = str(args['reverse']).lower() + callback = args['callback'] if 'callback' in args else None + error = args['error'] if 'error' in args else None - if 'start' in args: - params['start'] = str(args['start']) + params = dict() - if 'end' in args: - params['end'] = str(args['end']) + params['count'] = str(args['count']) if 'count' in args else 100 + params['reverse'] = str(args['reverse']).lower() if 'reverse' in args else 'false' + params['start'] = str(args['start']) if 'start' in args else None + params['end'] = str(args['end']) if 'end' in args else None ## Fail if bad input. if not channel : raise Exception('Missing Channel') return False - ## Capture Callback - if 'callback' in args : - callback = args['callback'] - else : - callback = None - ## Get History return self._request({ 'urlcomponents' : [ 'v2', @@ -421,7 +371,8 @@ class PubnubBase(object): self.subscribe_key, 'channel', channel, - ],'urlparams' : params }, callback=callback); + ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) def time(self, args = None) : """ @@ -439,10 +390,9 @@ class PubnubBase(object): """ ## Capture Callback - if args and 'callback' in args: - callback = args['callback'] - else : - callback = None + + callback = callback if args and 'callback' in args else None + time = self._request({'urlcomponents' : [ 'time', '0' @@ -466,5 +416,6 @@ class PubnubBase(object): ch for ch in list(bit) ]) for bit in request["urlcomponents"]]) if ("urlparams" in request): - url = url + '?' + "&".join([ x + "=" + str(y) for x,y in request["urlparams"].items()]) + url = url + '?' + "&".join([ x + "=" + str(y) for x,y in request["urlparams"].items() if y is not None]) + #print(url) return url diff --git a/common/PubnubCoreAsync.py b/common/PubnubCoreAsync.py index 4251d47..f7b57cc 100644 --- a/common/PubnubCoreAsync.py +++ b/common/PubnubCoreAsync.py @@ -5,9 +5,14 @@ except ImportError: import Crypto.Hash.SHA256 as digestmod sha256 = digestmod.new import hmac -import threading -from threading import current_thread -import threading + +class EmptyLock(): + def __enter__(self): + pass + def __exit__(self,a,b,c): + pass + +empty_lock = EmptyLock() class PubnubCoreAsync(PubnubBase): @@ -23,7 +28,9 @@ class PubnubCoreAsync(PubnubBase): auth_key = None, ssl_on = False, origin = 'pubsub.pubnub.com', - uuid = None + uuid = None, + _tt_lock=empty_lock, + _channel_list_lock=empty_lock ) : """ #** @@ -53,29 +60,20 @@ class PubnubCoreAsync(PubnubBase): UUID=uuid ) - self.subscriptions = {} - self.timetoken = 0 - self.last_timetoken = 0 - self.version = '3.3.4' - self.accept_encoding = 'gzip' - self.SUB_RECEIVER = None - self._connect = None - self._tt_lock = threading.RLock() + self.subscriptions = {} + self.timetoken = 0 + self.last_timetoken = 0 + self.version = '3.3.4' + self.accept_encoding = 'gzip' + self.SUB_RECEIVER = None + self._connect = None + self._tt_lock = _tt_lock + self._channel_list_lock = _channel_list_lock def get_channel_list(self, channels): channel = '' first = True - if self._channel_list_lock: - with self._channel_list_lock: - for ch in channels: - if not channels[ch]['subscribed']: - continue - if not first: - channel += ',' - else: - first = False - channel += ch - else: + with self._channel_list_lock: for ch in channels: if not channels[ch]['subscribed']: continue @@ -84,9 +82,15 @@ class PubnubCoreAsync(PubnubBase): else: first = False channel += ch - return channel + + def each(l, func): + if func is None: + return + for i in l: + func(i) + def subscribe( self, args=None, sync=False ) : """ #** @@ -122,12 +126,12 @@ class PubnubCoreAsync(PubnubBase): if args is None: _invoke(error, "Arguments Missing") return - channel = args['channel'] if 'channel' in args else None - callback = args['callback'] if 'callback' in args else None - connect = args['connect'] if 'connect' in args else None - disconnect = args['disconnect'] if 'disconnect' in args else None - reconnect = args['reconnect'] if 'reconnect' in args else None - error = args['error'] if 'error' in args else None + channel = args['channel'] if 'channel' in args else None + callback = args['callback'] if 'callback' in args else None + connect = args['connect'] if 'connect' in args else None + disconnect = args['disconnect'] if 'disconnect' in args else None + reconnect = args['reconnect'] if 'reconnect' in args else None + error = args['error'] if 'error' in args else None with self._tt_lock: self.last_timetoken = self.timetoken if self.timetoken != 0 else self.last_timetoken @@ -160,10 +164,15 @@ class PubnubCoreAsync(PubnubBase): chobj['connected'] = True _invoke(chobj['connect'],chobj['name']) - def _invoke_error(err=None): - for ch in self.subscriptions: - chobj = self.subscriptions[ch] - _invoke(chobj.error,err) + def _invoke_error(channel_list=None, err=None): + if channel_list is None: + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + _invoke(chobj['error'],err) + else: + for ch in channel_list: + chobj = self.subscriptions[ch] + _invoke(chobj['error'],err) ''' if callback is None: @@ -184,19 +193,7 @@ class PubnubCoreAsync(PubnubBase): ## New Channel? if not channel in self.subscriptions: - if self._channel_list_lock: - with self._channel_list_lock: - self.subscriptions[channel] = { - 'name' : channel, - 'first' : False, - 'connected' : False, - 'subscribed' : True, - 'callback' : callback, - 'connect' : connect, - 'disconnect' : disconnect, - 'reconnect' : reconnect - } - else: + with self._channel_list_lock: self.subscriptions[channel] = { 'name' : channel, 'first' : False, @@ -205,9 +202,11 @@ class PubnubCoreAsync(PubnubBase): 'callback' : callback, 'connect' : connect, 'disconnect' : disconnect, - 'reconnect' : reconnect + 'reconnect' : reconnect, + 'error' : error } + ## return if already connected to channel if channel in self.subscriptions and 'connected' in self.subscriptions[channel] and self.subscriptions[channel]['connected'] is True: _invoke(error, "Already Connected") @@ -222,8 +221,11 @@ class PubnubCoreAsync(PubnubBase): def sub_callback(response): ## ERROR ? - if not response or error in response: - _invoke_error() + #print response + if not response or ('message' in response and response['message'] == 'Forbidden'): + _invoke_error(response['payload']['channels'], response['message']) + _connect() + return _invoke_connect() @@ -250,7 +252,6 @@ class PubnubCoreAsync(PubnubBase): _connect() - channel_list = self.get_channel_list(self.subscriptions) ## CONNECT TO PUBNUB SUBSCRIBE SERVERS try: @@ -260,9 +261,9 @@ class PubnubCoreAsync(PubnubBase): channel_list, '0', str(self.timetoken) - ], "urlparams" : {"uuid":self.uuid} }, sub_callback, single=True ) + ], "urlparams" : {"uuid":self.uuid, "auth" : self.auth_key} }, sub_callback, sub_callback, single=True ) except Exception as e: - print e + print(e) self.timeout( 1, _connect) return @@ -283,14 +284,18 @@ class PubnubCoreAsync(PubnubBase): def unsubscribe( self, args ): - #print(args['channel']) - channel = str(args['channel']) - if not (channel in self.subscriptions): + + if 'channel' in self.subscriptions is False: return False + channel = str(args['channel']) + + ## DISCONNECT - self.subscriptions[channel]['connected'] = 0 - self.subscriptions[channel]['subscribed'] = False - self.subscriptions[channel]['timetoken'] = 0 - self.subscriptions[channel]['first'] = False + with self._channel_list_lock: + if channel in self.subscriptions: + self.subscriptions[channel]['connected'] = 0 + self.subscriptions[channel]['subscribed'] = False + self.subscriptions[channel]['timetoken'] = 0 + self.subscriptions[channel]['first'] = False self.CONNECT() diff --git a/python-tornado/Pubnub.py b/python-tornado/Pubnub.py index 61f7c3d..ccff021 100644 --- a/python-tornado/Pubnub.py +++ b/python-tornado/Pubnub.py @@ -176,12 +176,13 @@ import time import hashlib import uuid import sys -from urllib import quote + +try: from urllib.parse import quote +except: from urllib2 import quote from base64 import urlsafe_b64encode from hashlib import sha256 -from urllib import quote -from urllib import urlopen + import hmac @@ -233,12 +234,11 @@ class PubnubBase(object): self.uuid = UUID or str(uuid.uuid4()) if type(sys.version_info) is tuple: - self.python_version = 2 - self.pc = PubnubCrypto2() + self.python_version = 2 + self.pc = PubnubCrypto2() else: self.python_version = 3 self.pc = PubnubCrypto3() - if not isinstance(self.uuid, str): raise AttributeError("pres_uuid must be a string") @@ -357,7 +357,10 @@ class PubnubBase(object): if (callback != None): callback({'message' : response['message'], 'payload' : response['payload']}) else: if (callback != None):callback(response) - if (callback != None): return _new_format_callback + if (callback != None): + return _new_format_callback + else: + return None def publish( self, args ) : @@ -392,23 +395,28 @@ class PubnubBase(object): if 'callback' in args : callback = args['callback'] else : - callback = None + callback = None + + if 'error' in args : + error = args['error'] + else : + error = None - #message = json.dumps(args['message'], separators=(',',':')) message = self.encrypt(args['message']) - signature = self.sign(channel, message) + #signature = self.sign(channel, message) ## Send Message return self._request({"urlcomponents": [ 'publish', self.publish_key, self.subscribe_key, - signature, + '0', channel, '0', message - ], 'urlparams' : {'auth' : self.auth_key}}, self._return_wrapped_callback(callback)) + ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) def presence( self, args ) : """ @@ -472,12 +480,10 @@ class PubnubBase(object): """ channel = str(args['channel']) - ## Capture Callback - if 'callback' in args : - callback = args['callback'] - else : - callback = None - + + callback = args['callback'] if 'callback' in args else None + error = args['error'] if 'error' in args else None + ## Fail if bad input. if not channel : raise Exception('Missing Channel') @@ -488,59 +494,16 @@ class PubnubBase(object): 'v2','presence', 'sub_key', self.subscribe_key, 'channel', channel - ]}, callback); - - - def history( self, args ) : + ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) + + 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 = 'limit' in args 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 'callback' in args : - 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. #* @@ -556,34 +519,21 @@ class PubnubBase(object): ## Capture User Input channel = str(args['channel']) - params = dict() - count = 100 - - if 'count' in args: - count = int(args['count']) - - params['count'] = str(count) - - if 'reverse' in args: - params['reverse'] = str(args['reverse']).lower() + callback = args['callback'] if 'callback' in args else None + error = args['error'] if 'error' in args else None - if 'start' in args: - params['start'] = str(args['start']) + params = dict() - if 'end' in args: - params['end'] = str(args['end']) + params['count'] = str(args['count']) if 'count' in args else 100 + params['reverse'] = str(args['reverse']).lower() if 'reverse' in args else 'false' + params['start'] = str(args['start']) if 'start' in args else None + params['end'] = str(args['end']) if 'end' in args else None ## Fail if bad input. if not channel : raise Exception('Missing Channel') return False - ## Capture Callback - if 'callback' in args : - callback = args['callback'] - else : - callback = None - ## Get History return self._request({ 'urlcomponents' : [ 'v2', @@ -592,7 +542,8 @@ class PubnubBase(object): self.subscribe_key, 'channel', channel, - ],'urlparams' : params }, callback=callback); + ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) def time(self, args = None) : """ @@ -610,10 +561,9 @@ class PubnubBase(object): """ ## Capture Callback - if args and 'callback' in args: - callback = args['callback'] - else : - callback = None + + callback = callback if args and 'callback' in args else None + time = self._request({'urlcomponents' : [ 'time', '0' @@ -637,7 +587,8 @@ class PubnubBase(object): ch for ch in list(bit) ]) for bit in request["urlcomponents"]]) if ("urlparams" in request): - url = url + '?' + "&".join([ x + "=" + str(y) for x,y in request["urlparams"].items()]) + url = url + '?' + "&".join([ x + "=" + str(y) for x,y in request["urlparams"].items() if y is not None]) + #print(url) return url @@ -648,9 +599,14 @@ except ImportError: import Crypto.Hash.SHA256 as digestmod sha256 = digestmod.new import hmac -import threading -from threading import current_thread -import threading + +class EmptyLock(): + def __enter__(self): + pass + def __exit__(self,a,b,c): + pass + +empty_lock = EmptyLock() class PubnubCoreAsync(PubnubBase): @@ -666,7 +622,9 @@ class PubnubCoreAsync(PubnubBase): auth_key = None, ssl_on = False, origin = 'pubsub.pubnub.com', - uuid = None + uuid = None, + _tt_lock=empty_lock, + _channel_list_lock=empty_lock ) : """ #** @@ -696,29 +654,20 @@ class PubnubCoreAsync(PubnubBase): UUID=uuid ) - self.subscriptions = {} - self.timetoken = 0 - self.last_timetoken = 0 - self.version = '3.3.4' - self.accept_encoding = 'gzip' - self.SUB_RECEIVER = None - self._connect = None - self._tt_lock = threading.RLock() + self.subscriptions = {} + self.timetoken = 0 + self.last_timetoken = 0 + self.version = '3.3.4' + self.accept_encoding = 'gzip' + self.SUB_RECEIVER = None + self._connect = None + self._tt_lock = _tt_lock + self._channel_list_lock = _channel_list_lock def get_channel_list(self, channels): channel = '' first = True - if self._channel_list_lock: - with self._channel_list_lock: - for ch in channels: - if not channels[ch]['subscribed']: - continue - if not first: - channel += ',' - else: - first = False - channel += ch - else: + with self._channel_list_lock: for ch in channels: if not channels[ch]['subscribed']: continue @@ -727,9 +676,15 @@ class PubnubCoreAsync(PubnubBase): else: first = False channel += ch - return channel + + def each(l, func): + if func is None: + return + for i in l: + func(i) + def subscribe( self, args=None, sync=False ) : """ #** @@ -765,12 +720,12 @@ class PubnubCoreAsync(PubnubBase): if args is None: _invoke(error, "Arguments Missing") return - channel = args['channel'] if 'channel' in args else None - callback = args['callback'] if 'callback' in args else None - connect = args['connect'] if 'connect' in args else None - disconnect = args['disconnect'] if 'disconnect' in args else None - reconnect = args['reconnect'] if 'reconnect' in args else None - error = args['error'] if 'error' in args else None + channel = args['channel'] if 'channel' in args else None + callback = args['callback'] if 'callback' in args else None + connect = args['connect'] if 'connect' in args else None + disconnect = args['disconnect'] if 'disconnect' in args else None + reconnect = args['reconnect'] if 'reconnect' in args else None + error = args['error'] if 'error' in args else None with self._tt_lock: self.last_timetoken = self.timetoken if self.timetoken != 0 else self.last_timetoken @@ -803,10 +758,15 @@ class PubnubCoreAsync(PubnubBase): chobj['connected'] = True _invoke(chobj['connect'],chobj['name']) - def _invoke_error(err=None): - for ch in self.subscriptions: - chobj = self.subscriptions[ch] - _invoke(chobj.error,err) + def _invoke_error(channel_list=None, err=None): + if channel_list is None: + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + _invoke(chobj['error'],err) + else: + for ch in channel_list: + chobj = self.subscriptions[ch] + _invoke(chobj['error'],err) ''' if callback is None: @@ -827,19 +787,7 @@ class PubnubCoreAsync(PubnubBase): ## New Channel? if not channel in self.subscriptions: - if self._channel_list_lock: - with self._channel_list_lock: - self.subscriptions[channel] = { - 'name' : channel, - 'first' : False, - 'connected' : False, - 'subscribed' : True, - 'callback' : callback, - 'connect' : connect, - 'disconnect' : disconnect, - 'reconnect' : reconnect - } - else: + with self._channel_list_lock: self.subscriptions[channel] = { 'name' : channel, 'first' : False, @@ -848,9 +796,11 @@ class PubnubCoreAsync(PubnubBase): 'callback' : callback, 'connect' : connect, 'disconnect' : disconnect, - 'reconnect' : reconnect + 'reconnect' : reconnect, + 'error' : error } + ## return if already connected to channel if channel in self.subscriptions and 'connected' in self.subscriptions[channel] and self.subscriptions[channel]['connected'] is True: _invoke(error, "Already Connected") @@ -865,8 +815,11 @@ class PubnubCoreAsync(PubnubBase): def sub_callback(response): ## ERROR ? - if not response or error in response: - _invoke_error() + #print response + if not response or ('message' in response and response['message'] == 'Forbidden'): + _invoke_error(response['payload']['channels'], response['message']) + _connect() + return _invoke_connect() @@ -893,7 +846,6 @@ class PubnubCoreAsync(PubnubBase): _connect() - channel_list = self.get_channel_list(self.subscriptions) ## CONNECT TO PUBNUB SUBSCRIBE SERVERS try: @@ -903,9 +855,9 @@ class PubnubCoreAsync(PubnubBase): channel_list, '0', str(self.timetoken) - ], "urlparams" : {"uuid":self.uuid} }, sub_callback, single=True ) + ], "urlparams" : {"uuid":self.uuid, "auth" : self.auth_key} }, sub_callback, sub_callback, single=True ) except Exception as e: - print e + print(e) self.timeout( 1, _connect) return @@ -926,16 +878,20 @@ class PubnubCoreAsync(PubnubBase): def unsubscribe( self, args ): - #print(args['channel']) - channel = str(args['channel']) - if not (channel in self.subscriptions): + + if 'channel' in self.subscriptions is False: return False + channel = str(args['channel']) + + ## DISCONNECT - self.subscriptions[channel]['connected'] = 0 - self.subscriptions[channel]['subscribed'] = False - self.subscriptions[channel]['timetoken'] = 0 - self.subscriptions[channel]['first'] = False + with self._channel_list_lock: + if channel in self.subscriptions: + self.subscriptions[channel]['connected'] = 0 + self.subscriptions[channel]['subscribed'] = False + self.subscriptions[channel]['timetoken'] = 0 + self.subscriptions[channel]['first'] = False self.CONNECT() @@ -984,9 +940,13 @@ class Pubnub(PubnubCoreAsync): self.headers['V'] = self.version self.http = tornado.httpclient.AsyncHTTPClient(max_clients=1000) self.id = None - self._channel_list_lock = None + + def _request( self, request, callback=None, error=None, single=False ) : + + def _invoke(func, data): + if func is not None: + func(data) - def _request( self, request, callback, single=False ) : url = self.getUrl(request) request = tornado.httpclient.HTTPRequest( url, 'GET', self.headers, connect_timeout=10, request_timeout=310 ) if single is True: @@ -997,18 +957,30 @@ class Pubnub(PubnubCoreAsync): if single is True: if not id == self.id: return None - + body = response._get_body() + if body is None: return - + #print(body) 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())) + return + try: + data = json.loads(body) + except TypeError as e: + try: + data = json.loads(body.decode("utf-8")) + except: + _invoke(error, {'error' : 'json decode error'}) + + if 'error' in data and 'status' in data and 'status' != 200: + _invoke(error, data) + else: + _invoke(callback, data) self.http.fetch( request=request, diff --git a/python-tornado/examples/publish-example.py b/python-tornado/examples/publish-example.py index b9eaa15..bb8b199 100644 --- a/python-tornado/examples/publish-example.py +++ b/python-tornado/examples/publish-example.py @@ -10,54 +10,59 @@ ## ----------------------------------- import sys -import tornado +from twisted.internet import reactor sys.path.append('../') -sys.path.append('../..') -sys.path.append('../../common') +sys.path.append('../../') from Pubnub import Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len(sys.argv) > 4 and sys.argv[4] or 'demo' ##(Cipher key is Optional) +cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' ##(Cipher key is Optional) ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- ## Initiate Pubnub State ## ----------------------------------------------------------------------- -pubnub = Pubnub( publish_key=publish_key, subscribe_key=subscribe_key, secret_key=secret_key,cipher_key=cipher_key, ssl_on=ssl_on ) -#pubnub = Pubnub( publish_key, subscribe_key, secret_key, ssl_on ) +pubnub = Pubnub( publish_key, subscribe_key, secret_key, cipher_key, ssl_on ) crazy = 'hello_world' +## ----------------------------------------------------------------------- +## Publish Example +## ----------------------------------------------------------------------- def publish_complete(info): print(info) +def publish_error(info): + print('ERROR : ' + str(info)) + ## Publish string pubnub.publish({ 'channel' : crazy, 'message' : 'Hello World!', - 'callback' : publish_complete + 'callback' : publish_complete, + 'error' : publish_error }) ## Publish list li = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] + pubnub.publish({ 'channel' : crazy, 'message' : li, - 'callback' : publish_complete + 'callback' : publish_complete, + 'error' : publish_error }) def done_cb(info): publish_complete(info) - tornado.ioloop.IOLoop.instance().stop() -## Publish Dictionary Object pubnub.publish({ 'channel' : crazy, 'message' : { 'some_key' : 'some_val' }, - 'callback' : done_cb + 'callback' : done_cb, + 'error' : publish_error }) -## ----------------------------------------------------------------------- -## IO Event Loop -## ----------------------------------------------------------------------- -tornado.ioloop.IOLoop.instance().start() + + +pubnub.start() diff --git a/python-tornado/tests/subscribe-test.py b/python-tornado/tests/subscribe-test.py index 0d4c65e..be4a416 100755 --- a/python-tornado/tests/subscribe-test.py +++ b/python-tornado/tests/subscribe-test.py @@ -38,31 +38,31 @@ received = 0 ## Subscribe Example ## ----------------------------------------------------------------------- def message_received(message): - print message + print(message) def check_received(message): global current global errors global received - print message - print current + print(message) + print(current) if message <= current: - print 'ERROR' + print('ERROR') #sys.exit() errors += 1 else: received += 1 - print 'active thread count : ', threading.activeCount() - print 'errors = ' , errors - print current_thread().getName(), ' , ', 'received = ', received + print('active thread count : ' + str( threading.activeCount())) + print('errors = ' + str(errors)) + print(current_thread().getName() + ' , ' + 'received = ' + str(received)) if received != message: - print '********** MISSED **************** ', message - received + print('********** MISSED **************** ' + str( message - received )) current = message def connected_test(ch) : - print 'Connected' , ch + print('Connected ' + ch) def connected(ch) : pass @@ -103,7 +103,6 @@ def subscribe(channel): }) -print threading.activeCount() pubnub.timeout(15,cb1) diff --git a/python-tornado/unassembled/Platform.py b/python-tornado/unassembled/Platform.py index 501993e..5200136 100644 --- a/python-tornado/unassembled/Platform.py +++ b/python-tornado/unassembled/Platform.py @@ -43,9 +43,13 @@ class Pubnub(PubnubCoreAsync): self.headers['V'] = self.version self.http = tornado.httpclient.AsyncHTTPClient(max_clients=1000) self.id = None - self._channel_list_lock = None + + def _request( self, request, callback=None, error=None, single=False ) : + + def _invoke(func, data): + if func is not None: + func(data) - def _request( self, request, callback, single=False ) : url = self.getUrl(request) request = tornado.httpclient.HTTPRequest( url, 'GET', self.headers, connect_timeout=10, request_timeout=310 ) if single is True: @@ -56,18 +60,30 @@ class Pubnub(PubnubCoreAsync): if single is True: if not id == self.id: return None - + body = response._get_body() + if body is None: return - + #print(body) 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())) + return + try: + data = json.loads(body) + except TypeError as e: + try: + data = json.loads(body.decode("utf-8")) + except: + _invoke(error, {'error' : 'json decode error'}) + + if 'error' in data and 'status' in data and 'status' != 200: + _invoke(error, data) + else: + _invoke(callback, data) self.http.fetch( request=request, diff --git a/python-twisted/Pubnub.py b/python-twisted/Pubnub.py index 7171efe..383ee6d 100644 --- a/python-twisted/Pubnub.py +++ b/python-twisted/Pubnub.py @@ -176,12 +176,13 @@ import time import hashlib import uuid import sys -from urllib import quote + +try: from urllib.parse import quote +except: from urllib2 import quote from base64 import urlsafe_b64encode from hashlib import sha256 -from urllib import quote -from urllib import urlopen + import hmac @@ -233,12 +234,11 @@ class PubnubBase(object): self.uuid = UUID or str(uuid.uuid4()) if type(sys.version_info) is tuple: - self.python_version = 2 - self.pc = PubnubCrypto2() + self.python_version = 2 + self.pc = PubnubCrypto2() else: self.python_version = 3 self.pc = PubnubCrypto3() - if not isinstance(self.uuid, str): raise AttributeError("pres_uuid must be a string") @@ -357,7 +357,10 @@ class PubnubBase(object): if (callback != None): callback({'message' : response['message'], 'payload' : response['payload']}) else: if (callback != None):callback(response) - if (callback != None): return _new_format_callback + if (callback != None): + return _new_format_callback + else: + return None def publish( self, args ) : @@ -392,23 +395,28 @@ class PubnubBase(object): if 'callback' in args : callback = args['callback'] else : - callback = None + callback = None + + if 'error' in args : + error = args['error'] + else : + error = None - #message = json.dumps(args['message'], separators=(',',':')) message = self.encrypt(args['message']) - signature = self.sign(channel, message) + #signature = self.sign(channel, message) ## Send Message return self._request({"urlcomponents": [ 'publish', self.publish_key, self.subscribe_key, - signature, + '0', channel, '0', message - ], 'urlparams' : {'auth' : self.auth_key}}, self._return_wrapped_callback(callback)) + ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) def presence( self, args ) : """ @@ -472,12 +480,10 @@ class PubnubBase(object): """ channel = str(args['channel']) - ## Capture Callback - if 'callback' in args : - callback = args['callback'] - else : - callback = None - + + callback = args['callback'] if 'callback' in args else None + error = args['error'] if 'error' in args else None + ## Fail if bad input. if not channel : raise Exception('Missing Channel') @@ -488,59 +494,16 @@ class PubnubBase(object): 'v2','presence', 'sub_key', self.subscribe_key, 'channel', channel - ]}, callback); - - - def history( self, args ) : + ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) + + 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 = 'limit' in args 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 'callback' in args : - 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. #* @@ -556,34 +519,21 @@ class PubnubBase(object): ## Capture User Input channel = str(args['channel']) - params = dict() - count = 100 - - if 'count' in args: - count = int(args['count']) - - params['count'] = str(count) - - if 'reverse' in args: - params['reverse'] = str(args['reverse']).lower() + callback = args['callback'] if 'callback' in args else None + error = args['error'] if 'error' in args else None - if 'start' in args: - params['start'] = str(args['start']) + params = dict() - if 'end' in args: - params['end'] = str(args['end']) + params['count'] = str(args['count']) if 'count' in args else 100 + params['reverse'] = str(args['reverse']).lower() if 'reverse' in args else 'false' + params['start'] = str(args['start']) if 'start' in args else None + params['end'] = str(args['end']) if 'end' in args else None ## Fail if bad input. if not channel : raise Exception('Missing Channel') return False - ## Capture Callback - if 'callback' in args : - callback = args['callback'] - else : - callback = None - ## Get History return self._request({ 'urlcomponents' : [ 'v2', @@ -592,7 +542,8 @@ class PubnubBase(object): self.subscribe_key, 'channel', channel, - ],'urlparams' : params }, callback=callback); + ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) def time(self, args = None) : """ @@ -610,10 +561,9 @@ class PubnubBase(object): """ ## Capture Callback - if args and 'callback' in args: - callback = args['callback'] - else : - callback = None + + callback = callback if args and 'callback' in args else None + time = self._request({'urlcomponents' : [ 'time', '0' @@ -637,7 +587,8 @@ class PubnubBase(object): ch for ch in list(bit) ]) for bit in request["urlcomponents"]]) if ("urlparams" in request): - url = url + '?' + "&".join([ x + "=" + str(y) for x,y in request["urlparams"].items()]) + url = url + '?' + "&".join([ x + "=" + str(y) for x,y in request["urlparams"].items() if y is not None]) + #print(url) return url @@ -648,9 +599,14 @@ except ImportError: import Crypto.Hash.SHA256 as digestmod sha256 = digestmod.new import hmac -import threading -from threading import current_thread -import threading + +class EmptyLock(): + def __enter__(self): + pass + def __exit__(self,a,b,c): + pass + +empty_lock = EmptyLock() class PubnubCoreAsync(PubnubBase): @@ -666,7 +622,9 @@ class PubnubCoreAsync(PubnubBase): auth_key = None, ssl_on = False, origin = 'pubsub.pubnub.com', - uuid = None + uuid = None, + _tt_lock=empty_lock, + _channel_list_lock=empty_lock ) : """ #** @@ -696,29 +654,20 @@ class PubnubCoreAsync(PubnubBase): UUID=uuid ) - self.subscriptions = {} - self.timetoken = 0 - self.last_timetoken = 0 - self.version = '3.3.4' - self.accept_encoding = 'gzip' - self.SUB_RECEIVER = None - self._connect = None - self._tt_lock = threading.RLock() + self.subscriptions = {} + self.timetoken = 0 + self.last_timetoken = 0 + self.version = '3.3.4' + self.accept_encoding = 'gzip' + self.SUB_RECEIVER = None + self._connect = None + self._tt_lock = _tt_lock + self._channel_list_lock = _channel_list_lock def get_channel_list(self, channels): channel = '' first = True - if self._channel_list_lock: - with self._channel_list_lock: - for ch in channels: - if not channels[ch]['subscribed']: - continue - if not first: - channel += ',' - else: - first = False - channel += ch - else: + with self._channel_list_lock: for ch in channels: if not channels[ch]['subscribed']: continue @@ -727,9 +676,15 @@ class PubnubCoreAsync(PubnubBase): else: first = False channel += ch - return channel + + def each(l, func): + if func is None: + return + for i in l: + func(i) + def subscribe( self, args=None, sync=False ) : """ #** @@ -765,12 +720,12 @@ class PubnubCoreAsync(PubnubBase): if args is None: _invoke(error, "Arguments Missing") return - channel = args['channel'] if 'channel' in args else None - callback = args['callback'] if 'callback' in args else None - connect = args['connect'] if 'connect' in args else None - disconnect = args['disconnect'] if 'disconnect' in args else None - reconnect = args['reconnect'] if 'reconnect' in args else None - error = args['error'] if 'error' in args else None + channel = args['channel'] if 'channel' in args else None + callback = args['callback'] if 'callback' in args else None + connect = args['connect'] if 'connect' in args else None + disconnect = args['disconnect'] if 'disconnect' in args else None + reconnect = args['reconnect'] if 'reconnect' in args else None + error = args['error'] if 'error' in args else None with self._tt_lock: self.last_timetoken = self.timetoken if self.timetoken != 0 else self.last_timetoken @@ -803,10 +758,15 @@ class PubnubCoreAsync(PubnubBase): chobj['connected'] = True _invoke(chobj['connect'],chobj['name']) - def _invoke_error(err=None): - for ch in self.subscriptions: - chobj = self.subscriptions[ch] - _invoke(chobj.error,err) + def _invoke_error(channel_list=None, err=None): + if channel_list is None: + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + _invoke(chobj['error'],err) + else: + for ch in channel_list: + chobj = self.subscriptions[ch] + _invoke(chobj['error'],err) ''' if callback is None: @@ -827,19 +787,7 @@ class PubnubCoreAsync(PubnubBase): ## New Channel? if not channel in self.subscriptions: - if self._channel_list_lock: - with self._channel_list_lock: - self.subscriptions[channel] = { - 'name' : channel, - 'first' : False, - 'connected' : False, - 'subscribed' : True, - 'callback' : callback, - 'connect' : connect, - 'disconnect' : disconnect, - 'reconnect' : reconnect - } - else: + with self._channel_list_lock: self.subscriptions[channel] = { 'name' : channel, 'first' : False, @@ -848,9 +796,11 @@ class PubnubCoreAsync(PubnubBase): 'callback' : callback, 'connect' : connect, 'disconnect' : disconnect, - 'reconnect' : reconnect + 'reconnect' : reconnect, + 'error' : error } + ## return if already connected to channel if channel in self.subscriptions and 'connected' in self.subscriptions[channel] and self.subscriptions[channel]['connected'] is True: _invoke(error, "Already Connected") @@ -865,8 +815,11 @@ class PubnubCoreAsync(PubnubBase): def sub_callback(response): ## ERROR ? - if not response or error in response: - _invoke_error() + #print response + if not response or ('message' in response and response['message'] == 'Forbidden'): + _invoke_error(response['payload']['channels'], response['message']) + _connect() + return _invoke_connect() @@ -893,7 +846,6 @@ class PubnubCoreAsync(PubnubBase): _connect() - channel_list = self.get_channel_list(self.subscriptions) ## CONNECT TO PUBNUB SUBSCRIBE SERVERS try: @@ -903,9 +855,9 @@ class PubnubCoreAsync(PubnubBase): channel_list, '0', str(self.timetoken) - ], "urlparams" : {"uuid":self.uuid} }, sub_callback, single=True ) + ], "urlparams" : {"uuid":self.uuid, "auth" : self.auth_key} }, sub_callback, sub_callback, single=True ) except Exception as e: - print e + print(e) self.timeout( 1, _connect) return @@ -926,16 +878,20 @@ class PubnubCoreAsync(PubnubBase): def unsubscribe( self, args ): - #print(args['channel']) - channel = str(args['channel']) - if not (channel in self.subscriptions): + + if 'channel' in self.subscriptions is False: return False + channel = str(args['channel']) + + ## DISCONNECT - self.subscriptions[channel]['connected'] = 0 - self.subscriptions[channel]['subscribed'] = False - self.subscriptions[channel]['timetoken'] = 0 - self.subscriptions[channel]['first'] = False + with self._channel_list_lock: + if channel in self.subscriptions: + self.subscriptions[channel]['connected'] = 0 + self.subscriptions[channel]['subscribed'] = False + self.subscriptions[channel]['timetoken'] = 0 + self.subscriptions[channel]['first'] = False self.CONNECT() @@ -951,6 +907,9 @@ from twisted.internet.task import LoopingCall import twisted from hashlib import sha256 import time +import json +from twisted.python.compat import ( + _PY3, unicode, intToBytes, networkString, nativeString) pnconn_pool = HTTPConnectionPool(reactor, persistent=True) pnconn_pool.maxPersistentPerHost = 100000 @@ -968,8 +927,9 @@ class Pubnub(PubnubCoreAsync): self, publish_key, subscribe_key, - secret_key = False, - cipher_key = False, + secret_key=False, + cipher_key=False, + auth_key=None, ssl_on = False, origin = 'pubsub.pubnub.com' ) : @@ -978,6 +938,7 @@ class Pubnub(PubnubCoreAsync): subscribe_key=subscribe_key, secret_key=secret_key, cipher_key=cipher_key, + auth_key=auth_key, ssl_on=ssl_on, origin=origin, ) @@ -985,11 +946,14 @@ class Pubnub(PubnubCoreAsync): self.headers['User-Agent'] = ['Python-Twisted'] #self.headers['Accept-Encoding'] = [self.accept_encoding] self.headers['V'] = [self.version] - self._channel_list_lock = None - def _request( self, request, callback, single=False ) : + def _request( self, request, callback=None, error=None, single=False ) : global pnconn_pool + def _invoke(func, data): + if func is not None: + func(data) + ## Build URL ''' url = self.origin + '/' + "/".join([ @@ -1006,7 +970,12 @@ class Pubnub(PubnubCoreAsync): pool = self.ssl and None or pnconn_pool )), [('gzip', GzipDecoder)]) - request = agent.request( 'GET', url, Headers(self.headers), None ) + try: + request = agent.request( 'GET', url, Headers(self.headers), None ) + except TypeError as te: + print(url.encode()) + request = agent.request( 'GET', url.encode(), Headers(self.headers), None ) + if single is True: id = time.time() @@ -1014,35 +983,65 @@ class Pubnub(PubnubCoreAsync): def received(response): finished = Deferred() - response.deliverBody(PubNubResponse(finished)) + if response.code == 403: + response.deliverBody(PubNub403Response(finished)) + else: + response.deliverBody(PubNubResponse(finished)) + + return finished + + def error_handler(response): + finished = Deferred() + if response.code == 403: + response.deliverBody(PubNub403Response(finished)) + else: + response.deliverBody(PubNubResponse(finished)) + return finished def complete(data): if single is True: - if not id == self.id: + if id != self.id: return None try: - callback(eval(data)) + data = json.loads(data) except Exception as e: - pass - #need error handling here + try: + data = json.loads(data.decode("utf-8")) + except: + _invoke(error, {'error' : 'json decode error'}) + + if 'error' in data and 'status' in data and 'status' != 200: + _invoke(error, data) + else: + _invoke(callback, data) def abort(): pass request.addCallback(received) - request.addBoth(complete) + request.addCallback(complete) + request.addErrback(error_handler) return abort class WebClientContextFactory(ClientContextFactory): def getContext(self, hostname, port): return ClientContextFactory.getContext(self) + +class PubNub403Response(Protocol): + def __init__( self, finished ): + self.finished = finished + + def dataReceived( self, bytes ): + #print '403 resp ', bytes + self.finished.callback(bytes) class PubNubResponse(Protocol): def __init__( self, finished ): self.finished = finished def dataReceived( self, bytes ): - self.finished.callback(bytes) + #print bytes + self.finished.callback(bytes) diff --git a/python-twisted/examples/publish-example.py b/python-twisted/examples/publish-example.py index d09ad8d..d15b21b 100644 --- a/python-twisted/examples/publish-example.py +++ b/python-twisted/examples/publish-example.py @@ -19,12 +19,13 @@ publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' ##(Cipher key is Optional) -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False +auth_key = len(sys.argv) > 5 and sys.argv[5] or 'abcd' ##(Cipher key is Optional) +ssl_on = len(sys.argv) > 6 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- ## Initiate Pubnub State ## ----------------------------------------------------------------------- -pubnub = Pubnub( publish_key, subscribe_key, secret_key, cipher_key, ssl_on ) +pubnub = Pubnub( publish_key, subscribe_key, secret_key, cipher_key, auth_key, ssl_on ) crazy = 'hello_world' ## ----------------------------------------------------------------------- @@ -33,32 +34,36 @@ crazy = 'hello_world' def publish_complete(info): print(info) +def publish_error(info): + print('ERROR : ' + str(info)) + ## Publish string pubnub.publish({ 'channel' : crazy, 'message' : 'Hello World!', - 'callback' : publish_complete + 'callback' : publish_complete, + 'error' : publish_error }) ## Publish list li = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] + pubnub.publish({ 'channel' : crazy, 'message' : li, - 'callback' : publish_complete + 'callback' : publish_complete, + 'error' : publish_error }) def done_cb(info): publish_complete(info) - reactor.stop() -## Publish Dictionary Object + pubnub.publish({ 'channel' : crazy, 'message' : { 'some_key' : 'some_val' }, - 'callback' : done_cb + 'callback' : done_cb, + 'error' : publish_error }) -## ----------------------------------------------------------------------- -## IO Event Loop -## ----------------------------------------------------------------------- -reactor.run() + +pubnub.start() diff --git a/python-twisted/unassembled/Platform.py b/python-twisted/unassembled/Platform.py index 5268446..c7fe5cd 100644 --- a/python-twisted/unassembled/Platform.py +++ b/python-twisted/unassembled/Platform.py @@ -10,6 +10,9 @@ from twisted.internet.task import LoopingCall import twisted from hashlib import sha256 import time +import json +from twisted.python.compat import ( + _PY3, unicode, intToBytes, networkString, nativeString) pnconn_pool = HTTPConnectionPool(reactor, persistent=True) pnconn_pool.maxPersistentPerHost = 100000 @@ -27,8 +30,9 @@ class Pubnub(PubnubCoreAsync): self, publish_key, subscribe_key, - secret_key = False, - cipher_key = False, + secret_key=False, + cipher_key=False, + auth_key=None, ssl_on = False, origin = 'pubsub.pubnub.com' ) : @@ -37,6 +41,7 @@ class Pubnub(PubnubCoreAsync): subscribe_key=subscribe_key, secret_key=secret_key, cipher_key=cipher_key, + auth_key=auth_key, ssl_on=ssl_on, origin=origin, ) @@ -44,11 +49,14 @@ class Pubnub(PubnubCoreAsync): self.headers['User-Agent'] = ['Python-Twisted'] #self.headers['Accept-Encoding'] = [self.accept_encoding] self.headers['V'] = [self.version] - self._channel_list_lock = None - def _request( self, request, callback, single=False ) : + def _request( self, request, callback=None, error=None, single=False ) : global pnconn_pool + def _invoke(func, data): + if func is not None: + func(data) + ## Build URL ''' url = self.origin + '/' + "/".join([ @@ -65,7 +73,12 @@ class Pubnub(PubnubCoreAsync): pool = self.ssl and None or pnconn_pool )), [('gzip', GzipDecoder)]) - request = agent.request( 'GET', url, Headers(self.headers), None ) + try: + request = agent.request( 'GET', url, Headers(self.headers), None ) + except TypeError as te: + print(url.encode()) + request = agent.request( 'GET', url.encode(), Headers(self.headers), None ) + if single is True: id = time.time() @@ -73,35 +86,65 @@ class Pubnub(PubnubCoreAsync): def received(response): finished = Deferred() - response.deliverBody(PubNubResponse(finished)) + if response.code == 403: + response.deliverBody(PubNub403Response(finished)) + else: + response.deliverBody(PubNubResponse(finished)) + + return finished + + def error_handler(response): + finished = Deferred() + if response.code == 403: + response.deliverBody(PubNub403Response(finished)) + else: + response.deliverBody(PubNubResponse(finished)) + return finished def complete(data): if single is True: - if not id == self.id: + if id != self.id: return None try: - callback(eval(data)) + data = json.loads(data) except Exception as e: - pass - #need error handling here + try: + data = json.loads(data.decode("utf-8")) + except: + _invoke(error, {'error' : 'json decode error'}) + + if 'error' in data and 'status' in data and 'status' != 200: + _invoke(error, data) + else: + _invoke(callback, data) def abort(): pass request.addCallback(received) - request.addBoth(complete) + request.addCallback(complete) + request.addErrback(error_handler) return abort class WebClientContextFactory(ClientContextFactory): def getContext(self, hostname, port): return ClientContextFactory.getContext(self) + +class PubNub403Response(Protocol): + def __init__( self, finished ): + self.finished = finished + + def dataReceived( self, bytes ): + #print '403 resp ', bytes + self.finished.callback(bytes) class PubNubResponse(Protocol): def __init__( self, finished ): self.finished = finished def dataReceived( self, bytes ): - self.finished.callback(bytes) + #print bytes + self.finished.callback(bytes) diff --git a/python/Pubnub.py b/python/Pubnub.py index f3c518c..95eafd0 100644 --- a/python/Pubnub.py +++ b/python/Pubnub.py @@ -176,12 +176,13 @@ import time import hashlib import uuid import sys -from urllib import quote + +try: from urllib.parse import quote +except: from urllib2 import quote from base64 import urlsafe_b64encode from hashlib import sha256 -from urllib import quote -from urllib import urlopen + import hmac @@ -233,12 +234,11 @@ class PubnubBase(object): self.uuid = UUID or str(uuid.uuid4()) if type(sys.version_info) is tuple: - self.python_version = 2 - self.pc = PubnubCrypto2() + self.python_version = 2 + self.pc = PubnubCrypto2() else: self.python_version = 3 self.pc = PubnubCrypto3() - if not isinstance(self.uuid, str): raise AttributeError("pres_uuid must be a string") @@ -357,7 +357,10 @@ class PubnubBase(object): if (callback != None): callback({'message' : response['message'], 'payload' : response['payload']}) else: if (callback != None):callback(response) - if (callback != None): return _new_format_callback + if (callback != None): + return _new_format_callback + else: + return None def publish( self, args ) : @@ -392,23 +395,28 @@ class PubnubBase(object): if 'callback' in args : callback = args['callback'] else : - callback = None + callback = None + + if 'error' in args : + error = args['error'] + else : + error = None - #message = json.dumps(args['message'], separators=(',',':')) message = self.encrypt(args['message']) - signature = self.sign(channel, message) + #signature = self.sign(channel, message) ## Send Message return self._request({"urlcomponents": [ 'publish', self.publish_key, self.subscribe_key, - signature, + '0', channel, '0', message - ], 'urlparams' : {'auth' : self.auth_key}}, self._return_wrapped_callback(callback)) + ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) def presence( self, args ) : """ @@ -472,12 +480,10 @@ class PubnubBase(object): """ channel = str(args['channel']) - ## Capture Callback - if 'callback' in args : - callback = args['callback'] - else : - callback = None - + + callback = args['callback'] if 'callback' in args else None + error = args['error'] if 'error' in args else None + ## Fail if bad input. if not channel : raise Exception('Missing Channel') @@ -488,59 +494,16 @@ class PubnubBase(object): 'v2','presence', 'sub_key', self.subscribe_key, 'channel', channel - ]}, callback); - - - def history( self, args ) : + ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) + + 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 = 'limit' in args 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 'callback' in args : - 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. #* @@ -556,34 +519,21 @@ class PubnubBase(object): ## Capture User Input channel = str(args['channel']) - params = dict() - count = 100 - - if 'count' in args: - count = int(args['count']) + callback = args['callback'] if 'callback' in args else None + error = args['error'] if 'error' in args else None - params['count'] = str(count) - - if 'reverse' in args: - params['reverse'] = str(args['reverse']).lower() - - if 'start' in args: - params['start'] = str(args['start']) + params = dict() - if 'end' in args: - params['end'] = str(args['end']) + params['count'] = str(args['count']) if 'count' in args else 100 + params['reverse'] = str(args['reverse']).lower() if 'reverse' in args else 'false' + params['start'] = str(args['start']) if 'start' in args else None + params['end'] = str(args['end']) if 'end' in args else None ## Fail if bad input. if not channel : raise Exception('Missing Channel') return False - ## Capture Callback - if 'callback' in args : - callback = args['callback'] - else : - callback = None - ## Get History return self._request({ 'urlcomponents' : [ 'v2', @@ -592,7 +542,8 @@ class PubnubBase(object): self.subscribe_key, 'channel', channel, - ],'urlparams' : params }, callback=callback); + ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) def time(self, args = None) : """ @@ -610,10 +561,9 @@ class PubnubBase(object): """ ## Capture Callback - if args and 'callback' in args: - callback = args['callback'] - else : - callback = None + + callback = callback if args and 'callback' in args else None + time = self._request({'urlcomponents' : [ 'time', '0' @@ -637,7 +587,8 @@ class PubnubBase(object): ch for ch in list(bit) ]) for bit in request["urlcomponents"]]) if ("urlparams" in request): - url = url + '?' + "&".join([ x + "=" + str(y) for x,y in request["urlparams"].items()]) + url = url + '?' + "&".join([ x + "=" + str(y) for x,y in request["urlparams"].items() if y is not None]) + #print(url) return url @@ -648,9 +599,14 @@ except ImportError: import Crypto.Hash.SHA256 as digestmod sha256 = digestmod.new import hmac -import threading -from threading import current_thread -import threading + +class EmptyLock(): + def __enter__(self): + pass + def __exit__(self,a,b,c): + pass + +empty_lock = EmptyLock() class PubnubCoreAsync(PubnubBase): @@ -666,7 +622,9 @@ class PubnubCoreAsync(PubnubBase): auth_key = None, ssl_on = False, origin = 'pubsub.pubnub.com', - uuid = None + uuid = None, + _tt_lock=empty_lock, + _channel_list_lock=empty_lock ) : """ #** @@ -696,29 +654,20 @@ class PubnubCoreAsync(PubnubBase): UUID=uuid ) - self.subscriptions = {} - self.timetoken = 0 - self.last_timetoken = 0 - self.version = '3.3.4' - self.accept_encoding = 'gzip' - self.SUB_RECEIVER = None - self._connect = None - self._tt_lock = threading.RLock() + self.subscriptions = {} + self.timetoken = 0 + self.last_timetoken = 0 + self.version = '3.3.4' + self.accept_encoding = 'gzip' + self.SUB_RECEIVER = None + self._connect = None + self._tt_lock = _tt_lock + self._channel_list_lock = _channel_list_lock def get_channel_list(self, channels): channel = '' first = True - if self._channel_list_lock: - with self._channel_list_lock: - for ch in channels: - if not channels[ch]['subscribed']: - continue - if not first: - channel += ',' - else: - first = False - channel += ch - else: + with self._channel_list_lock: for ch in channels: if not channels[ch]['subscribed']: continue @@ -727,9 +676,15 @@ class PubnubCoreAsync(PubnubBase): else: first = False channel += ch - return channel + + def each(l, func): + if func is None: + return + for i in l: + func(i) + def subscribe( self, args=None, sync=False ) : """ #** @@ -765,12 +720,12 @@ class PubnubCoreAsync(PubnubBase): if args is None: _invoke(error, "Arguments Missing") return - channel = args['channel'] if 'channel' in args else None - callback = args['callback'] if 'callback' in args else None - connect = args['connect'] if 'connect' in args else None - disconnect = args['disconnect'] if 'disconnect' in args else None - reconnect = args['reconnect'] if 'reconnect' in args else None - error = args['error'] if 'error' in args else None + channel = args['channel'] if 'channel' in args else None + callback = args['callback'] if 'callback' in args else None + connect = args['connect'] if 'connect' in args else None + disconnect = args['disconnect'] if 'disconnect' in args else None + reconnect = args['reconnect'] if 'reconnect' in args else None + error = args['error'] if 'error' in args else None with self._tt_lock: self.last_timetoken = self.timetoken if self.timetoken != 0 else self.last_timetoken @@ -803,10 +758,15 @@ class PubnubCoreAsync(PubnubBase): chobj['connected'] = True _invoke(chobj['connect'],chobj['name']) - def _invoke_error(err=None): - for ch in self.subscriptions: - chobj = self.subscriptions[ch] - _invoke(chobj.error,err) + def _invoke_error(channel_list=None, err=None): + if channel_list is None: + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + _invoke(chobj['error'],err) + else: + for ch in channel_list: + chobj = self.subscriptions[ch] + _invoke(chobj['error'],err) ''' if callback is None: @@ -827,19 +787,7 @@ class PubnubCoreAsync(PubnubBase): ## New Channel? if not channel in self.subscriptions: - if self._channel_list_lock: - with self._channel_list_lock: - self.subscriptions[channel] = { - 'name' : channel, - 'first' : False, - 'connected' : False, - 'subscribed' : True, - 'callback' : callback, - 'connect' : connect, - 'disconnect' : disconnect, - 'reconnect' : reconnect - } - else: + with self._channel_list_lock: self.subscriptions[channel] = { 'name' : channel, 'first' : False, @@ -848,9 +796,11 @@ class PubnubCoreAsync(PubnubBase): 'callback' : callback, 'connect' : connect, 'disconnect' : disconnect, - 'reconnect' : reconnect + 'reconnect' : reconnect, + 'error' : error } + ## return if already connected to channel if channel in self.subscriptions and 'connected' in self.subscriptions[channel] and self.subscriptions[channel]['connected'] is True: _invoke(error, "Already Connected") @@ -865,8 +815,11 @@ class PubnubCoreAsync(PubnubBase): def sub_callback(response): ## ERROR ? - if not response or error in response: - _invoke_error() + #print response + if not response or ('message' in response and response['message'] == 'Forbidden'): + _invoke_error(response['payload']['channels'], response['message']) + _connect() + return _invoke_connect() @@ -893,7 +846,6 @@ class PubnubCoreAsync(PubnubBase): _connect() - channel_list = self.get_channel_list(self.subscriptions) ## CONNECT TO PUBNUB SUBSCRIBE SERVERS try: @@ -903,9 +855,9 @@ class PubnubCoreAsync(PubnubBase): channel_list, '0', str(self.timetoken) - ], "urlparams" : {"uuid":self.uuid} }, sub_callback, single=True ) + ], "urlparams" : {"uuid":self.uuid, "auth" : self.auth_key} }, sub_callback, sub_callback, single=True ) except Exception as e: - print e + print(e) self.timeout( 1, _connect) return @@ -926,16 +878,20 @@ class PubnubCoreAsync(PubnubBase): def unsubscribe( self, args ): - #print(args['channel']) - channel = str(args['channel']) - if not (channel in self.subscriptions): + + if 'channel' in self.subscriptions is False: return False + channel = str(args['channel']) + + ## DISCONNECT - self.subscriptions[channel]['connected'] = 0 - self.subscriptions[channel]['subscribed'] = False - self.subscriptions[channel]['timetoken'] = 0 - self.subscriptions[channel]['first'] = False + with self._channel_list_lock: + if channel in self.subscriptions: + self.subscriptions[channel]['connected'] = 0 + self.subscriptions[channel]['subscribed'] = False + self.subscriptions[channel]['timetoken'] = 0 + self.subscriptions[channel]['first'] = False self.CONNECT() @@ -953,19 +909,43 @@ from threading import current_thread latest_sub_callback_lock = threading.RLock() latest_sub_callback = {'id' : None, 'callback' : None} + + + class HTTPClient: - def __init__(self, url, callback, id=None): + def __init__(self, url, urllib_func=None, callback=None, error=None, id=None): self.url = url self.id = id self.callback = callback + self.error = error self.stop = False + self._urllib_func = urllib_func def cancel(self): self.stop = True self.callback = None + self.error = None + def run(self): - data = urllib2.urlopen(self.url, timeout=310).read() + + def _invoke(func, data): + if func is not None: + func(data) + + if self._urllib_func is None: + return + + ''' + try: + resp = urllib2.urlopen(self.url, timeout=320) + except urllib2.HTTPError as http_error: + resp = http_error + ''' + resp = self._urllib_func(self.url, timeout=320) + data = resp[0] + code = resp[1] + if self.stop is True: return if self.callback is None: @@ -975,14 +955,49 @@ class HTTPClient: if latest_sub_callback['id'] != self.id: return else: - print(data) if latest_sub_callback['callback'] is not None: latest_sub_callback['id'] = 0 - latest_sub_callback['callback'](json.loads(data)) + try: + data = json.loads(data) + except: + _invoke(latest_sub_callback['error'], {'error' : 'json decoding error'}) + return + if code != 200: + _invoke(latest_sub_callback['error'],data) + else: + _invoke(latest_sub_callback['callback'],data) else: - self.callback(json.loads(data)) + try: + data = json.loads(data) + except: + _invoke(self.error, {'error' : 'json decoding error'}) + return + + if code != 200: + _invoke(self.error,data) + else: + _invoke(self.callback,data) +def _urllib_request_2(url, timeout=320): + try: + resp = urllib2.urlopen(url,timeout=timeout) + except urllib2.HTTPError as http_error: + resp = http_error + return (resp.read(),resp.code) + +def _urllib_request_3(url, timeout=320): + #print(url) + try: + resp = urllib.request.urlopen(url,timeout=timeout) + except urllib.request.HTTPError as http_error: + resp = http_error + r = resp.read().decode("utf-8") + #print(r) + return (r,resp.code) + +_urllib_request = None + class Pubnub(PubnubCoreAsync): def __init__( self, @@ -1003,13 +1018,15 @@ class Pubnub(PubnubCoreAsync): auth_key = auth_key, ssl_on = ssl_on, origin = origin, - uuid = pres_uuid + uuid = pres_uuid, + _tt_lock=threading.RLock(), + _channel_list_lock=threading.RLock() ) + global _urllib_request if self.python_version == 2: - self._request = self._request2 + _urllib_request = _urllib_request_2 else: - self._request = self._request3 - self._channel_list_lock = threading.RLock() + _urllib_request = _urllib_request_3 def timeout(self, interval, func): def cb(): @@ -1018,17 +1035,20 @@ class Pubnub(PubnubCoreAsync): thread = threading.Thread(target=cb) thread.start() - def _request2_async( self, request, callback, single=False ) : + + def _request_async( self, request, callback=None, error=None, single=False ) : + global _urllib_request ## Build URL url = self.getUrl(request) if single is True: id = time.time() - client = HTTPClient(url, None, id) + client = HTTPClient(url=url, urllib_func=_urllib_request, callback=None, error=None, id=id) with latest_sub_callback_lock: latest_sub_callback['id'] = id latest_sub_callback['callback'] = callback + latest_sub_callback['error'] = error else: - client = HTTPClient(url, callback) + client = HTTPClient(url=url, urllib_func=_urllib_request, callback=callback, error=error) thread = threading.Thread(target=client.run) thread.start() @@ -1037,31 +1057,30 @@ class Pubnub(PubnubCoreAsync): return abort - def _request2_sync( self, request) : - + def _request_sync( self, request) : + global _urllib_request ## Build URL url = self.getUrl(request) ## Send Request Expecting JSONP Response + response = _urllib_request(url, timeout=320) try: - try: usock = urllib2.urlopen( url, None, 310 ) - except TypeError: usock = urllib2.urlopen( url, None ) - response = usock.read() - usock.close() - resp_json = json.loads(response) - except Exception as e: - print e - return None - + resp_json = json.loads(response[0]) + except: + return [0,"JSON Error"] + + if response[1] != 200 and 'status' in resp_json: + return {'message' : resp_json['message'], 'payload' : resp_json['payload']} + return resp_json - def _request2(self, request, callback=None, single=False): + def _request(self, request, callback=None, error=None, single=False): if callback is None: - return self._request2_sync(request) + return self._request_sync(request) else: - self._request2_async(request, callback, single=single) - + self._request_async(request, callback, error, single=single) +''' def _request3_sync( self, request) : ## Build URL @@ -1083,3 +1102,4 @@ class Pubnub(PubnubCoreAsync): return self._request3_sync(request,single=single) else: self._request3_async(request, callback, single=single) + ''' diff --git a/python/examples/publish-example.py b/python/examples/publish-example.py index 31ae198..bb8b199 100755 --- a/python/examples/publish-example.py +++ b/python/examples/publish-example.py @@ -1,43 +1,68 @@ +## 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.1 Real-time Push Cloud API +## ----------------------------------- + import sys -sys.path.append('.') -sys.path.append('..') +from twisted.internet import reactor +sys.path.append('../') +sys.path.append('../../') from Pubnub import Pubnub -## Initiate Class -pubnub = Pubnub( publish_key='demo', subscribe_key='demo', cipher_key='enigma', ssl_on=False ) -#pubnub = Pubnub( publish_key='demo', subscribe_key='demo', ssl_on=False ) +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' ##(Cipher key is Optional) +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False +## ----------------------------------------------------------------------- +## Initiate Pubnub State +## ----------------------------------------------------------------------- +pubnub = Pubnub( publish_key, subscribe_key, secret_key, cipher_key, ssl_on ) +crazy = 'hello_world' + +## ----------------------------------------------------------------------- ## Publish Example -info = pubnub.publish({ - 'channel' : 'abcd', - 'message' : { - 'iam' : 'object' - } -}) -print(info) +## ----------------------------------------------------------------------- +def publish_complete(info): + print(info) -info = pubnub.publish({ - 'channel' : 'abcd', - 'message' : "hi I am string" -}) -print(info) +def publish_error(info): + print('ERROR : ' + str(info)) -info = pubnub.publish({ - 'channel' : 'abcd', - 'message' : 1234 +## Publish string +pubnub.publish({ + 'channel' : crazy, + 'message' : 'Hello World!', + 'callback' : publish_complete, + 'error' : publish_error }) -print(info) -info = pubnub.publish({ - 'channel' : 'abcd', - 'message' : "1234" +## Publish list +li = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] + +pubnub.publish({ + 'channel' : crazy, + 'message' : li, + 'callback' : publish_complete, + 'error' : publish_error }) -print(info) -info = pubnub.publish({ - 'channel' : 'abcd', - 'message' : [ - 'i' , 'am', 'array' - ] +def done_cb(info): + publish_complete(info) + +pubnub.publish({ + 'channel' : crazy, + 'message' : { 'some_key' : 'some_val' }, + 'callback' : done_cb, + 'error' : publish_error }) -print(info) + + +pubnub.start() diff --git a/python/tests/subscribe-test.py b/python/tests/subscribe-test.py index 0d4c65e..be4a416 100755 --- a/python/tests/subscribe-test.py +++ b/python/tests/subscribe-test.py @@ -38,31 +38,31 @@ received = 0 ## Subscribe Example ## ----------------------------------------------------------------------- def message_received(message): - print message + print(message) def check_received(message): global current global errors global received - print message - print current + print(message) + print(current) if message <= current: - print 'ERROR' + print('ERROR') #sys.exit() errors += 1 else: received += 1 - print 'active thread count : ', threading.activeCount() - print 'errors = ' , errors - print current_thread().getName(), ' , ', 'received = ', received + print('active thread count : ' + str( threading.activeCount())) + print('errors = ' + str(errors)) + print(current_thread().getName() + ' , ' + 'received = ' + str(received)) if received != message: - print '********** MISSED **************** ', message - received + print('********** MISSED **************** ' + str( message - received )) current = message def connected_test(ch) : - print 'Connected' , ch + print('Connected ' + ch) def connected(ch) : pass @@ -103,7 +103,6 @@ def subscribe(channel): }) -print threading.activeCount() pubnub.timeout(15,cb1) diff --git a/python/unassembled/Platform.py b/python/unassembled/Platform.py index 22893f8..0ffccbb 100644 --- a/python/unassembled/Platform.py +++ b/python/unassembled/Platform.py @@ -12,19 +12,43 @@ from threading import current_thread latest_sub_callback_lock = threading.RLock() latest_sub_callback = {'id' : None, 'callback' : None} + + + class HTTPClient: - def __init__(self, url, callback, id=None): + def __init__(self, url, urllib_func=None, callback=None, error=None, id=None): self.url = url self.id = id self.callback = callback + self.error = error self.stop = False + self._urllib_func = urllib_func def cancel(self): self.stop = True self.callback = None + self.error = None + def run(self): - data = urllib2.urlopen(self.url, timeout=310).read() + + def _invoke(func, data): + if func is not None: + func(data) + + if self._urllib_func is None: + return + + ''' + try: + resp = urllib2.urlopen(self.url, timeout=320) + except urllib2.HTTPError as http_error: + resp = http_error + ''' + resp = self._urllib_func(self.url, timeout=320) + data = resp[0] + code = resp[1] + if self.stop is True: return if self.callback is None: @@ -34,13 +58,48 @@ class HTTPClient: if latest_sub_callback['id'] != self.id: return else: - print(data) if latest_sub_callback['callback'] is not None: latest_sub_callback['id'] = 0 - latest_sub_callback['callback'](json.loads(data)) + try: + data = json.loads(data) + except: + _invoke(latest_sub_callback['error'], {'error' : 'json decoding error'}) + return + if code != 200: + _invoke(latest_sub_callback['error'],data) + else: + _invoke(latest_sub_callback['callback'],data) else: - self.callback(json.loads(data)) - + try: + data = json.loads(data) + except: + _invoke(self.error, {'error' : 'json decoding error'}) + return + + if code != 200: + _invoke(self.error,data) + else: + _invoke(self.callback,data) + + +def _urllib_request_2(url, timeout=320): + try: + resp = urllib2.urlopen(url,timeout=timeout) + except urllib2.HTTPError as http_error: + resp = http_error + return (resp.read(),resp.code) + +def _urllib_request_3(url, timeout=320): + #print(url) + try: + resp = urllib.request.urlopen(url,timeout=timeout) + except urllib.request.HTTPError as http_error: + resp = http_error + r = resp.read().decode("utf-8") + #print(r) + return (r,resp.code) + +_urllib_request = None class Pubnub(PubnubCoreAsync): def __init__( @@ -62,13 +121,15 @@ class Pubnub(PubnubCoreAsync): auth_key = auth_key, ssl_on = ssl_on, origin = origin, - uuid = pres_uuid + uuid = pres_uuid, + _tt_lock=threading.RLock(), + _channel_list_lock=threading.RLock() ) + global _urllib_request if self.python_version == 2: - self._request = self._request2 + _urllib_request = _urllib_request_2 else: - self._request = self._request3 - self._channel_list_lock = threading.RLock() + _urllib_request = _urllib_request_3 def timeout(self, interval, func): def cb(): @@ -77,17 +138,20 @@ class Pubnub(PubnubCoreAsync): thread = threading.Thread(target=cb) thread.start() - def _request2_async( self, request, callback, single=False ) : + + def _request_async( self, request, callback=None, error=None, single=False ) : + global _urllib_request ## Build URL url = self.getUrl(request) if single is True: id = time.time() - client = HTTPClient(url, None, id) + client = HTTPClient(url=url, urllib_func=_urllib_request, callback=None, error=None, id=id) with latest_sub_callback_lock: latest_sub_callback['id'] = id latest_sub_callback['callback'] = callback + latest_sub_callback['error'] = error else: - client = HTTPClient(url, callback) + client = HTTPClient(url=url, urllib_func=_urllib_request, callback=callback, error=error) thread = threading.Thread(target=client.run) thread.start() @@ -96,31 +160,30 @@ class Pubnub(PubnubCoreAsync): return abort - def _request2_sync( self, request) : - + def _request_sync( self, request) : + global _urllib_request ## Build URL url = self.getUrl(request) ## Send Request Expecting JSONP Response + response = _urllib_request(url, timeout=320) try: - try: usock = urllib2.urlopen( url, None, 310 ) - except TypeError: usock = urllib2.urlopen( url, None ) - response = usock.read() - usock.close() - resp_json = json.loads(response) - except Exception as e: - print e - return None - + resp_json = json.loads(response[0]) + except: + return [0,"JSON Error"] + + if response[1] != 200 and 'status' in resp_json: + return {'message' : resp_json['message'], 'payload' : resp_json['payload']} + return resp_json - def _request2(self, request, callback=None, single=False): + def _request(self, request, callback=None, error=None, single=False): if callback is None: - return self._request2_sync(request) + return self._request_sync(request) else: - self._request2_async(request, callback, single=single) - + self._request_async(request, callback, error, single=single) +''' def _request3_sync( self, request) : ## Build URL @@ -142,3 +205,4 @@ class Pubnub(PubnubCoreAsync): return self._request3_sync(request,single=single) else: self._request3_async(request, callback, single=single) + ''' -- cgit v1.2.3 From 9dc2555746adf717da0db808f4096af2167a1580 Mon Sep 17 00:00:00 2001 From: Devendra Date: Thu, 17 Apr 2014 00:28:05 +0530 Subject: adding ver 1 of dev console --- common/PubnubBase.py | 4 +- python-tornado/Pubnub.py | 4 +- python-twisted/Pubnub.py | 4 +- python/Pubnub.py | 4 +- python/examples/dev-console.py | 182 +++++++++++++++++++++++++++++++++++++ python/examples/publish-example.py | 5 +- 6 files changed, 193 insertions(+), 10 deletions(-) create mode 100755 python/examples/dev-console.py diff --git a/common/PubnubBase.py b/common/PubnubBase.py index 98c68eb..075327d 100644 --- a/common/PubnubBase.py +++ b/common/PubnubBase.py @@ -120,7 +120,7 @@ class PubnubBase(object): params=params ) - signature = self._pam_sign(sign_input) + query['signature'] = self._pam_sign(sign_input) ''' url = ("https://pubsub.pubnub.com/v1/auth/{apitype}/sub-key/".format(apitype="audit" if (apicode) else "grant") + @@ -133,7 +133,7 @@ class PubnubBase(object): 'v1', 'auth', "audit" if (apicode) else "grant" , 'sub-key', self.subscribe_key - ], 'urlparams' : {'auth' : self.auth_key, 'signature' : signature}}, + ], 'urlparams' : query}, self._return_wrapped_callback(callback)) def grant( self, channel, authkey=False, read=True, write=True, ttl=5, callback=None): diff --git a/python-tornado/Pubnub.py b/python-tornado/Pubnub.py index ccff021..757cdd7 100644 --- a/python-tornado/Pubnub.py +++ b/python-tornado/Pubnub.py @@ -291,7 +291,7 @@ class PubnubBase(object): params=params ) - signature = self._pam_sign(sign_input) + query['signature'] = self._pam_sign(sign_input) ''' url = ("https://pubsub.pubnub.com/v1/auth/{apitype}/sub-key/".format(apitype="audit" if (apicode) else "grant") + @@ -304,7 +304,7 @@ class PubnubBase(object): 'v1', 'auth', "audit" if (apicode) else "grant" , 'sub-key', self.subscribe_key - ], 'urlparams' : {'auth' : self.auth_key, 'signature' : signature}}, + ], 'urlparams' : query}, self._return_wrapped_callback(callback)) def grant( self, channel, authkey=False, read=True, write=True, ttl=5, callback=None): diff --git a/python-twisted/Pubnub.py b/python-twisted/Pubnub.py index 383ee6d..b9e6b52 100644 --- a/python-twisted/Pubnub.py +++ b/python-twisted/Pubnub.py @@ -291,7 +291,7 @@ class PubnubBase(object): params=params ) - signature = self._pam_sign(sign_input) + query['signature'] = self._pam_sign(sign_input) ''' url = ("https://pubsub.pubnub.com/v1/auth/{apitype}/sub-key/".format(apitype="audit" if (apicode) else "grant") + @@ -304,7 +304,7 @@ class PubnubBase(object): 'v1', 'auth', "audit" if (apicode) else "grant" , 'sub-key', self.subscribe_key - ], 'urlparams' : {'auth' : self.auth_key, 'signature' : signature}}, + ], 'urlparams' : query}, self._return_wrapped_callback(callback)) def grant( self, channel, authkey=False, read=True, write=True, ttl=5, callback=None): diff --git a/python/Pubnub.py b/python/Pubnub.py index 95eafd0..169bd54 100644 --- a/python/Pubnub.py +++ b/python/Pubnub.py @@ -291,7 +291,7 @@ class PubnubBase(object): params=params ) - signature = self._pam_sign(sign_input) + query['signature'] = self._pam_sign(sign_input) ''' url = ("https://pubsub.pubnub.com/v1/auth/{apitype}/sub-key/".format(apitype="audit" if (apicode) else "grant") + @@ -304,7 +304,7 @@ class PubnubBase(object): 'v1', 'auth', "audit" if (apicode) else "grant" , 'sub-key', self.subscribe_key - ], 'urlparams' : {'auth' : self.auth_key, 'signature' : signature}}, + ], 'urlparams' : query}, self._return_wrapped_callback(callback)) def grant( self, channel, authkey=False, read=True, write=True, ttl=5, callback=None): diff --git a/python/examples/dev-console.py b/python/examples/dev-console.py new file mode 100755 index 0000000..372599a --- /dev/null +++ b/python/examples/dev-console.py @@ -0,0 +1,182 @@ +## 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.1 Real-time Push Cloud API +## ----------------------------------- + +import sys +from twisted.internet import reactor +sys.path.append('../') +sys.path.append('../../') +from Pubnub import Pubnub + +from optparse import OptionParser + + +parser = OptionParser() + +parser.add_option("--publish-key", + dest="publish_key", default="demo", + help="Publish Key ( default : 'demo' )") + +parser.add_option("--subscribe-key", + dest="subscribe_key", default="demo", + help="Subscribe Key ( default : 'demo' )") + +parser.add_option("--secret-key", + dest="secret_key", default="demo", + help="Secret Key ( default : 'demo' )") + +parser.add_option("--cipher-key", + dest="cipher_key", default="", + help="Cipher Key") + +parser.add_option("--auth-key", + dest="auth_key", default=None, + help="Auth Key") + +parser.add_option("--origin", + dest="origin", default="pubsub.pubnub.com", + help="Origin ( default: pubsub.pubnub.com )") + +parser.add_option("--ssl-on", + action="store_false", dest="ssl", default=False, + help="SSL") + +(options, args) = parser.parse_args() + +print options + +pubnub = Pubnub(options.publish_key, options.subscribe_key, options.secret_key, options.cipher_key, options.auth_key, options.ssl) + + +class color: + PURPLE = '\033[95m' + CYAN = '\033[96m' + DARKCYAN = '\033[36m' + BLUE = '\033[94m' + GREEN = '\033[92m' + YELLOW = '\033[93m' + RED = '\033[91m' + BOLD = '\033[1m' + UNDERLINE = '\033[4m' + END = '\033[0m' + + +def print_ok(msg): + print(color.GREEN + str(msg) + color.END) + +def print_error(msg): + print(color.RED + color.BOLD + str(msg) + color.END) + +def get_input(message, t=None): + while True: + try: + command = raw_input(message) + if t is not None: + command = t(command) + else: + command = eval("'" + command + "'") + return command + except ValueError: + print_error("Invalid input : " + command) + + + +def _publish_command_handler(): + + channel = get_input("[PUBLISH] Enter Channel Name ", str) + while True: + message = get_input("[PUBLISH] Enter Message ( QUIT for exit from publish mode ) ") + if message == 'QUIT' or message == 'quit': + return + def _callback(r): + print_ok(r) + def _error(r): + print_error(r) + pubnub.publish({ + 'channel' : channel, + 'message' : message, + 'callback' : _callback, + 'error' : _error + }) + + +def _subscribe_command_handler(): + channel = get_input("[SUBSCRIBE] Enter Channel Name ", str) + def _callback(r): + print_ok(r) + def _error(r): + print_error(r) + pubnub.subscribe({ + 'channel' : channel, + 'callback' : _callback, + 'error' : _error + }) + +def _grant_command_handler(): + pass + +def _revoke_command_handler(): + pass + +def _audit_command_handler(): + pass + +def _history_command_handler(): + pass + +def _here_now_command_handler(): + pass + + + +import threading + +def kill_all_threads(): + for thread in threading.enumerate(): + if thread.isAlive(): + try: + thread._Thread__stop() + except: + print(str(thread.getName()) + ' could not be terminated') + + +commands = [] +commands.append({"command" : "publish", "handler" : _publish_command_handler}) +commands.append({"command" : "subscribe", "handler" : _subscribe_command_handler}) +''' +commands.append({"command" : "here_now", "handler" : _here_now_command_handler}) +commands.append({"command" : "history", "handler" : _history_command_handler}) +commands.append({"command" : "grant", "handler" : _grant_command_handler}) +commands.append({"command" : "revoke", "handler" : _revoke_command_handler}) +commands.append({"command" : "audit", "handler" : _audit_command_handler}) +''' +# last command is quit. add new commands before this line +commands.append({"command" : "QUIT"}) + +def get_help(): + help = "" + for i,v in enumerate(commands): + help += "Enter " + str(i) + " for " + v['command'] + "\n" + return help + + +while True: + command = get_input(color.BLUE + get_help(), int) + + if command == len(commands) - 1: + kill_all_threads() + break + if command >= len(commands): + print_error("Invalid input " + str(command)) + continue + + commands[command]['handler']() + +#pubnub.start() diff --git a/python/examples/publish-example.py b/python/examples/publish-example.py index bb8b199..e632aef 100755 --- a/python/examples/publish-example.py +++ b/python/examples/publish-example.py @@ -19,12 +19,13 @@ publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' ##(Cipher key is Optional) -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False +auth_key = len(sys.argv) > 5 and sys.argv[4] or 'abcd' ##(Cipher key is Optional) +ssl_on = len(sys.argv) > 6 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- ## Initiate Pubnub State ## ----------------------------------------------------------------------- -pubnub = Pubnub( publish_key, subscribe_key, secret_key, cipher_key, ssl_on ) +pubnub = Pubnub( publish_key, subscribe_key, secret_key, cipher_key, auth_key, ssl_on ) crazy = 'hello_world' ## ----------------------------------------------------------------------- -- cgit v1.2.3 From 85416ee30a4f54183e2be30f9ef3cc1363f98c4d Mon Sep 17 00:00:00 2001 From: Devendra Date: Thu, 17 Apr 2014 01:06:51 +0530 Subject: adding more options to dev console --- common/PubnubBase.py | 6 ++-- python/Pubnub.py | 6 ++-- python/examples/dev-console.py | 65 +++++++++++++++++++++++++++++++++++++----- 3 files changed, 64 insertions(+), 13 deletions(-) diff --git a/common/PubnubBase.py b/common/PubnubBase.py index 075327d..aa71577 100644 --- a/common/PubnubBase.py +++ b/common/PubnubBase.py @@ -147,14 +147,14 @@ class PubnubBase(object): "ttl" : ttl }, callback=callback) - def revoke( self, channel, authkey=False, read=False, write=False, ttl=1, callback=None): + def revoke( self, channel, authkey=False, ttl=1, callback=None): """Revoke Access on a Channel.""" return self._pam_auth({ "channel" : channel, "auth" : authkey, - "r" : read and 1 or 0, - "w" : write and 1 or 0, + "r" : 0, + "w" : 0, "ttl" : ttl }, callback=callback) diff --git a/python/Pubnub.py b/python/Pubnub.py index 169bd54..64bc14b 100644 --- a/python/Pubnub.py +++ b/python/Pubnub.py @@ -318,14 +318,14 @@ class PubnubBase(object): "ttl" : ttl }, callback=callback) - def revoke( self, channel, authkey=False, read=False, write=False, ttl=1, callback=None): + def revoke( self, channel, authkey=False, ttl=1, callback=None): """Revoke Access on a Channel.""" return self._pam_auth({ "channel" : channel, "auth" : authkey, - "r" : read and 1 or 0, - "w" : write and 1 or 0, + "r" : 0, + "w" : 0, "ttl" : ttl }, callback=callback) diff --git a/python/examples/dev-console.py b/python/examples/dev-console.py index 372599a..33ec39f 100755 --- a/python/examples/dev-console.py +++ b/python/examples/dev-console.py @@ -78,10 +78,16 @@ def get_input(message, t=None): while True: try: command = raw_input(message) + if t is not None and t == bool: + if command in ["True", "true", "1", 1, "y", "Y", "yes", "Yes", "YES"]: + return True + else: + return False if t is not None: command = t(command) else: command = eval("'" + command + "'") + return command except ValueError: print_error("Invalid input : " + command) @@ -120,19 +126,65 @@ def _subscribe_command_handler(): }) def _grant_command_handler(): - pass + def _callback(r): + print_ok(r) + def _error(r): + print_error(r) + channel = get_input("[GRANT] Enter Channel Name ", str) + auth_key = get_input("[GRANT] Enter Auth Key ", str) + ttl = get_input("[GRANT] Enter ttl ", int) + read = get_input("[GRANT] Read ? ", bool) + write = get_input("[GRANT] Write ? ", bool) + pubnub.grant(channel, auth_key,read,write,ttl, _callback) def _revoke_command_handler(): - pass + def _callback(r): + print_ok(r) + def _error(r): + print_error(r) + channel = get_input("[REVOKE] Enter Channel Name ", str) + auth_key = get_input("[REVOKE] Enter Auth Key ", str) + ttl = get_input("[REVOKE] Enter ttl ", int) + + pubnub.revoke(channel, auth_key, ttl, _callback) def _audit_command_handler(): - pass + def _callback(r): + print_ok(r) + def _error(r): + print_error(r) + channel = get_input("[AUDIT] Enter Channel Name ", str) + auth_key = get_input("[AUDIT] Enter Auth Key ", str) + pubnub.audit(channel, auth_key, _callback) def _history_command_handler(): - pass + def _callback(r): + print_ok(r) + def _error(r): + print_error(r) + channel = get_input("[HISTORY] Enter Channel Name ", str) + count = get_input("[HISTORY] Enter Count ", int) + + pubnub.history({ + 'channel' : channel, + 'count' : count, + 'callback' : _callback, + 'error' : _error + }) + def _here_now_command_handler(): - pass + def _callback(r): + print_ok(r) + def _error(r): + print_error(r) + channel = get_input("[HERE NOW] Enter Channel Name ", str) + + pubnub.here_now({ + 'channel' : channel, + 'callback' : _callback, + 'error' : _error + }) @@ -150,13 +202,12 @@ def kill_all_threads(): commands = [] commands.append({"command" : "publish", "handler" : _publish_command_handler}) commands.append({"command" : "subscribe", "handler" : _subscribe_command_handler}) -''' commands.append({"command" : "here_now", "handler" : _here_now_command_handler}) commands.append({"command" : "history", "handler" : _history_command_handler}) commands.append({"command" : "grant", "handler" : _grant_command_handler}) commands.append({"command" : "revoke", "handler" : _revoke_command_handler}) commands.append({"command" : "audit", "handler" : _audit_command_handler}) -''' + # last command is quit. add new commands before this line commands.append({"command" : "QUIT"}) -- cgit v1.2.3 From 5d6a3e1356182663b03d62f9258d38459d49017e Mon Sep 17 00:00:00 2001 From: Devendra Date: Fri, 18 Apr 2014 01:23:19 +0530 Subject: fixing wrong version detection with python 2.7 --- common/PubnubBase.py | 8 ++++++-- python-tornado/Pubnub.py | 14 +++++++++----- python-twisted/Pubnub.py | 14 +++++++++----- python/Pubnub.py | 8 ++++++-- python/examples/dev-console.py | 1 - 5 files changed, 30 insertions(+), 15 deletions(-) diff --git a/common/PubnubBase.py b/common/PubnubBase.py index aa71577..585be70 100644 --- a/common/PubnubBase.py +++ b/common/PubnubBase.py @@ -66,8 +66,12 @@ class PubnubBase(object): self.python_version = 2 self.pc = PubnubCrypto2() else: - self.python_version = 3 - self.pc = PubnubCrypto3() + if sys.version_info.major == 2: + self.python_version = 2 + self.pc = PubnubCrypto2() + else: + self.python_version = 3 + self.pc = PubnubCrypto3() if not isinstance(self.uuid, str): raise AttributeError("pres_uuid must be a string") diff --git a/python-tornado/Pubnub.py b/python-tornado/Pubnub.py index 757cdd7..2c6c98f 100644 --- a/python-tornado/Pubnub.py +++ b/python-tornado/Pubnub.py @@ -237,8 +237,12 @@ class PubnubBase(object): self.python_version = 2 self.pc = PubnubCrypto2() else: - self.python_version = 3 - self.pc = PubnubCrypto3() + if sys.version_info.major == 2: + self.python_version = 2 + self.pc = PubnubCrypto2() + else: + self.python_version = 3 + self.pc = PubnubCrypto3() if not isinstance(self.uuid, str): raise AttributeError("pres_uuid must be a string") @@ -318,14 +322,14 @@ class PubnubBase(object): "ttl" : ttl }, callback=callback) - def revoke( self, channel, authkey=False, read=False, write=False, ttl=1, callback=None): + def revoke( self, channel, authkey=False, ttl=1, callback=None): """Revoke Access on a Channel.""" return self._pam_auth({ "channel" : channel, "auth" : authkey, - "r" : read and 1 or 0, - "w" : write and 1 or 0, + "r" : 0, + "w" : 0, "ttl" : ttl }, callback=callback) diff --git a/python-twisted/Pubnub.py b/python-twisted/Pubnub.py index b9e6b52..99eda47 100644 --- a/python-twisted/Pubnub.py +++ b/python-twisted/Pubnub.py @@ -237,8 +237,12 @@ class PubnubBase(object): self.python_version = 2 self.pc = PubnubCrypto2() else: - self.python_version = 3 - self.pc = PubnubCrypto3() + if sys.version_info.major == 2: + self.python_version = 2 + self.pc = PubnubCrypto2() + else: + self.python_version = 3 + self.pc = PubnubCrypto3() if not isinstance(self.uuid, str): raise AttributeError("pres_uuid must be a string") @@ -318,14 +322,14 @@ class PubnubBase(object): "ttl" : ttl }, callback=callback) - def revoke( self, channel, authkey=False, read=False, write=False, ttl=1, callback=None): + def revoke( self, channel, authkey=False, ttl=1, callback=None): """Revoke Access on a Channel.""" return self._pam_auth({ "channel" : channel, "auth" : authkey, - "r" : read and 1 or 0, - "w" : write and 1 or 0, + "r" : 0, + "w" : 0, "ttl" : ttl }, callback=callback) diff --git a/python/Pubnub.py b/python/Pubnub.py index 64bc14b..7af2e92 100644 --- a/python/Pubnub.py +++ b/python/Pubnub.py @@ -237,8 +237,12 @@ class PubnubBase(object): self.python_version = 2 self.pc = PubnubCrypto2() else: - self.python_version = 3 - self.pc = PubnubCrypto3() + if sys.version_info.major == 2: + self.python_version = 2 + self.pc = PubnubCrypto2() + else: + self.python_version = 3 + self.pc = PubnubCrypto3() if not isinstance(self.uuid, str): raise AttributeError("pres_uuid must be a string") diff --git a/python/examples/dev-console.py b/python/examples/dev-console.py index 33ec39f..08e08d9 100755 --- a/python/examples/dev-console.py +++ b/python/examples/dev-console.py @@ -10,7 +10,6 @@ ## ----------------------------------- import sys -from twisted.internet import reactor sys.path.append('../') sys.path.append('../../') from Pubnub import Pubnub -- cgit v1.2.3 From 4926061ebebbc060d14feac9c9d6b13880205724 Mon Sep 17 00:00:00 2001 From: Devendra Date: Tue, 22 Apr 2014 23:12:05 +0530 Subject: improvements to dev console --- common/PubnubBase.py | 1 - common/PubnubCoreAsync.py | 20 +++++++++----- python-tornado/Pubnub.py | 23 ++++++++++------ python-tornado/unassembled/Platform.py | 2 ++ python-twisted/Pubnub.py | 21 +++++++++------ python/Pubnub.py | 21 +++++++++------ python/examples/dev-console.py | 49 +++++++++++++++++++++++++++------- 7 files changed, 96 insertions(+), 41 deletions(-) diff --git a/common/PubnubBase.py b/common/PubnubBase.py index 585be70..522c69f 100644 --- a/common/PubnubBase.py +++ b/common/PubnubBase.py @@ -421,5 +421,4 @@ class PubnubBase(object): ]) for bit in request["urlcomponents"]]) if ("urlparams" in request): url = url + '?' + "&".join([ x + "=" + str(y) for x,y in request["urlparams"].items() if y is not None]) - #print(url) return url diff --git a/common/PubnubCoreAsync.py b/common/PubnubCoreAsync.py index f7b57cc..30d337c 100644 --- a/common/PubnubCoreAsync.py +++ b/common/PubnubCoreAsync.py @@ -84,6 +84,15 @@ class PubnubCoreAsync(PubnubBase): channel += ch return channel + def get_channel_array(self): + channels = self.subscriptions + channel = [] + with self._channel_list_lock: + for ch in channels: + if not channels[ch]['subscribed']: + continue + channel.append(ch) + return channel def each(l, func): if func is None: @@ -192,7 +201,7 @@ class PubnubCoreAsync(PubnubBase): ## New Channel? - if not channel in self.subscriptions: + if not channel in self.subscriptions or self.subscriptions[channel]['subscribed'] is False: with self._channel_list_lock: self.subscriptions[channel] = { 'name' : channel, @@ -221,7 +230,6 @@ class PubnubCoreAsync(PubnubBase): def sub_callback(response): ## ERROR ? - #print response if not response or ('message' in response and response['message'] == 'Forbidden'): _invoke_error(response['payload']['channels'], response['message']) _connect() @@ -230,9 +238,7 @@ class PubnubCoreAsync(PubnubBase): _invoke_connect() with self._tt_lock: - #print 'A tt : ', self.timetoken , ' last tt : ' , self.last_timetoken self.timetoken = self.last_timetoken if self.timetoken == 0 and self.last_timetoken != 0 else response[1] - #print 'B tt : ', self.timetoken , ' last tt : ' , self.last_timetoken if len(response) > 2: channel_list = response[2].split(',') response_list = response[0] @@ -247,12 +253,13 @@ class PubnubCoreAsync(PubnubBase): if chobj: _invoke(chobj['callback'], self.decrypt(r)) - #with self._tt_lock: - # self.timetoken = self.last_timetoken if self.timetoken == 0 and self.last_timetoken != 0 else response[1] _connect() channel_list = self.get_channel_list(self.subscriptions) + if len(channel_list) <= 0: + return + ## CONNECT TO PUBNUB SUBSCRIBE SERVERS try: self.SUB_RECEIVER = self._request( { "urlcomponents" : [ @@ -269,7 +276,6 @@ class PubnubCoreAsync(PubnubBase): self._connect = _connect - ## BEGIN SUBSCRIPTION (LISTEN FOR MESSAGES) _connect() diff --git a/python-tornado/Pubnub.py b/python-tornado/Pubnub.py index 2c6c98f..73cb62d 100644 --- a/python-tornado/Pubnub.py +++ b/python-tornado/Pubnub.py @@ -592,7 +592,6 @@ class PubnubBase(object): ]) for bit in request["urlcomponents"]]) if ("urlparams" in request): url = url + '?' + "&".join([ x + "=" + str(y) for x,y in request["urlparams"].items() if y is not None]) - #print(url) return url @@ -682,6 +681,15 @@ class PubnubCoreAsync(PubnubBase): channel += ch return channel + def get_channel_array(self): + channels = self.subscriptions + channel = [] + with self._channel_list_lock: + for ch in channels: + if not channels[ch]['subscribed']: + continue + channel.append(ch) + return channel def each(l, func): if func is None: @@ -790,7 +798,7 @@ class PubnubCoreAsync(PubnubBase): ## New Channel? - if not channel in self.subscriptions: + if not channel in self.subscriptions or self.subscriptions[channel]['subscribed'] is False: with self._channel_list_lock: self.subscriptions[channel] = { 'name' : channel, @@ -819,7 +827,6 @@ class PubnubCoreAsync(PubnubBase): def sub_callback(response): ## ERROR ? - #print response if not response or ('message' in response and response['message'] == 'Forbidden'): _invoke_error(response['payload']['channels'], response['message']) _connect() @@ -828,9 +835,7 @@ class PubnubCoreAsync(PubnubBase): _invoke_connect() with self._tt_lock: - #print 'A tt : ', self.timetoken , ' last tt : ' , self.last_timetoken self.timetoken = self.last_timetoken if self.timetoken == 0 and self.last_timetoken != 0 else response[1] - #print 'B tt : ', self.timetoken , ' last tt : ' , self.last_timetoken if len(response) > 2: channel_list = response[2].split(',') response_list = response[0] @@ -845,12 +850,13 @@ class PubnubCoreAsync(PubnubBase): if chobj: _invoke(chobj['callback'], self.decrypt(r)) - #with self._tt_lock: - # self.timetoken = self.last_timetoken if self.timetoken == 0 and self.last_timetoken != 0 else response[1] _connect() channel_list = self.get_channel_list(self.subscriptions) + if len(channel_list) <= 0: + return + ## CONNECT TO PUBNUB SUBSCRIBE SERVERS try: self.SUB_RECEIVER = self._request( { "urlcomponents" : [ @@ -867,7 +873,6 @@ class PubnubCoreAsync(PubnubBase): self._connect = _connect - ## BEGIN SUBSCRIPTION (LISTEN FOR MESSAGES) _connect() @@ -927,6 +932,7 @@ class Pubnub(PubnubCoreAsync): subscribe_key, secret_key = False, cipher_key = False, + auth_key = False, ssl_on = False, origin = 'pubsub.pubnub.com' ) : @@ -935,6 +941,7 @@ class Pubnub(PubnubCoreAsync): subscribe_key=subscribe_key, secret_key=secret_key, cipher_key=cipher_key, + auth_key=auth_key, ssl_on=ssl_on, origin=origin, ) diff --git a/python-tornado/unassembled/Platform.py b/python-tornado/unassembled/Platform.py index 5200136..02c374d 100644 --- a/python-tornado/unassembled/Platform.py +++ b/python-tornado/unassembled/Platform.py @@ -26,6 +26,7 @@ class Pubnub(PubnubCoreAsync): subscribe_key, secret_key = False, cipher_key = False, + auth_key = False, ssl_on = False, origin = 'pubsub.pubnub.com' ) : @@ -34,6 +35,7 @@ class Pubnub(PubnubCoreAsync): subscribe_key=subscribe_key, secret_key=secret_key, cipher_key=cipher_key, + auth_key=auth_key, ssl_on=ssl_on, origin=origin, ) diff --git a/python-twisted/Pubnub.py b/python-twisted/Pubnub.py index 99eda47..22d647b 100644 --- a/python-twisted/Pubnub.py +++ b/python-twisted/Pubnub.py @@ -592,7 +592,6 @@ class PubnubBase(object): ]) for bit in request["urlcomponents"]]) if ("urlparams" in request): url = url + '?' + "&".join([ x + "=" + str(y) for x,y in request["urlparams"].items() if y is not None]) - #print(url) return url @@ -682,6 +681,15 @@ class PubnubCoreAsync(PubnubBase): channel += ch return channel + def get_channel_array(self): + channels = self.subscriptions + channel = [] + with self._channel_list_lock: + for ch in channels: + if not channels[ch]['subscribed']: + continue + channel.append(ch) + return channel def each(l, func): if func is None: @@ -790,7 +798,7 @@ class PubnubCoreAsync(PubnubBase): ## New Channel? - if not channel in self.subscriptions: + if not channel in self.subscriptions or self.subscriptions[channel]['subscribed'] is False: with self._channel_list_lock: self.subscriptions[channel] = { 'name' : channel, @@ -819,7 +827,6 @@ class PubnubCoreAsync(PubnubBase): def sub_callback(response): ## ERROR ? - #print response if not response or ('message' in response and response['message'] == 'Forbidden'): _invoke_error(response['payload']['channels'], response['message']) _connect() @@ -828,9 +835,7 @@ class PubnubCoreAsync(PubnubBase): _invoke_connect() with self._tt_lock: - #print 'A tt : ', self.timetoken , ' last tt : ' , self.last_timetoken self.timetoken = self.last_timetoken if self.timetoken == 0 and self.last_timetoken != 0 else response[1] - #print 'B tt : ', self.timetoken , ' last tt : ' , self.last_timetoken if len(response) > 2: channel_list = response[2].split(',') response_list = response[0] @@ -845,12 +850,13 @@ class PubnubCoreAsync(PubnubBase): if chobj: _invoke(chobj['callback'], self.decrypt(r)) - #with self._tt_lock: - # self.timetoken = self.last_timetoken if self.timetoken == 0 and self.last_timetoken != 0 else response[1] _connect() channel_list = self.get_channel_list(self.subscriptions) + if len(channel_list) <= 0: + return + ## CONNECT TO PUBNUB SUBSCRIBE SERVERS try: self.SUB_RECEIVER = self._request( { "urlcomponents" : [ @@ -867,7 +873,6 @@ class PubnubCoreAsync(PubnubBase): self._connect = _connect - ## BEGIN SUBSCRIPTION (LISTEN FOR MESSAGES) _connect() diff --git a/python/Pubnub.py b/python/Pubnub.py index 7af2e92..bca3ee5 100644 --- a/python/Pubnub.py +++ b/python/Pubnub.py @@ -592,7 +592,6 @@ class PubnubBase(object): ]) for bit in request["urlcomponents"]]) if ("urlparams" in request): url = url + '?' + "&".join([ x + "=" + str(y) for x,y in request["urlparams"].items() if y is not None]) - #print(url) return url @@ -682,6 +681,15 @@ class PubnubCoreAsync(PubnubBase): channel += ch return channel + def get_channel_array(self): + channels = self.subscriptions + channel = [] + with self._channel_list_lock: + for ch in channels: + if not channels[ch]['subscribed']: + continue + channel.append(ch) + return channel def each(l, func): if func is None: @@ -790,7 +798,7 @@ class PubnubCoreAsync(PubnubBase): ## New Channel? - if not channel in self.subscriptions: + if not channel in self.subscriptions or self.subscriptions[channel]['subscribed'] is False: with self._channel_list_lock: self.subscriptions[channel] = { 'name' : channel, @@ -819,7 +827,6 @@ class PubnubCoreAsync(PubnubBase): def sub_callback(response): ## ERROR ? - #print response if not response or ('message' in response and response['message'] == 'Forbidden'): _invoke_error(response['payload']['channels'], response['message']) _connect() @@ -828,9 +835,7 @@ class PubnubCoreAsync(PubnubBase): _invoke_connect() with self._tt_lock: - #print 'A tt : ', self.timetoken , ' last tt : ' , self.last_timetoken self.timetoken = self.last_timetoken if self.timetoken == 0 and self.last_timetoken != 0 else response[1] - #print 'B tt : ', self.timetoken , ' last tt : ' , self.last_timetoken if len(response) > 2: channel_list = response[2].split(',') response_list = response[0] @@ -845,12 +850,13 @@ class PubnubCoreAsync(PubnubBase): if chobj: _invoke(chobj['callback'], self.decrypt(r)) - #with self._tt_lock: - # self.timetoken = self.last_timetoken if self.timetoken == 0 and self.last_timetoken != 0 else response[1] _connect() channel_list = self.get_channel_list(self.subscriptions) + if len(channel_list) <= 0: + return + ## CONNECT TO PUBNUB SUBSCRIBE SERVERS try: self.SUB_RECEIVER = self._request( { "urlcomponents" : [ @@ -867,7 +873,6 @@ class PubnubCoreAsync(PubnubBase): self._connect = _connect - ## BEGIN SUBSCRIPTION (LISTEN FOR MESSAGES) _connect() diff --git a/python/examples/dev-console.py b/python/examples/dev-console.py index 08e08d9..532edbe 100755 --- a/python/examples/dev-console.py +++ b/python/examples/dev-console.py @@ -47,11 +47,15 @@ parser.add_option("--ssl-on", action="store_false", dest="ssl", default=False, help="SSL") +parser.add_option("--uuid", + dest="uuid", default=None, + help="UUID") + (options, args) = parser.parse_args() print options -pubnub = Pubnub(options.publish_key, options.subscribe_key, options.secret_key, options.cipher_key, options.auth_key, options.ssl) +pubnub = Pubnub(options.publish_key, options.subscribe_key, options.secret_key, options.cipher_key, options.auth_key, options.ssl, options.origin, options.uuid) class color: @@ -67,11 +71,19 @@ class color: END = '\033[0m' -def print_ok(msg): - print(color.GREEN + str(msg) + color.END) +def print_ok(msg, channel=None): + chstr = " [Channel : " + channel + "] " if channel is not None else "" + try: + print(color.GREEN + chstr + str(msg) + color.END) + except: + print(msg) -def print_error(msg): - print(color.RED + color.BOLD + str(msg) + color.END) +def print_error(msg, channel=None): + chstr = " [Channel : " + channel + "] " if channel is not None else "" + try: + print(color.RED + color.BOLD + chstr + str(msg) + color.END) + except: + print(msg) def get_input(message, t=None): while True: @@ -115,15 +127,27 @@ def _publish_command_handler(): def _subscribe_command_handler(): channel = get_input("[SUBSCRIBE] Enter Channel Name ", str) def _callback(r): - print_ok(r) + print_ok(r, channel) def _error(r): - print_error(r) + print_error(r, channel) pubnub.subscribe({ 'channel' : channel, 'callback' : _callback, 'error' : _error }) +def _unsubscribe_command_handler(): + channel = get_input("[UNSUBSCRIBE] Enter Channel Name ", str) + def _callback(r): + print_ok(r) + def _error(r): + print_error(r) + pubnub.unsubscribe({ + 'channel' : channel, + 'callback' : _callback, + 'error' : _error + }) + def _grant_command_handler(): def _callback(r): print_ok(r) @@ -201,6 +225,7 @@ def kill_all_threads(): commands = [] commands.append({"command" : "publish", "handler" : _publish_command_handler}) commands.append({"command" : "subscribe", "handler" : _subscribe_command_handler}) +commands.append({"command" : "unsubscribe", "handler" : _unsubscribe_command_handler}) commands.append({"command" : "here_now", "handler" : _here_now_command_handler}) commands.append({"command" : "history", "handler" : _history_command_handler}) commands.append({"command" : "grant", "handler" : _grant_command_handler}) @@ -212,14 +237,20 @@ commands.append({"command" : "QUIT"}) def get_help(): help = "" + help += "Channels currently subscribed to : " + help += str(pubnub.get_channel_array()) + help += "\n" for i,v in enumerate(commands): help += "Enter " + str(i) + " for " + v['command'] + "\n" return help while True: - command = get_input(color.BLUE + get_help(), int) - + try: + command = get_input(color.BLUE + get_help(), int) + except KeyboardInterrupt: + kill_all_threads() + break if command == len(commands) - 1: kill_all_threads() break -- cgit v1.2.3 From f1ce4ae3179d51e88aca266d107531209d2d98a2 Mon Sep 17 00:00:00 2001 From: Devendra Date: Tue, 22 Apr 2014 23:56:29 +0530 Subject: dev console improvements --- python/examples/dev-console.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/python/examples/dev-console.py b/python/examples/dev-console.py index 532edbe..52ed910 100755 --- a/python/examples/dev-console.py +++ b/python/examples/dev-console.py @@ -53,7 +53,7 @@ parser.add_option("--uuid", (options, args) = parser.parse_args() -print options +print(options) pubnub = Pubnub(options.publish_key, options.subscribe_key, options.secret_key, options.cipher_key, options.auth_key, options.ssl, options.origin, options.uuid) @@ -88,7 +88,10 @@ def print_error(msg, channel=None): def get_input(message, t=None): while True: try: - command = raw_input(message) + try: + command = raw_input(message) + except NameError: + command = input(message) if t is not None and t == bool: if command in ["True", "true", "1", 1, "y", "Y", "yes", "Yes", "YES"]: return True @@ -218,8 +221,11 @@ def kill_all_threads(): if thread.isAlive(): try: thread._Thread__stop() - except: - print(str(thread.getName()) + ' could not be terminated') + except Exception as e: + pass + #print(e) + #thread.exit() + #print(str(thread.getName()) + ' could not be terminated') commands = [] -- cgit v1.2.3 From b2f1e0ed2337b61073a595eaf36afd718a21a3fe Mon Sep 17 00:00:00 2001 From: Devendra Date: Wed, 23 Apr 2014 02:10:55 +0530 Subject: fixing issues reported by Dara in dev console --- common/PubnubCoreAsync.py | 1 + python-tornado/Pubnub.py | 1 + python-twisted/Pubnub.py | 1 + python/Pubnub.py | 1 + python/examples/dev-console.py | 55 ++++++++++++++++++++++-------------------- 5 files changed, 33 insertions(+), 26 deletions(-) diff --git a/common/PubnubCoreAsync.py b/common/PubnubCoreAsync.py index 30d337c..db10575 100644 --- a/common/PubnubCoreAsync.py +++ b/common/PubnubCoreAsync.py @@ -69,6 +69,7 @@ class PubnubCoreAsync(PubnubBase): self._connect = None self._tt_lock = _tt_lock self._channel_list_lock = _channel_list_lock + self._connect = lambda: None def get_channel_list(self, channels): channel = '' diff --git a/python-tornado/Pubnub.py b/python-tornado/Pubnub.py index 73cb62d..5607df0 100644 --- a/python-tornado/Pubnub.py +++ b/python-tornado/Pubnub.py @@ -666,6 +666,7 @@ class PubnubCoreAsync(PubnubBase): self._connect = None self._tt_lock = _tt_lock self._channel_list_lock = _channel_list_lock + self._connect = lambda: None def get_channel_list(self, channels): channel = '' diff --git a/python-twisted/Pubnub.py b/python-twisted/Pubnub.py index 22d647b..f5259ac 100644 --- a/python-twisted/Pubnub.py +++ b/python-twisted/Pubnub.py @@ -666,6 +666,7 @@ class PubnubCoreAsync(PubnubBase): self._connect = None self._tt_lock = _tt_lock self._channel_list_lock = _channel_list_lock + self._connect = lambda: None def get_channel_list(self, channels): channel = '' diff --git a/python/Pubnub.py b/python/Pubnub.py index bca3ee5..d41f626 100644 --- a/python/Pubnub.py +++ b/python/Pubnub.py @@ -666,6 +666,7 @@ class PubnubCoreAsync(PubnubBase): self._connect = None self._tt_lock = _tt_lock self._channel_list_lock = _channel_list_lock + self._connect = lambda: None def get_channel_list(self, channels): channel = '' diff --git a/python/examples/dev-console.py b/python/examples/dev-console.py index 52ed910..c4c6bc8 100755 --- a/python/examples/dev-console.py +++ b/python/examples/dev-console.py @@ -70,21 +70,37 @@ class color: UNDERLINE = '\033[4m' END = '\033[0m' +from datetime import datetime def print_ok(msg, channel=None): - chstr = " [Channel : " + channel + "] " if channel is not None else "" + chstr = color.PURPLE + "[" + datetime.now().strftime('%Y-%m-%d %H:%M:%S') + "] " + color.END + chstr += color.CYAN + "[Channel : " + channel + "] " if channel is not None else "" + color.END try: - print(color.GREEN + chstr + str(msg) + color.END) - except: + print(chstr + color.GREEN + str(msg) + color.END) + except Exception as e: print(msg) def print_error(msg, channel=None): - chstr = " [Channel : " + channel + "] " if channel is not None else "" + chstr = color.PURPLE + "[" + datetime.now().strftime('%Y-%m-%d %H:%M:%S') + "] " + color.END + chstr += color.CYAN + "[Channel : " + channel + "] " if channel is not None else "" + color.END try: - print(color.RED + color.BOLD + chstr + str(msg) + color.END) + print( chstr + color.RED + color.BOLD +str(msg) + color.END) except: print(msg) +import threading + +def kill_all_threads(): + for thread in threading.enumerate(): + if thread.isAlive(): + try: + thread._Thread__stop() + except Exception as e: + pass + #print(e) + #thread.exit() + #print(str(thread.getName()) + ' could not be terminated') + def get_input(message, t=None): while True: try: @@ -92,6 +108,8 @@ def get_input(message, t=None): command = raw_input(message) except NameError: command = input(message) + except KeyboardInterrupt: + return None if t is not None and t == bool: if command in ["True", "true", "1", 1, "y", "Y", "yes", "Yes", "YES"]: return True @@ -111,9 +129,11 @@ def get_input(message, t=None): def _publish_command_handler(): channel = get_input("[PUBLISH] Enter Channel Name ", str) + if channel is None: + return while True: - message = get_input("[PUBLISH] Enter Message ( QUIT for exit from publish mode ) ") - if message == 'QUIT' or message == 'quit': + message = get_input("[PUBLISH] Enter Message ( QUIT or CTRL-C for exit from publish mode ) ") + if message == 'QUIT' or message == 'quit' or message == None: return def _callback(r): print_ok(r) @@ -214,19 +234,6 @@ def _here_now_command_handler(): -import threading - -def kill_all_threads(): - for thread in threading.enumerate(): - if thread.isAlive(): - try: - thread._Thread__stop() - except Exception as e: - pass - #print(e) - #thread.exit() - #print(str(thread.getName()) + ' could not be terminated') - commands = [] commands.append({"command" : "publish", "handler" : _publish_command_handler}) @@ -252,12 +259,8 @@ def get_help(): while True: - try: - command = get_input(color.BLUE + get_help(), int) - except KeyboardInterrupt: - kill_all_threads() - break - if command == len(commands) - 1: + command = get_input(color.BLUE + get_help(), int) + if command == len(commands) - 1 or command is None: kill_all_threads() break if command >= len(commands): -- cgit v1.2.3 From 69240816755406b26b364f37ca521fdb269581d1 Mon Sep 17 00:00:00 2001 From: Devendra Date: Wed, 23 Apr 2014 02:28:42 +0530 Subject: fixed error on missing channel --- python/examples/dev-console.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/python/examples/dev-console.py b/python/examples/dev-console.py index c4c6bc8..adade8f 100755 --- a/python/examples/dev-console.py +++ b/python/examples/dev-console.py @@ -110,6 +110,12 @@ def get_input(message, t=None): command = input(message) except KeyboardInterrupt: return None + + command = command.strip() + + if command is None or len(command) == 0: + raise ValueError + if t is not None and t == bool: if command in ["True", "true", "1", 1, "y", "Y", "yes", "Yes", "YES"]: return True -- cgit v1.2.3 From fdb46e56fa6794940f9fbe51a2863d58e927e655 Mon Sep 17 00:00:00 2001 From: Devendra Date: Wed, 23 Apr 2014 12:54:16 +0530 Subject: switching to positional arguments --- common/PubnubBase.py | 73 ++++++---------------------- common/PubnubCoreAsync.py | 35 ++----------- python/Pubnub.py | 108 +++++++---------------------------------- python/examples/dev-console.py | 34 ++----------- 4 files changed, 39 insertions(+), 211 deletions(-) diff --git a/common/PubnubBase.py b/common/PubnubBase.py index 522c69f..14ae6c4 100644 --- a/common/PubnubBase.py +++ b/common/PubnubBase.py @@ -76,7 +76,9 @@ class PubnubBase(object): if not isinstance(self.uuid, str): raise AttributeError("pres_uuid must be a string") - def sign(self, channel, message): + ''' + + def _sign(self, channel, message): ## Sign Message if self.secret_key: signature = hashlib.md5('/'.join([ @@ -89,6 +91,7 @@ class PubnubBase(object): else: signature = '0' return signature + ''' def _pam_sign( self, msg ): """Calculate a signature by secret key and message.""" @@ -196,7 +199,7 @@ class PubnubBase(object): return None - def publish( self, args ) : + def publish(channel, message, callback=None, error=None): """ #** #* Publish @@ -217,28 +220,9 @@ class PubnubBase(object): 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 'callback' in args : - callback = args['callback'] - else : - callback = None - - if 'error' in args : - error = args['error'] - else : - error = None message = self.encrypt(args['message']) - #signature = self.sign(channel, message) - ## Send Message return self._request({"urlcomponents": [ 'publish', @@ -251,7 +235,7 @@ class PubnubBase(object): ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), error=self._return_wrapped_callback(error)) - def presence( self, args ) : + def presence( self, channel, callback, error=None) : """ #** #* presence @@ -273,26 +257,10 @@ class PubnubBase(object): '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': self._return_wrapped_callback(callback)}) + return self.subscribe({'channel': channel+'-pnpres', 'subscribe_key':self.subscribe_key, 'callback': self._return_wrapped_callback(callback)}) - def here_now( self, args ) : + def here_now( self, channel, callback, error=None) : """ #** #* Here Now @@ -330,7 +298,7 @@ class PubnubBase(object): ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), error=self._return_wrapped_callback(error)) - def history(self, args) : + def history(self, channel, count=100, reverse=False, start=None, end=None, callback=None, error=None) : """ #** #* History @@ -349,23 +317,13 @@ class PubnubBase(object): print(history) """ - ## Capture User Input - channel = str(args['channel']) - - callback = args['callback'] if 'callback' in args else None - error = args['error'] if 'error' in args else None params = dict() - params['count'] = str(args['count']) if 'count' in args else 100 - params['reverse'] = str(args['reverse']).lower() if 'reverse' in args else 'false' - params['start'] = str(args['start']) if 'start' in args else None - params['end'] = str(args['end']) if 'end' in args else None - - ## Fail if bad input. - if not channel : - raise Exception('Missing Channel') - return False + params['count'] = count + params['reverse'] = reverse + params['start'] = start + params['end'] = end ## Get History return self._request({ 'urlcomponents' : [ @@ -378,7 +336,7 @@ class PubnubBase(object): ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), error=self._return_wrapped_callback(error)) - def time(self, args = None) : + def time(self,callback=None) : """ #** #* Time @@ -393,9 +351,6 @@ class PubnubBase(object): print(timestamp) """ - ## Capture Callback - - callback = callback if args and 'callback' in args else None time = self._request({'urlcomponents' : [ 'time', diff --git a/common/PubnubCoreAsync.py b/common/PubnubCoreAsync.py index db10575..deb6038 100644 --- a/common/PubnubCoreAsync.py +++ b/common/PubnubCoreAsync.py @@ -101,7 +101,7 @@ class PubnubCoreAsync(PubnubBase): for i in l: func(i) - def subscribe( self, args=None, sync=False ) : + def subscribe( self, channel, callback, error=None, connect=None, disconnect=None, reconnect=None, sync=False ) : """ #** #* Subscribe @@ -133,27 +133,11 @@ class PubnubCoreAsync(PubnubBase): }) """ - if args is None: - _invoke(error, "Arguments Missing") - return - channel = args['channel'] if 'channel' in args else None - callback = args['callback'] if 'callback' in args else None - connect = args['connect'] if 'connect' in args else None - disconnect = args['disconnect'] if 'disconnect' in args else None - reconnect = args['reconnect'] if 'reconnect' in args else None - error = args['error'] if 'error' in args else None with self._tt_lock: self.last_timetoken = self.timetoken if self.timetoken != 0 else self.last_timetoken self.timetoken = 0 - if channel is None: - _invoke(error, "Channel Missing") - return - if callback is None: - _invoke(error, "Callback Missing") - return - if sync is True and self.susbcribe_sync is not None: self.susbcribe_sync(args) return @@ -184,16 +168,6 @@ class PubnubCoreAsync(PubnubBase): chobj = self.subscriptions[ch] _invoke(chobj['error'],err) - ''' - if callback is None: - _invoke(error, "Callback Missing") - return - - if channel is None: - _invoke(error, "Channel Missing") - return - ''' - def _get_channel(): for ch in self.subscriptions: chobj = self.subscriptions[ch] @@ -290,14 +264,11 @@ class PubnubCoreAsync(PubnubBase): self._connect() - def unsubscribe( self, args ): + def unsubscribe( self, channel ): - if 'channel' in self.subscriptions is False: + if channel in self.subscriptions is False: return False - channel = str(args['channel']) - - ## DISCONNECT with self._channel_list_lock: if channel in self.subscriptions: diff --git a/python/Pubnub.py b/python/Pubnub.py index d41f626..230915c 100644 --- a/python/Pubnub.py +++ b/python/Pubnub.py @@ -247,7 +247,9 @@ class PubnubBase(object): if not isinstance(self.uuid, str): raise AttributeError("pres_uuid must be a string") - def sign(self, channel, message): + ''' + + def _sign(self, channel, message): ## Sign Message if self.secret_key: signature = hashlib.md5('/'.join([ @@ -260,6 +262,7 @@ class PubnubBase(object): else: signature = '0' return signature + ''' def _pam_sign( self, msg ): """Calculate a signature by secret key and message.""" @@ -367,7 +370,7 @@ class PubnubBase(object): return None - def publish( self, args ) : + def publish(channel, message, callback=None, error=None): """ #** #* Publish @@ -388,28 +391,9 @@ class PubnubBase(object): 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 'callback' in args : - callback = args['callback'] - else : - callback = None - - if 'error' in args : - error = args['error'] - else : - error = None message = self.encrypt(args['message']) - #signature = self.sign(channel, message) - ## Send Message return self._request({"urlcomponents": [ 'publish', @@ -422,7 +406,7 @@ class PubnubBase(object): ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), error=self._return_wrapped_callback(error)) - def presence( self, args ) : + def presence( self, channel, callback, error=None) : """ #** #* presence @@ -444,26 +428,10 @@ class PubnubBase(object): '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': self._return_wrapped_callback(callback)}) + return self.subscribe({'channel': channel+'-pnpres', 'subscribe_key':self.subscribe_key, 'callback': self._return_wrapped_callback(callback)}) - def here_now( self, args ) : + def here_now( self, channel, callback, error=None) : """ #** #* Here Now @@ -501,7 +469,7 @@ class PubnubBase(object): ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), error=self._return_wrapped_callback(error)) - def history(self, args) : + def history(self, channel, count=100, reverse=False, start=None, end=None, callback=None, error=None) : """ #** #* History @@ -520,23 +488,13 @@ class PubnubBase(object): print(history) """ - ## Capture User Input - channel = str(args['channel']) - - callback = args['callback'] if 'callback' in args else None - error = args['error'] if 'error' in args else None params = dict() - params['count'] = str(args['count']) if 'count' in args else 100 - params['reverse'] = str(args['reverse']).lower() if 'reverse' in args else 'false' - params['start'] = str(args['start']) if 'start' in args else None - params['end'] = str(args['end']) if 'end' in args else None - - ## Fail if bad input. - if not channel : - raise Exception('Missing Channel') - return False + params['count'] = count + params['reverse'] = reverse + params['start'] = start + params['end'] = end ## Get History return self._request({ 'urlcomponents' : [ @@ -549,7 +507,7 @@ class PubnubBase(object): ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), error=self._return_wrapped_callback(error)) - def time(self, args = None) : + def time(self,callback=None) : """ #** #* Time @@ -564,9 +522,6 @@ class PubnubBase(object): print(timestamp) """ - ## Capture Callback - - callback = callback if args and 'callback' in args else None time = self._request({'urlcomponents' : [ 'time', @@ -698,7 +653,7 @@ class PubnubCoreAsync(PubnubBase): for i in l: func(i) - def subscribe( self, args=None, sync=False ) : + def subscribe( self, channel, callback, error=None, connect=None, disconnect=None, reconnect=None, sync=False ) : """ #** #* Subscribe @@ -730,27 +685,11 @@ class PubnubCoreAsync(PubnubBase): }) """ - if args is None: - _invoke(error, "Arguments Missing") - return - channel = args['channel'] if 'channel' in args else None - callback = args['callback'] if 'callback' in args else None - connect = args['connect'] if 'connect' in args else None - disconnect = args['disconnect'] if 'disconnect' in args else None - reconnect = args['reconnect'] if 'reconnect' in args else None - error = args['error'] if 'error' in args else None with self._tt_lock: self.last_timetoken = self.timetoken if self.timetoken != 0 else self.last_timetoken self.timetoken = 0 - if channel is None: - _invoke(error, "Channel Missing") - return - if callback is None: - _invoke(error, "Callback Missing") - return - if sync is True and self.susbcribe_sync is not None: self.susbcribe_sync(args) return @@ -781,16 +720,6 @@ class PubnubCoreAsync(PubnubBase): chobj = self.subscriptions[ch] _invoke(chobj['error'],err) - ''' - if callback is None: - _invoke(error, "Callback Missing") - return - - if channel is None: - _invoke(error, "Channel Missing") - return - ''' - def _get_channel(): for ch in self.subscriptions: chobj = self.subscriptions[ch] @@ -887,14 +816,11 @@ class PubnubCoreAsync(PubnubBase): self._connect() - def unsubscribe( self, args ): + def unsubscribe( self, channel ): - if 'channel' in self.subscriptions is False: + if channel in self.subscriptions is False: return False - channel = str(args['channel']) - - ## DISCONNECT with self._channel_list_lock: if channel in self.subscriptions: diff --git a/python/examples/dev-console.py b/python/examples/dev-console.py index adade8f..383fa68 100755 --- a/python/examples/dev-console.py +++ b/python/examples/dev-console.py @@ -145,12 +145,7 @@ def _publish_command_handler(): print_ok(r) def _error(r): print_error(r) - pubnub.publish({ - 'channel' : channel, - 'message' : message, - 'callback' : _callback, - 'error' : _error - }) + pubnub.publish(channel, message, _callback, _error) def _subscribe_command_handler(): @@ -159,11 +154,7 @@ def _subscribe_command_handler(): print_ok(r, channel) def _error(r): print_error(r, channel) - pubnub.subscribe({ - 'channel' : channel, - 'callback' : _callback, - 'error' : _error - }) + pubnub.subscribe(channel, _callback, _error) def _unsubscribe_command_handler(): channel = get_input("[UNSUBSCRIBE] Enter Channel Name ", str) @@ -171,11 +162,7 @@ def _unsubscribe_command_handler(): print_ok(r) def _error(r): print_error(r) - pubnub.unsubscribe({ - 'channel' : channel, - 'callback' : _callback, - 'error' : _error - }) + pubnub.unsubscribe(channel) def _grant_command_handler(): def _callback(r): @@ -217,12 +204,7 @@ def _history_command_handler(): channel = get_input("[HISTORY] Enter Channel Name ", str) count = get_input("[HISTORY] Enter Count ", int) - pubnub.history({ - 'channel' : channel, - 'count' : count, - 'callback' : _callback, - 'error' : _error - }) + pubnub.history(channel, count, callback=_callback, error=_error) def _here_now_command_handler(): @@ -232,13 +214,7 @@ def _here_now_command_handler(): print_error(r) channel = get_input("[HERE NOW] Enter Channel Name ", str) - pubnub.here_now({ - 'channel' : channel, - 'callback' : _callback, - 'error' : _error - }) - - + pubnub.here_now(channel, callback=_callback, error=_error) commands = [] -- cgit v1.2.3 From 09cd0c015ae276aa849297a6a976065b2b3f247b Mon Sep 17 00:00:00 2001 From: Devendra Date: Wed, 23 Apr 2014 14:03:13 +0530 Subject: modifying code for pep 8 compliance --- common/PubnubBase.py | 226 +++++------ common/PubnubCore.py | 53 ++- common/PubnubCoreAsync.py | 146 ++++--- common/PubnubCrypto.py | 63 +-- common/PubnubUnitTest.py | 59 +-- common/unit-test-async.py | 94 +++-- python-tornado/Pubnub.py | 566 ++++++++++++-------------- python-tornado/examples/here-now-example.py | 22 +- python-tornado/examples/history-example.py | 26 +- python-tornado/examples/publish-example.py | 48 ++- python-tornado/examples/subscribe-example.py | 27 +- python-tornado/examples/uuid-example.py | 5 +- python-tornado/tests/delivery.py | 140 ++++--- python-tornado/tests/subscribe-test.py | 90 +++-- python-tornado/tests/unit-tests.py | 82 ++-- python-tornado/unassembled/Platform.py | 47 ++- python-twisted/Pubnub.py | 576 +++++++++++++-------------- python-twisted/examples/here-now-example.py | 22 +- python-twisted/examples/history-example.py | 24 +- python-twisted/examples/publish-example.py | 52 ++- python-twisted/examples/subscribe-example.py | 25 +- python-twisted/examples/uuid-example.py | 4 +- python-twisted/tests/delivery.py | 140 ++++--- python-twisted/tests/subscribe-test.py | 86 ++-- python-twisted/tests/unit-test-full.py | 177 ++++---- python-twisted/tests/unit-tests.py | 148 +++---- python-twisted/unassembled/Platform.py | 57 +-- python/Pubnub.py | 521 ++++++++++++------------ python/examples/dev-console.py | 106 +++-- python/examples/here-now-example.py | 26 +- python/examples/history-example.py | 7 +- python/examples/publish-example.py | 52 ++- python/examples/subscribe-example.py | 34 +- python/tests/subscribe-test.py | 90 +++-- python/tests/unit-test.py | 38 +- python/unassembled/Platform.py | 86 ++-- 36 files changed, 2042 insertions(+), 1923 deletions(-) diff --git a/common/PubnubBase.py b/common/PubnubBase.py index 14ae6c4..5863da9 100644 --- a/common/PubnubBase.py +++ b/common/PubnubBase.py @@ -1,32 +1,37 @@ -try: import json -except ImportError: import simplejson as json +try: + import json +except ImportError: + import simplejson as json import time import hashlib import uuid import sys -try: from urllib.parse import quote -except: from urllib2 import quote +try: + from urllib.parse import quote +except: + from urllib2 import quote -from base64 import urlsafe_b64encode +from base64 import urlsafe_b64encode from hashlib import sha256 import hmac + class PubnubBase(object): def __init__( self, publish_key, subscribe_key, - secret_key = False, - cipher_key = False, - auth_key = None, - ssl_on = False, - origin = 'pubsub.pubnub.com', - UUID = None - ) : + secret_key=False, + cipher_key=False, + auth_key=None, + ssl_on=False, + origin='pubsub.pubnub.com', + UUID=None + ): """ #** #* Pubnub @@ -38,41 +43,41 @@ class PubnubBase(object): #* @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) + #* @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.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.auth_key = auth_key - + self.secret_key = secret_key + self.cipher_key = cipher_key + self.ssl = ssl_on + self.auth_key = auth_key - if self.ssl : + if self.ssl: self.origin = 'https://' + self.origin - else : - self.origin = 'http://' + self.origin - + else: + self.origin = 'http://' + self.origin + self.uuid = UUID or str(uuid.uuid4()) if type(sys.version_info) is tuple: - self.python_version = 2 - self.pc = PubnubCrypto2() + self.python_version = 2 + self.pc = PubnubCrypto2() else: if sys.version_info.major == 2: - self.python_version = 2 - self.pc = PubnubCrypto2() + self.python_version = 2 + self.pc = PubnubCrypto2() else: self.python_version = 3 - self.pc = PubnubCrypto3() - + self.pc = PubnubCrypto3() + if not isinstance(self.uuid, str): raise AttributeError("pres_uuid must be a string") @@ -93,7 +98,7 @@ class PubnubBase(object): return signature ''' - def _pam_sign( self, msg ): + def _pam_sign(self, msg): """Calculate a signature by secret key and message.""" return urlsafe_b64encode(hmac.new( @@ -102,7 +107,7 @@ class PubnubBase(object): sha256 ).digest()) - def _pam_auth( self, query , apicode=0, callback=None): + def _pam_auth(self, query, apicode=0, callback=None): """Issue an authenticated request.""" if 'timestamp' not in query: @@ -129,57 +134,50 @@ class PubnubBase(object): query['signature'] = self._pam_sign(sign_input) - ''' - url = ("https://pubsub.pubnub.com/v1/auth/{apitype}/sub-key/".format(apitype="audit" if (apicode) else "grant") + - self.subscribe_key + "?" + - params + "&signature=" + - quote(signature, safe="")) - ''' - return self._request({"urlcomponents": [ - 'v1', 'auth', "audit" if (apicode) else "grant" , + 'v1', 'auth', "audit" if (apicode) else "grant", 'sub-key', self.subscribe_key - ], 'urlparams' : query}, - self._return_wrapped_callback(callback)) + ], 'urlparams': query}, + self._return_wrapped_callback(callback)) - def grant( self, channel, authkey=False, read=True, write=True, ttl=5, callback=None): + def grant(self, channel, authkey=False, read=True, + write=True, ttl=5, callback=None): """Grant Access on a Channel.""" return self._pam_auth({ - "channel" : channel, - "auth" : authkey, - "r" : read and 1 or 0, - "w" : write and 1 or 0, - "ttl" : ttl + "channel": channel, + "auth": authkey, + "r": read and 1 or 0, + "w": write and 1 or 0, + "ttl": ttl }, callback=callback) - def revoke( self, channel, authkey=False, ttl=1, callback=None): + def revoke(self, channel, authkey=False, ttl=1, callback=None): """Revoke Access on a Channel.""" return self._pam_auth({ - "channel" : channel, - "auth" : authkey, - "r" : 0, - "w" : 0, - "ttl" : ttl + "channel": channel, + "auth": authkey, + "r": 0, + "w": 0, + "ttl": ttl }, callback=callback) def audit(self, channel=False, authkey=False, callback=None): return self._pam_auth({ - "channel" : channel, - "auth" : authkey - },1, callback=callback) - - + "channel": channel, + "auth": authkey + }, 1, callback=callback) 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(self.pc.encrypt( + self.cipher_key, json.dumps(message)).replace('\n', '')) + else: message = json.dumps(message) - return message; + return message def decrypt(self, message): if self.cipher_key: @@ -190,15 +188,17 @@ class PubnubBase(object): def _return_wrapped_callback(self, callback=None): def _new_format_callback(response): if 'payload' in response: - if (callback != None): callback({'message' : response['message'], 'payload' : response['payload']}) + if (callback is not None): + callback({'message': response['message'], + 'payload': response['payload']}) else: - if (callback != None):callback(response) - if (callback != None): + if (callback is not None): + callback(response) + if (callback is not None): return _new_format_callback else: return None - def publish(channel, message, callback=None, error=None): """ #** @@ -232,10 +232,11 @@ class PubnubBase(object): channel, '0', message - ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) - - def presence( self, channel, callback, error=None) : + ], 'urlparams': {'auth': self.auth_key}}, + callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) + + def presence(self, channel, callback, error=None): """ #** #* presence @@ -254,13 +255,15 @@ class PubnubBase(object): pubnub.presence({ 'channel' : 'hello_world', - 'callback' : receive + 'callback' : receive }) """ - return self.subscribe({'channel': channel+'-pnpres', 'subscribe_key':self.subscribe_key, 'callback': self._return_wrapped_callback(callback)}) - - - def here_now( self, channel, callback, error=None) : + return self.subscribe({ + 'channel': channel + '-pnpres', + 'subscribe_key': self.subscribe_key, + 'callback': self._return_wrapped_callback(callback)}) + + def here_now(self, channel, callback, error=None): """ #** #* Here Now @@ -281,33 +284,31 @@ class PubnubBase(object): """ channel = str(args['channel']) - - callback = args['callback'] if 'callback' in args else None - error = args['error'] if 'error' in args else None + callback = args['callback'] if 'callback' in args else None + error = args['error'] if 'error' in args else None ## Fail if bad input. - if not channel : + if not channel: raise Exception('Missing Channel') return False - + ## Get Presence Here Now return self._request({"urlcomponents": [ - 'v2','presence', + 'v2', 'presence', 'sub_key', self.subscribe_key, 'channel', channel - ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) + ], 'urlparams': {'auth': self.auth_key}}, + callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) - def history(self, channel, count=100, reverse=False, start=None, end=None, callback=None, error=None) : + def history(self, channel, count=100, reverse=False, + start=None, end=None, callback=None, error=None): """ #** #* History #* #* Load 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({ @@ -318,25 +319,26 @@ class PubnubBase(object): """ - params = dict() + params = dict() - params['count'] = count - params['reverse'] = reverse - params['start'] = start - params['end'] = end + params['count'] = count + params['reverse'] = reverse + params['start'] = start + params['end'] = end ## Get History - return self._request({ 'urlcomponents' : [ + return self._request({'urlcomponents': [ 'v2', 'history', 'sub-key', self.subscribe_key, 'channel', channel, - ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) + ], 'urlparams': {'auth': self.auth_key}}, + callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) - def time(self,callback=None) : + def time(self, callback=None): """ #** #* Time @@ -352,28 +354,28 @@ class PubnubBase(object): """ - time = self._request({'urlcomponents' : [ + time = self._request({'urlcomponents': [ 'time', '0' ]}, callback) - if time != None: + if time is not None: return time[0] - - def _encode( self, request ) : + 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): + "".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"]]) + "".join([' ~`!@#$%^&*()+=[]\\{}|;\':",./<>?'.find(ch) > -1 and + hex(ord(ch)).replace('0x', '%').upper() or + ch for ch in list(bit) + ]) for bit in request["urlcomponents"]]) if ("urlparams" in request): - url = url + '?' + "&".join([ x + "=" + str(y) for x,y in request["urlparams"].items() if y is not None]) + url = url + '?' + "&".join([x + "=" + str(y) for x, y in request[ + "urlparams"].items() if y is not None]) return url diff --git a/common/PubnubCore.py b/common/PubnubCore.py index 7fb67d6..1c00215 100644 --- a/common/PubnubCore.py +++ b/common/PubnubCore.py @@ -3,13 +3,13 @@ class PubnubCore(PubnubCoreAsync): self, publish_key, subscribe_key, - secret_key = False, - cipher_key = False, - auth_key = None, - ssl_on = False, - origin = 'pubsub.pubnub.com', - uuid = None - ) : + secret_key=False, + cipher_key=False, + auth_key=None, + ssl_on=False, + origin='pubsub.pubnub.com', + uuid=None + ): """ #** #* Pubnub @@ -21,7 +21,8 @@ class PubnubCore(PubnubCoreAsync): #* @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) + #* @param string pres_uuid optional + #* identifier for presence (auto-generated if not supplied) #** ## Initiat Class @@ -37,16 +38,14 @@ class PubnubCore(PubnubCoreAsync): ssl_on=ssl_on, origin=origin, UUID=uuid - ) + ) self.subscriptions = {} - self.timetoken = 0 - self.version = '3.4' + self.timetoken = 0 + self.version = '3.4' self.accept_encoding = 'gzip' - - - def subscribe_sync( self, args ) : + def subscribe_sync(self, args): """ #** #* Subscribe @@ -65,50 +64,50 @@ class PubnubCore(PubnubCoreAsync): pubnub.subscribe({ 'channel' : 'hello_world', - 'callback' : receive + 'callback' : receive }) """ ## Fail if missing channel - if not 'channel' in args : + if not 'channel' in args: raise Exception('Missing Channel.') return False ## Fail if missing callback - if not 'callback' in args : + if not 'callback' in args: raise Exception('Missing Callback.') return False ## Capture User Input - channel = str(args['channel']) - callback = args['callback'] + channel = str(args['channel']) + callback = args['callback'] subscribe_key = args.get('subscribe_key') or self.subscribe_key ## Begin Subscribe - while True : + while True: timetoken = 'timetoken' in args and args['timetoken'] or 0 - try : + try: ## Wait for Message - response = self._request({"urlcomponents" : [ + response = self._request({"urlcomponents": [ 'subscribe', subscribe_key, channel, '0', str(timetoken) - ],"urlparams" : {"uuid" : self.uuid }}) + ], "urlparams": {"uuid": self.uuid}}) - messages = response[0] + messages = response[0] args['timetoken'] = response[1] ## If it was a timeout - if not len(messages) : + if not len(messages): continue ## Run user Callback and Reconnect if user permits. - for message in messages : - if not callback(self.decrypt(message)) : + for message in messages: + if not callback(self.decrypt(message)): return except Exception: diff --git a/common/PubnubCoreAsync.py b/common/PubnubCoreAsync.py index deb6038..de7627f 100644 --- a/common/PubnubCoreAsync.py +++ b/common/PubnubCoreAsync.py @@ -6,32 +6,38 @@ except ImportError: sha256 = digestmod.new import hmac + class EmptyLock(): def __enter__(self): pass - def __exit__(self,a,b,c): + + def __exit__(self, a, b, c): pass empty_lock = EmptyLock() + class PubnubCoreAsync(PubnubBase): - def start(self): pass - def stop(self): pass + def start(self): + pass + + def stop(self): + pass def __init__( self, publish_key, subscribe_key, - secret_key = False, - cipher_key = False, - auth_key = None, - ssl_on = False, - origin = 'pubsub.pubnub.com', - uuid = None, + secret_key=False, + cipher_key=False, + auth_key=None, + ssl_on=False, + origin='pubsub.pubnub.com', + uuid=None, _tt_lock=empty_lock, _channel_list_lock=empty_lock - ) : + ): """ #** #* Pubnub @@ -58,18 +64,18 @@ class PubnubCoreAsync(PubnubBase): ssl_on=ssl_on, origin=origin, UUID=uuid - ) - - self.subscriptions = {} - self.timetoken = 0 - self.last_timetoken = 0 - self.version = '3.3.4' - self.accept_encoding = 'gzip' - self.SUB_RECEIVER = None - self._connect = None - self._tt_lock = _tt_lock - self._channel_list_lock = _channel_list_lock - self._connect = lambda: None + ) + + self.subscriptions = {} + self.timetoken = 0 + self.last_timetoken = 0 + self.version = '3.3.4' + self.accept_encoding = 'gzip' + self.SUB_RECEIVER = None + self._connect = None + self._tt_lock = _tt_lock + self._channel_list_lock = _channel_list_lock + self._connect = lambda: None def get_channel_list(self, channels): channel = '' @@ -101,7 +107,8 @@ class PubnubCoreAsync(PubnubBase): for i in l: func(i) - def subscribe( self, channel, callback, error=None, connect=None, disconnect=None, reconnect=None, sync=False ) : + def subscribe(self, channel, callback, error=None, + connect=None, disconnect=None, reconnect=None, sync=False): """ #** #* Subscribe @@ -135,14 +142,15 @@ class PubnubCoreAsync(PubnubBase): """ with self._tt_lock: - self.last_timetoken = self.timetoken if self.timetoken != 0 else self.last_timetoken + self.last_timetoken = self.timetoken if self.timetoken != 0 \ + else self.last_timetoken self.timetoken = 0 if sync is True and self.susbcribe_sync is not None: self.susbcribe_sync(args) return - def _invoke(func,msg=None): + def _invoke(func, msg=None): if func is not None: if msg is not None: func(msg) @@ -156,17 +164,17 @@ class PubnubCoreAsync(PubnubBase): chobj = self.subscriptions[ch] if chobj['connected'] is False: chobj['connected'] = True - _invoke(chobj['connect'],chobj['name']) + _invoke(chobj['connect'], chobj['name']) def _invoke_error(channel_list=None, err=None): if channel_list is None: for ch in self.subscriptions: chobj = self.subscriptions[ch] - _invoke(chobj['error'],err) + _invoke(chobj['error'], err) else: for ch in channel_list: chobj = self.subscriptions[ch] - _invoke(chobj['error'],err) + _invoke(chobj['error'], err) def _get_channel(): for ch in self.subscriptions: @@ -174,53 +182,58 @@ class PubnubCoreAsync(PubnubBase): if chobj['subscribed'] is True: return chobj - ## New Channel? - if not channel in self.subscriptions or self.subscriptions[channel]['subscribed'] is False: - with self._channel_list_lock: - self.subscriptions[channel] = { - 'name' : channel, - 'first' : False, - 'connected' : False, - 'subscribed' : True, - 'callback' : callback, - 'connect' : connect, - 'disconnect' : disconnect, - 'reconnect' : reconnect, - 'error' : error - } - + if not channel in self.subscriptions or \ + self.subscriptions[channel]['subscribed'] is False: + with self._channel_list_lock: + self.subscriptions[channel] = { + 'name': channel, + 'first': False, + 'connected': False, + 'subscribed': True, + 'callback': callback, + 'connect': connect, + 'disconnect': disconnect, + 'reconnect': reconnect, + 'error': error + } ## return if already connected to channel - if channel in self.subscriptions and 'connected' in self.subscriptions[channel] and self.subscriptions[channel]['connected'] is True: - _invoke(error, "Already Connected") - return - - + if channel in self.subscriptions and \ + 'connected' in self.subscriptions[channel] and \ + self.subscriptions[channel]['connected'] is True: + _invoke(error, "Already Connected") + return - ## SUBSCRIPTION RECURSION + ## SUBSCRIPTION RECURSION def _connect(): - + self._reset_offline() def sub_callback(response): ## ERROR ? - if not response or ('message' in response and response['message'] == 'Forbidden'): - _invoke_error(response['payload']['channels'], response['message']) - _connect() - return + if not response or \ + ('message' in response and + response['message'] == 'Forbidden'): + _invoke_error(response['payload'][ + 'channels'], response['message']) + _connect() + return _invoke_connect() with self._tt_lock: - self.timetoken = self.last_timetoken if self.timetoken == 0 and self.last_timetoken != 0 else response[1] + self.timetoken = \ + self.last_timetoken if self.timetoken == 0 and \ + self.last_timetoken != 0 else response[1] if len(response) > 2: channel_list = response[2].split(',') response_list = response[0] for ch in enumerate(channel_list): if ch[1] in self.subscriptions: chobj = self.subscriptions[ch[1]] - _invoke(chobj['callback'],self.decrypt(response_list[ch[0]])) + _invoke(chobj['callback'], + self.decrypt(response_list[ch[0]])) else: response_list = response[0] chobj = _get_channel() @@ -230,23 +243,25 @@ class PubnubCoreAsync(PubnubBase): _connect() - channel_list = self.get_channel_list(self.subscriptions) if len(channel_list) <= 0: return ## CONNECT TO PUBNUB SUBSCRIBE SERVERS try: - self.SUB_RECEIVER = self._request( { "urlcomponents" : [ + self.SUB_RECEIVER = self._request({"urlcomponents": [ 'subscribe', self.subscribe_key, channel_list, '0', str(self.timetoken) - ], "urlparams" : {"uuid":self.uuid, "auth" : self.auth_key} }, sub_callback, sub_callback, single=True ) + ], "urlparams": {"uuid": self.uuid, "auth": self.auth_key}}, + sub_callback, + sub_callback, + single=True) except Exception as e: print(e) - self.timeout( 1, _connect) + self.timeout(1, _connect) return self._connect = _connect @@ -263,8 +278,7 @@ class PubnubCoreAsync(PubnubBase): self._reset_offline() self._connect() - - def unsubscribe( self, channel ): + def unsubscribe(self, channel): if channel in self.subscriptions is False: return False @@ -272,8 +286,8 @@ class PubnubCoreAsync(PubnubBase): ## DISCONNECT with self._channel_list_lock: if channel in self.subscriptions: - self.subscriptions[channel]['connected'] = 0 - self.subscriptions[channel]['subscribed'] = False - self.subscriptions[channel]['timetoken'] = 0 - self.subscriptions[channel]['first'] = False + self.subscriptions[channel]['connected'] = 0 + self.subscriptions[channel]['subscribed'] = False + self.subscriptions[channel]['timetoken'] = 0 + self.subscriptions[channel]['first'] = False self.CONNECT() diff --git a/common/PubnubCrypto.py b/common/PubnubCrypto.py index 3489216..295a76e 100644 --- a/common/PubnubCrypto.py +++ b/common/PubnubCrypto.py @@ -1,10 +1,11 @@ from Crypto.Cipher import AES from Crypto.Hash import MD5 -from base64 import encodestring, decodestring +from base64 import encodestring, decodestring import hashlib import hmac -class PubnubCrypto2() : + +class PubnubCrypto2(): """ #** #* PubnubCrypto @@ -15,8 +16,8 @@ class PubnubCrypto2() : pc = PubnubCrypto """ - - def pad( self, msg, block_size=16 ): + + def pad(self, msg, block_size=16): """ #** #* pad @@ -28,9 +29,9 @@ class PubnubCrypto2() : #** """ padding = block_size - (len(msg) % block_size) - return msg + chr(padding)*padding - - def depad( self, msg ): + return msg + chr(padding) * padding + + def depad(self, msg): """ #** #* depad @@ -41,7 +42,7 @@ class PubnubCrypto2() : """ return msg[0:-ord(msg[-1])] - def getSecret( self, key ): + def getSecret(self, key): """ #** #* getSecret @@ -52,7 +53,7 @@ class PubnubCrypto2() : """ return hashlib.sha256(key).hexdigest() - def encrypt( self, key, msg ): + def encrypt(self, key, msg): """ #** #* encrypt @@ -62,11 +63,12 @@ class PubnubCrypto2() : #** """ secret = self.getSecret(key) - Initial16bytes='0123456789012345' - cipher = AES.new(secret[0:32],AES.MODE_CBC,Initial16bytes) + 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 ): + + def decrypt(self, key, msg): """ #** #* decrypt @@ -76,12 +78,12 @@ class PubnubCrypto2() : #** """ secret = self.getSecret(key) - Initial16bytes='0123456789012345' - cipher = AES.new(secret[0:32],AES.MODE_CBC,Initial16bytes) + Initial16bytes = '0123456789012345' + cipher = AES.new(secret[0:32], AES.MODE_CBC, Initial16bytes) return self.depad((cipher.decrypt(decodestring(msg)))) -class PubnubCrypto3() : +class PubnubCrypto3(): """ #** #* PubnubCrypto @@ -92,8 +94,8 @@ class PubnubCrypto3() : pc = PubnubCrypto """ - - def pad( self, msg, block_size=16 ): + + def pad(self, msg, block_size=16): """ #** #* pad @@ -105,9 +107,9 @@ class PubnubCrypto3() : #** """ padding = block_size - (len(msg) % block_size) - return msg + (chr(padding)*padding).encode('utf-8') - - def depad( self, msg ): + return msg + (chr(padding) * padding).encode('utf-8') + + def depad(self, msg): """ #** #* depad @@ -118,7 +120,7 @@ class PubnubCrypto3() : """ return msg[0:-ord(msg[-1])] - def getSecret( self, key ): + def getSecret(self, key): """ #** #* getSecret @@ -129,7 +131,7 @@ class PubnubCrypto3() : """ return hashlib.sha256(key.encode("utf-8")).hexdigest() - def encrypt( self, key, msg ): + def encrypt(self, key, msg): """ #** #* encrypt @@ -139,10 +141,12 @@ class PubnubCrypto3() : #** """ secret = self.getSecret(key) - Initial16bytes='0123456789012345' - cipher = AES.new(secret[0:32],AES.MODE_CBC,Initial16bytes) - return encodestring(cipher.encrypt(self.pad(msg.encode('utf-8')))).decode('utf-8') - def decrypt( self, key, msg ): + Initial16bytes = '0123456789012345' + cipher = AES.new(secret[0:32], AES.MODE_CBC, Initial16bytes) + return encodestring( + cipher.encrypt(self.pad(msg.encode('utf-8')))).decode('utf-8') + + def decrypt(self, key, msg): """ #** #* decrypt @@ -152,6 +156,7 @@ class PubnubCrypto3() : #** """ secret = self.getSecret(key) - Initial16bytes='0123456789012345' - cipher = AES.new(secret[0:32],AES.MODE_CBC,Initial16bytes) - return (cipher.decrypt(decodestring(msg.encode('utf-8')))).decode('utf-8') + Initial16bytes = '0123456789012345' + cipher = AES.new(secret[0:32], AES.MODE_CBC, Initial16bytes) + return (cipher.decrypt( + decodestring(msg.encode('utf-8')))).decode('utf-8') diff --git a/common/PubnubUnitTest.py b/common/PubnubUnitTest.py index 2f9d28c..518d226 100644 --- a/common/PubnubUnitTest.py +++ b/common/PubnubUnitTest.py @@ -1,36 +1,37 @@ import time + class Suite(): - def __init__(self, pubnub, expected): - self.pubnub = pubnub - self.total = expected - self.passed = 0 - self.failed = 0 - self.started = False + def __init__(self, pubnub, expected): + self.pubnub = pubnub + self.total = expected + self.passed = 0 + self.failed = 0 + self.started = False - def test(self, condition , name, message = None, response = None): + def test(self, condition, name, message=None, response=None): - if condition: - self.passed += 1 - msg = "PASS : " + name - if message: - msg += ", " + message - if response: - msg += ", " + response - print msg - else: - self.failed += 1 - msg = "FAIL : " + name - if message: - msg += ", " + message - if response: - msg += ", " + response - print msg + if condition: + self.passed += 1 + msg = "PASS : " + name + if message: + msg += ", " + message + if response: + msg += ", " + response + print msg + else: + self.failed += 1 + msg = "FAIL : " + name + if message: + msg += ", " + message + if response: + msg += ", " + response + print msg - if self.total == self.failed + self.passed: - print "\n======== RESULT ========" - print "Total\t:\t", self.total - print "Passed\t:\t", self.passed - print "Failed\t:\t", self.failed - self.pubnub.stop() + if self.total == self.failed + self.passed: + print "\n======== RESULT ========" + print "Total\t:\t", self.total + print "Passed\t:\t", self.passed + print "Failed\t:\t", self.failed + self.pubnub.stop() diff --git a/common/unit-test-async.py b/common/unit-test-async.py index f95c759..8123fdb 100644 --- a/common/unit-test-async.py +++ b/common/unit-test-async.py @@ -1,4 +1,4 @@ -## www.pubnub.com - PubNub Real-time push service in the cloud. +## www.pubnub.com - PubNub Real-time push service in the cloud. # coding=utf8 ## PubNub Real-time Push APIs and Notifications Framework @@ -17,42 +17,45 @@ sys.path.append('./') sys.path.append('../common/') from Pubnub import Pubnub -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or None -cipher_key = len(sys.argv) > 4 and sys.argv[4] or None -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False +secret_key = len(sys.argv) > 3 and sys.argv[3] or None +cipher_key = len(sys.argv) > 4 and sys.argv[4] or None +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- ## Initiat Class ## ----------------------------------------------------------------------- -pubnub = Pubnub( publish_key, subscribe_key, secret_key, cipher_key, ssl_on ) +pubnub = Pubnub(publish_key, subscribe_key, secret_key, cipher_key, ssl_on) ch = 'python-async-test-channel-' expect = 0 done = 0 failures = 0 passes = 0 + def stop(): global done global count pubnub.stop() print "============================" - print 'Total\t:\t' , failures + passes - print 'PASS\t:\t' , passes + print 'Total\t:\t', failures + passes + print 'PASS\t:\t', passes print 'FAIL\t:\t', failures print "============================" ## --------------------------------------------------------------------------- ## Unit Test Function ## --------------------------------------------------------------------------- -def test( trial, name ) : + + +def test(trial, name): global failures global passes global done done += 1 #print trial - if trial == False: + if trial is False: print 'FAIL : ', name failures += 1 else: @@ -61,77 +64,87 @@ def test( trial, name ) : if done == expect: stop() + def test_publish(): channel = ch + str(random.random()) + def publish_cb(messages): test(messages[0] == 1, "Publish Test") pubnub.publish({ - 'channel' : channel, - 'message' : {'one': 'Hello World! --> ɂ顶@#$%^&*()!', 'two': 'hello2'}, - 'callback' : publish_cb - }) + 'channel': channel, + 'message': {'one': 'Hello World! --> ɂ顶@#$%^&*()!', 'two': 'hello2'}, + 'callback': publish_cb + }) def test_history(): channel = ch + str(random.random()) + def history_cb(messages): - test(len(messages) <= 1, "History Test") + test(len(messages) <= 1, "History Test") pubnub.history({ - 'channel' : channel, - 'limit' : 1, - 'callback' : history_cb + 'channel': channel, + 'limit': 1, + 'callback': history_cb }) - def test_subscribe(): message = "Testing Subscribe " + str(random.random()) channel = ch + str(random.random()) + def subscribe_connect_cb(): def publish_cb(response): - test(response[0] == 1, 'Publish Test in subscribe Connect Callback') + test(response[0] == 1, + 'Publish Test in subscribe Connect Callback') pubnub.publish({ - 'channel' : channel, - 'message' : message, - 'callback' : publish_cb + 'channel': channel, + 'message': message, + 'callback': publish_cb }) + def subscribe_cb(response): - test(response == message , 'Subscribe Receive Test in subscribe Callback') + test(response == message, + 'Subscribe Receive Test in subscribe Callback') pubnub.subscribe({ - 'channel' : channel, - 'connect' : subscribe_connect_cb, + 'channel': channel, + 'connect': subscribe_connect_cb, 'callback': subscribe_cb - }) - + }) + def test_here_now(): - channel = ch + str(random.random()) + channel = ch + str(random.random()) message = "Testing Subscribe" + def subscribe_connect_cb(): def here_now_cb(response): test(response["occupancy"] > 0, 'Here Now Test') + def publish_cb(response): - test(response[0] == 1, 'Here Now Test: Publish Test in subscribe Connect Callback') + test(response[0] == 1, + 'Here Now Test: Publish Test in \ + subscribe Connect Callback') pubnub.publish({ - 'channel' : channel, - 'message' : message, - 'callback' : publish_cb + 'channel': channel, + 'message': message, + 'callback': publish_cb }) time.sleep(5) pubnub.here_now({ - 'channel' : channel, - 'callback' : here_now_cb + 'channel': channel, + 'callback': here_now_cb }) - def subscribe_cb(response): - test(response == message , 'Here Now Test: Subscribe Receive Test in subscribe Callback') + test(response == message, + 'Here Now Test: Subscribe Receive Test in subscribe Callback') pubnub.subscribe({ - 'channel' : channel, - 'connect' : subscribe_connect_cb, + 'channel': channel, + 'connect': subscribe_connect_cb, 'callback': subscribe_cb - }) + }) expect = 7 test_publish() @@ -140,7 +153,6 @@ test_subscribe() test_here_now() - pubnub.start() if failures > 0: raise Exception('Fail', failures) diff --git a/python-tornado/Pubnub.py b/python-tornado/Pubnub.py index 5607df0..718d74e 100644 --- a/python-tornado/Pubnub.py +++ b/python-tornado/Pubnub.py @@ -12,11 +12,12 @@ from Crypto.Cipher import AES from Crypto.Hash import MD5 -from base64 import encodestring, decodestring +from base64 import encodestring, decodestring import hashlib import hmac -class PubnubCrypto2() : + +class PubnubCrypto2(): """ #** #* PubnubCrypto @@ -27,8 +28,8 @@ class PubnubCrypto2() : pc = PubnubCrypto """ - - def pad( self, msg, block_size=16 ): + + def pad(self, msg, block_size=16): """ #** #* pad @@ -40,9 +41,9 @@ class PubnubCrypto2() : #** """ padding = block_size - (len(msg) % block_size) - return msg + chr(padding)*padding - - def depad( self, msg ): + return msg + chr(padding) * padding + + def depad(self, msg): """ #** #* depad @@ -53,7 +54,7 @@ class PubnubCrypto2() : """ return msg[0:-ord(msg[-1])] - def getSecret( self, key ): + def getSecret(self, key): """ #** #* getSecret @@ -64,7 +65,7 @@ class PubnubCrypto2() : """ return hashlib.sha256(key).hexdigest() - def encrypt( self, key, msg ): + def encrypt(self, key, msg): """ #** #* encrypt @@ -74,11 +75,12 @@ class PubnubCrypto2() : #** """ secret = self.getSecret(key) - Initial16bytes='0123456789012345' - cipher = AES.new(secret[0:32],AES.MODE_CBC,Initial16bytes) + 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 ): + + def decrypt(self, key, msg): """ #** #* decrypt @@ -88,12 +90,12 @@ class PubnubCrypto2() : #** """ secret = self.getSecret(key) - Initial16bytes='0123456789012345' - cipher = AES.new(secret[0:32],AES.MODE_CBC,Initial16bytes) + Initial16bytes = '0123456789012345' + cipher = AES.new(secret[0:32], AES.MODE_CBC, Initial16bytes) return self.depad((cipher.decrypt(decodestring(msg)))) -class PubnubCrypto3() : +class PubnubCrypto3(): """ #** #* PubnubCrypto @@ -104,8 +106,8 @@ class PubnubCrypto3() : pc = PubnubCrypto """ - - def pad( self, msg, block_size=16 ): + + def pad(self, msg, block_size=16): """ #** #* pad @@ -117,9 +119,9 @@ class PubnubCrypto3() : #** """ padding = block_size - (len(msg) % block_size) - return msg + (chr(padding)*padding).encode('utf-8') - - def depad( self, msg ): + return msg + (chr(padding) * padding).encode('utf-8') + + def depad(self, msg): """ #** #* depad @@ -130,7 +132,7 @@ class PubnubCrypto3() : """ return msg[0:-ord(msg[-1])] - def getSecret( self, key ): + def getSecret(self, key): """ #** #* getSecret @@ -141,7 +143,7 @@ class PubnubCrypto3() : """ return hashlib.sha256(key.encode("utf-8")).hexdigest() - def encrypt( self, key, msg ): + def encrypt(self, key, msg): """ #** #* encrypt @@ -151,10 +153,12 @@ class PubnubCrypto3() : #** """ secret = self.getSecret(key) - Initial16bytes='0123456789012345' - cipher = AES.new(secret[0:32],AES.MODE_CBC,Initial16bytes) - return encodestring(cipher.encrypt(self.pad(msg.encode('utf-8')))).decode('utf-8') - def decrypt( self, key, msg ): + Initial16bytes = '0123456789012345' + cipher = AES.new(secret[0:32], AES.MODE_CBC, Initial16bytes) + return encodestring( + cipher.encrypt(self.pad(msg.encode('utf-8')))).decode('utf-8') + + def decrypt(self, key, msg): """ #** #* decrypt @@ -164,40 +168,46 @@ class PubnubCrypto3() : #** """ secret = self.getSecret(key) - Initial16bytes='0123456789012345' - cipher = AES.new(secret[0:32],AES.MODE_CBC,Initial16bytes) - return (cipher.decrypt(decodestring(msg.encode('utf-8')))).decode('utf-8') + Initial16bytes = '0123456789012345' + cipher = AES.new(secret[0:32], AES.MODE_CBC, Initial16bytes) + return (cipher.decrypt( + decodestring(msg.encode('utf-8')))).decode('utf-8') -try: import json -except ImportError: import simplejson as json +try: + import json +except ImportError: + import simplejson as json import time import hashlib import uuid import sys -try: from urllib.parse import quote -except: from urllib2 import quote +try: + from urllib.parse import quote +except: + from urllib2 import quote -from base64 import urlsafe_b64encode +from base64 import urlsafe_b64encode from hashlib import sha256 import hmac + class PubnubBase(object): def __init__( self, publish_key, subscribe_key, - secret_key = False, - cipher_key = False, - auth_key = None, - ssl_on = False, - origin = 'pubsub.pubnub.com', - UUID = None - ) : + secret_key=False, + cipher_key=False, + auth_key=None, + ssl_on=False, + origin='pubsub.pubnub.com', + UUID=None + ): """ #** #* Pubnub @@ -209,45 +219,47 @@ class PubnubBase(object): #* @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) + #* @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.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.auth_key = auth_key + self.secret_key = secret_key + self.cipher_key = cipher_key + self.ssl = ssl_on + self.auth_key = auth_key - - if self.ssl : + if self.ssl: self.origin = 'https://' + self.origin - else : - self.origin = 'http://' + self.origin - + else: + self.origin = 'http://' + self.origin + self.uuid = UUID or str(uuid.uuid4()) if type(sys.version_info) is tuple: - self.python_version = 2 - self.pc = PubnubCrypto2() + self.python_version = 2 + self.pc = PubnubCrypto2() else: if sys.version_info.major == 2: - self.python_version = 2 - self.pc = PubnubCrypto2() + self.python_version = 2 + self.pc = PubnubCrypto2() else: self.python_version = 3 - self.pc = PubnubCrypto3() - + self.pc = PubnubCrypto3() + if not isinstance(self.uuid, str): raise AttributeError("pres_uuid must be a string") - def sign(self, channel, message): + ''' + + def _sign(self, channel, message): ## Sign Message if self.secret_key: signature = hashlib.md5('/'.join([ @@ -260,8 +272,9 @@ class PubnubBase(object): else: signature = '0' return signature + ''' - def _pam_sign( self, msg ): + def _pam_sign(self, msg): """Calculate a signature by secret key and message.""" return urlsafe_b64encode(hmac.new( @@ -270,7 +283,7 @@ class PubnubBase(object): sha256 ).digest()) - def _pam_auth( self, query , apicode=0, callback=None): + def _pam_auth(self, query, apicode=0, callback=None): """Issue an authenticated request.""" if 'timestamp' not in query: @@ -297,57 +310,50 @@ class PubnubBase(object): query['signature'] = self._pam_sign(sign_input) - ''' - url = ("https://pubsub.pubnub.com/v1/auth/{apitype}/sub-key/".format(apitype="audit" if (apicode) else "grant") + - self.subscribe_key + "?" + - params + "&signature=" + - quote(signature, safe="")) - ''' - return self._request({"urlcomponents": [ - 'v1', 'auth', "audit" if (apicode) else "grant" , + 'v1', 'auth', "audit" if (apicode) else "grant", 'sub-key', self.subscribe_key - ], 'urlparams' : query}, - self._return_wrapped_callback(callback)) + ], 'urlparams': query}, + self._return_wrapped_callback(callback)) - def grant( self, channel, authkey=False, read=True, write=True, ttl=5, callback=None): + def grant(self, channel, authkey=False, read=True, + write=True, ttl=5, callback=None): """Grant Access on a Channel.""" return self._pam_auth({ - "channel" : channel, - "auth" : authkey, - "r" : read and 1 or 0, - "w" : write and 1 or 0, - "ttl" : ttl + "channel": channel, + "auth": authkey, + "r": read and 1 or 0, + "w": write and 1 or 0, + "ttl": ttl }, callback=callback) - def revoke( self, channel, authkey=False, ttl=1, callback=None): + def revoke(self, channel, authkey=False, ttl=1, callback=None): """Revoke Access on a Channel.""" return self._pam_auth({ - "channel" : channel, - "auth" : authkey, - "r" : 0, - "w" : 0, - "ttl" : ttl + "channel": channel, + "auth": authkey, + "r": 0, + "w": 0, + "ttl": ttl }, callback=callback) def audit(self, channel=False, authkey=False, callback=None): return self._pam_auth({ - "channel" : channel, - "auth" : authkey - },1, callback=callback) - - + "channel": channel, + "auth": authkey + }, 1, callback=callback) 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(self.pc.encrypt( + self.cipher_key, json.dumps(message)).replace('\n', '')) + else: message = json.dumps(message) - return message; + return message def decrypt(self, message): if self.cipher_key: @@ -358,16 +364,18 @@ class PubnubBase(object): def _return_wrapped_callback(self, callback=None): def _new_format_callback(response): if 'payload' in response: - if (callback != None): callback({'message' : response['message'], 'payload' : response['payload']}) + if (callback is not None): + callback({'message': response['message'], + 'payload': response['payload']}) else: - if (callback != None):callback(response) - if (callback != None): + if (callback is not None): + callback(response) + if (callback is not None): return _new_format_callback else: return None - - def publish( self, args ) : + def publish(channel, message, callback=None, error=None): """ #** #* Publish @@ -388,28 +396,9 @@ class PubnubBase(object): 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 'callback' in args : - callback = args['callback'] - else : - callback = None - - if 'error' in args : - error = args['error'] - else : - error = None message = self.encrypt(args['message']) - #signature = self.sign(channel, message) - ## Send Message return self._request({"urlcomponents": [ 'publish', @@ -419,10 +408,11 @@ class PubnubBase(object): channel, '0', message - ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) - - def presence( self, args ) : + ], 'urlparams': {'auth': self.auth_key}}, + callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) + + def presence(self, channel, callback, error=None): """ #** #* presence @@ -441,29 +431,15 @@ class PubnubBase(object): pubnub.presence({ 'channel' : 'hello_world', - 'callback' : receive + 'callback' : receive }) """ + return self.subscribe({ + 'channel': channel + '-pnpres', + 'subscribe_key': self.subscribe_key, + 'callback': self._return_wrapped_callback(callback)}) - ## 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': self._return_wrapped_callback(callback)}) - - - def here_now( self, args ) : + def here_now(self, channel, callback, error=None): """ #** #* Here Now @@ -484,33 +460,31 @@ class PubnubBase(object): """ channel = str(args['channel']) - - callback = args['callback'] if 'callback' in args else None - error = args['error'] if 'error' in args else None + callback = args['callback'] if 'callback' in args else None + error = args['error'] if 'error' in args else None ## Fail if bad input. - if not channel : + if not channel: raise Exception('Missing Channel') return False - + ## Get Presence Here Now return self._request({"urlcomponents": [ - 'v2','presence', + 'v2', 'presence', 'sub_key', self.subscribe_key, 'channel', channel - ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) + ], 'urlparams': {'auth': self.auth_key}}, + callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) - def history(self, args) : + def history(self, channel, count=100, reverse=False, + start=None, end=None, callback=None, error=None): """ #** #* History #* #* Load 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({ @@ -520,36 +494,27 @@ class PubnubBase(object): print(history) """ - ## Capture User Input - channel = str(args['channel']) - callback = args['callback'] if 'callback' in args else None - error = args['error'] if 'error' in args else None + params = dict() - params = dict() - - params['count'] = str(args['count']) if 'count' in args else 100 - params['reverse'] = str(args['reverse']).lower() if 'reverse' in args else 'false' - params['start'] = str(args['start']) if 'start' in args else None - params['end'] = str(args['end']) if 'end' in args else None - - ## Fail if bad input. - if not channel : - raise Exception('Missing Channel') - return False + params['count'] = count + params['reverse'] = reverse + params['start'] = start + params['end'] = end ## Get History - return self._request({ 'urlcomponents' : [ + return self._request({'urlcomponents': [ 'v2', 'history', 'sub-key', self.subscribe_key, 'channel', channel, - ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) + ], 'urlparams': {'auth': self.auth_key}}, + callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) - def time(self, args = None) : + def time(self, callback=None): """ #** #* Time @@ -564,34 +529,31 @@ class PubnubBase(object): print(timestamp) """ - ## Capture Callback - callback = callback if args and 'callback' in args else None - - time = self._request({'urlcomponents' : [ + time = self._request({'urlcomponents': [ 'time', '0' ]}, callback) - if time != None: + if time is not None: return time[0] - - def _encode( self, request ) : + 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): + "".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"]]) + "".join([' ~`!@#$%^&*()+=[]\\{}|;\':",./<>?'.find(ch) > -1 and + hex(ord(ch)).replace('0x', '%').upper() or + ch for ch in list(bit) + ]) for bit in request["urlcomponents"]]) if ("urlparams" in request): - url = url + '?' + "&".join([ x + "=" + str(y) for x,y in request["urlparams"].items() if y is not None]) + url = url + '?' + "&".join([x + "=" + str(y) for x, y in request[ + "urlparams"].items() if y is not None]) return url @@ -603,32 +565,38 @@ except ImportError: sha256 = digestmod.new import hmac + class EmptyLock(): def __enter__(self): pass - def __exit__(self,a,b,c): + + def __exit__(self, a, b, c): pass empty_lock = EmptyLock() + class PubnubCoreAsync(PubnubBase): - def start(self): pass - def stop(self): pass + def start(self): + pass + + def stop(self): + pass def __init__( self, publish_key, subscribe_key, - secret_key = False, - cipher_key = False, - auth_key = None, - ssl_on = False, - origin = 'pubsub.pubnub.com', - uuid = None, + secret_key=False, + cipher_key=False, + auth_key=None, + ssl_on=False, + origin='pubsub.pubnub.com', + uuid=None, _tt_lock=empty_lock, _channel_list_lock=empty_lock - ) : + ): """ #** #* Pubnub @@ -655,18 +623,18 @@ class PubnubCoreAsync(PubnubBase): ssl_on=ssl_on, origin=origin, UUID=uuid - ) - - self.subscriptions = {} - self.timetoken = 0 - self.last_timetoken = 0 - self.version = '3.3.4' - self.accept_encoding = 'gzip' - self.SUB_RECEIVER = None - self._connect = None - self._tt_lock = _tt_lock - self._channel_list_lock = _channel_list_lock - self._connect = lambda: None + ) + + self.subscriptions = {} + self.timetoken = 0 + self.last_timetoken = 0 + self.version = '3.3.4' + self.accept_encoding = 'gzip' + self.SUB_RECEIVER = None + self._connect = None + self._tt_lock = _tt_lock + self._channel_list_lock = _channel_list_lock + self._connect = lambda: None def get_channel_list(self, channels): channel = '' @@ -698,7 +666,8 @@ class PubnubCoreAsync(PubnubBase): for i in l: func(i) - def subscribe( self, args=None, sync=False ) : + def subscribe(self, channel, callback, error=None, + connect=None, disconnect=None, reconnect=None, sync=False): """ #** #* Subscribe @@ -730,32 +699,17 @@ class PubnubCoreAsync(PubnubBase): }) """ - if args is None: - _invoke(error, "Arguments Missing") - return - channel = args['channel'] if 'channel' in args else None - callback = args['callback'] if 'callback' in args else None - connect = args['connect'] if 'connect' in args else None - disconnect = args['disconnect'] if 'disconnect' in args else None - reconnect = args['reconnect'] if 'reconnect' in args else None - error = args['error'] if 'error' in args else None with self._tt_lock: - self.last_timetoken = self.timetoken if self.timetoken != 0 else self.last_timetoken + self.last_timetoken = self.timetoken if self.timetoken != 0 \ + else self.last_timetoken self.timetoken = 0 - if channel is None: - _invoke(error, "Channel Missing") - return - if callback is None: - _invoke(error, "Callback Missing") - return - if sync is True and self.susbcribe_sync is not None: self.susbcribe_sync(args) return - def _invoke(func,msg=None): + def _invoke(func, msg=None): if func is not None: if msg is not None: func(msg) @@ -769,27 +723,17 @@ class PubnubCoreAsync(PubnubBase): chobj = self.subscriptions[ch] if chobj['connected'] is False: chobj['connected'] = True - _invoke(chobj['connect'],chobj['name']) + _invoke(chobj['connect'], chobj['name']) def _invoke_error(channel_list=None, err=None): if channel_list is None: for ch in self.subscriptions: chobj = self.subscriptions[ch] - _invoke(chobj['error'],err) + _invoke(chobj['error'], err) else: for ch in channel_list: chobj = self.subscriptions[ch] - _invoke(chobj['error'],err) - - ''' - if callback is None: - _invoke(error, "Callback Missing") - return - - if channel is None: - _invoke(error, "Channel Missing") - return - ''' + _invoke(chobj['error'], err) def _get_channel(): for ch in self.subscriptions: @@ -797,53 +741,58 @@ class PubnubCoreAsync(PubnubBase): if chobj['subscribed'] is True: return chobj - ## New Channel? - if not channel in self.subscriptions or self.subscriptions[channel]['subscribed'] is False: - with self._channel_list_lock: - self.subscriptions[channel] = { - 'name' : channel, - 'first' : False, - 'connected' : False, - 'subscribed' : True, - 'callback' : callback, - 'connect' : connect, - 'disconnect' : disconnect, - 'reconnect' : reconnect, - 'error' : error - } - + if not channel in self.subscriptions or \ + self.subscriptions[channel]['subscribed'] is False: + with self._channel_list_lock: + self.subscriptions[channel] = { + 'name': channel, + 'first': False, + 'connected': False, + 'subscribed': True, + 'callback': callback, + 'connect': connect, + 'disconnect': disconnect, + 'reconnect': reconnect, + 'error': error + } ## return if already connected to channel - if channel in self.subscriptions and 'connected' in self.subscriptions[channel] and self.subscriptions[channel]['connected'] is True: - _invoke(error, "Already Connected") - return - - + if channel in self.subscriptions and \ + 'connected' in self.subscriptions[channel] and \ + self.subscriptions[channel]['connected'] is True: + _invoke(error, "Already Connected") + return - ## SUBSCRIPTION RECURSION + ## SUBSCRIPTION RECURSION def _connect(): - + self._reset_offline() def sub_callback(response): ## ERROR ? - if not response or ('message' in response and response['message'] == 'Forbidden'): - _invoke_error(response['payload']['channels'], response['message']) - _connect() - return + if not response or \ + ('message' in response and + response['message'] == 'Forbidden'): + _invoke_error(response['payload'][ + 'channels'], response['message']) + _connect() + return _invoke_connect() with self._tt_lock: - self.timetoken = self.last_timetoken if self.timetoken == 0 and self.last_timetoken != 0 else response[1] + self.timetoken = \ + self.last_timetoken if self.timetoken == 0 and \ + self.last_timetoken != 0 else response[1] if len(response) > 2: channel_list = response[2].split(',') response_list = response[0] for ch in enumerate(channel_list): if ch[1] in self.subscriptions: chobj = self.subscriptions[ch[1]] - _invoke(chobj['callback'],self.decrypt(response_list[ch[0]])) + _invoke(chobj['callback'], + self.decrypt(response_list[ch[0]])) else: response_list = response[0] chobj = _get_channel() @@ -853,23 +802,25 @@ class PubnubCoreAsync(PubnubBase): _connect() - channel_list = self.get_channel_list(self.subscriptions) if len(channel_list) <= 0: return ## CONNECT TO PUBNUB SUBSCRIBE SERVERS try: - self.SUB_RECEIVER = self._request( { "urlcomponents" : [ + self.SUB_RECEIVER = self._request({"urlcomponents": [ 'subscribe', self.subscribe_key, channel_list, '0', str(self.timetoken) - ], "urlparams" : {"uuid":self.uuid, "auth" : self.auth_key} }, sub_callback, sub_callback, single=True ) + ], "urlparams": {"uuid": self.uuid, "auth": self.auth_key}}, + sub_callback, + sub_callback, + single=True) except Exception as e: print(e) - self.timeout( 1, _connect) + self.timeout(1, _connect) return self._connect = _connect @@ -886,22 +837,18 @@ class PubnubCoreAsync(PubnubBase): self._reset_offline() self._connect() + def unsubscribe(self, channel): - def unsubscribe( self, args ): - - if 'channel' in self.subscriptions is False: + if channel in self.subscriptions is False: return False - channel = str(args['channel']) - - ## DISCONNECT with self._channel_list_lock: if channel in self.subscriptions: - self.subscriptions[channel]['connected'] = 0 - self.subscriptions[channel]['subscribed'] = False - self.subscriptions[channel]['timetoken'] = 0 - self.subscriptions[channel]['first'] = False + self.subscriptions[channel]['connected'] = 0 + self.subscriptions[channel]['subscribed'] = False + self.subscriptions[channel]['timetoken'] = 0 + self.subscriptions[channel]['first'] = False self.CONNECT() @@ -920,23 +867,28 @@ 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 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, - auth_key = False, - ssl_on = False, - origin = 'pubsub.pubnub.com' - ) : + secret_key=False, + cipher_key=False, + auth_key=False, + ssl_on=False, + origin='pubsub.pubnub.com' + ): super(Pubnub, self).__init__( publish_key=publish_key, subscribe_key=subscribe_key, @@ -945,22 +897,26 @@ class Pubnub(PubnubCoreAsync): auth_key=auth_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) self.id = None - - def _request( self, request, callback=None, error=None, single=False ) : + + def _request(self, request, callback=None, error=None, single=False): def _invoke(func, data): if func is not None: func(data) url = self.getUrl(request) - request = tornado.httpclient.HTTPRequest( url, 'GET', self.headers, connect_timeout=10, request_timeout=310 ) + request = tornado.httpclient.HTTPRequest( + url, 'GET', + self.headers, + connect_timeout=10, + request_timeout=310) if single is True: id = time.time() self.id = id @@ -968,13 +924,14 @@ class Pubnub(PubnubCoreAsync): def responseCallback(response): if single is True: if not id == self.id: - return None - + return None + body = response._get_body() if body is None: return #print(body) + def handle_exc(*args): return True if response.error is not None: @@ -987,7 +944,7 @@ class Pubnub(PubnubCoreAsync): try: data = json.loads(body.decode("utf-8")) except: - _invoke(error, {'error' : 'json decode error'}) + _invoke(error, {'error': 'json decode error'}) if 'error' in data and 'status' in data and 'status' != 200: _invoke(error, data) @@ -1003,4 +960,3 @@ class Pubnub(PubnubCoreAsync): pass return abort - diff --git a/python-tornado/examples/here-now-example.py b/python-tornado/examples/here-now-example.py index 85e3432..e6e45a3 100644 --- a/python-tornado/examples/here-now-example.py +++ b/python-tornado/examples/here-now-example.py @@ -1,4 +1,4 @@ -## www.pubnub.com - PubNub Real-time push service in the cloud. +## www.pubnub.com - PubNub Real-time push service in the cloud. # coding=utf8 ## PubNub Real-time Push APIs and Notifications Framework @@ -15,28 +15,30 @@ sys.path.append('..') sys.path.append('../../common') from Pubnub import Pubnub -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- ## Initiate Pubnub State ## ----------------------------------------------------------------------- -pubnub = Pubnub( publish_key, subscribe_key, secret_key, cipher_key, ssl_on ) -crazy = 'hello_world' +pubnub = Pubnub(publish_key, subscribe_key, secret_key, cipher_key, ssl_on) +crazy = 'hello_world' ## ----------------------------------------------------------------------- ## History Example ## ----------------------------------------------------------------------- + + def here_now_complete(messages): print(messages) pubnub.stop() -pubnub.here_now( { - 'channel' : crazy, - 'callback' : here_now_complete +pubnub.here_now({ + 'channel': crazy, + 'callback': here_now_complete }) ## ----------------------------------------------------------------------- diff --git a/python-tornado/examples/history-example.py b/python-tornado/examples/history-example.py index c1619f4..00bdaf3 100644 --- a/python-tornado/examples/history-example.py +++ b/python-tornado/examples/history-example.py @@ -1,4 +1,4 @@ -## www.pubnub.com - PubNub Real-time push service in the cloud. +## www.pubnub.com - PubNub Real-time push service in the cloud. # coding=utf8 ## PubNub Real-time Push APIs and Notifications Framework @@ -13,30 +13,32 @@ import sys import tornado from Pubnub import Pubnub -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- ## Initiate Pubnub State ## ----------------------------------------------------------------------- -pubnub = Pubnub( publish_key, subscribe_key, secret_key,cipher_key, ssl_on ) -crazy = 'hello_world' +pubnub = Pubnub(publish_key, subscribe_key, secret_key, cipher_key, ssl_on) +crazy = 'hello_world' ## ----------------------------------------------------------------------- ## History Example ## ----------------------------------------------------------------------- + + def history_complete(messages): print(messages) tornado.ioloop.IOLoop.instance().stop() -pubnub.history( { - 'channel' : crazy, - 'limit' : 10, - 'callback' : history_complete -}) +pubnub.history({ + 'channel': crazy, + 'limit': 10, + 'callback': history_complete + }) ## ----------------------------------------------------------------------- ## IO Event Loop diff --git a/python-tornado/examples/publish-example.py b/python-tornado/examples/publish-example.py index bb8b199..38d713c 100644 --- a/python-tornado/examples/publish-example.py +++ b/python-tornado/examples/publish-example.py @@ -1,4 +1,4 @@ -## www.pubnub.com - PubNub Real-time push service in the cloud. +## www.pubnub.com - PubNub Real-time push service in the cloud. # coding=utf8 ## PubNub Real-time Push APIs and Notifications Framework @@ -15,53 +15,59 @@ sys.path.append('../') sys.path.append('../../') from Pubnub import Pubnub -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' ##(Cipher key is Optional) -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len( + sys.argv) > 4 and sys.argv[4] or '' # (Cipher key is Optional) +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- ## Initiate Pubnub State ## ----------------------------------------------------------------------- -pubnub = Pubnub( publish_key, subscribe_key, secret_key, cipher_key, ssl_on ) -crazy = 'hello_world' +pubnub = Pubnub(publish_key, subscribe_key, secret_key, cipher_key, ssl_on) +crazy = 'hello_world' ## ----------------------------------------------------------------------- ## Publish Example ## ----------------------------------------------------------------------- + + def publish_complete(info): print(info) + def publish_error(info): - print('ERROR : ' + str(info)) + print('ERROR : ' + str(info)) ## Publish string pubnub.publish({ - 'channel' : crazy, - 'message' : 'Hello World!', - 'callback' : publish_complete, - 'error' : publish_error + 'channel': crazy, + 'message': 'Hello World!', + 'callback': publish_complete, + 'error': publish_error }) ## Publish list -li = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] +li = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', + 'Saturday'] pubnub.publish({ - 'channel' : crazy, - 'message' : li, - 'callback' : publish_complete, - 'error' : publish_error + 'channel': crazy, + 'message': li, + 'callback': publish_complete, + 'error': publish_error }) + def done_cb(info): publish_complete(info) pubnub.publish({ - 'channel' : crazy, - 'message' : { 'some_key' : 'some_val' }, - 'callback' : done_cb, - 'error' : publish_error + 'channel': crazy, + 'message': {'some_key': 'some_val'}, + 'callback': done_cb, + 'error': publish_error }) diff --git a/python-tornado/examples/subscribe-example.py b/python-tornado/examples/subscribe-example.py index dfe8010..34ee886 100644 --- a/python-tornado/examples/subscribe-example.py +++ b/python-tornado/examples/subscribe-example.py @@ -1,4 +1,4 @@ -## www.pubnub.com - PubNub Real-time push service in the cloud. +## www.pubnub.com - PubNub Real-time push service in the cloud. # coding=utf8 ## PubNub Real-time Push APIs and Notifications Framework @@ -15,29 +15,33 @@ sys.path.append('../') sys.path.append('../..') from Pubnub import Pubnub -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len(sys.argv) > 4 and sys.argv[4] or 'demo' ##(Cipher key is Optional) -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len( + sys.argv) > 4 and sys.argv[4] or 'demo' # (Cipher key is Optional) +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- ## Initiate Pubnub State ## ----------------------------------------------------------------------- -pubnub = Pubnub( publish_key=publish_key, subscribe_key=subscribe_key, secret_key=secret_key,cipher_key=cipher_key, ssl_on=ssl_on ) +pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, + secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) #pubnub = Pubnub( publish_key, subscribe_key, secret_key, ssl_on ) -crazy = 'hello_world' +crazy = 'hello_world' + def connect_cb(): print 'Connect' + def subscribe_result(response): print response pubnub.subscribe({ - 'channel' : crazy, - 'callback' : subscribe_result, - 'connect' : connect_cb + 'channel': crazy, + 'callback': subscribe_result, + 'connect': connect_cb }) ## ----------------------------------------------------------------------- ## Publish Example @@ -54,7 +58,8 @@ pubnub.publish({ }) ## Publish list -li = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] +li = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', + 'Saturday'] pubnub.publish({ 'channel' : crazy, 'message' : li, diff --git a/python-tornado/examples/uuid-example.py b/python-tornado/examples/uuid-example.py index f24671b..33e19f8 100644 --- a/python-tornado/examples/uuid-example.py +++ b/python-tornado/examples/uuid-example.py @@ -1,4 +1,4 @@ -## www.pubnub.com - PubNub Real-time push service in the cloud. +## www.pubnub.com - PubNub Real-time push service in the cloud. # coding=utf8 ## PubNub Real-time Push APIs and Notifications Framework @@ -17,7 +17,7 @@ from Pubnub import Pubnub ## ----------------------------------------------------------------------- ## Initiate Pubnub State ## ----------------------------------------------------------------------- -pubnub = Pubnub( "", "", "", False ) +pubnub = Pubnub("", "", "", False) ## ----------------------------------------------------------------------- ## UUID Example @@ -25,4 +25,3 @@ pubnub = Pubnub( "", "", "", False ) uuid = pubnub.uuid() print "UUID: " print uuid - diff --git a/python-tornado/tests/delivery.py b/python-tornado/tests/delivery.py index f3633e6..cb04332 100644 --- a/python-tornado/tests/delivery.py +++ b/python-tornado/tests/delivery.py @@ -1,4 +1,4 @@ -## www.pubnub.com - PubNub Real-time push service in the cloud. +## www.pubnub.com - PubNub Real-time push service in the cloud. # coding=utf8 ## PubNub Real-time Push APIs and Notifications Framework @@ -20,92 +20,99 @@ from Pubnub import Pubnub ## ----------------------------------------------------------------------- ## Configuration ## ----------------------------------------------------------------------- -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len(sys.argv) > 4 and sys.argv[4] or 'demo' -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False -origin = len(sys.argv) > 6 and sys.argv[6] or 'pubsub.pubnub.com' +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or 'demo' +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False +origin = len(sys.argv) > 6 and sys.argv[6] or 'pubsub.pubnub.com' ## ----------------------------------------------------------------------- ## Analytics ## ----------------------------------------------------------------------- analytics = { - 'publishes' : 0, ## Total Send Requests - 'received' : 0, ## Total Received Messages (Deliveries) - 'queued' : 0, ## Total Unreceived Queue (UnDeliveries) - 'successful_publishes' : 0, ## Confirmed Successful Publish Request - 'failed_publishes' : 0, ## Confirmed UNSuccessful Publish Request - 'failed_deliveries' : 0, ## (successful_publishes - received) - 'deliverability' : 0 ## Percentage Delivery + 'publishes': 0, # Total Send Requests + 'received': 0, # Total Received Messages (Deliveries) + 'queued': 0, # Total Unreceived Queue (UnDeliveries) + 'successful_publishes': 0, # Confirmed Successful Publish Request + 'failed_publishes': 0, # Confirmed UNSuccessful Publish Request + 'failed_deliveries': 0, # (successful_publishes - received) + 'deliverability': 0 # Percentage Delivery } trips = { - 'last' : None, - 'current' : None, - 'max' : 0, - 'avg' : 0 + 'last': None, + 'current': None, + 'max': 0, + 'avg': 0 } ## ----------------------------------------------------------------------- ## Initiat Class ## ----------------------------------------------------------------------- channel = 'deliverability-' + str(time.time()) -pubnub = Pubnub( +pubnub = Pubnub( publish_key, subscribe_key, - secret_key = secret_key, - cipher_key = cipher_key, - ssl_on = ssl_on, - origin = origin + secret_key=secret_key, + cipher_key=cipher_key, + ssl_on=ssl_on, + origin=origin ) ## ----------------------------------------------------------------------- ## BENCHMARK ## ----------------------------------------------------------------------- -def publish_sent(info = None): - if info and info[0]: analytics['successful_publishes'] += 1 - else: analytics['failed_publishes'] += 1 + + +def publish_sent(info=None): + if info and info[0]: + analytics['successful_publishes'] += 1 + else: + analytics['failed_publishes'] += 1 analytics['publishes'] += 1 - analytics['queued'] += 1 + analytics['queued'] += 1 + + pubnub.timeout(send, 0.1) - pubnub.timeout( send, 0.1 ) def send(): if analytics['queued'] > 100: analytics['queued'] -= 10 - return pubnub.timeout( send, 10 ) + return pubnub.timeout(send, 10) pubnub.publish({ - 'channel' : channel, - 'callback' : publish_sent, - 'message' : "1234567890" + 'channel': channel, + 'callback': publish_sent, + 'message': "1234567890" }) + def received(message): - analytics['queued'] -= 1 + analytics['queued'] -= 1 analytics['received'] += 1 current_trip = trips['current'] = str(datetime.datetime.now())[0:19] - last_trip = trips['last'] = str( + last_trip = trips['last'] = str( datetime.datetime.now() - datetime.timedelta(seconds=1) )[0:19] ## New Trip Span (1 Second) - if not trips.has_key(current_trip) : + if current_trip not in trips: trips[current_trip] = 0 ## Average - if trips.has_key(last_trip): + if last_trip in trips: trips['avg'] = (trips['avg'] + trips[last_trip]) / 2 ## Increment Trip Counter trips[current_trip] = trips[current_trip] + 1 ## Update Max - if trips[current_trip] > trips['max'] : + if trips[current_trip] > trips['max']: trips['max'] = trips[current_trip] + def show_status(): ## Update Failed Deliveries analytics['failed_deliveries'] = \ @@ -114,45 +121,46 @@ def show_status(): ## Update Deliverability analytics['deliverability'] = ( - float(analytics['received']) / \ + float(analytics['received']) / float(analytics['successful_publishes'] or 1.0) ) * 100.0 ## Print Display - print( ( - "max:%(max)03d/sec " + \ - "avg:%(avg)03d/sec " + \ - "pubs:%(publishes)05d " + \ - "received:%(received)05d " + \ - "spub:%(successful_publishes)05d " + \ - "fpub:%(failed_publishes)05d " + \ - "failed:%(failed_deliveries)05d " + \ - "queued:%(queued)03d " + \ - "delivery:%(deliverability)03f%% " + \ - "" - ) % { - 'max' : trips['max'], - 'avg' : trips['avg'], - 'publishes' : analytics['publishes'], - 'received' : analytics['received'], - 'successful_publishes' : analytics['successful_publishes'], - 'failed_publishes' : analytics['failed_publishes'], - 'failed_deliveries' : analytics['failed_deliveries'], - 'publishes' : analytics['publishes'], - 'deliverability' : analytics['deliverability'], - 'queued' : analytics['queued'] - } ) - pubnub.timeout( show_status, 1 ) + print(( + "max:%(max)03d/sec " + + "avg:%(avg)03d/sec " + + "pubs:%(publishes)05d " + + "received:%(received)05d " + + "spub:%(successful_publishes)05d " + + "fpub:%(failed_publishes)05d " + + "failed:%(failed_deliveries)05d " + + "queued:%(queued)03d " + + "delivery:%(deliverability)03f%% " + + "" + ) % { + 'max': trips['max'], + 'avg': trips['avg'], + 'publishes': analytics['publishes'], + 'received': analytics['received'], + 'successful_publishes': analytics['successful_publishes'], + 'failed_publishes': analytics['failed_publishes'], + 'failed_deliveries': analytics['failed_deliveries'], + 'publishes': analytics['publishes'], + 'deliverability': analytics['deliverability'], + 'queued': analytics['queued'] + }) + pubnub.timeout(show_status, 1) + def connected(): show_status() - pubnub.timeout( send, 1 ) + pubnub.timeout(send, 1) -print( "Connected: %s\n" % origin ) +print("Connected: %s\n" % origin) pubnub.subscribe({ - 'channel' : channel, - 'connect' : connected, - 'callback' : received + 'channel': channel, + 'connect': connected, + 'callback': received }) ## ----------------------------------------------------------------------- diff --git a/python-tornado/tests/subscribe-test.py b/python-tornado/tests/subscribe-test.py index be4a416..d8a3ea2 100755 --- a/python-tornado/tests/subscribe-test.py +++ b/python-tornado/tests/subscribe-test.py @@ -1,4 +1,4 @@ -## www.pubnub.com - PubNub Real-time push service in the cloud. +## www.pubnub.com - PubNub Real-time push service in the cloud. # coding=utf8 ## PubNub Real-time Push APIs and Notifications Framework @@ -16,18 +16,18 @@ from Pubnub import Pubnub from functools import partial from threading import current_thread import threading -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len(sys.argv) > 4 and sys.argv[4] or None -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or None +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- ## Initiate Pubnub State ## ----------------------------------------------------------------------- #pubnub = Pubnub( publish_key, subscribe_key, secret_key, cipher_key, ssl_on ) -pubnub = Pubnub( publish_key, subscribe_key, secret_key, ssl_on ) -crazy = 'hello_world' +pubnub = Pubnub(publish_key, subscribe_key, secret_key, ssl_on) +crazy = 'hello_world' current = -1 @@ -37,9 +37,12 @@ received = 0 ## ----------------------------------------------------------------------- ## Subscribe Example ## ----------------------------------------------------------------------- + + def message_received(message): print(message) + def check_received(message): global current global errors @@ -52,19 +55,20 @@ def check_received(message): errors += 1 else: received += 1 - print('active thread count : ' + str( threading.activeCount())) + print('active thread count : ' + str(threading.activeCount())) print('errors = ' + str(errors)) - print(current_thread().getName() + ' , ' + 'received = ' + str(received)) + print(current_thread().getName() + ' , ' + 'received = ' + str(received)) if received != message: - print('********** MISSED **************** ' + str( message - received )) + print('********** MISSED **************** ' + str(message - received)) current = message - -def connected_test(ch) : - print('Connected ' + ch) -def connected(ch) : +def connected_test(ch): + print('Connected ' + ch) + + +def connected(ch): pass @@ -75,56 +79,60 @@ pubnub.subscribe({ 'callback' : message_received }) ''' + + def cb1(): - pubnub.subscribe({ - 'channel' : 'efgh1', - 'connect' : connected, - 'callback' : message_received - }) + pubnub.subscribe({ + 'channel': 'efgh1', + 'connect': connected, + 'callback': message_received + }) + def cb2(): - pubnub.subscribe({ - 'channel' : 'dsm-test', - 'connect' : connected_test, - 'callback' : check_received - }) + pubnub.subscribe({ + 'channel': 'dsm-test', + 'connect': connected_test, + 'callback': check_received + }) + def cb3(): - pubnub.unsubscribe({'channel' : 'efgh1'}) + pubnub.unsubscribe({'channel': 'efgh1'}) -def cb4(): - pubnub.unsubscribe({'channel' : 'abcd1'}) -def subscribe(channel): - pubnub.subscribe({ - 'channel' : channel, - 'connect' : connected, - 'callback' : message_received - }) +def cb4(): + pubnub.unsubscribe({'channel': 'abcd1'}) +def subscribe(channel): + pubnub.subscribe({ + 'channel': channel, + 'connect': connected, + 'callback': message_received + }) -pubnub.timeout(15,cb1) +pubnub.timeout(15, cb1) -pubnub.timeout(30,cb2) +pubnub.timeout(30, cb2) -pubnub.timeout(45,cb3) +pubnub.timeout(45, cb3) -pubnub.timeout(60,cb4) +pubnub.timeout(60, cb4) #''' -for x in range(1,1000): +for x in range(1, 1000): #print x def y(t): subscribe('channel-' + str(t)) def z(t): - pubnub.unsubscribe({'channel' : 'channel-' + str(t)}) + pubnub.unsubscribe({'channel': 'channel-' + str(t)}) - pubnub.timeout(x + 5, partial(y,x)) - pubnub.timeout(x + 25, partial(z, x)) + pubnub.timeout(x + 5, partial(y, x)) + pubnub.timeout(x + 25, partial(z, x)) x += 10 #''' diff --git a/python-tornado/tests/unit-tests.py b/python-tornado/tests/unit-tests.py index fdaa194..b4b51f4 100644 --- a/python-tornado/tests/unit-tests.py +++ b/python-tornado/tests/unit-tests.py @@ -9,65 +9,63 @@ sys.path.append('.') from PubnubUnitTest import Suite from Pubnub import Pubnub -pubnub = Pubnub("demo","demo") +pubnub = Pubnub("demo", "demo") tests_count = 1 + 2 -test_suite = Suite(pubnub,tests_count) +test_suite = Suite(pubnub, tests_count) tests = [] def test_publish(): - name = "Publish Test" - def success(r): - test_suite.test(r[0] == 1, name) + name = "Publish Test" - def fail(e): - test_suite.test(False, msg , e) + def success(r): + test_suite.test(r[0] == 1, name) + def fail(e): + test_suite.test(False, msg, e) - pubnub.publish({ - 'channel' : 'hello', - 'message' : 'hi', - 'callback' : success, - 'error' : fail - }) + pubnub.publish({ + 'channel': 'hello', + 'message': 'hi', + 'callback': success, + 'error': fail + }) tests.append(test_publish) def test_subscribe_publish(): - channel = "hello" - name = "Subscribe Publish Test" - publish_msg = "This is Pubnub Python-Twisted" - def connect(): - def success(r): - test_suite.test(r[0] == 1, name, "publish success") - - def fail(e): - test_suite.test(False, name , "Publish Failed", e) - - pubnub.publish({ - 'channel' : channel, - 'message' : publish_msg, - 'callback' : success, - 'error' : fail - }) - - def callback(r): - test_suite.test(r == publish_msg, name, "message received") - - pubnub.subscribe({ - 'channel' : channel, - 'callback' : callback, - 'connect' : connect - }) + channel = "hello" + name = "Subscribe Publish Test" + publish_msg = "This is Pubnub Python-Twisted" + + def connect(): + def success(r): + test_suite.test(r[0] == 1, name, "publish success") + + def fail(e): + test_suite.test(False, name, "Publish Failed", e) + + pubnub.publish({ + 'channel': channel, + 'message': publish_msg, + 'callback': success, + 'error': fail + }) + + def callback(r): + test_suite.test(r == publish_msg, name, "message received") + + pubnub.subscribe({ + 'channel': channel, + 'callback': callback, + 'connect': connect + }) tests.append(test_subscribe_publish) - - - for t in tests: - t() + t() pubnub.start() diff --git a/python-tornado/unassembled/Platform.py b/python-tornado/unassembled/Platform.py index 02c374d..871a400 100644 --- a/python-tornado/unassembled/Platform.py +++ b/python-tornado/unassembled/Platform.py @@ -13,23 +13,28 @@ 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 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, - auth_key = False, - ssl_on = False, - origin = 'pubsub.pubnub.com' - ) : + secret_key=False, + cipher_key=False, + auth_key=False, + ssl_on=False, + origin='pubsub.pubnub.com' + ): super(Pubnub, self).__init__( publish_key=publish_key, subscribe_key=subscribe_key, @@ -38,22 +43,26 @@ class Pubnub(PubnubCoreAsync): auth_key=auth_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) self.id = None - - def _request( self, request, callback=None, error=None, single=False ) : + + def _request(self, request, callback=None, error=None, single=False): def _invoke(func, data): if func is not None: func(data) url = self.getUrl(request) - request = tornado.httpclient.HTTPRequest( url, 'GET', self.headers, connect_timeout=10, request_timeout=310 ) + request = tornado.httpclient.HTTPRequest( + url, 'GET', + self.headers, + connect_timeout=10, + request_timeout=310) if single is True: id = time.time() self.id = id @@ -61,13 +70,14 @@ class Pubnub(PubnubCoreAsync): def responseCallback(response): if single is True: if not id == self.id: - return None - + return None + body = response._get_body() if body is None: return #print(body) + def handle_exc(*args): return True if response.error is not None: @@ -80,7 +90,7 @@ class Pubnub(PubnubCoreAsync): try: data = json.loads(body.decode("utf-8")) except: - _invoke(error, {'error' : 'json decode error'}) + _invoke(error, {'error': 'json decode error'}) if 'error' in data and 'status' in data and 'status' != 200: _invoke(error, data) @@ -96,4 +106,3 @@ class Pubnub(PubnubCoreAsync): pass return abort - diff --git a/python-twisted/Pubnub.py b/python-twisted/Pubnub.py index f5259ac..c312033 100644 --- a/python-twisted/Pubnub.py +++ b/python-twisted/Pubnub.py @@ -12,11 +12,12 @@ from Crypto.Cipher import AES from Crypto.Hash import MD5 -from base64 import encodestring, decodestring +from base64 import encodestring, decodestring import hashlib import hmac -class PubnubCrypto2() : + +class PubnubCrypto2(): """ #** #* PubnubCrypto @@ -27,8 +28,8 @@ class PubnubCrypto2() : pc = PubnubCrypto """ - - def pad( self, msg, block_size=16 ): + + def pad(self, msg, block_size=16): """ #** #* pad @@ -40,9 +41,9 @@ class PubnubCrypto2() : #** """ padding = block_size - (len(msg) % block_size) - return msg + chr(padding)*padding - - def depad( self, msg ): + return msg + chr(padding) * padding + + def depad(self, msg): """ #** #* depad @@ -53,7 +54,7 @@ class PubnubCrypto2() : """ return msg[0:-ord(msg[-1])] - def getSecret( self, key ): + def getSecret(self, key): """ #** #* getSecret @@ -64,7 +65,7 @@ class PubnubCrypto2() : """ return hashlib.sha256(key).hexdigest() - def encrypt( self, key, msg ): + def encrypt(self, key, msg): """ #** #* encrypt @@ -74,11 +75,12 @@ class PubnubCrypto2() : #** """ secret = self.getSecret(key) - Initial16bytes='0123456789012345' - cipher = AES.new(secret[0:32],AES.MODE_CBC,Initial16bytes) + 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 ): + + def decrypt(self, key, msg): """ #** #* decrypt @@ -88,12 +90,12 @@ class PubnubCrypto2() : #** """ secret = self.getSecret(key) - Initial16bytes='0123456789012345' - cipher = AES.new(secret[0:32],AES.MODE_CBC,Initial16bytes) + Initial16bytes = '0123456789012345' + cipher = AES.new(secret[0:32], AES.MODE_CBC, Initial16bytes) return self.depad((cipher.decrypt(decodestring(msg)))) -class PubnubCrypto3() : +class PubnubCrypto3(): """ #** #* PubnubCrypto @@ -104,8 +106,8 @@ class PubnubCrypto3() : pc = PubnubCrypto """ - - def pad( self, msg, block_size=16 ): + + def pad(self, msg, block_size=16): """ #** #* pad @@ -117,9 +119,9 @@ class PubnubCrypto3() : #** """ padding = block_size - (len(msg) % block_size) - return msg + (chr(padding)*padding).encode('utf-8') - - def depad( self, msg ): + return msg + (chr(padding) * padding).encode('utf-8') + + def depad(self, msg): """ #** #* depad @@ -130,7 +132,7 @@ class PubnubCrypto3() : """ return msg[0:-ord(msg[-1])] - def getSecret( self, key ): + def getSecret(self, key): """ #** #* getSecret @@ -141,7 +143,7 @@ class PubnubCrypto3() : """ return hashlib.sha256(key.encode("utf-8")).hexdigest() - def encrypt( self, key, msg ): + def encrypt(self, key, msg): """ #** #* encrypt @@ -151,10 +153,12 @@ class PubnubCrypto3() : #** """ secret = self.getSecret(key) - Initial16bytes='0123456789012345' - cipher = AES.new(secret[0:32],AES.MODE_CBC,Initial16bytes) - return encodestring(cipher.encrypt(self.pad(msg.encode('utf-8')))).decode('utf-8') - def decrypt( self, key, msg ): + Initial16bytes = '0123456789012345' + cipher = AES.new(secret[0:32], AES.MODE_CBC, Initial16bytes) + return encodestring( + cipher.encrypt(self.pad(msg.encode('utf-8')))).decode('utf-8') + + def decrypt(self, key, msg): """ #** #* decrypt @@ -164,40 +168,46 @@ class PubnubCrypto3() : #** """ secret = self.getSecret(key) - Initial16bytes='0123456789012345' - cipher = AES.new(secret[0:32],AES.MODE_CBC,Initial16bytes) - return (cipher.decrypt(decodestring(msg.encode('utf-8')))).decode('utf-8') + Initial16bytes = '0123456789012345' + cipher = AES.new(secret[0:32], AES.MODE_CBC, Initial16bytes) + return (cipher.decrypt( + decodestring(msg.encode('utf-8')))).decode('utf-8') -try: import json -except ImportError: import simplejson as json +try: + import json +except ImportError: + import simplejson as json import time import hashlib import uuid import sys -try: from urllib.parse import quote -except: from urllib2 import quote +try: + from urllib.parse import quote +except: + from urllib2 import quote -from base64 import urlsafe_b64encode +from base64 import urlsafe_b64encode from hashlib import sha256 import hmac + class PubnubBase(object): def __init__( self, publish_key, subscribe_key, - secret_key = False, - cipher_key = False, - auth_key = None, - ssl_on = False, - origin = 'pubsub.pubnub.com', - UUID = None - ) : + secret_key=False, + cipher_key=False, + auth_key=None, + ssl_on=False, + origin='pubsub.pubnub.com', + UUID=None + ): """ #** #* Pubnub @@ -209,45 +219,47 @@ class PubnubBase(object): #* @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) + #* @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.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.auth_key = auth_key - + self.secret_key = secret_key + self.cipher_key = cipher_key + self.ssl = ssl_on + self.auth_key = auth_key - if self.ssl : + if self.ssl: self.origin = 'https://' + self.origin - else : - self.origin = 'http://' + self.origin - + else: + self.origin = 'http://' + self.origin + self.uuid = UUID or str(uuid.uuid4()) if type(sys.version_info) is tuple: - self.python_version = 2 - self.pc = PubnubCrypto2() + self.python_version = 2 + self.pc = PubnubCrypto2() else: if sys.version_info.major == 2: - self.python_version = 2 - self.pc = PubnubCrypto2() + self.python_version = 2 + self.pc = PubnubCrypto2() else: self.python_version = 3 - self.pc = PubnubCrypto3() - + self.pc = PubnubCrypto3() + if not isinstance(self.uuid, str): raise AttributeError("pres_uuid must be a string") - def sign(self, channel, message): + ''' + + def _sign(self, channel, message): ## Sign Message if self.secret_key: signature = hashlib.md5('/'.join([ @@ -260,8 +272,9 @@ class PubnubBase(object): else: signature = '0' return signature + ''' - def _pam_sign( self, msg ): + def _pam_sign(self, msg): """Calculate a signature by secret key and message.""" return urlsafe_b64encode(hmac.new( @@ -270,7 +283,7 @@ class PubnubBase(object): sha256 ).digest()) - def _pam_auth( self, query , apicode=0, callback=None): + def _pam_auth(self, query, apicode=0, callback=None): """Issue an authenticated request.""" if 'timestamp' not in query: @@ -297,57 +310,50 @@ class PubnubBase(object): query['signature'] = self._pam_sign(sign_input) - ''' - url = ("https://pubsub.pubnub.com/v1/auth/{apitype}/sub-key/".format(apitype="audit" if (apicode) else "grant") + - self.subscribe_key + "?" + - params + "&signature=" + - quote(signature, safe="")) - ''' - return self._request({"urlcomponents": [ - 'v1', 'auth', "audit" if (apicode) else "grant" , + 'v1', 'auth', "audit" if (apicode) else "grant", 'sub-key', self.subscribe_key - ], 'urlparams' : query}, - self._return_wrapped_callback(callback)) + ], 'urlparams': query}, + self._return_wrapped_callback(callback)) - def grant( self, channel, authkey=False, read=True, write=True, ttl=5, callback=None): + def grant(self, channel, authkey=False, read=True, + write=True, ttl=5, callback=None): """Grant Access on a Channel.""" return self._pam_auth({ - "channel" : channel, - "auth" : authkey, - "r" : read and 1 or 0, - "w" : write and 1 or 0, - "ttl" : ttl + "channel": channel, + "auth": authkey, + "r": read and 1 or 0, + "w": write and 1 or 0, + "ttl": ttl }, callback=callback) - def revoke( self, channel, authkey=False, ttl=1, callback=None): + def revoke(self, channel, authkey=False, ttl=1, callback=None): """Revoke Access on a Channel.""" return self._pam_auth({ - "channel" : channel, - "auth" : authkey, - "r" : 0, - "w" : 0, - "ttl" : ttl + "channel": channel, + "auth": authkey, + "r": 0, + "w": 0, + "ttl": ttl }, callback=callback) def audit(self, channel=False, authkey=False, callback=None): return self._pam_auth({ - "channel" : channel, - "auth" : authkey - },1, callback=callback) - - + "channel": channel, + "auth": authkey + }, 1, callback=callback) 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(self.pc.encrypt( + self.cipher_key, json.dumps(message)).replace('\n', '')) + else: message = json.dumps(message) - return message; + return message def decrypt(self, message): if self.cipher_key: @@ -358,16 +364,18 @@ class PubnubBase(object): def _return_wrapped_callback(self, callback=None): def _new_format_callback(response): if 'payload' in response: - if (callback != None): callback({'message' : response['message'], 'payload' : response['payload']}) + if (callback is not None): + callback({'message': response['message'], + 'payload': response['payload']}) else: - if (callback != None):callback(response) - if (callback != None): + if (callback is not None): + callback(response) + if (callback is not None): return _new_format_callback else: return None - - def publish( self, args ) : + def publish(channel, message, callback=None, error=None): """ #** #* Publish @@ -388,28 +396,9 @@ class PubnubBase(object): 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 'callback' in args : - callback = args['callback'] - else : - callback = None - - if 'error' in args : - error = args['error'] - else : - error = None message = self.encrypt(args['message']) - #signature = self.sign(channel, message) - ## Send Message return self._request({"urlcomponents": [ 'publish', @@ -419,10 +408,11 @@ class PubnubBase(object): channel, '0', message - ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) - - def presence( self, args ) : + ], 'urlparams': {'auth': self.auth_key}}, + callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) + + def presence(self, channel, callback, error=None): """ #** #* presence @@ -441,29 +431,15 @@ class PubnubBase(object): pubnub.presence({ 'channel' : 'hello_world', - 'callback' : receive + 'callback' : receive }) """ + return self.subscribe({ + 'channel': channel + '-pnpres', + 'subscribe_key': self.subscribe_key, + 'callback': self._return_wrapped_callback(callback)}) - ## 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': self._return_wrapped_callback(callback)}) - - - def here_now( self, args ) : + def here_now(self, channel, callback, error=None): """ #** #* Here Now @@ -484,33 +460,31 @@ class PubnubBase(object): """ channel = str(args['channel']) - - callback = args['callback'] if 'callback' in args else None - error = args['error'] if 'error' in args else None + callback = args['callback'] if 'callback' in args else None + error = args['error'] if 'error' in args else None ## Fail if bad input. - if not channel : + if not channel: raise Exception('Missing Channel') return False - + ## Get Presence Here Now return self._request({"urlcomponents": [ - 'v2','presence', + 'v2', 'presence', 'sub_key', self.subscribe_key, 'channel', channel - ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) + ], 'urlparams': {'auth': self.auth_key}}, + callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) - def history(self, args) : + def history(self, channel, count=100, reverse=False, + start=None, end=None, callback=None, error=None): """ #** #* History #* #* Load 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({ @@ -520,36 +494,27 @@ class PubnubBase(object): print(history) """ - ## Capture User Input - channel = str(args['channel']) - - callback = args['callback'] if 'callback' in args else None - error = args['error'] if 'error' in args else None - - params = dict() - params['count'] = str(args['count']) if 'count' in args else 100 - params['reverse'] = str(args['reverse']).lower() if 'reverse' in args else 'false' - params['start'] = str(args['start']) if 'start' in args else None - params['end'] = str(args['end']) if 'end' in args else None + params = dict() - ## Fail if bad input. - if not channel : - raise Exception('Missing Channel') - return False + params['count'] = count + params['reverse'] = reverse + params['start'] = start + params['end'] = end ## Get History - return self._request({ 'urlcomponents' : [ + return self._request({'urlcomponents': [ 'v2', 'history', 'sub-key', self.subscribe_key, 'channel', channel, - ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) + ], 'urlparams': {'auth': self.auth_key}}, + callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) - def time(self, args = None) : + def time(self, callback=None): """ #** #* Time @@ -564,34 +529,31 @@ class PubnubBase(object): print(timestamp) """ - ## Capture Callback - callback = callback if args and 'callback' in args else None - - time = self._request({'urlcomponents' : [ + time = self._request({'urlcomponents': [ 'time', '0' ]}, callback) - if time != None: + if time is not None: return time[0] - - def _encode( self, request ) : + 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): + "".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"]]) + "".join([' ~`!@#$%^&*()+=[]\\{}|;\':",./<>?'.find(ch) > -1 and + hex(ord(ch)).replace('0x', '%').upper() or + ch for ch in list(bit) + ]) for bit in request["urlcomponents"]]) if ("urlparams" in request): - url = url + '?' + "&".join([ x + "=" + str(y) for x,y in request["urlparams"].items() if y is not None]) + url = url + '?' + "&".join([x + "=" + str(y) for x, y in request[ + "urlparams"].items() if y is not None]) return url @@ -603,32 +565,38 @@ except ImportError: sha256 = digestmod.new import hmac + class EmptyLock(): def __enter__(self): pass - def __exit__(self,a,b,c): + + def __exit__(self, a, b, c): pass empty_lock = EmptyLock() + class PubnubCoreAsync(PubnubBase): - def start(self): pass - def stop(self): pass + def start(self): + pass + + def stop(self): + pass def __init__( self, publish_key, subscribe_key, - secret_key = False, - cipher_key = False, - auth_key = None, - ssl_on = False, - origin = 'pubsub.pubnub.com', - uuid = None, + secret_key=False, + cipher_key=False, + auth_key=None, + ssl_on=False, + origin='pubsub.pubnub.com', + uuid=None, _tt_lock=empty_lock, _channel_list_lock=empty_lock - ) : + ): """ #** #* Pubnub @@ -655,18 +623,18 @@ class PubnubCoreAsync(PubnubBase): ssl_on=ssl_on, origin=origin, UUID=uuid - ) - - self.subscriptions = {} - self.timetoken = 0 - self.last_timetoken = 0 - self.version = '3.3.4' - self.accept_encoding = 'gzip' - self.SUB_RECEIVER = None - self._connect = None - self._tt_lock = _tt_lock - self._channel_list_lock = _channel_list_lock - self._connect = lambda: None + ) + + self.subscriptions = {} + self.timetoken = 0 + self.last_timetoken = 0 + self.version = '3.3.4' + self.accept_encoding = 'gzip' + self.SUB_RECEIVER = None + self._connect = None + self._tt_lock = _tt_lock + self._channel_list_lock = _channel_list_lock + self._connect = lambda: None def get_channel_list(self, channels): channel = '' @@ -698,7 +666,8 @@ class PubnubCoreAsync(PubnubBase): for i in l: func(i) - def subscribe( self, args=None, sync=False ) : + def subscribe(self, channel, callback, error=None, + connect=None, disconnect=None, reconnect=None, sync=False): """ #** #* Subscribe @@ -730,32 +699,17 @@ class PubnubCoreAsync(PubnubBase): }) """ - if args is None: - _invoke(error, "Arguments Missing") - return - channel = args['channel'] if 'channel' in args else None - callback = args['callback'] if 'callback' in args else None - connect = args['connect'] if 'connect' in args else None - disconnect = args['disconnect'] if 'disconnect' in args else None - reconnect = args['reconnect'] if 'reconnect' in args else None - error = args['error'] if 'error' in args else None with self._tt_lock: - self.last_timetoken = self.timetoken if self.timetoken != 0 else self.last_timetoken + self.last_timetoken = self.timetoken if self.timetoken != 0 \ + else self.last_timetoken self.timetoken = 0 - if channel is None: - _invoke(error, "Channel Missing") - return - if callback is None: - _invoke(error, "Callback Missing") - return - if sync is True and self.susbcribe_sync is not None: self.susbcribe_sync(args) return - def _invoke(func,msg=None): + def _invoke(func, msg=None): if func is not None: if msg is not None: func(msg) @@ -769,27 +723,17 @@ class PubnubCoreAsync(PubnubBase): chobj = self.subscriptions[ch] if chobj['connected'] is False: chobj['connected'] = True - _invoke(chobj['connect'],chobj['name']) + _invoke(chobj['connect'], chobj['name']) def _invoke_error(channel_list=None, err=None): if channel_list is None: for ch in self.subscriptions: chobj = self.subscriptions[ch] - _invoke(chobj['error'],err) + _invoke(chobj['error'], err) else: for ch in channel_list: chobj = self.subscriptions[ch] - _invoke(chobj['error'],err) - - ''' - if callback is None: - _invoke(error, "Callback Missing") - return - - if channel is None: - _invoke(error, "Channel Missing") - return - ''' + _invoke(chobj['error'], err) def _get_channel(): for ch in self.subscriptions: @@ -797,53 +741,58 @@ class PubnubCoreAsync(PubnubBase): if chobj['subscribed'] is True: return chobj - ## New Channel? - if not channel in self.subscriptions or self.subscriptions[channel]['subscribed'] is False: - with self._channel_list_lock: - self.subscriptions[channel] = { - 'name' : channel, - 'first' : False, - 'connected' : False, - 'subscribed' : True, - 'callback' : callback, - 'connect' : connect, - 'disconnect' : disconnect, - 'reconnect' : reconnect, - 'error' : error - } - + if not channel in self.subscriptions or \ + self.subscriptions[channel]['subscribed'] is False: + with self._channel_list_lock: + self.subscriptions[channel] = { + 'name': channel, + 'first': False, + 'connected': False, + 'subscribed': True, + 'callback': callback, + 'connect': connect, + 'disconnect': disconnect, + 'reconnect': reconnect, + 'error': error + } ## return if already connected to channel - if channel in self.subscriptions and 'connected' in self.subscriptions[channel] and self.subscriptions[channel]['connected'] is True: - _invoke(error, "Already Connected") - return - - + if channel in self.subscriptions and \ + 'connected' in self.subscriptions[channel] and \ + self.subscriptions[channel]['connected'] is True: + _invoke(error, "Already Connected") + return - ## SUBSCRIPTION RECURSION + ## SUBSCRIPTION RECURSION def _connect(): - + self._reset_offline() def sub_callback(response): ## ERROR ? - if not response or ('message' in response and response['message'] == 'Forbidden'): - _invoke_error(response['payload']['channels'], response['message']) - _connect() - return + if not response or \ + ('message' in response and + response['message'] == 'Forbidden'): + _invoke_error(response['payload'][ + 'channels'], response['message']) + _connect() + return _invoke_connect() with self._tt_lock: - self.timetoken = self.last_timetoken if self.timetoken == 0 and self.last_timetoken != 0 else response[1] + self.timetoken = \ + self.last_timetoken if self.timetoken == 0 and \ + self.last_timetoken != 0 else response[1] if len(response) > 2: channel_list = response[2].split(',') response_list = response[0] for ch in enumerate(channel_list): if ch[1] in self.subscriptions: chobj = self.subscriptions[ch[1]] - _invoke(chobj['callback'],self.decrypt(response_list[ch[0]])) + _invoke(chobj['callback'], + self.decrypt(response_list[ch[0]])) else: response_list = response[0] chobj = _get_channel() @@ -853,23 +802,25 @@ class PubnubCoreAsync(PubnubBase): _connect() - channel_list = self.get_channel_list(self.subscriptions) if len(channel_list) <= 0: return ## CONNECT TO PUBNUB SUBSCRIBE SERVERS try: - self.SUB_RECEIVER = self._request( { "urlcomponents" : [ + self.SUB_RECEIVER = self._request({"urlcomponents": [ 'subscribe', self.subscribe_key, channel_list, '0', str(self.timetoken) - ], "urlparams" : {"uuid":self.uuid, "auth" : self.auth_key} }, sub_callback, sub_callback, single=True ) + ], "urlparams": {"uuid": self.uuid, "auth": self.auth_key}}, + sub_callback, + sub_callback, + single=True) except Exception as e: print(e) - self.timeout( 1, _connect) + self.timeout(1, _connect) return self._connect = _connect @@ -886,22 +837,18 @@ class PubnubCoreAsync(PubnubBase): self._reset_offline() self._connect() + def unsubscribe(self, channel): - def unsubscribe( self, args ): - - if 'channel' in self.subscriptions is False: + if channel in self.subscriptions is False: return False - channel = str(args['channel']) - - ## DISCONNECT with self._channel_list_lock: if channel in self.subscriptions: - self.subscriptions[channel]['connected'] = 0 - self.subscriptions[channel]['subscribed'] = False - self.subscriptions[channel]['timetoken'] = 0 - self.subscriptions[channel]['first'] = False + self.subscriptions[channel]['connected'] = 0 + self.subscriptions[channel]['subscribed'] = False + self.subscriptions[channel]['timetoken'] = 0 + self.subscriptions[channel]['first'] = False self.CONNECT() @@ -909,7 +856,8 @@ from twisted.web.client import getPage from twisted.internet import reactor from twisted.internet.defer import Deferred from twisted.internet.protocol import Protocol -from twisted.web.client import Agent, ContentDecoderAgent, RedirectAgent, GzipDecoder +from twisted.web.client import Agent, ContentDecoderAgent +from twisted.web.client import RedirectAgent, GzipDecoder from twisted.web.client import HTTPConnectionPool from twisted.web.http_headers import Headers from twisted.internet.ssl import ClientContextFactory @@ -922,16 +870,21 @@ from twisted.python.compat import ( _PY3, unicode, intToBytes, networkString, nativeString) pnconn_pool = HTTPConnectionPool(reactor, persistent=True) -pnconn_pool.maxPersistentPerHost = 100000 +pnconn_pool.maxPersistentPerHost = 100000 pnconn_pool.cachedConnectionTimeout = 310 pnconn_pool.retryAutomatically = True + class Pubnub(PubnubCoreAsync): - def start(self): reactor.run() - def stop(self): reactor.stop() - def timeout( self, delay, callback ): - reactor.callLater( delay, callback ) + def start(self): + reactor.run() + + def stop(self): + reactor.stop() + + def timeout(self, delay, callback): + reactor.callLater(delay, callback) def __init__( self, @@ -940,9 +893,9 @@ class Pubnub(PubnubCoreAsync): secret_key=False, cipher_key=False, auth_key=None, - ssl_on = False, - origin = 'pubsub.pubnub.com' - ) : + ssl_on=False, + origin='pubsub.pubnub.com' + ): super(Pubnub, self).__init__( publish_key=publish_key, subscribe_key=subscribe_key, @@ -951,13 +904,13 @@ class Pubnub(PubnubCoreAsync): auth_key=auth_key, ssl_on=ssl_on, origin=origin, - ) + ) self.headers = {} self.headers['User-Agent'] = ['Python-Twisted'] #self.headers['Accept-Encoding'] = [self.accept_encoding] self.headers['V'] = [self.version] - def _request( self, request, callback=None, error=None, single=False ) : + def _request(self, request, callback=None, error=None, single=False): global pnconn_pool def _invoke(func, data): @@ -974,18 +927,19 @@ class Pubnub(PubnubCoreAsync): ''' url = self.getUrl(request) - agent = ContentDecoderAgent(RedirectAgent(Agent( + agent = ContentDecoderAgent(RedirectAgent(Agent( reactor, - contextFactory = WebClientContextFactory(), - pool = self.ssl and None or pnconn_pool + contextFactory=WebClientContextFactory(), + pool=self.ssl and None or pnconn_pool )), [('gzip', GzipDecoder)]) try: - request = agent.request( 'GET', url, Headers(self.headers), None ) + request = agent.request( + 'GET', url, Headers(self.headers), None) except TypeError as te: print(url.encode()) - request = agent.request( 'GET', url.encode(), Headers(self.headers), None ) - + request = agent.request( + 'GET', url.encode(), Headers(self.headers), None) if single is True: id = time.time() @@ -1019,7 +973,7 @@ class Pubnub(PubnubCoreAsync): try: data = json.loads(data.decode("utf-8")) except: - _invoke(error, {'error' : 'json decode error'}) + _invoke(error, {'error': 'json decode error'}) if 'error' in data and 'status' in data and 'status' != 200: _invoke(error, data) @@ -1035,23 +989,25 @@ class Pubnub(PubnubCoreAsync): return abort + class WebClientContextFactory(ClientContextFactory): def getContext(self, hostname, port): return ClientContextFactory.getContext(self) + class PubNub403Response(Protocol): - def __init__( self, finished ): + def __init__(self, finished): self.finished = finished - def dataReceived( self, bytes ): + def dataReceived(self, bytes): #print '403 resp ', bytes self.finished.callback(bytes) - + + class PubNubResponse(Protocol): - def __init__( self, finished ): + def __init__(self, finished): self.finished = finished - def dataReceived( self, bytes ): + def dataReceived(self, bytes): #print bytes self.finished.callback(bytes) - diff --git a/python-twisted/examples/here-now-example.py b/python-twisted/examples/here-now-example.py index b3c9dc0..bba7d21 100644 --- a/python-twisted/examples/here-now-example.py +++ b/python-twisted/examples/here-now-example.py @@ -1,4 +1,4 @@ -## www.pubnub.com - PubNub Real-time push service in the cloud. +## www.pubnub.com - PubNub Real-time push service in the cloud. # coding=utf8 ## PubNub Real-time Push APIs and Notifications Framework @@ -13,28 +13,30 @@ import sys from twisted.internet import reactor from Pubnub import Pubnub -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- ## Initiate Pubnub State ## ----------------------------------------------------------------------- -pubnub = Pubnub( publish_key, subscribe_key, secret_key, cipher_key, ssl_on ) -crazy = 'hello_world' +pubnub = Pubnub(publish_key, subscribe_key, secret_key, cipher_key, ssl_on) +crazy = 'hello_world' ## ----------------------------------------------------------------------- ## History Example ## ----------------------------------------------------------------------- + + def here_now_complete(messages): print(messages) reactor.stop() -pubnub.here_now( { - 'channel' : crazy, - 'callback' : here_now_complete +pubnub.here_now({ + 'channel': crazy, + 'callback': here_now_complete }) ## ----------------------------------------------------------------------- diff --git a/python-twisted/examples/history-example.py b/python-twisted/examples/history-example.py index 5f352ef..f128cd7 100644 --- a/python-twisted/examples/history-example.py +++ b/python-twisted/examples/history-example.py @@ -1,4 +1,4 @@ -## www.pubnub.com - PubNub Real-time push service in the cloud. +## www.pubnub.com - PubNub Real-time push service in the cloud. # coding=utf8 ## PubNub Real-time Push APIs and Notifications Framework @@ -14,29 +14,31 @@ from twisted.internet import reactor sys.path.append('../') from Pubnub import Pubnub -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- ## Initiate Pubnub State ## ----------------------------------------------------------------------- -pubnub = Pubnub( publish_key, subscribe_key, secret_key, cipher_key, ssl_on ) -crazy = 'hello_world' +pubnub = Pubnub(publish_key, subscribe_key, secret_key, cipher_key, ssl_on) +crazy = 'hello_world' ## ----------------------------------------------------------------------- ## History Example ## ----------------------------------------------------------------------- + + def history_complete(messages): print(messages) reactor.stop() -pubnub.history( { - 'channel' : crazy, - 'limit' : 10, - 'callback' : history_complete +pubnub.history({ + 'channel': crazy, + 'limit': 10, + 'callback': history_complete }) ## ----------------------------------------------------------------------- diff --git a/python-twisted/examples/publish-example.py b/python-twisted/examples/publish-example.py index d15b21b..6b5b19a 100644 --- a/python-twisted/examples/publish-example.py +++ b/python-twisted/examples/publish-example.py @@ -1,4 +1,4 @@ -## www.pubnub.com - PubNub Real-time push service in the cloud. +## www.pubnub.com - PubNub Real-time push service in the cloud. # coding=utf8 ## PubNub Real-time Push APIs and Notifications Framework @@ -15,54 +15,62 @@ sys.path.append('../') sys.path.append('../../') from Pubnub import Pubnub -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' ##(Cipher key is Optional) -auth_key = len(sys.argv) > 5 and sys.argv[5] or 'abcd' ##(Cipher key is Optional) -ssl_on = len(sys.argv) > 6 and bool(sys.argv[5]) or False +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len( + sys.argv) > 4 and sys.argv[4] or '' # (Cipher key is Optional) +auth_key = len( + sys.argv) > 5 and sys.argv[5] or 'abcd' # (Cipher key is Optional) +ssl_on = len(sys.argv) > 6 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- ## Initiate Pubnub State ## ----------------------------------------------------------------------- -pubnub = Pubnub( publish_key, subscribe_key, secret_key, cipher_key, auth_key, ssl_on ) -crazy = 'hello_world' +pubnub = Pubnub( + publish_key, subscribe_key, secret_key, cipher_key, auth_key, ssl_on) +crazy = 'hello_world' ## ----------------------------------------------------------------------- ## Publish Example ## ----------------------------------------------------------------------- + + def publish_complete(info): print(info) + def publish_error(info): - print('ERROR : ' + str(info)) + print('ERROR : ' + str(info)) ## Publish string pubnub.publish({ - 'channel' : crazy, - 'message' : 'Hello World!', - 'callback' : publish_complete, - 'error' : publish_error + 'channel': crazy, + 'message': 'Hello World!', + 'callback': publish_complete, + 'error': publish_error }) ## Publish list -li = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] +li = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', + 'Saturday'] pubnub.publish({ - 'channel' : crazy, - 'message' : li, - 'callback' : publish_complete, - 'error' : publish_error + 'channel': crazy, + 'message': li, + 'callback': publish_complete, + 'error': publish_error }) + def done_cb(info): publish_complete(info) pubnub.publish({ - 'channel' : crazy, - 'message' : { 'some_key' : 'some_val' }, - 'callback' : done_cb, - 'error' : publish_error + 'channel': crazy, + 'message': {'some_key': 'some_val'}, + 'callback': done_cb, + 'error': publish_error }) diff --git a/python-twisted/examples/subscribe-example.py b/python-twisted/examples/subscribe-example.py index cf4a919..168a2d2 100644 --- a/python-twisted/examples/subscribe-example.py +++ b/python-twisted/examples/subscribe-example.py @@ -1,4 +1,4 @@ -## www.pubnub.com - PubNub Real-time push service in the cloud. +## www.pubnub.com - PubNub Real-time push service in the cloud. # coding=utf8 ## PubNub Real-time Push APIs and Notifications Framework @@ -14,32 +14,35 @@ from twisted.internet import reactor sys.path.append('../') from Pubnub import Pubnub -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len(sys.argv) > 4 and sys.argv[4] or None -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or None +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- ## Initiate Pubnub State ## ----------------------------------------------------------------------- #pubnub = Pubnub( publish_key, subscribe_key, secret_key, cipher_key, ssl_on ) -pubnub = Pubnub( publish_key, subscribe_key, secret_key, ssl_on ) -crazy = 'hello_world' +pubnub = Pubnub(publish_key, subscribe_key, secret_key, ssl_on) +crazy = 'hello_world' ## ----------------------------------------------------------------------- ## Subscribe Example ## ----------------------------------------------------------------------- + + def message_received(message): print(message) -def connected() : + +def connected(): print 'Connected' pubnub.subscribe({ - 'channel' : crazy, - 'connect' : connected, - 'callback' : message_received + 'channel': crazy, + 'connect': connected, + 'callback': message_received }) ## ----------------------------------------------------------------------- diff --git a/python-twisted/examples/uuid-example.py b/python-twisted/examples/uuid-example.py index 94840e0..581051b 100644 --- a/python-twisted/examples/uuid-example.py +++ b/python-twisted/examples/uuid-example.py @@ -1,4 +1,4 @@ -## www.pubnub.com - PubNub Real-time push service in the cloud. +## www.pubnub.com - PubNub Real-time push service in the cloud. # coding=utf8 ## PubNub Real-time Push APIs and Notifications Framework @@ -17,7 +17,7 @@ from Pubnub import Pubnub ## ----------------------------------------------------------------------- ## Initiate Pubnub State ## ----------------------------------------------------------------------- -pubnub = Pubnub( "", "", "", False ) +pubnub = Pubnub("", "", "", False) ## ----------------------------------------------------------------------- ## UUID Example diff --git a/python-twisted/tests/delivery.py b/python-twisted/tests/delivery.py index dc6b9e2..3ba221b 100644 --- a/python-twisted/tests/delivery.py +++ b/python-twisted/tests/delivery.py @@ -1,4 +1,4 @@ -## www.pubnub.com - PubNub Real-time push service in the cloud. +## www.pubnub.com - PubNub Real-time push service in the cloud. # coding=utf8 ## PubNub Real-time Push APIs and Notifications Framework @@ -20,93 +20,100 @@ from Pubnub import Pubnub ## ----------------------------------------------------------------------- ## Configuration ## ----------------------------------------------------------------------- -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len(sys.argv) > 4 and sys.argv[4] or 'demo' -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False -origin = len(sys.argv) > 6 and sys.argv[6] or 'pubsub.pubnub.com' +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or 'demo' +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False +origin = len(sys.argv) > 6 and sys.argv[6] or 'pubsub.pubnub.com' origin = '184.72.9.220' ## ----------------------------------------------------------------------- ## Analytics ## ----------------------------------------------------------------------- analytics = { - 'publishes' : 0, ## Total Send Requests - 'received' : 0, ## Total Received Messages (Deliveries) - 'queued' : 0, ## Total Unreceived Queue (UnDeliveries) - 'successful_publishes' : 0, ## Confirmed Successful Publish Request - 'failed_publishes' : 0, ## Confirmed UNSuccessful Publish Request - 'failed_deliveries' : 0, ## (successful_publishes - received) - 'deliverability' : 0 ## Percentage Delivery + 'publishes': 0, # Total Send Requests + 'received': 0, # Total Received Messages (Deliveries) + 'queued': 0, # Total Unreceived Queue (UnDeliveries) + 'successful_publishes': 0, # Confirmed Successful Publish Request + 'failed_publishes': 0, # Confirmed UNSuccessful Publish Request + 'failed_deliveries': 0, # (successful_publishes - received) + 'deliverability': 0 # Percentage Delivery } trips = { - 'last' : None, - 'current' : None, - 'max' : 0, - 'avg' : 0 + 'last': None, + 'current': None, + 'max': 0, + 'avg': 0 } ## ----------------------------------------------------------------------- ## Initiat Class ## ----------------------------------------------------------------------- channel = 'deliverability-' + str(time.time()) -pubnub = Pubnub( +pubnub = Pubnub( publish_key, subscribe_key, - secret_key = secret_key, - cipher_key = cipher_key, - ssl_on = ssl_on, - origin = origin + secret_key=secret_key, + cipher_key=cipher_key, + ssl_on=ssl_on, + origin=origin ) ## ----------------------------------------------------------------------- ## BENCHMARK ## ----------------------------------------------------------------------- -def publish_sent(info = None): - if info and info[0]: analytics['successful_publishes'] += 1 - else: analytics['failed_publishes'] += 1 + + +def publish_sent(info=None): + if info and info[0]: + analytics['successful_publishes'] += 1 + else: + analytics['failed_publishes'] += 1 analytics['publishes'] += 1 - analytics['queued'] += 1 + analytics['queued'] += 1 + + pubnub.timeout(send, 0.1) - pubnub.timeout( send, 0.1 ) def send(): if analytics['queued'] > 100: analytics['queued'] -= 10 - return pubnub.timeout( send, 10 ) + return pubnub.timeout(send, 10) pubnub.publish({ - 'channel' : channel, - 'callback' : publish_sent, - 'message' : "1234567890" + 'channel': channel, + 'callback': publish_sent, + 'message': "1234567890" }) + def received(message): - analytics['queued'] -= 1 + analytics['queued'] -= 1 analytics['received'] += 1 current_trip = trips['current'] = str(datetime.datetime.now())[0:19] - last_trip = trips['last'] = str( + last_trip = trips['last'] = str( datetime.datetime.now() - datetime.timedelta(seconds=1) )[0:19] ## New Trip Span (1 Second) - if not trips.has_key(current_trip) : + if current_trip not in trips: trips[current_trip] = 0 ## Average - if trips.has_key(last_trip): + if last_trip in trips: trips['avg'] = (trips['avg'] + trips[last_trip]) / 2 ## Increment Trip Counter trips[current_trip] = trips[current_trip] + 1 ## Update Max - if trips[current_trip] > trips['max'] : + if trips[current_trip] > trips['max']: trips['max'] = trips[current_trip] + def show_status(): ## Update Failed Deliveries analytics['failed_deliveries'] = \ @@ -115,45 +122,46 @@ def show_status(): ## Update Deliverability analytics['deliverability'] = ( - float(analytics['received']) / \ + float(analytics['received']) / float(analytics['successful_publishes'] or 1.0) ) * 100.0 ## Print Display - print( ( - "max:%(max)03d/sec " + \ - "avg:%(avg)03d/sec " + \ - "pubs:%(publishes)05d " + \ - "received:%(received)05d " + \ - "spub:%(successful_publishes)05d " + \ - "fpub:%(failed_publishes)05d " + \ - "failed:%(failed_deliveries)05d " + \ - "queued:%(queued)03d " + \ - "delivery:%(deliverability)03f%% " + \ - "" - ) % { - 'max' : trips['max'], - 'avg' : trips['avg'], - 'publishes' : analytics['publishes'], - 'received' : analytics['received'], - 'successful_publishes' : analytics['successful_publishes'], - 'failed_publishes' : analytics['failed_publishes'], - 'failed_deliveries' : analytics['failed_deliveries'], - 'publishes' : analytics['publishes'], - 'deliverability' : analytics['deliverability'], - 'queued' : analytics['queued'] - } ) - pubnub.timeout( show_status, 1 ) + print(( + "max:%(max)03d/sec " + + "avg:%(avg)03d/sec " + + "pubs:%(publishes)05d " + + "received:%(received)05d " + + "spub:%(successful_publishes)05d " + + "fpub:%(failed_publishes)05d " + + "failed:%(failed_deliveries)05d " + + "queued:%(queued)03d " + + "delivery:%(deliverability)03f%% " + + "" + ) % { + 'max': trips['max'], + 'avg': trips['avg'], + 'publishes': analytics['publishes'], + 'received': analytics['received'], + 'successful_publishes': analytics['successful_publishes'], + 'failed_publishes': analytics['failed_publishes'], + 'failed_deliveries': analytics['failed_deliveries'], + 'publishes': analytics['publishes'], + 'deliverability': analytics['deliverability'], + 'queued': analytics['queued'] + }) + pubnub.timeout(show_status, 1) + def connected(): show_status() - pubnub.timeout( send, 1 ) + pubnub.timeout(send, 1) -print( "Connected: %s\n" % origin ) +print("Connected: %s\n" % origin) pubnub.subscribe({ - 'channel' : channel, - 'connect' : connected, - 'callback' : received + 'channel': channel, + 'connect': connected, + 'callback': received }) ## ----------------------------------------------------------------------- diff --git a/python-twisted/tests/subscribe-test.py b/python-twisted/tests/subscribe-test.py index 0d4c65e..6ff4a35 100755 --- a/python-twisted/tests/subscribe-test.py +++ b/python-twisted/tests/subscribe-test.py @@ -1,4 +1,4 @@ -## www.pubnub.com - PubNub Real-time push service in the cloud. +## www.pubnub.com - PubNub Real-time push service in the cloud. # coding=utf8 ## PubNub Real-time Push APIs and Notifications Framework @@ -16,18 +16,18 @@ from Pubnub import Pubnub from functools import partial from threading import current_thread import threading -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len(sys.argv) > 4 and sys.argv[4] or None -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or None +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- ## Initiate Pubnub State ## ----------------------------------------------------------------------- #pubnub = Pubnub( publish_key, subscribe_key, secret_key, cipher_key, ssl_on ) -pubnub = Pubnub( publish_key, subscribe_key, secret_key, ssl_on ) -crazy = 'hello_world' +pubnub = Pubnub(publish_key, subscribe_key, secret_key, ssl_on) +crazy = 'hello_world' current = -1 @@ -37,9 +37,12 @@ received = 0 ## ----------------------------------------------------------------------- ## Subscribe Example ## ----------------------------------------------------------------------- + + def message_received(message): print message + def check_received(message): global current global errors @@ -53,18 +56,19 @@ def check_received(message): else: received += 1 print 'active thread count : ', threading.activeCount() - print 'errors = ' , errors + print 'errors = ', errors print current_thread().getName(), ' , ', 'received = ', received if received != message: - print '********** MISSED **************** ', message - received + print '********** MISSED **************** ', message - received current = message - -def connected_test(ch) : - print 'Connected' , ch -def connected(ch) : +def connected_test(ch): + print 'Connected', ch + + +def connected(ch): pass @@ -75,57 +79,63 @@ pubnub.subscribe({ 'callback' : message_received }) ''' + + def cb1(): - pubnub.subscribe({ - 'channel' : 'efgh1', - 'connect' : connected, - 'callback' : message_received - }) + pubnub.subscribe({ + 'channel': 'efgh1', + 'connect': connected, + 'callback': message_received + }) + def cb2(): - pubnub.subscribe({ - 'channel' : 'dsm-test', - 'connect' : connected_test, - 'callback' : check_received - }) + pubnub.subscribe({ + 'channel': 'dsm-test', + 'connect': connected_test, + 'callback': check_received + }) + def cb3(): - pubnub.unsubscribe({'channel' : 'efgh1'}) + pubnub.unsubscribe({'channel': 'efgh1'}) + def cb4(): - pubnub.unsubscribe({'channel' : 'abcd1'}) + pubnub.unsubscribe({'channel': 'abcd1'}) + def subscribe(channel): - pubnub.subscribe({ - 'channel' : channel, - 'connect' : connected, - 'callback' : message_received - }) + pubnub.subscribe({ + 'channel': channel, + 'connect': connected, + 'callback': message_received + }) print threading.activeCount() -pubnub.timeout(15,cb1) +pubnub.timeout(15, cb1) -pubnub.timeout(30,cb2) +pubnub.timeout(30, cb2) -pubnub.timeout(45,cb3) +pubnub.timeout(45, cb3) -pubnub.timeout(60,cb4) +pubnub.timeout(60, cb4) #''' -for x in range(1,1000): +for x in range(1, 1000): #print x def y(t): subscribe('channel-' + str(t)) def z(t): - pubnub.unsubscribe({'channel' : 'channel-' + str(t)}) + pubnub.unsubscribe({'channel': 'channel-' + str(t)}) - pubnub.timeout(x + 5, partial(y,x)) - pubnub.timeout(x + 25, partial(z, x)) + pubnub.timeout(x + 5, partial(y, x)) + pubnub.timeout(x + 25, partial(z, x)) x += 10 #''' diff --git a/python-twisted/tests/unit-test-full.py b/python-twisted/tests/unit-test-full.py index c5940af..f8be1cc 100644 --- a/python-twisted/tests/unit-test-full.py +++ b/python-twisted/tests/unit-test-full.py @@ -1,4 +1,4 @@ -## www.pubnub.com - PubNub Real-time push service in the cloud. +## www.pubnub.com - PubNub Real-time push service in the cloud. # coding=utf8 ## PubNub Real-time Push APIs and Notifications Framework @@ -8,10 +8,10 @@ ## TODO Tests ## ## - wait 20 minutes, send a message, receive and success. -## - -## - -## -## +## - +## - +## +## ## ----------------------------------- ## PubNub 3.1 Real-time Push Cloud API @@ -23,21 +23,21 @@ sys.path.append('./') sys.path.append('../common/') from Pubnub import Pubnub -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or None -cipher_key = len(sys.argv) > 4 and sys.argv[4] or None -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False +secret_key = len(sys.argv) > 3 and sys.argv[3] or None +cipher_key = len(sys.argv) > 4 and sys.argv[4] or None +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- ## Command Line Options Supplied PubNub ## ----------------------------------------------------------------------- pubnub_user_supplied_options = Pubnub( - publish_key, ## OPTIONAL (supply None to disable) - subscribe_key, ## REQUIRED - secret_key, ## OPTIONAL (supply None to disable) - cipher_key, ## OPTIONAL (supply None to disable) - ssl_on ## OPTIONAL (supply None to disable) + publish_key, # OPTIONAL (supply None to disable) + subscribe_key, # REQUIRED + secret_key, # OPTIONAL (supply None to disable) + cipher_key, # OPTIONAL (supply None to disable) + ssl_on # OPTIONAL (supply None to disable) ) ## ----------------------------------------------------------------------- @@ -54,15 +54,15 @@ pubnub_high_security = Pubnub( 'sec-c-MTliNDE0NTAtYjY4Ni00MDRkLTllYTItNDhiZGE0N2JlYzBl', ## Cipher Key - 'YWxzamRmbVjFaa05HVnGFqZHM3NXRBS73jxmhVMkjiwVVXV1d5UrXR1JLSkZFRr'+ - 'WVd4emFtUm1iR0TFpUZvbiBoYXMgYmVlbxWkhNaF3uUi8kM0YkJTEVlZYVFjBYi'+ - 'jFkWFIxSkxTa1pGUjd874hjklaTFpUwRVuIFNob3VsZCB5UwRkxUR1J6YVhlQWa'+ - 'V1ZkNGVH32mDkdho3pqtRnRVbTFpUjBaeGUgYXNrZWQtZFoKjda40ZWlyYWl1eX'+ - 'U4RkNtdmNub2l1dHE2TTA1jd84jkdJTbFJXYkZwWlZtRnKkWVrSRhhWbFpZVmFz'+ - 'c2RkZmTFpUpGa1dGSXhTa3hUYTFwR1Vpkm9yIGluZm9ybWFNfdsWQdSiiYXNWVX'+ - 'RSblJWYlRGcFVqQmFlRmRyYUU0MFpXbHlZV2wxZVhVNFJrTnR51YjJsMWRIRTJU'+ - 'W91ciBpbmZvcm1hdGliBzdWJtaXR0ZWQb3UZSBhIHJlc3BvbnNlLCB3ZWxsIHJl'+ - 'VEExWdHVybiB0am0aW9uIb24gYXMgd2UgcG9zc2libHkgY2FuLuhcFe24ldWVns'+ + 'YWxzamRmbVjFaa05HVnGFqZHM3NXRBS73jxmhVMkjiwVVXV1d5UrXR1JLSkZFRr' + + 'WVd4emFtUm1iR0TFpUZvbiBoYXMgYmVlbxWkhNaF3uUi8kM0YkJTEVlZYVFjBYi' + + 'jFkWFIxSkxTa1pGUjd874hjklaTFpUwRVuIFNob3VsZCB5UwRkxUR1J6YVhlQWa' + + 'V1ZkNGVH32mDkdho3pqtRnRVbTFpUjBaeGUgYXNrZWQtZFoKjda40ZWlyYWl1eX' + + 'U4RkNtdmNub2l1dHE2TTA1jd84jkdJTbFJXYkZwWlZtRnKkWVrSRhhWbFpZVmFz' + + 'c2RkZmTFpUpGa1dGSXhTa3hUYTFwR1Vpkm9yIGluZm9ybWFNfdsWQdSiiYXNWVX' + + 'RSblJWYlRGcFVqQmFlRmRyYUU0MFpXbHlZV2wxZVhVNFJrTnR51YjJsMWRIRTJU' + + 'W91ciBpbmZvcm1hdGliBzdWJtaXR0ZWQb3UZSBhIHJlc3BvbnNlLCB3ZWxsIHJl' + + 'VEExWdHVybiB0am0aW9uIb24gYXMgd2UgcG9zc2libHkgY2FuLuhcFe24ldWVns' + 'dSaTFpU3hVUjFKNllWaFdhRmxZUWpCaQo34gcmVxdWlGFzIHNveqQl83snBfVl3', ## 2048bit SSL ON - ENABLED TRUE @@ -72,19 +72,24 @@ pubnub_high_security = Pubnub( ## ----------------------------------------------------------------------- ## Channel | Message Test Data (UTF-8) ## ----------------------------------------------------------------------- -crazy = ' ~`â¦â§!@#$%^&*(顶顅Ȓ)+=[]\\{}|;\':",./<>?abcd' -many_channels = [ str(x) + '-many_channel_test' for x in range(10) ] -runthroughs = 0 -planned_tests = 2 +crazy = ' ~`â¦â§!@#$%^&*(顶顅Ȓ)+=[]\\{}|;\':",./<>?abcd' +many_channels = [str(x) + '-many_channel_test' for x in range(10)] +runthroughs = 0 +planned_tests = 2 delivery_retries = 0 -max_retries = 10 +max_retries = 10 ## ----------------------------------------------------------------------- ## Unit Test Function ## ----------------------------------------------------------------------- -def test( trial, name ) : - if trial : print( 'PASS: ' + name ) - else : print( '- FAIL - ' + name ) + + +def test(trial, name): + if trial: + print('PASS: ' + name) + else: + print('- FAIL - ' + name) + def test_pubnub(pubnub): global runthroughs, planned_tests, delivery_retries, max_retries @@ -94,36 +99,38 @@ def test_pubnub(pubnub): ## ----------------------------------------------------------------------- def phase2(): status = { - 'sent' : 0, - 'received' : 0, - 'connections' : 0 + 'sent': 0, + 'received': 0, + 'connections': 0 } - def received( message, chan ): + def received(message, chan): global runthroughs - test( status['received'] <= status['sent'], 'many sends' ) + test(status['received'] <= status['sent'], 'many sends') status['received'] += 1 - pubnub.unsubscribe({ 'channel' : chan }) + pubnub.unsubscribe({'channel': chan}) if status['received'] == len(many_channels): runthroughs += 1 - if runthroughs == planned_tests: pubnub.stop() + if runthroughs == planned_tests: + pubnub.stop() - def publish_complete( info, chan ): + def publish_complete(info, chan): global delivery_retries, max_retries status['sent'] += 1 - test( info, 'publish complete' ) - test( info and len(info) > 2, 'publish response' ) + test(info, 'publish complete') + test(info and len(info) > 2, 'publish response') if not info[0]: delivery_retries += 1 - if max_retries > delivery_retries: sendit(chan) + if max_retries > delivery_retries: + sendit(chan) def sendit(chan): tchan = chan pubnub.publish({ - 'channel' : chan, - 'message' : "Hello World", - 'callback' : (lambda msg:publish_complete( msg, tchan )) + 'channel': chan, + 'message': "Hello World", + 'callback': (lambda msg: publish_complete(msg, tchan)) }) def connected(chan): @@ -131,88 +138,89 @@ def test_pubnub(pubnub): sendit(chan) def delivered(info): - if info and info[0]: status['sent'] += 1 + if info and info[0]: + status['sent'] += 1 def subscribe(chan): pubnub.subscribe({ - 'channel' : chan, - 'connect' : (lambda:connected(chan+'')), - 'callback' : (lambda msg:received( msg, chan )) + 'channel': chan, + 'connect': (lambda: connected(chan + '')), + 'callback': (lambda msg: received(msg, chan)) }) ## Subscribe All Channels - for chan in many_channels: subscribe(chan) - + for chan in many_channels: + subscribe(chan) + ## ----------------------------------------------------------------------- ## Time Example ## ----------------------------------------------------------------------- def time_complete(timetoken): - test( timetoken, 'timetoken fetch' ) - test( isinstance( timetoken, int ), 'timetoken int type' ) + test(timetoken, 'timetoken fetch') + test(isinstance(timetoken, int), 'timetoken int type') - pubnub.time({ 'callback' : time_complete }) + pubnub.time({'callback': time_complete}) ## ----------------------------------------------------------------------- ## Publish Example ## ----------------------------------------------------------------------- def publish_complete(info): - test( info, 'publish complete' ) - test( info and len(info) > 2, 'publish response' ) + test(info, 'publish complete') + test(info and len(info) > 2, 'publish response') - pubnub.history( { - 'channel' : crazy, - 'limit' : 10, - 'callback' : history_complete + pubnub.history({ + 'channel': crazy, + 'limit': 10, + 'callback': history_complete }) ## ----------------------------------------------------------------------- ## History Example ## ----------------------------------------------------------------------- def history_complete(messages): - test( messages and len(messages) > 0, 'history' ) - test( messages, 'history' ) - + test(messages and len(messages) > 0, 'history') + test(messages, 'history') pubnub.publish({ - 'channel' : crazy, - 'message' : "Hello World", - 'callback' : publish_complete + 'channel': crazy, + 'message': "Hello World", + 'callback': publish_complete }) ## ----------------------------------------------------------------------- ## Subscribe Example ## ----------------------------------------------------------------------- def message_received(message): - test( message, 'message received' ) - pubnub.unsubscribe({ 'channel' : crazy }) + test(message, 'message received') + pubnub.unsubscribe({'channel': crazy}) - def done() : - pubnub.unsubscribe({ 'channel' : crazy }) + def done(): + pubnub.unsubscribe({'channel': crazy}) pubnub.publish({ - 'channel' : crazy, - 'message' : "Hello World", - 'callback' : (lambda x:x) + 'channel': crazy, + 'message': "Hello World", + 'callback': (lambda x: x) }) - def dumpster(message) : - test( 0, 'never see this' ) + def dumpster(message): + test(0, 'never see this') pubnub.subscribe({ - 'channel' : crazy, - 'connect' : done, - 'callback' : dumpster + 'channel': crazy, + 'connect': done, + 'callback': dumpster }) - def connected() : + def connected(): pubnub.publish({ - 'channel' : crazy, - 'message' : { 'Info' : 'Connected!' } + 'channel': crazy, + 'message': {'Info': 'Connected!'} }) pubnub.subscribe({ - 'channel' : crazy, - 'connect' : connected, - 'callback' : message_received + 'channel': crazy, + 'connect': connected, + 'callback': message_received }) phase2() @@ -223,4 +231,3 @@ def test_pubnub(pubnub): test_pubnub(pubnub_user_supplied_options) test_pubnub(pubnub_high_security) pubnub_high_security.start() - diff --git a/python-twisted/tests/unit-tests.py b/python-twisted/tests/unit-tests.py index f143a3a..d0e5722 100644 --- a/python-twisted/tests/unit-tests.py +++ b/python-twisted/tests/unit-tests.py @@ -10,98 +10,102 @@ sys.path.append('.') from PubnubUnitTest import Suite from Pubnub import Pubnub -pubnub = Pubnub("demo","demo") +pubnub = Pubnub("demo", "demo") tests_count = 1 + 2 + 1 -test_suite = Suite(pubnub,tests_count) +test_suite = Suite(pubnub, tests_count) tests = [] - def test_publish(): - channel = "hello" + str(time.time()) - name = "Publish Test" - def success(r): - test_suite.test(r[0] == 1, name) + channel = "hello" + str(time.time()) + name = "Publish Test" - def fail(e): - test_suite.test(False, msg , e) + def success(r): + test_suite.test(r[0] == 1, name) + def fail(e): + test_suite.test(False, msg, e) - pubnub.publish({ - 'channel' : 'hello', - 'message' : 'hi', - 'callback' : success, - 'error' : fail - }) + pubnub.publish({ + 'channel': 'hello', + 'message': 'hi', + 'callback': success, + 'error': fail + }) tests.append(test_publish) #""" + + def test_subscribe_publish(): - channel = "hello" + str(time.time()) - name = "Subscribe Publish Test" - publish_msg = "This is Pubnub Python-Twisted" - def connect(): - #print 'connect' - def success(r): - test_suite.test(r[0] == 1, name, "publish success") - - def fail(e): - test_suite.test(False, name , "Publish Failed", e) - - pubnub.publish({ - 'channel' : channel, - 'message' : publish_msg, - 'callback' : success, - 'error' : fail - }) - - def callback(r): - test_suite.test(r == publish_msg, name, "message received") - - pubnub.subscribe({ - 'channel' : channel, - 'callback' : callback, - 'connect' : connect - }) + channel = "hello" + str(time.time()) + name = "Subscribe Publish Test" + publish_msg = "This is Pubnub Python-Twisted" + + def connect(): + #print 'connect' + def success(r): + test_suite.test(r[0] == 1, name, "publish success") + + def fail(e): + test_suite.test(False, name, "Publish Failed", e) + + pubnub.publish({ + 'channel': channel, + 'message': publish_msg, + 'callback': success, + 'error': fail + }) + + def callback(r): + test_suite.test(r == publish_msg, name, "message received") + + pubnub.subscribe({ + 'channel': channel, + 'callback': callback, + 'connect': connect + }) tests.append(test_subscribe_publish) #""" + def test_here_now(): - channel = "hello12" #+ str(time.time()) - name = "Here Now Test" - - def connect(): - print 'connect' - def call_here_now(): - print 'call_here_now' - def success(r): - test_suite.test(r['occupancy'] == 1, name, "Here Now success") - - def fail(e): - test_suite.test(False, name , "Here Now Failed", e) - - pubnub.here_now({ - 'channel' : channel, - 'callback' : success, - 'error' : fail - }) - pubnub.timeout(5, call_here_now) - - def callback(r): - pass - print 'Subscribe' - pubnub.subscribe({ - 'channel' : channel, - 'callback' : callback, - 'connect' : connect - }) + channel = "hello12" # + str(time.time()) + name = "Here Now Test" + + def connect(): + print 'connect' + + def call_here_now(): + print 'call_here_now' + + def success(r): + test_suite.test(r['occupancy'] == 1, name, "Here Now success") + + def fail(e): + test_suite.test(False, name, "Here Now Failed", e) + + pubnub.here_now({ + 'channel': channel, + 'callback': success, + 'error': fail + }) + pubnub.timeout(5, call_here_now) + + def callback(r): + pass + print 'Subscribe' + pubnub.subscribe({ + 'channel': channel, + 'callback': callback, + 'connect': connect + }) tests.append(test_here_now) - - -for t in tests: t() +for t in tests: + t() pubnub.start() diff --git a/python-twisted/unassembled/Platform.py b/python-twisted/unassembled/Platform.py index c7fe5cd..d6d91ac 100644 --- a/python-twisted/unassembled/Platform.py +++ b/python-twisted/unassembled/Platform.py @@ -2,7 +2,8 @@ from twisted.web.client import getPage from twisted.internet import reactor from twisted.internet.defer import Deferred from twisted.internet.protocol import Protocol -from twisted.web.client import Agent, ContentDecoderAgent, RedirectAgent, GzipDecoder +from twisted.web.client import Agent, ContentDecoderAgent +from twisted.web.client import RedirectAgent, GzipDecoder from twisted.web.client import HTTPConnectionPool from twisted.web.http_headers import Headers from twisted.internet.ssl import ClientContextFactory @@ -15,16 +16,21 @@ from twisted.python.compat import ( _PY3, unicode, intToBytes, networkString, nativeString) pnconn_pool = HTTPConnectionPool(reactor, persistent=True) -pnconn_pool.maxPersistentPerHost = 100000 +pnconn_pool.maxPersistentPerHost = 100000 pnconn_pool.cachedConnectionTimeout = 310 pnconn_pool.retryAutomatically = True + class Pubnub(PubnubCoreAsync): - def start(self): reactor.run() - def stop(self): reactor.stop() - def timeout( self, delay, callback ): - reactor.callLater( delay, callback ) + def start(self): + reactor.run() + + def stop(self): + reactor.stop() + + def timeout(self, delay, callback): + reactor.callLater(delay, callback) def __init__( self, @@ -33,9 +39,9 @@ class Pubnub(PubnubCoreAsync): secret_key=False, cipher_key=False, auth_key=None, - ssl_on = False, - origin = 'pubsub.pubnub.com' - ) : + ssl_on=False, + origin='pubsub.pubnub.com' + ): super(Pubnub, self).__init__( publish_key=publish_key, subscribe_key=subscribe_key, @@ -44,13 +50,13 @@ class Pubnub(PubnubCoreAsync): auth_key=auth_key, ssl_on=ssl_on, origin=origin, - ) + ) self.headers = {} self.headers['User-Agent'] = ['Python-Twisted'] #self.headers['Accept-Encoding'] = [self.accept_encoding] self.headers['V'] = [self.version] - def _request( self, request, callback=None, error=None, single=False ) : + def _request(self, request, callback=None, error=None, single=False): global pnconn_pool def _invoke(func, data): @@ -67,18 +73,19 @@ class Pubnub(PubnubCoreAsync): ''' url = self.getUrl(request) - agent = ContentDecoderAgent(RedirectAgent(Agent( + agent = ContentDecoderAgent(RedirectAgent(Agent( reactor, - contextFactory = WebClientContextFactory(), - pool = self.ssl and None or pnconn_pool + contextFactory=WebClientContextFactory(), + pool=self.ssl and None or pnconn_pool )), [('gzip', GzipDecoder)]) try: - request = agent.request( 'GET', url, Headers(self.headers), None ) + request = agent.request( + 'GET', url, Headers(self.headers), None) except TypeError as te: print(url.encode()) - request = agent.request( 'GET', url.encode(), Headers(self.headers), None ) - + request = agent.request( + 'GET', url.encode(), Headers(self.headers), None) if single is True: id = time.time() @@ -112,7 +119,7 @@ class Pubnub(PubnubCoreAsync): try: data = json.loads(data.decode("utf-8")) except: - _invoke(error, {'error' : 'json decode error'}) + _invoke(error, {'error': 'json decode error'}) if 'error' in data and 'status' in data and 'status' != 200: _invoke(error, data) @@ -128,23 +135,25 @@ class Pubnub(PubnubCoreAsync): return abort + class WebClientContextFactory(ClientContextFactory): def getContext(self, hostname, port): return ClientContextFactory.getContext(self) + class PubNub403Response(Protocol): - def __init__( self, finished ): + def __init__(self, finished): self.finished = finished - def dataReceived( self, bytes ): + def dataReceived(self, bytes): #print '403 resp ', bytes self.finished.callback(bytes) - + + class PubNubResponse(Protocol): - def __init__( self, finished ): + def __init__(self, finished): self.finished = finished - def dataReceived( self, bytes ): + def dataReceived(self, bytes): #print bytes self.finished.callback(bytes) - diff --git a/python/Pubnub.py b/python/Pubnub.py index 230915c..93f416b 100644 --- a/python/Pubnub.py +++ b/python/Pubnub.py @@ -12,11 +12,12 @@ from Crypto.Cipher import AES from Crypto.Hash import MD5 -from base64 import encodestring, decodestring +from base64 import encodestring, decodestring import hashlib import hmac -class PubnubCrypto2() : + +class PubnubCrypto2(): """ #** #* PubnubCrypto @@ -27,8 +28,8 @@ class PubnubCrypto2() : pc = PubnubCrypto """ - - def pad( self, msg, block_size=16 ): + + def pad(self, msg, block_size=16): """ #** #* pad @@ -40,9 +41,9 @@ class PubnubCrypto2() : #** """ padding = block_size - (len(msg) % block_size) - return msg + chr(padding)*padding - - def depad( self, msg ): + return msg + chr(padding) * padding + + def depad(self, msg): """ #** #* depad @@ -53,7 +54,7 @@ class PubnubCrypto2() : """ return msg[0:-ord(msg[-1])] - def getSecret( self, key ): + def getSecret(self, key): """ #** #* getSecret @@ -64,7 +65,7 @@ class PubnubCrypto2() : """ return hashlib.sha256(key).hexdigest() - def encrypt( self, key, msg ): + def encrypt(self, key, msg): """ #** #* encrypt @@ -74,11 +75,12 @@ class PubnubCrypto2() : #** """ secret = self.getSecret(key) - Initial16bytes='0123456789012345' - cipher = AES.new(secret[0:32],AES.MODE_CBC,Initial16bytes) + 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 ): + + def decrypt(self, key, msg): """ #** #* decrypt @@ -88,12 +90,12 @@ class PubnubCrypto2() : #** """ secret = self.getSecret(key) - Initial16bytes='0123456789012345' - cipher = AES.new(secret[0:32],AES.MODE_CBC,Initial16bytes) + Initial16bytes = '0123456789012345' + cipher = AES.new(secret[0:32], AES.MODE_CBC, Initial16bytes) return self.depad((cipher.decrypt(decodestring(msg)))) -class PubnubCrypto3() : +class PubnubCrypto3(): """ #** #* PubnubCrypto @@ -104,8 +106,8 @@ class PubnubCrypto3() : pc = PubnubCrypto """ - - def pad( self, msg, block_size=16 ): + + def pad(self, msg, block_size=16): """ #** #* pad @@ -117,9 +119,9 @@ class PubnubCrypto3() : #** """ padding = block_size - (len(msg) % block_size) - return msg + (chr(padding)*padding).encode('utf-8') - - def depad( self, msg ): + return msg + (chr(padding) * padding).encode('utf-8') + + def depad(self, msg): """ #** #* depad @@ -130,7 +132,7 @@ class PubnubCrypto3() : """ return msg[0:-ord(msg[-1])] - def getSecret( self, key ): + def getSecret(self, key): """ #** #* getSecret @@ -141,7 +143,7 @@ class PubnubCrypto3() : """ return hashlib.sha256(key.encode("utf-8")).hexdigest() - def encrypt( self, key, msg ): + def encrypt(self, key, msg): """ #** #* encrypt @@ -151,10 +153,12 @@ class PubnubCrypto3() : #** """ secret = self.getSecret(key) - Initial16bytes='0123456789012345' - cipher = AES.new(secret[0:32],AES.MODE_CBC,Initial16bytes) - return encodestring(cipher.encrypt(self.pad(msg.encode('utf-8')))).decode('utf-8') - def decrypt( self, key, msg ): + Initial16bytes = '0123456789012345' + cipher = AES.new(secret[0:32], AES.MODE_CBC, Initial16bytes) + return encodestring( + cipher.encrypt(self.pad(msg.encode('utf-8')))).decode('utf-8') + + def decrypt(self, key, msg): """ #** #* decrypt @@ -164,40 +168,46 @@ class PubnubCrypto3() : #** """ secret = self.getSecret(key) - Initial16bytes='0123456789012345' - cipher = AES.new(secret[0:32],AES.MODE_CBC,Initial16bytes) - return (cipher.decrypt(decodestring(msg.encode('utf-8')))).decode('utf-8') + Initial16bytes = '0123456789012345' + cipher = AES.new(secret[0:32], AES.MODE_CBC, Initial16bytes) + return (cipher.decrypt( + decodestring(msg.encode('utf-8')))).decode('utf-8') -try: import json -except ImportError: import simplejson as json +try: + import json +except ImportError: + import simplejson as json import time import hashlib import uuid import sys -try: from urllib.parse import quote -except: from urllib2 import quote +try: + from urllib.parse import quote +except: + from urllib2 import quote -from base64 import urlsafe_b64encode +from base64 import urlsafe_b64encode from hashlib import sha256 import hmac + class PubnubBase(object): def __init__( self, publish_key, subscribe_key, - secret_key = False, - cipher_key = False, - auth_key = None, - ssl_on = False, - origin = 'pubsub.pubnub.com', - UUID = None - ) : + secret_key=False, + cipher_key=False, + auth_key=None, + ssl_on=False, + origin='pubsub.pubnub.com', + UUID=None + ): """ #** #* Pubnub @@ -209,41 +219,41 @@ class PubnubBase(object): #* @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) + #* @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.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.auth_key = auth_key + self.secret_key = secret_key + self.cipher_key = cipher_key + self.ssl = ssl_on + self.auth_key = auth_key - - if self.ssl : + if self.ssl: self.origin = 'https://' + self.origin - else : - self.origin = 'http://' + self.origin - + else: + self.origin = 'http://' + self.origin + self.uuid = UUID or str(uuid.uuid4()) if type(sys.version_info) is tuple: - self.python_version = 2 - self.pc = PubnubCrypto2() + self.python_version = 2 + self.pc = PubnubCrypto2() else: if sys.version_info.major == 2: - self.python_version = 2 - self.pc = PubnubCrypto2() + self.python_version = 2 + self.pc = PubnubCrypto2() else: self.python_version = 3 - self.pc = PubnubCrypto3() - + self.pc = PubnubCrypto3() + if not isinstance(self.uuid, str): raise AttributeError("pres_uuid must be a string") @@ -264,7 +274,7 @@ class PubnubBase(object): return signature ''' - def _pam_sign( self, msg ): + def _pam_sign(self, msg): """Calculate a signature by secret key and message.""" return urlsafe_b64encode(hmac.new( @@ -273,7 +283,7 @@ class PubnubBase(object): sha256 ).digest()) - def _pam_auth( self, query , apicode=0, callback=None): + def _pam_auth(self, query, apicode=0, callback=None): """Issue an authenticated request.""" if 'timestamp' not in query: @@ -300,57 +310,50 @@ class PubnubBase(object): query['signature'] = self._pam_sign(sign_input) - ''' - url = ("https://pubsub.pubnub.com/v1/auth/{apitype}/sub-key/".format(apitype="audit" if (apicode) else "grant") + - self.subscribe_key + "?" + - params + "&signature=" + - quote(signature, safe="")) - ''' - return self._request({"urlcomponents": [ - 'v1', 'auth', "audit" if (apicode) else "grant" , + 'v1', 'auth', "audit" if (apicode) else "grant", 'sub-key', self.subscribe_key - ], 'urlparams' : query}, - self._return_wrapped_callback(callback)) + ], 'urlparams': query}, + self._return_wrapped_callback(callback)) - def grant( self, channel, authkey=False, read=True, write=True, ttl=5, callback=None): + def grant(self, channel, authkey=False, read=True, + write=True, ttl=5, callback=None): """Grant Access on a Channel.""" return self._pam_auth({ - "channel" : channel, - "auth" : authkey, - "r" : read and 1 or 0, - "w" : write and 1 or 0, - "ttl" : ttl + "channel": channel, + "auth": authkey, + "r": read and 1 or 0, + "w": write and 1 or 0, + "ttl": ttl }, callback=callback) - def revoke( self, channel, authkey=False, ttl=1, callback=None): + def revoke(self, channel, authkey=False, ttl=1, callback=None): """Revoke Access on a Channel.""" return self._pam_auth({ - "channel" : channel, - "auth" : authkey, - "r" : 0, - "w" : 0, - "ttl" : ttl + "channel": channel, + "auth": authkey, + "r": 0, + "w": 0, + "ttl": ttl }, callback=callback) def audit(self, channel=False, authkey=False, callback=None): return self._pam_auth({ - "channel" : channel, - "auth" : authkey - },1, callback=callback) - - + "channel": channel, + "auth": authkey + }, 1, callback=callback) 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(self.pc.encrypt( + self.cipher_key, json.dumps(message)).replace('\n', '')) + else: message = json.dumps(message) - return message; + return message def decrypt(self, message): if self.cipher_key: @@ -361,15 +364,17 @@ class PubnubBase(object): def _return_wrapped_callback(self, callback=None): def _new_format_callback(response): if 'payload' in response: - if (callback != None): callback({'message' : response['message'], 'payload' : response['payload']}) + if (callback is not None): + callback({'message': response['message'], + 'payload': response['payload']}) else: - if (callback != None):callback(response) - if (callback != None): + if (callback is not None): + callback(response) + if (callback is not None): return _new_format_callback else: return None - def publish(channel, message, callback=None, error=None): """ #** @@ -403,10 +408,11 @@ class PubnubBase(object): channel, '0', message - ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) - - def presence( self, channel, callback, error=None) : + ], 'urlparams': {'auth': self.auth_key}}, + callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) + + def presence(self, channel, callback, error=None): """ #** #* presence @@ -425,13 +431,15 @@ class PubnubBase(object): pubnub.presence({ 'channel' : 'hello_world', - 'callback' : receive + 'callback' : receive }) """ - return self.subscribe({'channel': channel+'-pnpres', 'subscribe_key':self.subscribe_key, 'callback': self._return_wrapped_callback(callback)}) - - - def here_now( self, channel, callback, error=None) : + return self.subscribe({ + 'channel': channel + '-pnpres', + 'subscribe_key': self.subscribe_key, + 'callback': self._return_wrapped_callback(callback)}) + + def here_now(self, channel, callback, error=None): """ #** #* Here Now @@ -452,33 +460,31 @@ class PubnubBase(object): """ channel = str(args['channel']) - - callback = args['callback'] if 'callback' in args else None - error = args['error'] if 'error' in args else None + callback = args['callback'] if 'callback' in args else None + error = args['error'] if 'error' in args else None ## Fail if bad input. - if not channel : + if not channel: raise Exception('Missing Channel') return False - + ## Get Presence Here Now return self._request({"urlcomponents": [ - 'v2','presence', + 'v2', 'presence', 'sub_key', self.subscribe_key, 'channel', channel - ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) + ], 'urlparams': {'auth': self.auth_key}}, + callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) - def history(self, channel, count=100, reverse=False, start=None, end=None, callback=None, error=None) : + def history(self, channel, count=100, reverse=False, + start=None, end=None, callback=None, error=None): """ #** #* History #* #* Load 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({ @@ -489,25 +495,26 @@ class PubnubBase(object): """ - params = dict() + params = dict() - params['count'] = count - params['reverse'] = reverse - params['start'] = start - params['end'] = end + params['count'] = count + params['reverse'] = reverse + params['start'] = start + params['end'] = end ## Get History - return self._request({ 'urlcomponents' : [ + return self._request({'urlcomponents': [ 'v2', 'history', 'sub-key', self.subscribe_key, 'channel', channel, - ], 'urlparams' : {'auth' : self.auth_key}}, callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) + ], 'urlparams': {'auth': self.auth_key}}, + callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) - def time(self,callback=None) : + def time(self, callback=None): """ #** #* Time @@ -523,30 +530,30 @@ class PubnubBase(object): """ - time = self._request({'urlcomponents' : [ + time = self._request({'urlcomponents': [ 'time', '0' ]}, callback) - if time != None: + if time is not None: return time[0] - - def _encode( self, request ) : + 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): + "".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"]]) + "".join([' ~`!@#$%^&*()+=[]\\{}|;\':",./<>?'.find(ch) > -1 and + hex(ord(ch)).replace('0x', '%').upper() or + ch for ch in list(bit) + ]) for bit in request["urlcomponents"]]) if ("urlparams" in request): - url = url + '?' + "&".join([ x + "=" + str(y) for x,y in request["urlparams"].items() if y is not None]) + url = url + '?' + "&".join([x + "=" + str(y) for x, y in request[ + "urlparams"].items() if y is not None]) return url @@ -558,32 +565,38 @@ except ImportError: sha256 = digestmod.new import hmac + class EmptyLock(): def __enter__(self): pass - def __exit__(self,a,b,c): + + def __exit__(self, a, b, c): pass empty_lock = EmptyLock() + class PubnubCoreAsync(PubnubBase): - def start(self): pass - def stop(self): pass + def start(self): + pass + + def stop(self): + pass def __init__( self, publish_key, subscribe_key, - secret_key = False, - cipher_key = False, - auth_key = None, - ssl_on = False, - origin = 'pubsub.pubnub.com', - uuid = None, + secret_key=False, + cipher_key=False, + auth_key=None, + ssl_on=False, + origin='pubsub.pubnub.com', + uuid=None, _tt_lock=empty_lock, _channel_list_lock=empty_lock - ) : + ): """ #** #* Pubnub @@ -610,18 +623,18 @@ class PubnubCoreAsync(PubnubBase): ssl_on=ssl_on, origin=origin, UUID=uuid - ) - - self.subscriptions = {} - self.timetoken = 0 - self.last_timetoken = 0 - self.version = '3.3.4' - self.accept_encoding = 'gzip' - self.SUB_RECEIVER = None - self._connect = None - self._tt_lock = _tt_lock - self._channel_list_lock = _channel_list_lock - self._connect = lambda: None + ) + + self.subscriptions = {} + self.timetoken = 0 + self.last_timetoken = 0 + self.version = '3.3.4' + self.accept_encoding = 'gzip' + self.SUB_RECEIVER = None + self._connect = None + self._tt_lock = _tt_lock + self._channel_list_lock = _channel_list_lock + self._connect = lambda: None def get_channel_list(self, channels): channel = '' @@ -653,7 +666,8 @@ class PubnubCoreAsync(PubnubBase): for i in l: func(i) - def subscribe( self, channel, callback, error=None, connect=None, disconnect=None, reconnect=None, sync=False ) : + def subscribe(self, channel, callback, error=None, + connect=None, disconnect=None, reconnect=None, sync=False): """ #** #* Subscribe @@ -687,14 +701,15 @@ class PubnubCoreAsync(PubnubBase): """ with self._tt_lock: - self.last_timetoken = self.timetoken if self.timetoken != 0 else self.last_timetoken + self.last_timetoken = self.timetoken if self.timetoken != 0 \ + else self.last_timetoken self.timetoken = 0 if sync is True and self.susbcribe_sync is not None: self.susbcribe_sync(args) return - def _invoke(func,msg=None): + def _invoke(func, msg=None): if func is not None: if msg is not None: func(msg) @@ -708,17 +723,17 @@ class PubnubCoreAsync(PubnubBase): chobj = self.subscriptions[ch] if chobj['connected'] is False: chobj['connected'] = True - _invoke(chobj['connect'],chobj['name']) + _invoke(chobj['connect'], chobj['name']) def _invoke_error(channel_list=None, err=None): if channel_list is None: for ch in self.subscriptions: chobj = self.subscriptions[ch] - _invoke(chobj['error'],err) + _invoke(chobj['error'], err) else: for ch in channel_list: chobj = self.subscriptions[ch] - _invoke(chobj['error'],err) + _invoke(chobj['error'], err) def _get_channel(): for ch in self.subscriptions: @@ -726,53 +741,58 @@ class PubnubCoreAsync(PubnubBase): if chobj['subscribed'] is True: return chobj - ## New Channel? - if not channel in self.subscriptions or self.subscriptions[channel]['subscribed'] is False: - with self._channel_list_lock: - self.subscriptions[channel] = { - 'name' : channel, - 'first' : False, - 'connected' : False, - 'subscribed' : True, - 'callback' : callback, - 'connect' : connect, - 'disconnect' : disconnect, - 'reconnect' : reconnect, - 'error' : error - } - + if not channel in self.subscriptions or \ + self.subscriptions[channel]['subscribed'] is False: + with self._channel_list_lock: + self.subscriptions[channel] = { + 'name': channel, + 'first': False, + 'connected': False, + 'subscribed': True, + 'callback': callback, + 'connect': connect, + 'disconnect': disconnect, + 'reconnect': reconnect, + 'error': error + } ## return if already connected to channel - if channel in self.subscriptions and 'connected' in self.subscriptions[channel] and self.subscriptions[channel]['connected'] is True: - _invoke(error, "Already Connected") - return - - + if channel in self.subscriptions and \ + 'connected' in self.subscriptions[channel] and \ + self.subscriptions[channel]['connected'] is True: + _invoke(error, "Already Connected") + return - ## SUBSCRIPTION RECURSION + ## SUBSCRIPTION RECURSION def _connect(): - + self._reset_offline() def sub_callback(response): ## ERROR ? - if not response or ('message' in response and response['message'] == 'Forbidden'): - _invoke_error(response['payload']['channels'], response['message']) - _connect() - return + if not response or \ + ('message' in response and + response['message'] == 'Forbidden'): + _invoke_error(response['payload'][ + 'channels'], response['message']) + _connect() + return _invoke_connect() with self._tt_lock: - self.timetoken = self.last_timetoken if self.timetoken == 0 and self.last_timetoken != 0 else response[1] + self.timetoken = \ + self.last_timetoken if self.timetoken == 0 and \ + self.last_timetoken != 0 else response[1] if len(response) > 2: channel_list = response[2].split(',') response_list = response[0] for ch in enumerate(channel_list): if ch[1] in self.subscriptions: chobj = self.subscriptions[ch[1]] - _invoke(chobj['callback'],self.decrypt(response_list[ch[0]])) + _invoke(chobj['callback'], + self.decrypt(response_list[ch[0]])) else: response_list = response[0] chobj = _get_channel() @@ -782,23 +802,25 @@ class PubnubCoreAsync(PubnubBase): _connect() - channel_list = self.get_channel_list(self.subscriptions) if len(channel_list) <= 0: return ## CONNECT TO PUBNUB SUBSCRIBE SERVERS try: - self.SUB_RECEIVER = self._request( { "urlcomponents" : [ + self.SUB_RECEIVER = self._request({"urlcomponents": [ 'subscribe', self.subscribe_key, channel_list, '0', str(self.timetoken) - ], "urlparams" : {"uuid":self.uuid, "auth" : self.auth_key} }, sub_callback, sub_callback, single=True ) + ], "urlparams": {"uuid": self.uuid, "auth": self.auth_key}}, + sub_callback, + sub_callback, + single=True) except Exception as e: print(e) - self.timeout( 1, _connect) + self.timeout(1, _connect) return self._connect = _connect @@ -815,8 +837,7 @@ class PubnubCoreAsync(PubnubBase): self._reset_offline() self._connect() - - def unsubscribe( self, channel ): + def unsubscribe(self, channel): if channel in self.subscriptions is False: return False @@ -824,10 +845,10 @@ class PubnubCoreAsync(PubnubBase): ## DISCONNECT with self._channel_list_lock: if channel in self.subscriptions: - self.subscriptions[channel]['connected'] = 0 - self.subscriptions[channel]['subscribed'] = False - self.subscriptions[channel]['timetoken'] = 0 - self.subscriptions[channel]['first'] = False + self.subscriptions[channel]['connected'] = 0 + self.subscriptions[channel]['subscribed'] = False + self.subscriptions[channel]['timetoken'] = 0 + self.subscriptions[channel]['first'] = False self.CONNECT() @@ -843,13 +864,12 @@ import threading from threading import current_thread latest_sub_callback_lock = threading.RLock() -latest_sub_callback = {'id' : None, 'callback' : None} - - +latest_sub_callback = {'id': None, 'callback': None} class HTTPClient: - def __init__(self, url, urllib_func=None, callback=None, error=None, id=None): + def __init__(self, url, urllib_func=None, + callback=None, error=None, id=None): self.url = url self.id = id self.callback = callback @@ -862,7 +882,6 @@ class HTTPClient: self.callback = None self.error = None - def run(self): def _invoke(func, data): @@ -896,65 +915,68 @@ class HTTPClient: try: data = json.loads(data) except: - _invoke(latest_sub_callback['error'], {'error' : 'json decoding error'}) + _invoke(latest_sub_callback['error'], + {'error': 'json decoding error'}) return if code != 200: - _invoke(latest_sub_callback['error'],data) + _invoke(latest_sub_callback['error'], data) else: - _invoke(latest_sub_callback['callback'],data) + _invoke(latest_sub_callback['callback'], data) else: try: data = json.loads(data) except: - _invoke(self.error, {'error' : 'json decoding error'}) + _invoke(self.error, {'error': 'json decoding error'}) return if code != 200: - _invoke(self.error,data) + _invoke(self.error, data) else: - _invoke(self.callback,data) + _invoke(self.callback, data) def _urllib_request_2(url, timeout=320): try: - resp = urllib2.urlopen(url,timeout=timeout) + resp = urllib2.urlopen(url, timeout=timeout) except urllib2.HTTPError as http_error: resp = http_error - return (resp.read(),resp.code) + return (resp.read(), resp.code) + def _urllib_request_3(url, timeout=320): #print(url) try: - resp = urllib.request.urlopen(url,timeout=timeout) + resp = urllib.request.urlopen(url, timeout=timeout) except urllib.request.HTTPError as http_error: resp = http_error - r = resp.read().decode("utf-8") + r = resp.read().decode("utf-8") #print(r) - return (r,resp.code) + return (r, resp.code) _urllib_request = None + class Pubnub(PubnubCoreAsync): def __init__( self, publish_key, subscribe_key, - secret_key = False, - cipher_key = False, - auth_key = None, - ssl_on = False, - origin = 'pubsub.pubnub.com', - pres_uuid = None - ) : + secret_key=False, + cipher_key=False, + auth_key=None, + ssl_on=False, + origin='pubsub.pubnub.com', + pres_uuid=None + ): super(Pubnub, self).__init__( - publish_key = publish_key, - subscribe_key = subscribe_key, - secret_key = secret_key, - cipher_key = cipher_key, - auth_key = auth_key, - ssl_on = ssl_on, - origin = origin, - uuid = pres_uuid, + publish_key=publish_key, + subscribe_key=subscribe_key, + secret_key=secret_key, + cipher_key=cipher_key, + auth_key=auth_key, + ssl_on=ssl_on, + origin=origin, + uuid=pres_uuid, _tt_lock=threading.RLock(), _channel_list_lock=threading.RLock() ) @@ -971,29 +993,30 @@ class Pubnub(PubnubCoreAsync): thread = threading.Thread(target=cb) thread.start() - - def _request_async( self, request, callback=None, error=None, single=False ) : + def _request_async(self, request, callback=None, error=None, single=False): global _urllib_request ## Build URL url = self.getUrl(request) if single is True: id = time.time() - client = HTTPClient(url=url, urllib_func=_urllib_request, callback=None, error=None, id=id) + client = HTTPClient(url=url, urllib_func=_urllib_request, + callback=None, error=None, id=id) with latest_sub_callback_lock: latest_sub_callback['id'] = id latest_sub_callback['callback'] = callback latest_sub_callback['error'] = error else: - client = HTTPClient(url=url, urllib_func=_urllib_request, callback=callback, error=error) + client = HTTPClient(url=url, urllib_func=_urllib_request, + callback=callback, error=error) thread = threading.Thread(target=client.run) thread.start() + def abort(): - client.cancel(); + client.cancel() return abort - - def _request_sync( self, request) : + def _request_sync(self, request): global _urllib_request ## Build URL url = self.getUrl(request) @@ -1002,14 +1025,14 @@ class Pubnub(PubnubCoreAsync): try: resp_json = json.loads(response[0]) except: - return [0,"JSON Error"] + return [0, "JSON Error"] if response[1] != 200 and 'status' in resp_json: - return {'message' : resp_json['message'], 'payload' : resp_json['payload']} + return {'message': resp_json['message'], + 'payload': resp_json['payload']} return resp_json - def _request(self, request, callback=None, error=None, single=False): if callback is None: return self._request_sync(request) @@ -1027,7 +1050,7 @@ class Pubnub(PubnubCoreAsync): resp_json = json.loads(response.read().decode("utf-8")) except Exception as e: return None - + return resp_json def _request3_async( self, request, callback, single=False ) : diff --git a/python/examples/dev-console.py b/python/examples/dev-console.py index 383fa68..7814cef 100755 --- a/python/examples/dev-console.py +++ b/python/examples/dev-console.py @@ -1,4 +1,4 @@ -## www.pubnub.com - PubNub Real-time push service in the cloud. +## www.pubnub.com - PubNub Real-time push service in the cloud. # coding=utf8 ## PubNub Real-time Push APIs and Notifications Framework @@ -55,41 +55,55 @@ parser.add_option("--uuid", print(options) -pubnub = Pubnub(options.publish_key, options.subscribe_key, options.secret_key, options.cipher_key, options.auth_key, options.ssl, options.origin, options.uuid) +pubnub = Pubnub(options.publish_key, + options.subscribe_key, + options.secret_key, + options.cipher_key, + options.auth_key, + options.ssl, + options.origin, + options.uuid) class color: - PURPLE = '\033[95m' - CYAN = '\033[96m' - DARKCYAN = '\033[36m' - BLUE = '\033[94m' - GREEN = '\033[92m' - YELLOW = '\033[93m' - RED = '\033[91m' - BOLD = '\033[1m' - UNDERLINE = '\033[4m' - END = '\033[0m' + PURPLE = '\033[95m' + CYAN = '\033[96m' + DARKCYAN = '\033[36m' + BLUE = '\033[94m' + GREEN = '\033[92m' + YELLOW = '\033[93m' + RED = '\033[91m' + BOLD = '\033[1m' + UNDERLINE = '\033[4m' + END = '\033[0m' from datetime import datetime + def print_ok(msg, channel=None): - chstr = color.PURPLE + "[" + datetime.now().strftime('%Y-%m-%d %H:%M:%S') + "] " + color.END - chstr += color.CYAN + "[Channel : " + channel + "] " if channel is not None else "" + color.END + chstr = color.PURPLE + "[" + datetime.now().strftime( + '%Y-%m-%d %H:%M:%S') + "] " + color.END + chstr += color.CYAN + "[Channel : " + channel + \ + "] " if channel is not None else "" + color.END try: - print(chstr + color.GREEN + str(msg) + color.END) + print(chstr + color.GREEN + str(msg) + color.END) except Exception as e: print(msg) + def print_error(msg, channel=None): - chstr = color.PURPLE + "[" + datetime.now().strftime('%Y-%m-%d %H:%M:%S') + "] " + color.END - chstr += color.CYAN + "[Channel : " + channel + "] " if channel is not None else "" + color.END + chstr = color.PURPLE + "[" + datetime.now().strftime( + '%Y-%m-%d %H:%M:%S') + "] " + color.END + chstr += color.CYAN + "[Channel : " + channel + \ + "] " if channel is not None else "" + color.END try: - print( chstr + color.RED + color.BOLD +str(msg) + color.END) + print(chstr + color.RED + color.BOLD + str(msg) + color.END) except: print(msg) import threading + def kill_all_threads(): for thread in threading.enumerate(): if thread.isAlive(): @@ -101,6 +115,7 @@ def kill_all_threads(): #thread.exit() #print(str(thread.getName()) + ' could not be terminated') + def get_input(message, t=None): while True: try: @@ -117,7 +132,8 @@ def get_input(message, t=None): raise ValueError if t is not None and t == bool: - if command in ["True", "true", "1", 1, "y", "Y", "yes", "Yes", "YES"]: + valid = ["True", "true", "1", 1, "y", "Y", "yes", "Yes", "YES"] + if command in valid: return True else: return False @@ -131,18 +147,20 @@ def get_input(message, t=None): print_error("Invalid input : " + command) - def _publish_command_handler(): channel = get_input("[PUBLISH] Enter Channel Name ", str) if channel is None: return while True: - message = get_input("[PUBLISH] Enter Message ( QUIT or CTRL-C for exit from publish mode ) ") - if message == 'QUIT' or message == 'quit' or message == None: - return + message = get_input("[PUBLISH] Enter Message \ + ( QUIT or CTRL-C for exit from publish mode ) ") + if message == 'QUIT' or message == 'quit' or message is None: + return + def _callback(r): print_ok(r) + def _error(r): print_error(r) pubnub.publish(channel, message, _callback, _error) @@ -150,23 +168,30 @@ def _publish_command_handler(): def _subscribe_command_handler(): channel = get_input("[SUBSCRIBE] Enter Channel Name ", str) + def _callback(r): print_ok(r, channel) + def _error(r): print_error(r, channel) pubnub.subscribe(channel, _callback, _error) + def _unsubscribe_command_handler(): channel = get_input("[UNSUBSCRIBE] Enter Channel Name ", str) + def _callback(r): print_ok(r) + def _error(r): print_error(r) pubnub.unsubscribe(channel) + def _grant_command_handler(): def _callback(r): print_ok(r) + def _error(r): print_error(r) channel = get_input("[GRANT] Enter Channel Name ", str) @@ -174,11 +199,13 @@ def _grant_command_handler(): ttl = get_input("[GRANT] Enter ttl ", int) read = get_input("[GRANT] Read ? ", bool) write = get_input("[GRANT] Write ? ", bool) - pubnub.grant(channel, auth_key,read,write,ttl, _callback) + pubnub.grant(channel, auth_key, read, write, ttl, _callback) + def _revoke_command_handler(): def _callback(r): print_ok(r) + def _error(r): print_error(r) channel = get_input("[REVOKE] Enter Channel Name ", str) @@ -187,18 +214,22 @@ def _revoke_command_handler(): pubnub.revoke(channel, auth_key, ttl, _callback) + def _audit_command_handler(): def _callback(r): print_ok(r) + def _error(r): print_error(r) channel = get_input("[AUDIT] Enter Channel Name ", str) auth_key = get_input("[AUDIT] Enter Auth Key ", str) pubnub.audit(channel, auth_key, _callback) + def _history_command_handler(): def _callback(r): print_ok(r) + def _error(r): print_error(r) channel = get_input("[HISTORY] Enter Channel Name ", str) @@ -210,6 +241,7 @@ def _history_command_handler(): def _here_now_command_handler(): def _callback(r): print_ok(r) + def _error(r): print_error(r) channel = get_input("[HERE NOW] Enter Channel Name ", str) @@ -218,28 +250,32 @@ def _here_now_command_handler(): commands = [] -commands.append({"command" : "publish", "handler" : _publish_command_handler}) -commands.append({"command" : "subscribe", "handler" : _subscribe_command_handler}) -commands.append({"command" : "unsubscribe", "handler" : _unsubscribe_command_handler}) -commands.append({"command" : "here_now", "handler" : _here_now_command_handler}) -commands.append({"command" : "history", "handler" : _history_command_handler}) -commands.append({"command" : "grant", "handler" : _grant_command_handler}) -commands.append({"command" : "revoke", "handler" : _revoke_command_handler}) -commands.append({"command" : "audit", "handler" : _audit_command_handler}) +commands.append({"command": "publish", "handler": _publish_command_handler}) +commands.append( + {"command": "subscribe", "handler": _subscribe_command_handler}) +commands.append( + {"command": "unsubscribe", "handler": _unsubscribe_command_handler}) +commands.append( + {"command": "here_now", "handler": _here_now_command_handler}) +commands.append({"command": "history", "handler": _history_command_handler}) +commands.append({"command": "grant", "handler": _grant_command_handler}) +commands.append({"command": "revoke", "handler": _revoke_command_handler}) +commands.append({"command": "audit", "handler": _audit_command_handler}) # last command is quit. add new commands before this line -commands.append({"command" : "QUIT"}) +commands.append({"command": "QUIT"}) + def get_help(): help = "" help += "Channels currently subscribed to : " help += str(pubnub.get_channel_array()) help += "\n" - for i,v in enumerate(commands): + for i, v in enumerate(commands): help += "Enter " + str(i) + " for " + v['command'] + "\n" return help - + while True: command = get_input(color.BLUE + get_help(), int) if command == len(commands) - 1 or command is None: diff --git a/python/examples/here-now-example.py b/python/examples/here-now-example.py index b9f0b02..0888410 100644 --- a/python/examples/here-now-example.py +++ b/python/examples/here-now-example.py @@ -1,4 +1,4 @@ -## www.pubnub.com - PubNub Real-time push service in the cloud. +## www.pubnub.com - PubNub Real-time push service in the cloud. # coding=utf8 ## PubNub Real-time Push APIs and Notifications Framework @@ -14,24 +14,24 @@ sys.path.append('../') sys.path.append('./') from Pubnub import Pubnub -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- ## Initiate Pubnub State ## ----------------------------------------------------------------------- -pubnub = Pubnub( publish_key=publish_key, subscribe_key=subscribe_key, - secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) -crazy = 'hello_world' +pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, + secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) +crazy = 'hello_world' + def print_cb(message): - print(message) + print(message) -pubnub.here_now( { - 'channel' : crazy, - 'callback' : print_cb +pubnub.here_now({ + 'channel': crazy, + 'callback': print_cb }) - diff --git a/python/examples/history-example.py b/python/examples/history-example.py index bf78c7d..b5cc1fd 100755 --- a/python/examples/history-example.py +++ b/python/examples/history-example.py @@ -4,12 +4,11 @@ sys.path.append('./') from Pubnub import Pubnub ## Initiat Class -pubnub = Pubnub( 'demo', 'demo', None, False ) +pubnub = Pubnub('demo', 'demo', None, False) ## History Example history = pubnub.history({ - 'channel' : 'hello_world', - 'limit' : 1 + 'channel': 'hello_world', + 'limit': 1 }) print(history) - diff --git a/python/examples/publish-example.py b/python/examples/publish-example.py index e632aef..ebf3c73 100755 --- a/python/examples/publish-example.py +++ b/python/examples/publish-example.py @@ -1,4 +1,4 @@ -## www.pubnub.com - PubNub Real-time push service in the cloud. +## www.pubnub.com - PubNub Real-time push service in the cloud. # coding=utf8 ## PubNub Real-time Push APIs and Notifications Framework @@ -15,54 +15,62 @@ sys.path.append('../') sys.path.append('../../') from Pubnub import Pubnub -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' ##(Cipher key is Optional) -auth_key = len(sys.argv) > 5 and sys.argv[4] or 'abcd' ##(Cipher key is Optional) -ssl_on = len(sys.argv) > 6 and bool(sys.argv[5]) or False +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len( + sys.argv) > 4 and sys.argv[4] or '' # (Cipher key is Optional) +auth_key = len( + sys.argv) > 5 and sys.argv[4] or 'abcd' # (Cipher key is Optional) +ssl_on = len(sys.argv) > 6 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- ## Initiate Pubnub State ## ----------------------------------------------------------------------- -pubnub = Pubnub( publish_key, subscribe_key, secret_key, cipher_key, auth_key, ssl_on ) -crazy = 'hello_world' +pubnub = Pubnub( + publish_key, subscribe_key, secret_key, cipher_key, auth_key, ssl_on) +crazy = 'hello_world' ## ----------------------------------------------------------------------- ## Publish Example ## ----------------------------------------------------------------------- + + def publish_complete(info): print(info) + def publish_error(info): - print('ERROR : ' + str(info)) + print('ERROR : ' + str(info)) ## Publish string pubnub.publish({ - 'channel' : crazy, - 'message' : 'Hello World!', - 'callback' : publish_complete, - 'error' : publish_error + 'channel': crazy, + 'message': 'Hello World!', + 'callback': publish_complete, + 'error': publish_error }) ## Publish list -li = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] +li = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', + 'Saturday'] pubnub.publish({ - 'channel' : crazy, - 'message' : li, - 'callback' : publish_complete, - 'error' : publish_error + 'channel': crazy, + 'message': li, + 'callback': publish_complete, + 'error': publish_error }) + def done_cb(info): publish_complete(info) pubnub.publish({ - 'channel' : crazy, - 'message' : { 'some_key' : 'some_val' }, - 'callback' : done_cb, - 'error' : publish_error + 'channel': crazy, + 'message': {'some_key': 'some_val'}, + 'callback': done_cb, + 'error': publish_error }) diff --git a/python/examples/subscribe-example.py b/python/examples/subscribe-example.py index a67a08f..0a18899 100755 --- a/python/examples/subscribe-example.py +++ b/python/examples/subscribe-example.py @@ -8,48 +8,55 @@ import string from Pubnub import Pubnub ## Initiate Class -pubnub = Pubnub( 'demo', 'demo', None, False ) +pubnub = Pubnub('demo', 'demo', None, False) -print("My UUID is: "+pubnub.uuid) +print("My UUID is: " + pubnub.uuid) -channel = ''.join(random.choice(string.ascii_letters + string.digits) for x in range(20)) +channel = ''.join( + random.choice(string.ascii_letters + string.digits) for x in range(20)) ## Subscribe Example -def receive(message) : + + +def receive(message): print(message) return False + def pres_event(message): print(message) return False + def subscribe(): print("Listening for messages on '%s' channel..." % channel) pubnub.subscribe({ - 'channel' : channel, - 'callback' : receive + 'channel': channel, + 'callback': receive }) + def presence(): print("Listening for presence events on '%s' channel..." % channel) pubnub.presence({ - 'channel' : channel, - 'callback' : pres_event + 'channel': channel, + 'callback': pres_event }) + def publish(): print("Publishing a test message on '%s' channel..." % channel) pubnub.publish({ - 'channel' : channel, - 'message' : { 'text':'foo bar' } + 'channel': channel, + 'message': {'text': 'foo bar'} }) pres_thread = threading.Thread(target=presence) -pres_thread.daemon=True +pres_thread.daemon = True pres_thread.start() sub_thread = threading.Thread(target=subscribe) -sub_thread.daemon=True +sub_thread.daemon = True sub_thread.start() time.sleep(3) @@ -60,7 +67,6 @@ publish() print("waiting for subscribes and presence") pres_thread.join() -print(pubnub.here_now({'channel':channel})) +print(pubnub.here_now({'channel': channel})) sub_thread.join() - diff --git a/python/tests/subscribe-test.py b/python/tests/subscribe-test.py index be4a416..d8a3ea2 100755 --- a/python/tests/subscribe-test.py +++ b/python/tests/subscribe-test.py @@ -1,4 +1,4 @@ -## www.pubnub.com - PubNub Real-time push service in the cloud. +## www.pubnub.com - PubNub Real-time push service in the cloud. # coding=utf8 ## PubNub Real-time Push APIs and Notifications Framework @@ -16,18 +16,18 @@ from Pubnub import Pubnub from functools import partial from threading import current_thread import threading -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len(sys.argv) > 4 and sys.argv[4] or None -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or None +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- ## Initiate Pubnub State ## ----------------------------------------------------------------------- #pubnub = Pubnub( publish_key, subscribe_key, secret_key, cipher_key, ssl_on ) -pubnub = Pubnub( publish_key, subscribe_key, secret_key, ssl_on ) -crazy = 'hello_world' +pubnub = Pubnub(publish_key, subscribe_key, secret_key, ssl_on) +crazy = 'hello_world' current = -1 @@ -37,9 +37,12 @@ received = 0 ## ----------------------------------------------------------------------- ## Subscribe Example ## ----------------------------------------------------------------------- + + def message_received(message): print(message) + def check_received(message): global current global errors @@ -52,19 +55,20 @@ def check_received(message): errors += 1 else: received += 1 - print('active thread count : ' + str( threading.activeCount())) + print('active thread count : ' + str(threading.activeCount())) print('errors = ' + str(errors)) - print(current_thread().getName() + ' , ' + 'received = ' + str(received)) + print(current_thread().getName() + ' , ' + 'received = ' + str(received)) if received != message: - print('********** MISSED **************** ' + str( message - received )) + print('********** MISSED **************** ' + str(message - received)) current = message - -def connected_test(ch) : - print('Connected ' + ch) -def connected(ch) : +def connected_test(ch): + print('Connected ' + ch) + + +def connected(ch): pass @@ -75,56 +79,60 @@ pubnub.subscribe({ 'callback' : message_received }) ''' + + def cb1(): - pubnub.subscribe({ - 'channel' : 'efgh1', - 'connect' : connected, - 'callback' : message_received - }) + pubnub.subscribe({ + 'channel': 'efgh1', + 'connect': connected, + 'callback': message_received + }) + def cb2(): - pubnub.subscribe({ - 'channel' : 'dsm-test', - 'connect' : connected_test, - 'callback' : check_received - }) + pubnub.subscribe({ + 'channel': 'dsm-test', + 'connect': connected_test, + 'callback': check_received + }) + def cb3(): - pubnub.unsubscribe({'channel' : 'efgh1'}) + pubnub.unsubscribe({'channel': 'efgh1'}) -def cb4(): - pubnub.unsubscribe({'channel' : 'abcd1'}) -def subscribe(channel): - pubnub.subscribe({ - 'channel' : channel, - 'connect' : connected, - 'callback' : message_received - }) +def cb4(): + pubnub.unsubscribe({'channel': 'abcd1'}) +def subscribe(channel): + pubnub.subscribe({ + 'channel': channel, + 'connect': connected, + 'callback': message_received + }) -pubnub.timeout(15,cb1) +pubnub.timeout(15, cb1) -pubnub.timeout(30,cb2) +pubnub.timeout(30, cb2) -pubnub.timeout(45,cb3) +pubnub.timeout(45, cb3) -pubnub.timeout(60,cb4) +pubnub.timeout(60, cb4) #''' -for x in range(1,1000): +for x in range(1, 1000): #print x def y(t): subscribe('channel-' + str(t)) def z(t): - pubnub.unsubscribe({'channel' : 'channel-' + str(t)}) + pubnub.unsubscribe({'channel': 'channel-' + str(t)}) - pubnub.timeout(x + 5, partial(y,x)) - pubnub.timeout(x + 25, partial(z, x)) + pubnub.timeout(x + 5, partial(y, x)) + pubnub.timeout(x + 25, partial(z, x)) x += 10 #''' diff --git a/python/tests/unit-test.py b/python/tests/unit-test.py index 762959e..fd1bb97 100755 --- a/python/tests/unit-test.py +++ b/python/tests/unit-test.py @@ -1,4 +1,4 @@ -## www.pubnub.com - PubNub Real-time push service in the cloud. +## www.pubnub.com - PubNub Real-time push service in the cloud. # coding=utf8 ## PubNub Real-time Push APIs and Notifications Framework @@ -15,53 +15,55 @@ sys.path.append('..') sys.path.append('../common') from Pubnub import Pubnub -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or None -ssl_on = len(sys.argv) > 4 and bool(sys.argv[4]) or False +secret_key = len(sys.argv) > 3 and sys.argv[3] or None +ssl_on = len(sys.argv) > 4 and bool(sys.argv[4]) or False ## ----------------------------------------------------------------------- ## Initiat Class ## ----------------------------------------------------------------------- -pubnub = Pubnub( publish_key, subscribe_key, secret_key, ssl_on ) -crazy = 'demo' +pubnub = Pubnub(publish_key, subscribe_key, secret_key, ssl_on) +crazy = 'demo' ## --------------------------------------------------------------------------- ## Unit Test Function ## --------------------------------------------------------------------------- -def test( trial, name ) : - if trial : - print( 'PASS: ' + name ) - else : - print( 'FAIL: ' + name ) + + +def test(trial, name): + if trial: + print('PASS: ' + name) + else: + print('FAIL: ' + name) ## ----------------------------------------------------------------------- ## Publish Example ## ----------------------------------------------------------------------- publish_success = pubnub.publish({ - 'channel' : crazy, - 'message' : crazy + 'channel': crazy, + 'message': crazy }) -test( publish_success[0] == 1, 'Publish First Message Success' ) +test(publish_success[0] == 1, 'Publish First Message Success') ## ----------------------------------------------------------------------- ## History Example ## ----------------------------------------------------------------------- history = pubnub.history({ - 'channel' : crazy, - 'limit' : 1 + 'channel': crazy, + 'limit': 1 }) test( history[0] == crazy, 'History Message: ' + history[0] ) -test( len(history) == 1, 'History Message Count' ) +test(len(history) == 1, 'History Message Count') ## ----------------------------------------------------------------------- ## PubNub Server Time Example ## ----------------------------------------------------------------------- timestamp = pubnub.time() -test( timestamp > 0, 'PubNub Server Time: ' + str(timestamp) ) +test(timestamp > 0, 'PubNub Server Time: ' + str(timestamp)) diff --git a/python/unassembled/Platform.py b/python/unassembled/Platform.py index 0ffccbb..83bb6f5 100644 --- a/python/unassembled/Platform.py +++ b/python/unassembled/Platform.py @@ -10,13 +10,12 @@ import threading from threading import current_thread latest_sub_callback_lock = threading.RLock() -latest_sub_callback = {'id' : None, 'callback' : None} - - +latest_sub_callback = {'id': None, 'callback': None} class HTTPClient: - def __init__(self, url, urllib_func=None, callback=None, error=None, id=None): + def __init__(self, url, urllib_func=None, + callback=None, error=None, id=None): self.url = url self.id = id self.callback = callback @@ -29,7 +28,6 @@ class HTTPClient: self.callback = None self.error = None - def run(self): def _invoke(func, data): @@ -63,65 +61,68 @@ class HTTPClient: try: data = json.loads(data) except: - _invoke(latest_sub_callback['error'], {'error' : 'json decoding error'}) + _invoke(latest_sub_callback['error'], + {'error': 'json decoding error'}) return if code != 200: - _invoke(latest_sub_callback['error'],data) + _invoke(latest_sub_callback['error'], data) else: - _invoke(latest_sub_callback['callback'],data) + _invoke(latest_sub_callback['callback'], data) else: try: data = json.loads(data) except: - _invoke(self.error, {'error' : 'json decoding error'}) + _invoke(self.error, {'error': 'json decoding error'}) return if code != 200: - _invoke(self.error,data) + _invoke(self.error, data) else: - _invoke(self.callback,data) + _invoke(self.callback, data) def _urllib_request_2(url, timeout=320): try: - resp = urllib2.urlopen(url,timeout=timeout) + resp = urllib2.urlopen(url, timeout=timeout) except urllib2.HTTPError as http_error: resp = http_error - return (resp.read(),resp.code) + return (resp.read(), resp.code) + def _urllib_request_3(url, timeout=320): #print(url) try: - resp = urllib.request.urlopen(url,timeout=timeout) + resp = urllib.request.urlopen(url, timeout=timeout) except urllib.request.HTTPError as http_error: resp = http_error - r = resp.read().decode("utf-8") + r = resp.read().decode("utf-8") #print(r) - return (r,resp.code) + return (r, resp.code) _urllib_request = None + class Pubnub(PubnubCoreAsync): def __init__( self, publish_key, subscribe_key, - secret_key = False, - cipher_key = False, - auth_key = None, - ssl_on = False, - origin = 'pubsub.pubnub.com', - pres_uuid = None - ) : + secret_key=False, + cipher_key=False, + auth_key=None, + ssl_on=False, + origin='pubsub.pubnub.com', + pres_uuid=None + ): super(Pubnub, self).__init__( - publish_key = publish_key, - subscribe_key = subscribe_key, - secret_key = secret_key, - cipher_key = cipher_key, - auth_key = auth_key, - ssl_on = ssl_on, - origin = origin, - uuid = pres_uuid, + publish_key=publish_key, + subscribe_key=subscribe_key, + secret_key=secret_key, + cipher_key=cipher_key, + auth_key=auth_key, + ssl_on=ssl_on, + origin=origin, + uuid=pres_uuid, _tt_lock=threading.RLock(), _channel_list_lock=threading.RLock() ) @@ -138,29 +139,30 @@ class Pubnub(PubnubCoreAsync): thread = threading.Thread(target=cb) thread.start() - - def _request_async( self, request, callback=None, error=None, single=False ) : + def _request_async(self, request, callback=None, error=None, single=False): global _urllib_request ## Build URL url = self.getUrl(request) if single is True: id = time.time() - client = HTTPClient(url=url, urllib_func=_urllib_request, callback=None, error=None, id=id) + client = HTTPClient(url=url, urllib_func=_urllib_request, + callback=None, error=None, id=id) with latest_sub_callback_lock: latest_sub_callback['id'] = id latest_sub_callback['callback'] = callback latest_sub_callback['error'] = error else: - client = HTTPClient(url=url, urllib_func=_urllib_request, callback=callback, error=error) + client = HTTPClient(url=url, urllib_func=_urllib_request, + callback=callback, error=error) thread = threading.Thread(target=client.run) thread.start() + def abort(): - client.cancel(); + client.cancel() return abort - - def _request_sync( self, request) : + def _request_sync(self, request): global _urllib_request ## Build URL url = self.getUrl(request) @@ -169,14 +171,14 @@ class Pubnub(PubnubCoreAsync): try: resp_json = json.loads(response[0]) except: - return [0,"JSON Error"] + return [0, "JSON Error"] if response[1] != 200 and 'status' in resp_json: - return {'message' : resp_json['message'], 'payload' : resp_json['payload']} + return {'message': resp_json['message'], + 'payload': resp_json['payload']} return resp_json - def _request(self, request, callback=None, error=None, single=False): if callback is None: return self._request_sync(request) @@ -194,7 +196,7 @@ class Pubnub(PubnubCoreAsync): resp_json = json.loads(response.read().decode("utf-8")) except Exception as e: return None - + return resp_json def _request3_async( self, request, callback, single=False ) : -- cgit v1.2.3 From 1d97c69f186719fe007a4fa0033d39d9a68a4e43 Mon Sep 17 00:00:00 2001 From: Devendra Date: Wed, 23 Apr 2014 14:13:37 +0530 Subject: modifying dev console to use new style classes --- python/examples/dev-console.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/python/examples/dev-console.py b/python/examples/dev-console.py index 7814cef..2e93c7e 100755 --- a/python/examples/dev-console.py +++ b/python/examples/dev-console.py @@ -55,17 +55,17 @@ parser.add_option("--uuid", print(options) -pubnub = Pubnub(options.publish_key, - options.subscribe_key, - options.secret_key, - options.cipher_key, - options.auth_key, - options.ssl, - options.origin, +pubnub = Pubnub(options.publish_key, + options.subscribe_key, + options.secret_key, + options.cipher_key, + options.auth_key, + options.ssl, + options.origin, options.uuid) -class color: +class color(object): PURPLE = '\033[95m' CYAN = '\033[96m' DARKCYAN = '\033[36m' -- cgit v1.2.3 From f7b89bfafae34fa22509c1d1c59d1284ec62c5df Mon Sep 17 00:00:00 2001 From: Devendra Date: Wed, 23 Apr 2014 21:35:06 +0530 Subject: exception handling changes --- common/PubnubBase.py | 13 +---- common/PubnubCore.py | 20 ++------ common/PubnubCoreAsync.py | 24 +++++----- python-tornado/Pubnub.py | 53 ++++++++++----------- python-tornado/examples/here-now-example.py | 8 ++-- python-tornado/unassembled/Platform.py | 16 ++++--- python-twisted/Pubnub.py | 74 +++++++++++------------------ python-twisted/examples/here-now-example.py | 13 +++-- python-twisted/unassembled/Platform.py | 37 +++++---------- python/Pubnub.py | 37 ++++++--------- python/examples/dev-console.py | 26 ++++------ 11 files changed, 128 insertions(+), 193 deletions(-) diff --git a/common/PubnubBase.py b/common/PubnubBase.py index 5863da9..9a20034 100644 --- a/common/PubnubBase.py +++ b/common/PubnubBase.py @@ -10,7 +10,7 @@ import sys try: from urllib.parse import quote -except: +except ImportError: from urllib2 import quote from base64 import urlsafe_b64encode @@ -221,7 +221,7 @@ class PubnubBase(object): """ - message = self.encrypt(args['message']) + message = self.encrypt(message) ## Send Message return self._request({"urlcomponents": [ @@ -282,15 +282,6 @@ class PubnubBase(object): print(here_now['uuids']) """ - channel = str(args['channel']) - - callback = args['callback'] if 'callback' in args else None - error = args['error'] if 'error' in args else None - - ## Fail if bad input. - if not channel: - raise Exception('Missing Channel') - return False ## Get Presence Here Now return self._request({"urlcomponents": [ diff --git a/common/PubnubCore.py b/common/PubnubCore.py index 1c00215..8454797 100644 --- a/common/PubnubCore.py +++ b/common/PubnubCore.py @@ -45,7 +45,7 @@ class PubnubCore(PubnubCoreAsync): self.version = '3.4' self.accept_encoding = 'gzip' - def subscribe_sync(self, args): + def subscribe_sync(self, channel, callback, timetoken=0): """ #** #* Subscribe @@ -69,25 +69,11 @@ class PubnubCore(PubnubCoreAsync): """ - ## 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 + subscribe_key = self.subscribe_key ## Begin Subscribe while True: - timetoken = 'timetoken' in args and args['timetoken'] or 0 try: ## Wait for Message response = self._request({"urlcomponents": [ @@ -99,7 +85,7 @@ class PubnubCore(PubnubCoreAsync): ], "urlparams": {"uuid": self.uuid}}) messages = response[0] - args['timetoken'] = response[1] + timetoken = response[1] ## If it was a timeout if not len(messages): diff --git a/common/PubnubCoreAsync.py b/common/PubnubCoreAsync.py index de7627f..f8e9e68 100644 --- a/common/PubnubCoreAsync.py +++ b/common/PubnubCoreAsync.py @@ -248,21 +248,23 @@ class PubnubCoreAsync(PubnubBase): return ## CONNECT TO PUBNUB SUBSCRIBE SERVERS - try: - self.SUB_RECEIVER = self._request({"urlcomponents": [ - 'subscribe', - self.subscribe_key, - channel_list, - '0', - str(self.timetoken) - ], "urlparams": {"uuid": self.uuid, "auth": self.auth_key}}, - sub_callback, - sub_callback, - single=True) + #try: + self.SUB_RECEIVER = self._request({"urlcomponents": [ + 'subscribe', + self.subscribe_key, + channel_list, + '0', + str(self.timetoken) + ], "urlparams": {"uuid": self.uuid, "auth": self.auth_key}}, + sub_callback, + sub_callback, + single=True) + ''' except Exception as e: print(e) self.timeout(1, _connect) return + ''' self._connect = _connect diff --git a/python-tornado/Pubnub.py b/python-tornado/Pubnub.py index 718d74e..3d0ba1d 100644 --- a/python-tornado/Pubnub.py +++ b/python-tornado/Pubnub.py @@ -186,7 +186,7 @@ import sys try: from urllib.parse import quote -except: +except ImportError: from urllib2 import quote from base64 import urlsafe_b64encode @@ -397,7 +397,7 @@ class PubnubBase(object): """ - message = self.encrypt(args['message']) + message = self.encrypt(message) ## Send Message return self._request({"urlcomponents": [ @@ -458,15 +458,6 @@ class PubnubBase(object): print(here_now['uuids']) """ - channel = str(args['channel']) - - callback = args['callback'] if 'callback' in args else None - error = args['error'] if 'error' in args else None - - ## Fail if bad input. - if not channel: - raise Exception('Missing Channel') - return False ## Get Presence Here Now return self._request({"urlcomponents": [ @@ -807,21 +798,23 @@ class PubnubCoreAsync(PubnubBase): return ## CONNECT TO PUBNUB SUBSCRIBE SERVERS - try: - self.SUB_RECEIVER = self._request({"urlcomponents": [ - 'subscribe', - self.subscribe_key, - channel_list, - '0', - str(self.timetoken) - ], "urlparams": {"uuid": self.uuid, "auth": self.auth_key}}, - sub_callback, - sub_callback, - single=True) + #try: + self.SUB_RECEIVER = self._request({"urlcomponents": [ + 'subscribe', + self.subscribe_key, + channel_list, + '0', + str(self.timetoken) + ], "urlparams": {"uuid": self.uuid, "auth": self.auth_key}}, + sub_callback, + sub_callback, + single=True) + ''' except Exception as e: print(e) self.timeout(1, _connect) return + ''' self._connect = _connect @@ -905,7 +898,8 @@ class Pubnub(PubnubCoreAsync): self.http = tornado.httpclient.AsyncHTTPClient(max_clients=1000) self.id = None - def _request(self, request, callback=None, error=None, single=False): + def _request(self, request, callback=None, error=None, + single=False, read_timeout=5, connect_timeout=5): def _invoke(func, data): if func is not None: @@ -915,8 +909,8 @@ class Pubnub(PubnubCoreAsync): request = tornado.httpclient.HTTPRequest( url, 'GET', self.headers, - connect_timeout=10, - request_timeout=310) + connect_timeout=connect_timeout, + request_timeout=read_timeout) if single is True: id = time.time() self.id = id @@ -930,20 +924,23 @@ class Pubnub(PubnubCoreAsync): if body is None: return - #print(body) def handle_exc(*args): return True if response.error is not None: with ExceptionStackContext(handle_exc): - response.rethrow() + if response.code in [403, 401]: + response.rethrow() + else: + _invoke(error, {"message": response.reason}) return + try: data = json.loads(body) except TypeError as e: try: data = json.loads(body.decode("utf-8")) - except: + except ValueError as ve: _invoke(error, {'error': 'json decode error'}) if 'error' in data and 'status' in data and 'status' != 200: diff --git a/python-tornado/examples/here-now-example.py b/python-tornado/examples/here-now-example.py index e6e45a3..6e69d53 100644 --- a/python-tornado/examples/here-now-example.py +++ b/python-tornado/examples/here-now-example.py @@ -10,7 +10,6 @@ ## ----------------------------------- import sys -import tornado sys.path.append('..') sys.path.append('../../common') from Pubnub import Pubnub @@ -34,12 +33,11 @@ crazy = 'hello_world' def here_now_complete(messages): print(messages) + print(type(messages)) pubnub.stop() -pubnub.here_now({ - 'channel': crazy, - 'callback': here_now_complete -}) +pubnub.here_now( + channel=crazy, callback=here_now_complete, error=here_now_complete) ## ----------------------------------------------------------------------- ## IO Event Loop diff --git a/python-tornado/unassembled/Platform.py b/python-tornado/unassembled/Platform.py index 871a400..b0e0be9 100644 --- a/python-tornado/unassembled/Platform.py +++ b/python-tornado/unassembled/Platform.py @@ -51,7 +51,8 @@ class Pubnub(PubnubCoreAsync): self.http = tornado.httpclient.AsyncHTTPClient(max_clients=1000) self.id = None - def _request(self, request, callback=None, error=None, single=False): + def _request(self, request, callback=None, error=None, + single=False, read_timeout=5, connect_timeout=5): def _invoke(func, data): if func is not None: @@ -61,8 +62,8 @@ class Pubnub(PubnubCoreAsync): request = tornado.httpclient.HTTPRequest( url, 'GET', self.headers, - connect_timeout=10, - request_timeout=310) + connect_timeout=connect_timeout, + request_timeout=read_timeout) if single is True: id = time.time() self.id = id @@ -76,20 +77,23 @@ class Pubnub(PubnubCoreAsync): if body is None: return - #print(body) def handle_exc(*args): return True if response.error is not None: with ExceptionStackContext(handle_exc): - response.rethrow() + if response.code in [403, 401]: + response.rethrow() + else: + _invoke(error, {"message": response.reason}) return + try: data = json.loads(body) except TypeError as e: try: data = json.loads(body.decode("utf-8")) - except: + except ValueError as ve: _invoke(error, {'error': 'json decode error'}) if 'error' in data and 'status' in data and 'status' != 200: diff --git a/python-twisted/Pubnub.py b/python-twisted/Pubnub.py index c312033..94d2624 100644 --- a/python-twisted/Pubnub.py +++ b/python-twisted/Pubnub.py @@ -186,7 +186,7 @@ import sys try: from urllib.parse import quote -except: +except ImportError: from urllib2 import quote from base64 import urlsafe_b64encode @@ -397,7 +397,7 @@ class PubnubBase(object): """ - message = self.encrypt(args['message']) + message = self.encrypt(message) ## Send Message return self._request({"urlcomponents": [ @@ -458,15 +458,6 @@ class PubnubBase(object): print(here_now['uuids']) """ - channel = str(args['channel']) - - callback = args['callback'] if 'callback' in args else None - error = args['error'] if 'error' in args else None - - ## Fail if bad input. - if not channel: - raise Exception('Missing Channel') - return False ## Get Presence Here Now return self._request({"urlcomponents": [ @@ -807,21 +798,23 @@ class PubnubCoreAsync(PubnubBase): return ## CONNECT TO PUBNUB SUBSCRIBE SERVERS - try: - self.SUB_RECEIVER = self._request({"urlcomponents": [ - 'subscribe', - self.subscribe_key, - channel_list, - '0', - str(self.timetoken) - ], "urlparams": {"uuid": self.uuid, "auth": self.auth_key}}, - sub_callback, - sub_callback, - single=True) + #try: + self.SUB_RECEIVER = self._request({"urlcomponents": [ + 'subscribe', + self.subscribe_key, + channel_list, + '0', + str(self.timetoken) + ], "urlparams": {"uuid": self.uuid, "auth": self.auth_key}}, + sub_callback, + sub_callback, + single=True) + ''' except Exception as e: print(e) self.timeout(1, _connect) return + ''' self._connect = _connect @@ -866,6 +859,10 @@ import twisted from hashlib import sha256 import time import json + +import traceback + + from twisted.python.compat import ( _PY3, unicode, intToBytes, networkString, nativeString) @@ -918,13 +915,7 @@ class Pubnub(PubnubCoreAsync): func(data) ## 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]) - ''' + url = self.getUrl(request) agent = ContentDecoderAgent(RedirectAgent(Agent( @@ -937,7 +928,6 @@ class Pubnub(PubnubCoreAsync): request = agent.request( 'GET', url, Headers(self.headers), None) except TypeError as te: - print(url.encode()) request = agent.request( 'GET', url.encode(), Headers(self.headers), None) @@ -946,18 +936,13 @@ class Pubnub(PubnubCoreAsync): self.id = id def received(response): - finished = Deferred() - if response.code == 403: - response.deliverBody(PubNub403Response(finished)) - else: - response.deliverBody(PubNubResponse(finished)) - - return finished + if not isinstance(response, twisted.web._newclient.Response): + _invoke(error, {"message": "Not Found"}) + return - def error_handler(response): finished = Deferred() - if response.code == 403: - response.deliverBody(PubNub403Response(finished)) + if response.code in [401, 403]: + response.deliverBody(PubNubPamResponse(finished)) else: response.deliverBody(PubNubResponse(finished)) @@ -969,10 +954,10 @@ class Pubnub(PubnubCoreAsync): return None try: data = json.loads(data) - except Exception as e: + except ValueError as e: try: data = json.loads(data.decode("utf-8")) - except: + except ValueError as e: _invoke(error, {'error': 'json decode error'}) if 'error' in data and 'status' in data and 'status' != 200: @@ -985,7 +970,6 @@ class Pubnub(PubnubCoreAsync): request.addCallback(received) request.addCallback(complete) - request.addErrback(error_handler) return abort @@ -995,12 +979,11 @@ class WebClientContextFactory(ClientContextFactory): return ClientContextFactory.getContext(self) -class PubNub403Response(Protocol): +class PubNubPamResponse(Protocol): def __init__(self, finished): self.finished = finished def dataReceived(self, bytes): - #print '403 resp ', bytes self.finished.callback(bytes) @@ -1009,5 +992,4 @@ class PubNubResponse(Protocol): self.finished = finished def dataReceived(self, bytes): - #print bytes self.finished.callback(bytes) diff --git a/python-twisted/examples/here-now-example.py b/python-twisted/examples/here-now-example.py index bba7d21..14f45c4 100644 --- a/python-twisted/examples/here-now-example.py +++ b/python-twisted/examples/here-now-example.py @@ -10,7 +10,8 @@ ## ----------------------------------- import sys -from twisted.internet import reactor +sys.path.append('..') +sys.path.append('../../common') from Pubnub import Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' @@ -32,14 +33,12 @@ crazy = 'hello_world' def here_now_complete(messages): print(messages) - reactor.stop() + pubnub.stop() -pubnub.here_now({ - 'channel': crazy, - 'callback': here_now_complete -}) +pubnub.here_now( + channel=crazy, callback=here_now_complete, error=here_now_complete) ## ----------------------------------------------------------------------- ## IO Event Loop ## ----------------------------------------------------------------------- -reactor.run() +pubnub.start() diff --git a/python-twisted/unassembled/Platform.py b/python-twisted/unassembled/Platform.py index d6d91ac..a9e811b 100644 --- a/python-twisted/unassembled/Platform.py +++ b/python-twisted/unassembled/Platform.py @@ -12,6 +12,10 @@ import twisted from hashlib import sha256 import time import json + +import traceback + + from twisted.python.compat import ( _PY3, unicode, intToBytes, networkString, nativeString) @@ -64,13 +68,7 @@ class Pubnub(PubnubCoreAsync): func(data) ## 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]) - ''' + url = self.getUrl(request) agent = ContentDecoderAgent(RedirectAgent(Agent( @@ -83,7 +81,6 @@ class Pubnub(PubnubCoreAsync): request = agent.request( 'GET', url, Headers(self.headers), None) except TypeError as te: - print(url.encode()) request = agent.request( 'GET', url.encode(), Headers(self.headers), None) @@ -92,18 +89,13 @@ class Pubnub(PubnubCoreAsync): self.id = id def received(response): - finished = Deferred() - if response.code == 403: - response.deliverBody(PubNub403Response(finished)) - else: - response.deliverBody(PubNubResponse(finished)) - - return finished + if not isinstance(response, twisted.web._newclient.Response): + _invoke(error, {"message": "Not Found"}) + return - def error_handler(response): finished = Deferred() - if response.code == 403: - response.deliverBody(PubNub403Response(finished)) + if response.code in [401, 403]: + response.deliverBody(PubNubPamResponse(finished)) else: response.deliverBody(PubNubResponse(finished)) @@ -115,10 +107,10 @@ class Pubnub(PubnubCoreAsync): return None try: data = json.loads(data) - except Exception as e: + except ValueError as e: try: data = json.loads(data.decode("utf-8")) - except: + except ValueError as e: _invoke(error, {'error': 'json decode error'}) if 'error' in data and 'status' in data and 'status' != 200: @@ -131,7 +123,6 @@ class Pubnub(PubnubCoreAsync): request.addCallback(received) request.addCallback(complete) - request.addErrback(error_handler) return abort @@ -141,12 +132,11 @@ class WebClientContextFactory(ClientContextFactory): return ClientContextFactory.getContext(self) -class PubNub403Response(Protocol): +class PubNubPamResponse(Protocol): def __init__(self, finished): self.finished = finished def dataReceived(self, bytes): - #print '403 resp ', bytes self.finished.callback(bytes) @@ -155,5 +145,4 @@ class PubNubResponse(Protocol): self.finished = finished def dataReceived(self, bytes): - #print bytes self.finished.callback(bytes) diff --git a/python/Pubnub.py b/python/Pubnub.py index 93f416b..3bf02a3 100644 --- a/python/Pubnub.py +++ b/python/Pubnub.py @@ -186,7 +186,7 @@ import sys try: from urllib.parse import quote -except: +except ImportError: from urllib2 import quote from base64 import urlsafe_b64encode @@ -397,7 +397,7 @@ class PubnubBase(object): """ - message = self.encrypt(args['message']) + message = self.encrypt(message) ## Send Message return self._request({"urlcomponents": [ @@ -458,15 +458,6 @@ class PubnubBase(object): print(here_now['uuids']) """ - channel = str(args['channel']) - - callback = args['callback'] if 'callback' in args else None - error = args['error'] if 'error' in args else None - - ## Fail if bad input. - if not channel: - raise Exception('Missing Channel') - return False ## Get Presence Here Now return self._request({"urlcomponents": [ @@ -807,21 +798,23 @@ class PubnubCoreAsync(PubnubBase): return ## CONNECT TO PUBNUB SUBSCRIBE SERVERS - try: - self.SUB_RECEIVER = self._request({"urlcomponents": [ - 'subscribe', - self.subscribe_key, - channel_list, - '0', - str(self.timetoken) - ], "urlparams": {"uuid": self.uuid, "auth": self.auth_key}}, - sub_callback, - sub_callback, - single=True) + #try: + self.SUB_RECEIVER = self._request({"urlcomponents": [ + 'subscribe', + self.subscribe_key, + channel_list, + '0', + str(self.timetoken) + ], "urlparams": {"uuid": self.uuid, "auth": self.auth_key}}, + sub_callback, + sub_callback, + single=True) + ''' except Exception as e: print(e) self.timeout(1, _connect) return + ''' self._connect = _connect diff --git a/python/examples/dev-console.py b/python/examples/dev-console.py index 2e93c7e..868ba7c 100755 --- a/python/examples/dev-console.py +++ b/python/examples/dev-console.py @@ -55,13 +55,13 @@ parser.add_option("--uuid", print(options) -pubnub = Pubnub(options.publish_key, - options.subscribe_key, - options.secret_key, - options.cipher_key, - options.auth_key, - options.ssl, - options.origin, +pubnub = Pubnub(options.publish_key, + options.subscribe_key, + options.secret_key, + options.cipher_key, + options.auth_key, + options.ssl, + options.origin, options.uuid) @@ -87,7 +87,7 @@ def print_ok(msg, channel=None): "] " if channel is not None else "" + color.END try: print(chstr + color.GREEN + str(msg) + color.END) - except Exception as e: + except UnicodeEncodeError as e: print(msg) @@ -98,7 +98,7 @@ def print_error(msg, channel=None): "] " if channel is not None else "" + color.END try: print(chstr + color.RED + color.BOLD + str(msg) + color.END) - except: + except UnicodeEncodeError as e: print(msg) import threading @@ -107,13 +107,7 @@ import threading def kill_all_threads(): for thread in threading.enumerate(): if thread.isAlive(): - try: - thread._Thread__stop() - except Exception as e: - pass - #print(e) - #thread.exit() - #print(str(thread.getName()) + ' could not be terminated') + thread._Thread__stop() def get_input(message, t=None): -- cgit v1.2.3 From 493e29a108255eb3ae3166dc920f40e2f4e5c4c4 Mon Sep 17 00:00:00 2001 From: Devendra Date: Thu, 24 Apr 2014 00:16:57 +0530 Subject: adding single file for all platforms --- Pubnub.py | 2405 +++++++++++++++++++++++++++ common/PubnubCoreAsync.py | 15 +- python-tornado/examples/here-now-example.py | 4 +- python-twisted/Pubnub.py | 7 +- python-twisted/unassembled/Platform.py | 7 +- python/Pubnub.py | 35 +- python/unassembled/Platform.py | 20 +- 7 files changed, 2470 insertions(+), 23 deletions(-) create mode 100644 Pubnub.py diff --git a/Pubnub.py b/Pubnub.py new file mode 100644 index 0000000..bd00709 --- /dev/null +++ b/Pubnub.py @@ -0,0 +1,2405 @@ +try: + import json +except ImportError: + import simplejson as json + +import time +import hashlib +import uuid +import sys + +try: + from urllib.parse import quote +except ImportError: + from urllib2 import quote + +from base64 import urlsafe_b64encode +from hashlib import sha256 + + +import hmac + + + +from Crypto.Cipher import AES +from Crypto.Hash import MD5 +from base64 import encodestring, decodestring +import hashlib +import hmac + + +class PubnubCrypto2(): + """ + #** + #* 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)))) + + +class PubnubCrypto3(): + """ + #** + #* 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).encode('utf-8') + + 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.encode("utf-8")).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) + return encodestring( + cipher.encrypt(self.pad(msg.encode('utf-8')))).decode('utf-8') + + 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 (cipher.decrypt( + decodestring(msg.encode('utf-8')))).decode('utf-8') + + +class PubnubBase(object): + def __init__( + self, + publish_key, + subscribe_key, + secret_key=False, + cipher_key=False, + auth_key=None, + 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.auth_key = auth_key + + if self.ssl: + self.origin = 'https://' + self.origin + else: + self.origin = 'http://' + self.origin + + self.uuid = UUID or str(uuid.uuid4()) + + if type(sys.version_info) is tuple: + self.python_version = 2 + self.pc = PubnubCrypto2() + else: + if sys.version_info.major == 2: + self.python_version = 2 + self.pc = PubnubCrypto2() + else: + self.python_version = 3 + self.pc = PubnubCrypto3() + + if not isinstance(self.uuid, str): + 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 _pam_sign(self, msg): + """Calculate a signature by secret key and message.""" + + return urlsafe_b64encode(hmac.new( + self.secret_key.encode("utf-8"), + msg.encode("utf-8"), + sha256 + ).digest()) + + def _pam_auth(self, query, apicode=0, callback=None): + """Issue an authenticated request.""" + + if 'timestamp' not in query: + query['timestamp'] = int(time.time()) + + ## Global Grant? + if 'auth' in query and not query['auth']: + del query['auth'] + + if 'channel' in query and not query['channel']: + del query['channel'] + + params = "&".join([ + x + "=" + quote( + str(query[x]), safe="" + ) for x in sorted(query) + ]) + sign_input = "{subkey}\n{pubkey}\n{apitype}\n{params}".format( + subkey=self.subscribe_key, + pubkey=self.publish_key, + apitype="audit" if (apicode) else "grant", + params=params + ) + + query['signature'] = self._pam_sign(sign_input) + + return self._request({"urlcomponents": [ + 'v1', 'auth', "audit" if (apicode) else "grant", + 'sub-key', + self.subscribe_key + ], 'urlparams': query}, + self._return_wrapped_callback(callback)) + + def grant(self, channel, authkey=False, read=True, + write=True, ttl=5, callback=None): + """Grant Access on a Channel.""" + + return self._pam_auth({ + "channel": channel, + "auth": authkey, + "r": read and 1 or 0, + "w": write and 1 or 0, + "ttl": ttl + }, callback=callback) + + def revoke(self, channel, authkey=False, ttl=1, callback=None): + """Revoke Access on a Channel.""" + + return self._pam_auth({ + "channel": channel, + "auth": authkey, + "r": 0, + "w": 0, + "ttl": ttl + }, callback=callback) + + def audit(self, channel=False, authkey=False, callback=None): + return self._pam_auth({ + "channel": channel, + "auth": authkey + }, 1, callback=callback) + + 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 _return_wrapped_callback(self, callback=None): + def _new_format_callback(response): + if 'payload' in response: + if (callback is not None): + callback({'message': response['message'], + 'payload': response['payload']}) + else: + if (callback is not None): + callback(response) + if (callback is not None): + return _new_format_callback + else: + return None + + def publish(channel, message, callback=None, error=None): + """ + #** + #* 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) + + """ + + message = self.encrypt(message) + + ## Send Message + return self._request({"urlcomponents": [ + 'publish', + self.publish_key, + self.subscribe_key, + '0', + channel, + '0', + message + ], 'urlparams': {'auth': self.auth_key}}, + callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) + + def presence(self, channel, callback, error=None): + """ + #** + #* 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 + }) + """ + return self.subscribe({ + 'channel': channel + '-pnpres', + 'subscribe_key': self.subscribe_key, + 'callback': self._return_wrapped_callback(callback)}) + + def here_now(self, channel, callback, error=None): + """ + #** + #* 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']) + + """ + + ## Get Presence Here Now + return self._request({"urlcomponents": [ + 'v2', 'presence', + 'sub_key', self.subscribe_key, + 'channel', channel + ], 'urlparams': {'auth': self.auth_key}}, + callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) + + def history(self, channel, count=100, reverse=False, + start=None, end=None, callback=None, error=None): + """ + #** + #* History + #* + #* Load history from a channel. + #* + + ## History Example + history = pubnub.detailedHistory({ + 'channel' : 'hello_world', + 'count' : 5 + }) + print(history) + + """ + + params = dict() + + params['count'] = count + params['reverse'] = reverse + params['start'] = start + params['end'] = end + + ## Get History + return self._request({'urlcomponents': [ + 'v2', + 'history', + 'sub-key', + self.subscribe_key, + 'channel', + channel, + ], 'urlparams': {'auth': self.auth_key}}, + callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) + + def time(self, callback=None): + """ + #** + #* Time + #* + #* Timestamp from PubNub Cloud. + #* + #* @return int timestamp. + #* + + ## PubNub Server Time Example + timestamp = pubnub.time() + print(timestamp) + + """ + + time = self._request({'urlcomponents': [ + 'time', + '0' + ]}, callback) + if time is not 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 ("urlparams" in request): + url = url + '?' + "&".join([x + "=" + str(y) for x, y in request[ + "urlparams"].items() if y is not None]) + return url + + +try: + from hashlib import sha256 + digestmod = sha256 +except ImportError: + import Crypto.Hash.SHA256 as digestmod + sha256 = digestmod.new +import hmac + + +class EmptyLock(): + def __enter__(self): + pass + + def __exit__(self, a, b, c): + pass + +empty_lock = EmptyLock() + + +class PubnubCoreAsync(PubnubBase): + + def start(self): + pass + + def stop(self): + pass + + def __init__( + self, + publish_key, + subscribe_key, + secret_key=False, + cipher_key=False, + auth_key=None, + ssl_on=False, + origin='pubsub.pubnub.com', + uuid=None, + _tt_lock=empty_lock, + _channel_list_lock=empty_lock + ): + """ + #** + #* 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, + auth_key=auth_key, + ssl_on=ssl_on, + origin=origin, + UUID=uuid + ) + + self.subscriptions = {} + self.timetoken = 0 + self.last_timetoken = 0 + self.version = '3.3.4' + self.accept_encoding = 'gzip' + self.SUB_RECEIVER = None + self._connect = None + self._tt_lock = _tt_lock + self._channel_list_lock = _channel_list_lock + self._connect = lambda: None + + def get_channel_list(self, channels): + channel = '' + first = True + with self._channel_list_lock: + for ch in channels: + if not channels[ch]['subscribed']: + continue + if not first: + channel += ',' + else: + first = False + channel += ch + return channel + + def get_channel_array(self): + channels = self.subscriptions + channel = [] + with self._channel_list_lock: + for ch in channels: + if not channels[ch]['subscribed']: + continue + channel.append(ch) + return channel + + def each(l, func): + if func is None: + return + for i in l: + func(i) + + def subscribe(self, channel, callback, error=None, + connect=None, disconnect=None, reconnect=None, sync=False): + """ + #** + #* 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 + }) + + """ + + with self._tt_lock: + self.last_timetoken = self.timetoken if self.timetoken != 0 \ + else self.last_timetoken + self.timetoken = 0 + + if sync is True and self.susbcribe_sync is not None: + self.susbcribe_sync(args) + return + + def _invoke(func, msg=None): + if func is not None: + if msg is not None: + func(msg) + else: + func() + + def _invoke_connect(): + if self._channel_list_lock: + with self._channel_list_lock: + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + if chobj['connected'] is False: + chobj['connected'] = True + _invoke(chobj['connect'], chobj['name']) + + def _invoke_error(channel_list=None, err=None): + if channel_list is None: + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + _invoke(chobj['error'], err) + else: + for ch in channel_list: + chobj = self.subscriptions[ch] + _invoke(chobj['error'], err) + + def _get_channel(): + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + if chobj['subscribed'] is True: + return chobj + + ## New Channel? + if not channel in self.subscriptions or \ + self.subscriptions[channel]['subscribed'] is False: + with self._channel_list_lock: + self.subscriptions[channel] = { + 'name': channel, + 'first': False, + 'connected': False, + 'subscribed': True, + 'callback': callback, + 'connect': connect, + 'disconnect': disconnect, + 'reconnect': reconnect, + 'error': error + } + + ## return if already connected to channel + if channel in self.subscriptions and \ + 'connected' in self.subscriptions[channel] and \ + self.subscriptions[channel]['connected'] is True: + _invoke(error, "Already Connected") + return + + ## SUBSCRIPTION RECURSION + def _connect(): + + self._reset_offline() + + def error_callback(response): + ## ERROR ? + if not response or \ + ('message' in response and + response['message'] == 'Forbidden'): + _invoke_error(response['payload'][ + 'channels'], response['message']) + _connect() + return + if 'message' in response: + _invoke_error(err=response['message']) + + + def sub_callback(response): + ## ERROR ? + if not response or \ + ('message' in response and + response['message'] == 'Forbidden'): + _invoke_error(response['payload'][ + 'channels'], response['message']) + _connect() + return + + _invoke_connect() + + with self._tt_lock: + self.timetoken = \ + self.last_timetoken if self.timetoken == 0 and \ + self.last_timetoken != 0 else response[1] + if len(response) > 2: + channel_list = response[2].split(',') + response_list = response[0] + for ch in enumerate(channel_list): + if ch[1] in self.subscriptions: + chobj = self.subscriptions[ch[1]] + _invoke(chobj['callback'], + self.decrypt(response_list[ch[0]])) + else: + response_list = response[0] + chobj = _get_channel() + for r in response_list: + if chobj: + _invoke(chobj['callback'], self.decrypt(r)) + + _connect() + + channel_list = self.get_channel_list(self.subscriptions) + if len(channel_list) <= 0: + return + + ## CONNECT TO PUBNUB SUBSCRIBE SERVERS + #try: + self.SUB_RECEIVER = self._request({"urlcomponents": [ + 'subscribe', + self.subscribe_key, + channel_list, + '0', + str(self.timetoken) + ], "urlparams": {"uuid": self.uuid, "auth": self.auth_key}}, + sub_callback, + error_callback, + single=True) + ''' + except Exception as e: + print(e) + self.timeout(1, _connect) + return + ''' + + self._connect = _connect + + ## BEGIN SUBSCRIPTION (LISTEN FOR MESSAGES) + _connect() + + def _reset_offline(self): + if self.SUB_RECEIVER is not None: + self.SUB_RECEIVER() + self.SUB_RECEIVER = None + + def CONNECT(self): + self._reset_offline() + self._connect() + + def unsubscribe(self, channel): + + if channel in self.subscriptions is False: + return False + + ## DISCONNECT + with self._channel_list_lock: + if channel in self.subscriptions: + self.subscriptions[channel]['connected'] = 0 + self.subscriptions[channel]['subscribed'] = False + self.subscriptions[channel]['timetoken'] = 0 + self.subscriptions[channel]['first'] = False + self.CONNECT() + + +class PubnubCore(PubnubCoreAsync): + def __init__( + self, + publish_key, + subscribe_key, + secret_key=False, + cipher_key=False, + auth_key=None, + 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 ) + + """ + super(PubnubCore, self).__init__( + publish_key=publish_key, + subscribe_key=subscribe_key, + secret_key=secret_key, + cipher_key=cipher_key, + auth_key=auth_key, + ssl_on=ssl_on, + origin=origin, + UUID=uuid + ) + + self.subscriptions = {} + self.timetoken = 0 + self.version = '3.4' + self.accept_encoding = 'gzip' + + def subscribe_sync(self, channel, callback, timetoken=0): + """ + #** + #* Subscribe + #* + #* This is BLOCKING. + #* Listen for a message on a channel. + #* + #* @param array args with channel and callback. + #* @return false on fail, array on success. + #** + + ## Subscribe Example + def receive(message) : + print(message) + return True + + pubnub.subscribe({ + 'channel' : 'hello_world', + 'callback' : receive + }) + + """ + + subscribe_key = self.subscribe_key + + ## Begin Subscribe + while True: + + try: + ## Wait for Message + response = self._request({"urlcomponents": [ + 'subscribe', + subscribe_key, + channel, + '0', + str(timetoken) + ], "urlparams": {"uuid": self.uuid}}) + + messages = response[0] + timetoken = response[1] + + ## If it was a timeout + if not len(messages): + continue + + ## Run user Callback and Reconnect if user permits. + for message in messages: + if not callback(self.decrypt(message)): + return + + except Exception: + time.sleep(1) + + return True + + +try: + import urllib.request +except ImportError: + import urllib2 + +import threading +import json +import time +import threading +from threading import current_thread + +latest_sub_callback_lock = threading.RLock() +latest_sub_callback = {'id': None, 'callback': None} + + +class HTTPClient: + def __init__(self, url, urllib_func=None, + callback=None, error=None, id=None): + self.url = url + self.id = id + self.callback = callback + self.error = error + self.stop = False + self._urllib_func = urllib_func + + def cancel(self): + self.stop = True + self.callback = None + self.error = None + + def run(self): + + def _invoke(func, data): + if func is not None: + func(data) + + if self._urllib_func is None: + return + + ''' + try: + resp = urllib2.urlopen(self.url, timeout=320) + except urllib2.HTTPError as http_error: + resp = http_error + ''' + resp = self._urllib_func(self.url, timeout=320) + data = resp[0] + code = resp[1] + + if self.stop is True: + return + if self.callback is None: + global latest_sub_callback + global latest_sub_callback_lock + with latest_sub_callback_lock: + if latest_sub_callback['id'] != self.id: + return + else: + if latest_sub_callback['callback'] is not None: + latest_sub_callback['id'] = 0 + print data + try: + data = json.loads(data) + except ValueError as e: + _invoke(latest_sub_callback['error'], + {'error': 'json decoding error'}) + return + print code + if code != 200: + print 'ERROR' + _invoke(latest_sub_callback['error'], data) + else: + print 'CALLBACK' + _invoke(latest_sub_callback['callback'], data) + else: + try: + data = json.loads(data) + except ValueError: + _invoke(self.error, {'error': 'json decoding error'}) + return + + if code != 200: + _invoke(self.error, data) + else: + _invoke(self.callback, data) + + +def _urllib_request_2(url, timeout=320): + try: + resp = urllib2.urlopen(url, timeout=timeout) + except urllib2.HTTPError as http_error: + resp = http_error + except urllib2.URLError as error: + #print error.reason + msg = { "message" : str(error.reason)} + #print str(msg) + return (json.dumps(msg),0) + + return (resp.read(), resp.code) + + +def _urllib_request_3(url, timeout=320): + #print(url) + try: + resp = urllib.request.urlopen(url, timeout=timeout) + except (urllib.request.HTTPError, urllib.request.URLError) as http_error: + resp = http_error + r = resp.read().decode("utf-8") + #print(r) + return (r, resp.code) + +_urllib_request = None + + +class PubnubAsync(PubnubCoreAsync): + def __init__( + self, + publish_key, + subscribe_key, + secret_key=False, + cipher_key=False, + auth_key=None, + ssl_on=False, + origin='pubsub.pubnub.com', + pres_uuid=None + ): + super(Pubnub, self).__init__( + publish_key=publish_key, + subscribe_key=subscribe_key, + secret_key=secret_key, + cipher_key=cipher_key, + auth_key=auth_key, + ssl_on=ssl_on, + origin=origin, + uuid=pres_uuid, + _tt_lock=threading.RLock(), + _channel_list_lock=threading.RLock() + ) + global _urllib_request + if self.python_version == 2: + _urllib_request = _urllib_request_2 + else: + _urllib_request = _urllib_request_3 + + def timeout(self, interval, func): + def cb(): + time.sleep(interval) + func() + thread = threading.Thread(target=cb) + thread.start() + + def _request_async(self, request, callback=None, error=None, single=False): + global _urllib_request + ## Build URL + url = self.getUrl(request) + if single is True: + id = time.time() + client = HTTPClient(url=url, urllib_func=_urllib_request, + callback=None, error=None, id=id) + with latest_sub_callback_lock: + latest_sub_callback['id'] = id + latest_sub_callback['callback'] = callback + latest_sub_callback['error'] = error + else: + client = HTTPClient(url=url, urllib_func=_urllib_request, + callback=callback, error=error) + + thread = threading.Thread(target=client.run) + thread.start() + + def abort(): + client.cancel() + return abort + + def _request_sync(self, request): + global _urllib_request + ## Build URL + url = self.getUrl(request) + ## Send Request Expecting JSONP Response + response = _urllib_request(url, timeout=320) + try: + resp_json = json.loads(response[0]) + except ValueError: + return [0, "JSON Error"] + + if response[1] != 200 and 'status' in resp_json: + return {'message': resp_json['message'], + 'payload': resp_json['payload']} + + return resp_json + + def _request(self, request, callback=None, error=None, single=False): + if callback is None: + return self._request_sync(request) + else: + self._request_async(request, callback, error, single=single) + +''' + + def _request3_sync( self, request) : + ## Build URL + url = self.getUrl(request) + ## Send Request Expecting JSONP Response + try: + response = urllib.request.urlopen(url,timeout=310) + resp_json = json.loads(response.read().decode("utf-8")) + except Exception as e: + return None + + return resp_json + + def _request3_async( self, request, callback, single=False ) : + pass + + def _request3(self, request, callback=None, single=False): + if callback is None: + return self._request3_sync(request,single=single) + else: + self._request3_async(request, callback, single=single) + ''' + + +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 PubnubTornado(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, + auth_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, + auth_key=auth_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) + self.id = None + + def _request(self, request, callback=None, error=None, + single=False, read_timeout=5, connect_timeout=5): + + def _invoke(func, data): + if func is not None: + func(data) + + url = self.getUrl(request) + request = tornado.httpclient.HTTPRequest( + url, 'GET', + self.headers, + connect_timeout=connect_timeout, + request_timeout=read_timeout) + if single is True: + id = time.time() + self.id = id + + def responseCallback(response): + if single is True: + if not id == self.id: + return None + + body = response._get_body() + + if body is None: + return + + def handle_exc(*args): + return True + if response.error is not None: + with ExceptionStackContext(handle_exc): + if response.code in [403, 401]: + response.rethrow() + else: + _invoke(error, {"message": response.reason}) + return + + try: + data = json.loads(body) + except TypeError as e: + try: + data = json.loads(body.decode("utf-8")) + except ValueError as ve: + _invoke(error, {'error': 'json decode error'}) + + if 'error' in data and 'status' in data and 'status' != 200: + _invoke(error, data) + else: + _invoke(callback, data) + + self.http.fetch( + request=request, + callback=responseCallback + ) + + def abort(): + pass + + return abort + +## 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 PubnubCrypto2(): + """ + #** + #* 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)))) + + +class PubnubCrypto3(): + """ + #** + #* 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).encode('utf-8') + + 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.encode("utf-8")).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) + return encodestring( + cipher.encrypt(self.pad(msg.encode('utf-8')))).decode('utf-8') + + 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 (cipher.decrypt( + decodestring(msg.encode('utf-8')))).decode('utf-8') + + +try: + import json +except ImportError: + import simplejson as json + +import time +import hashlib +import uuid +import sys + +try: + from urllib.parse import quote +except ImportError: + from urllib2 import quote + +from base64 import urlsafe_b64encode +from hashlib import sha256 + + +import hmac + + +class PubnubBase(object): + def __init__( + self, + publish_key, + subscribe_key, + secret_key=False, + cipher_key=False, + auth_key=None, + 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.auth_key = auth_key + + if self.ssl: + self.origin = 'https://' + self.origin + else: + self.origin = 'http://' + self.origin + + self.uuid = UUID or str(uuid.uuid4()) + + if type(sys.version_info) is tuple: + self.python_version = 2 + self.pc = PubnubCrypto2() + else: + if sys.version_info.major == 2: + self.python_version = 2 + self.pc = PubnubCrypto2() + else: + self.python_version = 3 + self.pc = PubnubCrypto3() + + if not isinstance(self.uuid, str): + 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 _pam_sign(self, msg): + """Calculate a signature by secret key and message.""" + + return urlsafe_b64encode(hmac.new( + self.secret_key.encode("utf-8"), + msg.encode("utf-8"), + sha256 + ).digest()) + + def _pam_auth(self, query, apicode=0, callback=None): + """Issue an authenticated request.""" + + if 'timestamp' not in query: + query['timestamp'] = int(time.time()) + + ## Global Grant? + if 'auth' in query and not query['auth']: + del query['auth'] + + if 'channel' in query and not query['channel']: + del query['channel'] + + params = "&".join([ + x + "=" + quote( + str(query[x]), safe="" + ) for x in sorted(query) + ]) + sign_input = "{subkey}\n{pubkey}\n{apitype}\n{params}".format( + subkey=self.subscribe_key, + pubkey=self.publish_key, + apitype="audit" if (apicode) else "grant", + params=params + ) + + query['signature'] = self._pam_sign(sign_input) + + return self._request({"urlcomponents": [ + 'v1', 'auth', "audit" if (apicode) else "grant", + 'sub-key', + self.subscribe_key + ], 'urlparams': query}, + self._return_wrapped_callback(callback)) + + def grant(self, channel, authkey=False, read=True, + write=True, ttl=5, callback=None): + """Grant Access on a Channel.""" + + return self._pam_auth({ + "channel": channel, + "auth": authkey, + "r": read and 1 or 0, + "w": write and 1 or 0, + "ttl": ttl + }, callback=callback) + + def revoke(self, channel, authkey=False, ttl=1, callback=None): + """Revoke Access on a Channel.""" + + return self._pam_auth({ + "channel": channel, + "auth": authkey, + "r": 0, + "w": 0, + "ttl": ttl + }, callback=callback) + + def audit(self, channel=False, authkey=False, callback=None): + return self._pam_auth({ + "channel": channel, + "auth": authkey + }, 1, callback=callback) + + 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 _return_wrapped_callback(self, callback=None): + def _new_format_callback(response): + if 'payload' in response: + if (callback is not None): + callback({'message': response['message'], + 'payload': response['payload']}) + else: + if (callback is not None): + callback(response) + if (callback is not None): + return _new_format_callback + else: + return None + + def publish(channel, message, callback=None, error=None): + """ + #** + #* 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) + + """ + + message = self.encrypt(message) + + ## Send Message + return self._request({"urlcomponents": [ + 'publish', + self.publish_key, + self.subscribe_key, + '0', + channel, + '0', + message + ], 'urlparams': {'auth': self.auth_key}}, + callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) + + def presence(self, channel, callback, error=None): + """ + #** + #* 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 + }) + """ + return self.subscribe({ + 'channel': channel + '-pnpres', + 'subscribe_key': self.subscribe_key, + 'callback': self._return_wrapped_callback(callback)}) + + def here_now(self, channel, callback, error=None): + """ + #** + #* 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']) + + """ + + ## Get Presence Here Now + return self._request({"urlcomponents": [ + 'v2', 'presence', + 'sub_key', self.subscribe_key, + 'channel', channel + ], 'urlparams': {'auth': self.auth_key}}, + callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) + + def history(self, channel, count=100, reverse=False, + start=None, end=None, callback=None, error=None): + """ + #** + #* History + #* + #* Load history from a channel. + #* + + ## History Example + history = pubnub.detailedHistory({ + 'channel' : 'hello_world', + 'count' : 5 + }) + print(history) + + """ + + params = dict() + + params['count'] = count + params['reverse'] = reverse + params['start'] = start + params['end'] = end + + ## Get History + return self._request({'urlcomponents': [ + 'v2', + 'history', + 'sub-key', + self.subscribe_key, + 'channel', + channel, + ], 'urlparams': {'auth': self.auth_key}}, + callback=self._return_wrapped_callback(callback), + error=self._return_wrapped_callback(error)) + + def time(self, callback=None): + """ + #** + #* Time + #* + #* Timestamp from PubNub Cloud. + #* + #* @return int timestamp. + #* + + ## PubNub Server Time Example + timestamp = pubnub.time() + print(timestamp) + + """ + + time = self._request({'urlcomponents': [ + 'time', + '0' + ]}, callback) + if time is not 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 ("urlparams" in request): + url = url + '?' + "&".join([x + "=" + str(y) for x, y in request[ + "urlparams"].items() if y is not None]) + return url + + +try: + from hashlib import sha256 + digestmod = sha256 +except ImportError: + import Crypto.Hash.SHA256 as digestmod + sha256 = digestmod.new +import hmac + + +class EmptyLock(): + def __enter__(self): + pass + + def __exit__(self, a, b, c): + pass + +empty_lock = EmptyLock() + + +class PubnubCoreAsync(PubnubBase): + + def start(self): + pass + + def stop(self): + pass + + def __init__( + self, + publish_key, + subscribe_key, + secret_key=False, + cipher_key=False, + auth_key=None, + ssl_on=False, + origin='pubsub.pubnub.com', + uuid=None, + _tt_lock=empty_lock, + _channel_list_lock=empty_lock + ): + """ + #** + #* 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, + auth_key=auth_key, + ssl_on=ssl_on, + origin=origin, + UUID=uuid + ) + + self.subscriptions = {} + self.timetoken = 0 + self.last_timetoken = 0 + self.version = '3.3.4' + self.accept_encoding = 'gzip' + self.SUB_RECEIVER = None + self._connect = None + self._tt_lock = _tt_lock + self._channel_list_lock = _channel_list_lock + self._connect = lambda: None + + def get_channel_list(self, channels): + channel = '' + first = True + with self._channel_list_lock: + for ch in channels: + if not channels[ch]['subscribed']: + continue + if not first: + channel += ',' + else: + first = False + channel += ch + return channel + + def get_channel_array(self): + channels = self.subscriptions + channel = [] + with self._channel_list_lock: + for ch in channels: + if not channels[ch]['subscribed']: + continue + channel.append(ch) + return channel + + def each(l, func): + if func is None: + return + for i in l: + func(i) + + def subscribe(self, channel, callback, error=None, + connect=None, disconnect=None, reconnect=None, sync=False): + """ + #** + #* 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 + }) + + """ + + with self._tt_lock: + self.last_timetoken = self.timetoken if self.timetoken != 0 \ + else self.last_timetoken + self.timetoken = 0 + + if sync is True and self.susbcribe_sync is not None: + self.susbcribe_sync(args) + return + + def _invoke(func, msg=None): + if func is not None: + if msg is not None: + func(msg) + else: + func() + + def _invoke_connect(): + if self._channel_list_lock: + with self._channel_list_lock: + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + if chobj['connected'] is False: + chobj['connected'] = True + _invoke(chobj['connect'], chobj['name']) + + def _invoke_error(channel_list=None, err=None): + if channel_list is None: + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + _invoke(chobj['error'], err) + else: + for ch in channel_list: + chobj = self.subscriptions[ch] + _invoke(chobj['error'], err) + + def _get_channel(): + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + if chobj['subscribed'] is True: + return chobj + + ## New Channel? + if not channel in self.subscriptions or \ + self.subscriptions[channel]['subscribed'] is False: + with self._channel_list_lock: + self.subscriptions[channel] = { + 'name': channel, + 'first': False, + 'connected': False, + 'subscribed': True, + 'callback': callback, + 'connect': connect, + 'disconnect': disconnect, + 'reconnect': reconnect, + 'error': error + } + + ## return if already connected to channel + if channel in self.subscriptions and \ + 'connected' in self.subscriptions[channel] and \ + self.subscriptions[channel]['connected'] is True: + _invoke(error, "Already Connected") + return + + ## SUBSCRIPTION RECURSION + def _connect(): + + self._reset_offline() + + def sub_callback(response): + ## ERROR ? + if not response or \ + ('message' in response and + response['message'] == 'Forbidden'): + _invoke_error(response['payload'][ + 'channels'], response['message']) + _connect() + return + + _invoke_connect() + + with self._tt_lock: + self.timetoken = \ + self.last_timetoken if self.timetoken == 0 and \ + self.last_timetoken != 0 else response[1] + if len(response) > 2: + channel_list = response[2].split(',') + response_list = response[0] + for ch in enumerate(channel_list): + if ch[1] in self.subscriptions: + chobj = self.subscriptions[ch[1]] + _invoke(chobj['callback'], + self.decrypt(response_list[ch[0]])) + else: + response_list = response[0] + chobj = _get_channel() + for r in response_list: + if chobj: + _invoke(chobj['callback'], self.decrypt(r)) + + _connect() + + channel_list = self.get_channel_list(self.subscriptions) + if len(channel_list) <= 0: + return + + ## CONNECT TO PUBNUB SUBSCRIBE SERVERS + #try: + self.SUB_RECEIVER = self._request({"urlcomponents": [ + 'subscribe', + self.subscribe_key, + channel_list, + '0', + str(self.timetoken) + ], "urlparams": {"uuid": self.uuid, "auth": self.auth_key}}, + sub_callback, + sub_callback, + single=True) + ''' + except Exception as e: + print(e) + self.timeout(1, _connect) + return + ''' + + self._connect = _connect + + ## BEGIN SUBSCRIPTION (LISTEN FOR MESSAGES) + _connect() + + def _reset_offline(self): + if self.SUB_RECEIVER is not None: + self.SUB_RECEIVER() + self.SUB_RECEIVER = None + + def CONNECT(self): + self._reset_offline() + self._connect() + + def unsubscribe(self, channel): + + if channel in self.subscriptions is False: + return False + + ## DISCONNECT + with self._channel_list_lock: + if channel in self.subscriptions: + self.subscriptions[channel]['connected'] = 0 + self.subscriptions[channel]['subscribed'] = False + self.subscriptions[channel]['timetoken'] = 0 + self.subscriptions[channel]['first'] = False + self.CONNECT() + + +try: + from twisted.web.client import getPage + from twisted.internet import reactor + from twisted.internet.defer import Deferred + from twisted.internet.protocol import Protocol + from twisted.web.client import Agent, ContentDecoderAgent + from twisted.web.client import RedirectAgent, GzipDecoder + from twisted.web.client import HTTPConnectionPool + from twisted.web.http_headers import Headers + from twisted.internet.ssl import ClientContextFactory + from twisted.internet.task import LoopingCall + import twisted + + from twisted.python.compat import ( + _PY3, unicode, intToBytes, networkString, nativeString) + + pnconn_pool = HTTPConnectionPool(reactor, persistent=True) + pnconn_pool.maxPersistentPerHost = 100000 + pnconn_pool.cachedConnectionTimeout = 15 + pnconn_pool.retryAutomatically = True +except ImportError: + pass + +from hashlib import sha256 +import time +import json + +import traceback + + + + +class PubnubTwisted(PubnubCoreAsync): + + def start(self): + reactor.run() + + def stop(self): + reactor.stop() + + def timeout(self, delay, callback): + reactor.callLater(delay, callback) + + def __init__( + self, + publish_key, + subscribe_key, + secret_key=False, + cipher_key=False, + auth_key=None, + 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, + auth_key=auth_key, + ssl_on=ssl_on, + origin=origin, + ) + self.headers = {} + self.headers['User-Agent'] = ['Python-Twisted'] + #self.headers['Accept-Encoding'] = [self.accept_encoding] + self.headers['V'] = [self.version] + + def _request(self, request, callback=None, error=None, single=False): + global pnconn_pool + + def _invoke(func, data): + if func is not None: + func(data) + + ## Build URL + + url = self.getUrl(request) + + agent = ContentDecoderAgent(RedirectAgent(Agent( + reactor, + contextFactory=WebClientContextFactory(), + pool=self.ssl and None or pnconn_pool + )), [('gzip', GzipDecoder)]) + + try: + request = agent.request( + 'GET', url, Headers(self.headers), None) + except TypeError as te: + request = agent.request( + 'GET', url.encode(), Headers(self.headers), None) + + if single is True: + id = time.time() + self.id = id + + def received(response): + if not isinstance(response, twisted.web._newclient.Response): + _invoke(error, {"message" : "Not Found"}) + return + + finished = Deferred() + if response.code in [401,403]: + response.deliverBody(PubNubPamResponse(finished)) + else: + response.deliverBody(PubNubResponse(finished)) + + return finished + + def complete(data): + if single is True: + if id != self.id: + return None + try: + data = json.loads(data) + except ValueError as e: + try: + data = json.loads(data.decode("utf-8")) + except ValueError as e: + _invoke(error, {'error': 'json decode error'}) + + if 'error' in data and 'status' in data and 'status' != 200: + _invoke(error, data) + else: + _invoke(callback, data) + + def abort(): + pass + + request.addCallback(received) + request.addCallback(complete) + + return abort + + +class WebClientContextFactory(ClientContextFactory): + def getContext(self, hostname, port): + return ClientContextFactory.getContext(self) + + +class PubNubPamResponse(Protocol): + def __init__(self, finished): + self.finished = finished + + def dataReceived(self, bytes): + self.finished.callback(bytes) + + +class PubNubResponse(Protocol): + def __init__(self, finished): + self.finished = finished + + def dataReceived(self, bytes): + self.finished.callback(bytes) + + +import tornado.httpclient + +try: + from hashlib import sha256 + digestmod = sha256 +except ImportError: + import Crypto.Hash.SHA256 as digestmod + sha256 = digestmod.new + +try: + import hmac + import tornado.ioloop + from tornado.stack_context import ExceptionStackContext + ioloop = tornado.ioloop.IOLoop.instance() +except ImportError: + pass + + +class PubnubTornado(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, + auth_key=False, + ssl_on=False, + origin='pubsub.pubnub.com' + ): + super(PubnubTornado, self).__init__( + publish_key=publish_key, + subscribe_key=subscribe_key, + secret_key=secret_key, + cipher_key=cipher_key, + auth_key=auth_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) + self.id = None + + def _request(self, request, callback=None, error=None, + single=False, read_timeout=5, connect_timeout=5): + + def _invoke(func, data): + if func is not None: + func(data) + + url = self.getUrl(request) + request = tornado.httpclient.HTTPRequest( + url, 'GET', + self.headers, + connect_timeout=connect_timeout, + request_timeout=read_timeout) + if single is True: + id = time.time() + self.id = id + + def responseCallback(response): + if single is True: + if not id == self.id: + return None + + body = response._get_body() + + if body is None: + return + + def handle_exc(*args): + return True + if response.error is not None: + with ExceptionStackContext(handle_exc): + if response.code in [403, 401]: + response.rethrow() + else: + _invoke(error, {"message": response.reason}) + return + + try: + data = json.loads(body) + except TypeError as e: + try: + data = json.loads(body.decode("utf-8")) + except ValueError as ve: + _invoke(error, {'error': 'json decode error'}) + + if 'error' in data and 'status' in data and 'status' != 200: + _invoke(error, data) + else: + _invoke(callback, data) + + self.http.fetch( + request=request, + callback=responseCallback + ) + + def abort(): + pass + + return abort + diff --git a/common/PubnubCoreAsync.py b/common/PubnubCoreAsync.py index f8e9e68..c9a44c3 100644 --- a/common/PubnubCoreAsync.py +++ b/common/PubnubCoreAsync.py @@ -210,6 +210,19 @@ class PubnubCoreAsync(PubnubBase): self._reset_offline() + def error_callback(response): + ## ERROR ? + if not response or \ + ('message' in response and + response['message'] == 'Forbidden'): + _invoke_error(response['payload'][ + 'channels'], response['message']) + _connect() + return + if 'message' in response: + _invoke_error(err=response['message']) + + def sub_callback(response): ## ERROR ? if not response or \ @@ -257,7 +270,7 @@ class PubnubCoreAsync(PubnubBase): str(self.timetoken) ], "urlparams": {"uuid": self.uuid, "auth": self.auth_key}}, sub_callback, - sub_callback, + error_callback, single=True) ''' except Exception as e: diff --git a/python-tornado/examples/here-now-example.py b/python-tornado/examples/here-now-example.py index 6e69d53..c701daf 100644 --- a/python-tornado/examples/here-now-example.py +++ b/python-tornado/examples/here-now-example.py @@ -10,9 +10,7 @@ ## ----------------------------------- import sys -sys.path.append('..') -sys.path.append('../../common') -from Pubnub import Pubnub +from Pubnub import PubnubTornado as Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' diff --git a/python-twisted/Pubnub.py b/python-twisted/Pubnub.py index 94d2624..efbbfd9 100644 --- a/python-twisted/Pubnub.py +++ b/python-twisted/Pubnub.py @@ -868,10 +868,9 @@ from twisted.python.compat import ( pnconn_pool = HTTPConnectionPool(reactor, persistent=True) pnconn_pool.maxPersistentPerHost = 100000 -pnconn_pool.cachedConnectionTimeout = 310 +pnconn_pool.cachedConnectionTimeout = 15 pnconn_pool.retryAutomatically = True - class Pubnub(PubnubCoreAsync): def start(self): @@ -937,11 +936,11 @@ class Pubnub(PubnubCoreAsync): def received(response): if not isinstance(response, twisted.web._newclient.Response): - _invoke(error, {"message": "Not Found"}) + _invoke(error, {"message" : "Not Found"}) return finished = Deferred() - if response.code in [401, 403]: + if response.code in [401,403]: response.deliverBody(PubNubPamResponse(finished)) else: response.deliverBody(PubNubResponse(finished)) diff --git a/python-twisted/unassembled/Platform.py b/python-twisted/unassembled/Platform.py index a9e811b..b220257 100644 --- a/python-twisted/unassembled/Platform.py +++ b/python-twisted/unassembled/Platform.py @@ -21,10 +21,9 @@ from twisted.python.compat import ( pnconn_pool = HTTPConnectionPool(reactor, persistent=True) pnconn_pool.maxPersistentPerHost = 100000 -pnconn_pool.cachedConnectionTimeout = 310 +pnconn_pool.cachedConnectionTimeout = 15 pnconn_pool.retryAutomatically = True - class Pubnub(PubnubCoreAsync): def start(self): @@ -90,11 +89,11 @@ class Pubnub(PubnubCoreAsync): def received(response): if not isinstance(response, twisted.web._newclient.Response): - _invoke(error, {"message": "Not Found"}) + _invoke(error, {"message" : "Not Found"}) return finished = Deferred() - if response.code in [401, 403]: + if response.code in [401,403]: response.deliverBody(PubNubPamResponse(finished)) else: response.deliverBody(PubNubResponse(finished)) diff --git a/python/Pubnub.py b/python/Pubnub.py index 3bf02a3..a52c46e 100644 --- a/python/Pubnub.py +++ b/python/Pubnub.py @@ -760,6 +760,19 @@ class PubnubCoreAsync(PubnubBase): self._reset_offline() + def error_callback(response): + ## ERROR ? + if not response or \ + ('message' in response and + response['message'] == 'Forbidden'): + _invoke_error(response['payload'][ + 'channels'], response['message']) + _connect() + return + if 'message' in response: + _invoke_error(err=response['message']) + + def sub_callback(response): ## ERROR ? if not response or \ @@ -807,7 +820,7 @@ class PubnubCoreAsync(PubnubBase): str(self.timetoken) ], "urlparams": {"uuid": self.uuid, "auth": self.auth_key}}, sub_callback, - sub_callback, + error_callback, single=True) ''' except Exception as e: @@ -847,7 +860,7 @@ class PubnubCoreAsync(PubnubBase): try: import urllib.request -except: +except ImportError: import urllib2 import threading @@ -905,20 +918,24 @@ class HTTPClient: else: if latest_sub_callback['callback'] is not None: latest_sub_callback['id'] = 0 + print data try: data = json.loads(data) - except: + except ValueError as e: _invoke(latest_sub_callback['error'], {'error': 'json decoding error'}) return + print code if code != 200: + print 'ERROR' _invoke(latest_sub_callback['error'], data) else: + print 'CALLBACK' _invoke(latest_sub_callback['callback'], data) else: try: data = json.loads(data) - except: + except ValueError: _invoke(self.error, {'error': 'json decoding error'}) return @@ -933,6 +950,12 @@ def _urllib_request_2(url, timeout=320): resp = urllib2.urlopen(url, timeout=timeout) except urllib2.HTTPError as http_error: resp = http_error + except urllib2.URLError as error: + #print error.reason + msg = { "message" : str(error.reason)} + #print str(msg) + return (json.dumps(msg),0) + return (resp.read(), resp.code) @@ -940,7 +963,7 @@ def _urllib_request_3(url, timeout=320): #print(url) try: resp = urllib.request.urlopen(url, timeout=timeout) - except urllib.request.HTTPError as http_error: + except (urllib.request.HTTPError, urllib.request.URLError) as http_error: resp = http_error r = resp.read().decode("utf-8") #print(r) @@ -1017,7 +1040,7 @@ class Pubnub(PubnubCoreAsync): response = _urllib_request(url, timeout=320) try: resp_json = json.loads(response[0]) - except: + except ValueError: return [0, "JSON Error"] if response[1] != 200 and 'status' in resp_json: diff --git a/python/unassembled/Platform.py b/python/unassembled/Platform.py index 83bb6f5..17180fa 100644 --- a/python/unassembled/Platform.py +++ b/python/unassembled/Platform.py @@ -1,6 +1,6 @@ try: import urllib.request -except: +except ImportError: import urllib2 import threading @@ -58,20 +58,24 @@ class HTTPClient: else: if latest_sub_callback['callback'] is not None: latest_sub_callback['id'] = 0 + print data try: data = json.loads(data) - except: + except ValueError as e: _invoke(latest_sub_callback['error'], {'error': 'json decoding error'}) return + print code if code != 200: + print 'ERROR' _invoke(latest_sub_callback['error'], data) else: + print 'CALLBACK' _invoke(latest_sub_callback['callback'], data) else: try: data = json.loads(data) - except: + except ValueError: _invoke(self.error, {'error': 'json decoding error'}) return @@ -86,6 +90,12 @@ def _urllib_request_2(url, timeout=320): resp = urllib2.urlopen(url, timeout=timeout) except urllib2.HTTPError as http_error: resp = http_error + except urllib2.URLError as error: + #print error.reason + msg = { "message" : str(error.reason)} + #print str(msg) + return (json.dumps(msg),0) + return (resp.read(), resp.code) @@ -93,7 +103,7 @@ def _urllib_request_3(url, timeout=320): #print(url) try: resp = urllib.request.urlopen(url, timeout=timeout) - except urllib.request.HTTPError as http_error: + except (urllib.request.HTTPError, urllib.request.URLError) as http_error: resp = http_error r = resp.read().decode("utf-8") #print(r) @@ -170,7 +180,7 @@ class Pubnub(PubnubCoreAsync): response = _urllib_request(url, timeout=320) try: resp_json = json.loads(response[0]) - except: + except ValueError: return [0, "JSON Error"] if response[1] != 200 and 'status' in resp_json: -- cgit v1.2.3 From 93379625e26c98a8cfab72c106ae40819843f956 Mon Sep 17 00:00:00 2001 From: Devendra Date: Thu, 24 Apr 2014 00:35:10 +0530 Subject: remove relative imports --- common/unit-test-async.py | 3 --- python-tornado/examples/publish-example.py | 2 -- python-tornado/examples/subscribe-example.py | 2 -- python-tornado/examples/uuid-example.py | 1 - python-tornado/tests/benchmark.py | 3 --- python-tornado/tests/delivery.py | 1 - python-tornado/tests/subscribe-test.py | 1 - python-tornado/tests/unit-tests.py | 4 ---- python-twisted/examples/here-now-example.py | 2 -- python-twisted/examples/history-example.py | 1 - python-twisted/examples/publish-example.py | 2 -- python-twisted/examples/subscribe-example.py | 1 - python-twisted/examples/uuid-example.py | 1 - python-twisted/tests/benchmark.py | 1 - python-twisted/tests/delivery.py | 1 - python-twisted/tests/subscribe-test.py | 1 - python-twisted/tests/unit-test-full.py | 3 --- python-twisted/tests/unit-tests.py | 4 ---- python/examples/dev-console.py | 2 -- python/examples/here-now-example.py | 2 -- python/examples/history-example.py | 2 -- python/examples/publish-example.py | 2 -- python/examples/subscribe-example.py | 2 -- python/tests/detailed-history-unit-test.py | 3 --- python/tests/subscribe-test.py | 1 - python/tests/unit-test.py | 3 --- 26 files changed, 51 deletions(-) diff --git a/common/unit-test-async.py b/common/unit-test-async.py index 8123fdb..c4dfb65 100644 --- a/common/unit-test-async.py +++ b/common/unit-test-async.py @@ -12,9 +12,6 @@ import sys import time import random -sys.path.append('../') -sys.path.append('./') -sys.path.append('../common/') from Pubnub import Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' diff --git a/python-tornado/examples/publish-example.py b/python-tornado/examples/publish-example.py index 38d713c..b02c41f 100644 --- a/python-tornado/examples/publish-example.py +++ b/python-tornado/examples/publish-example.py @@ -11,8 +11,6 @@ import sys from twisted.internet import reactor -sys.path.append('../') -sys.path.append('../../') from Pubnub import Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' diff --git a/python-tornado/examples/subscribe-example.py b/python-tornado/examples/subscribe-example.py index 34ee886..0724fa9 100644 --- a/python-tornado/examples/subscribe-example.py +++ b/python-tornado/examples/subscribe-example.py @@ -11,8 +11,6 @@ import sys import tornado -sys.path.append('../') -sys.path.append('../..') from Pubnub import Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' diff --git a/python-tornado/examples/uuid-example.py b/python-tornado/examples/uuid-example.py index 33e19f8..a1cabf6 100644 --- a/python-tornado/examples/uuid-example.py +++ b/python-tornado/examples/uuid-example.py @@ -11,7 +11,6 @@ import sys import tornado -sys.path.append('../') from Pubnub import Pubnub ## ----------------------------------------------------------------------- diff --git a/python-tornado/tests/benchmark.py b/python-tornado/tests/benchmark.py index 9d1840e..636a87a 100644 --- a/python-tornado/tests/benchmark.py +++ b/python-tornado/tests/benchmark.py @@ -12,9 +12,6 @@ import sys import datetime import tornado -sys.path.append('./') -sys.path.append('../') -sys.path.append('../common') from Pubnub import Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' diff --git a/python-tornado/tests/delivery.py b/python-tornado/tests/delivery.py index cb04332..d0eb9f9 100644 --- a/python-tornado/tests/delivery.py +++ b/python-tornado/tests/delivery.py @@ -14,7 +14,6 @@ import datetime import time import math -sys.path.append('../') from Pubnub import Pubnub ## ----------------------------------------------------------------------- diff --git a/python-tornado/tests/subscribe-test.py b/python-tornado/tests/subscribe-test.py index d8a3ea2..a2bafde 100755 --- a/python-tornado/tests/subscribe-test.py +++ b/python-tornado/tests/subscribe-test.py @@ -10,7 +10,6 @@ ## ----------------------------------- import sys -sys.path.append('../') import datetime from Pubnub import Pubnub from functools import partial diff --git a/python-tornado/tests/unit-tests.py b/python-tornado/tests/unit-tests.py index b4b51f4..0069a5c 100644 --- a/python-tornado/tests/unit-tests.py +++ b/python-tornado/tests/unit-tests.py @@ -1,10 +1,6 @@ import sys -sys.path.append('../../common') -sys.path.append('..') -sys.path.append('../common') -sys.path.append('.') from PubnubUnitTest import Suite from Pubnub import Pubnub diff --git a/python-twisted/examples/here-now-example.py b/python-twisted/examples/here-now-example.py index 14f45c4..0f34f36 100644 --- a/python-twisted/examples/here-now-example.py +++ b/python-twisted/examples/here-now-example.py @@ -10,8 +10,6 @@ ## ----------------------------------- import sys -sys.path.append('..') -sys.path.append('../../common') from Pubnub import Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' diff --git a/python-twisted/examples/history-example.py b/python-twisted/examples/history-example.py index f128cd7..72c7445 100644 --- a/python-twisted/examples/history-example.py +++ b/python-twisted/examples/history-example.py @@ -11,7 +11,6 @@ import sys from twisted.internet import reactor -sys.path.append('../') from Pubnub import Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' diff --git a/python-twisted/examples/publish-example.py b/python-twisted/examples/publish-example.py index 6b5b19a..5d6cc29 100644 --- a/python-twisted/examples/publish-example.py +++ b/python-twisted/examples/publish-example.py @@ -11,8 +11,6 @@ import sys from twisted.internet import reactor -sys.path.append('../') -sys.path.append('../../') from Pubnub import Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' diff --git a/python-twisted/examples/subscribe-example.py b/python-twisted/examples/subscribe-example.py index 168a2d2..b261b0d 100644 --- a/python-twisted/examples/subscribe-example.py +++ b/python-twisted/examples/subscribe-example.py @@ -11,7 +11,6 @@ import sys from twisted.internet import reactor -sys.path.append('../') from Pubnub import Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' diff --git a/python-twisted/examples/uuid-example.py b/python-twisted/examples/uuid-example.py index 581051b..840f48c 100644 --- a/python-twisted/examples/uuid-example.py +++ b/python-twisted/examples/uuid-example.py @@ -11,7 +11,6 @@ import sys from twisted.internet import reactor -sys.path.append('../') from Pubnub import Pubnub ## ----------------------------------------------------------------------- diff --git a/python-twisted/tests/benchmark.py b/python-twisted/tests/benchmark.py index d4d6d80..0e7b809 100644 --- a/python-twisted/tests/benchmark.py +++ b/python-twisted/tests/benchmark.py @@ -12,7 +12,6 @@ import sys import datetime from twisted.internet import reactor -sys.path.append('../') from Pubnub import Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' diff --git a/python-twisted/tests/delivery.py b/python-twisted/tests/delivery.py index 3ba221b..d36e895 100644 --- a/python-twisted/tests/delivery.py +++ b/python-twisted/tests/delivery.py @@ -14,7 +14,6 @@ import datetime import time import math -sys.path.append('../') from Pubnub import Pubnub ## ----------------------------------------------------------------------- diff --git a/python-twisted/tests/subscribe-test.py b/python-twisted/tests/subscribe-test.py index 6ff4a35..aca63ba 100755 --- a/python-twisted/tests/subscribe-test.py +++ b/python-twisted/tests/subscribe-test.py @@ -10,7 +10,6 @@ ## ----------------------------------- import sys -sys.path.append('../') import datetime from Pubnub import Pubnub from functools import partial diff --git a/python-twisted/tests/unit-test-full.py b/python-twisted/tests/unit-test-full.py index f8be1cc..374772f 100644 --- a/python-twisted/tests/unit-test-full.py +++ b/python-twisted/tests/unit-test-full.py @@ -18,9 +18,6 @@ ## ----------------------------------- import sys -sys.path.append('../') -sys.path.append('./') -sys.path.append('../common/') from Pubnub import Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' diff --git a/python-twisted/tests/unit-tests.py b/python-twisted/tests/unit-tests.py index d0e5722..169e1f1 100644 --- a/python-twisted/tests/unit-tests.py +++ b/python-twisted/tests/unit-tests.py @@ -2,10 +2,6 @@ import sys import time -sys.path.append('../../common') -sys.path.append('../common') -sys.path.append('..') -sys.path.append('.') from PubnubUnitTest import Suite from Pubnub import Pubnub diff --git a/python/examples/dev-console.py b/python/examples/dev-console.py index 868ba7c..6ff5209 100755 --- a/python/examples/dev-console.py +++ b/python/examples/dev-console.py @@ -10,8 +10,6 @@ ## ----------------------------------- import sys -sys.path.append('../') -sys.path.append('../../') from Pubnub import Pubnub from optparse import OptionParser diff --git a/python/examples/here-now-example.py b/python/examples/here-now-example.py index 0888410..9bb448c 100644 --- a/python/examples/here-now-example.py +++ b/python/examples/here-now-example.py @@ -10,8 +10,6 @@ ## ----------------------------------- import sys -sys.path.append('../') -sys.path.append('./') from Pubnub import Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' diff --git a/python/examples/history-example.py b/python/examples/history-example.py index b5cc1fd..092c929 100755 --- a/python/examples/history-example.py +++ b/python/examples/history-example.py @@ -1,6 +1,4 @@ import sys -sys.path.append('../') -sys.path.append('./') from Pubnub import Pubnub ## Initiat Class diff --git a/python/examples/publish-example.py b/python/examples/publish-example.py index ebf3c73..69ea053 100755 --- a/python/examples/publish-example.py +++ b/python/examples/publish-example.py @@ -11,8 +11,6 @@ import sys from twisted.internet import reactor -sys.path.append('../') -sys.path.append('../../') from Pubnub import Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' diff --git a/python/examples/subscribe-example.py b/python/examples/subscribe-example.py index 0a18899..0b1c949 100755 --- a/python/examples/subscribe-example.py +++ b/python/examples/subscribe-example.py @@ -1,6 +1,4 @@ import sys -sys.path.append('..') -sys.path.append('.') import threading import time import random diff --git a/python/tests/detailed-history-unit-test.py b/python/tests/detailed-history-unit-test.py index b1500b4..9663de9 100755 --- a/python/tests/detailed-history-unit-test.py +++ b/python/tests/detailed-history-unit-test.py @@ -10,9 +10,6 @@ ## ----------------------------------- import sys -sys.path.append('.') -sys.path.append('..') -sys.path.append('../common') from Pubnub import Pubnub import unittest as unittest diff --git a/python/tests/subscribe-test.py b/python/tests/subscribe-test.py index d8a3ea2..a2bafde 100755 --- a/python/tests/subscribe-test.py +++ b/python/tests/subscribe-test.py @@ -10,7 +10,6 @@ ## ----------------------------------- import sys -sys.path.append('../') import datetime from Pubnub import Pubnub from functools import partial diff --git a/python/tests/unit-test.py b/python/tests/unit-test.py index fd1bb97..a9a462c 100755 --- a/python/tests/unit-test.py +++ b/python/tests/unit-test.py @@ -10,9 +10,6 @@ ## ----------------------------------- import sys -sys.path.append('.') -sys.path.append('..') -sys.path.append('../common') from Pubnub import Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' -- cgit v1.2.3 From c5d2fb446378e78e9e164dbea969edd57314dc4b Mon Sep 17 00:00:00 2001 From: Devendra Date: Thu, 24 Apr 2014 00:59:50 +0530 Subject: removing files --- Makefile | 19 - Makefile.inc | 3 - python-tornado/Makefile | 28 - python-tornado/Pubnub.py | 959 ---------------------------- python-tornado/unassembled/Platform.py | 112 ---- python-twisted/Makefile | 28 - python-twisted/Pubnub.py | 994 ----------------------------- python-twisted/unassembled/Platform.py | 147 ----- python/Makefile | 29 - python/Pubnub.py | 1080 -------------------------------- python/unassembled/Platform.py | 220 ------- 11 files changed, 3619 deletions(-) delete mode 100644 Makefile delete mode 100644 Makefile.inc delete mode 100644 python-tornado/Makefile delete mode 100644 python-tornado/Pubnub.py delete mode 100644 python-tornado/unassembled/Platform.py delete mode 100644 python-twisted/Makefile delete mode 100644 python-twisted/Pubnub.py delete mode 100644 python-twisted/unassembled/Platform.py delete mode 100644 python/Makefile delete mode 100644 python/Pubnub.py delete mode 100644 python/unassembled/Platform.py diff --git a/Makefile b/Makefile deleted file mode 100644 index b82c77b..0000000 --- a/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -SUBDIRS = common python python-twisted python-tornado - -.PHONY: all test -all test: $(SUBDIRS) - -all: TARG=all -test: TARG=test - -$(SUBDIRS): force - @ $(MAKE) -C $@ $(TARG) - -.PHONY: clean -clean: - for dir in $(SUBDIRS); do \ - $(MAKE) clean -C $$dir; \ - done - -.PHONY: force -force :; diff --git a/Makefile.inc b/Makefile.inc deleted file mode 100644 index 68a78c6..0000000 --- a/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ -REPOS_DIR=.. -VERSION=$(shell cat $(REPOS_DIR)/VERSION) -ECHO=/bin/echo diff --git a/python-tornado/Makefile b/python-tornado/Makefile deleted file mode 100644 index bf23137..0000000 --- a/python-tornado/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -include ../Makefile.inc - - -.PHONY: all -all: build - -.PHONY: build -build: - cat ../common/LICENSE_HEADER > ./Pubnub.py - echo "\n" >> ./Pubnub.py - cat ../common/PubnubCrypto.py >> ./Pubnub.py - echo "\n" >> ./Pubnub.py - cat ../common/PubnubBase.py >> ./Pubnub.py - echo "\n" >> ./Pubnub.py - cat ../common/PubnubCoreAsync.py >> ./Pubnub.py - echo "\n" >> ./Pubnub.py - cat ./unassembled/Platform.py >> ./Pubnub.py - find -name "Pubnub*py" | xargs sed -i "s/PubNub\ [0-9]\.[0-9]\.[0-9]/PubNub\ $(VERSION)/g" - - -.PHONY: clean -clean: - rm -f Pubnub.py* - -.PHONY: test -test: - python tests/unit-tests.py - diff --git a/python-tornado/Pubnub.py b/python-tornado/Pubnub.py deleted file mode 100644 index 3d0ba1d..0000000 --- a/python-tornado/Pubnub.py +++ /dev/null @@ -1,959 +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 PubnubCrypto2(): - """ - #** - #* 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)))) - - -class PubnubCrypto3(): - """ - #** - #* 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).encode('utf-8') - - 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.encode("utf-8")).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) - return encodestring( - cipher.encrypt(self.pad(msg.encode('utf-8')))).decode('utf-8') - - 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 (cipher.decrypt( - decodestring(msg.encode('utf-8')))).decode('utf-8') - - -try: - import json -except ImportError: - import simplejson as json - -import time -import hashlib -import uuid -import sys - -try: - from urllib.parse import quote -except ImportError: - from urllib2 import quote - -from base64 import urlsafe_b64encode -from hashlib import sha256 - - -import hmac - - -class PubnubBase(object): - def __init__( - self, - publish_key, - subscribe_key, - secret_key=False, - cipher_key=False, - auth_key=None, - 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.auth_key = auth_key - - if self.ssl: - self.origin = 'https://' + self.origin - else: - self.origin = 'http://' + self.origin - - self.uuid = UUID or str(uuid.uuid4()) - - if type(sys.version_info) is tuple: - self.python_version = 2 - self.pc = PubnubCrypto2() - else: - if sys.version_info.major == 2: - self.python_version = 2 - self.pc = PubnubCrypto2() - else: - self.python_version = 3 - self.pc = PubnubCrypto3() - - if not isinstance(self.uuid, str): - 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 _pam_sign(self, msg): - """Calculate a signature by secret key and message.""" - - return urlsafe_b64encode(hmac.new( - self.secret_key.encode("utf-8"), - msg.encode("utf-8"), - sha256 - ).digest()) - - def _pam_auth(self, query, apicode=0, callback=None): - """Issue an authenticated request.""" - - if 'timestamp' not in query: - query['timestamp'] = int(time.time()) - - ## Global Grant? - if 'auth' in query and not query['auth']: - del query['auth'] - - if 'channel' in query and not query['channel']: - del query['channel'] - - params = "&".join([ - x + "=" + quote( - str(query[x]), safe="" - ) for x in sorted(query) - ]) - sign_input = "{subkey}\n{pubkey}\n{apitype}\n{params}".format( - subkey=self.subscribe_key, - pubkey=self.publish_key, - apitype="audit" if (apicode) else "grant", - params=params - ) - - query['signature'] = self._pam_sign(sign_input) - - return self._request({"urlcomponents": [ - 'v1', 'auth', "audit" if (apicode) else "grant", - 'sub-key', - self.subscribe_key - ], 'urlparams': query}, - self._return_wrapped_callback(callback)) - - def grant(self, channel, authkey=False, read=True, - write=True, ttl=5, callback=None): - """Grant Access on a Channel.""" - - return self._pam_auth({ - "channel": channel, - "auth": authkey, - "r": read and 1 or 0, - "w": write and 1 or 0, - "ttl": ttl - }, callback=callback) - - def revoke(self, channel, authkey=False, ttl=1, callback=None): - """Revoke Access on a Channel.""" - - return self._pam_auth({ - "channel": channel, - "auth": authkey, - "r": 0, - "w": 0, - "ttl": ttl - }, callback=callback) - - def audit(self, channel=False, authkey=False, callback=None): - return self._pam_auth({ - "channel": channel, - "auth": authkey - }, 1, callback=callback) - - 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 _return_wrapped_callback(self, callback=None): - def _new_format_callback(response): - if 'payload' in response: - if (callback is not None): - callback({'message': response['message'], - 'payload': response['payload']}) - else: - if (callback is not None): - callback(response) - if (callback is not None): - return _new_format_callback - else: - return None - - def publish(channel, message, callback=None, error=None): - """ - #** - #* 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) - - """ - - message = self.encrypt(message) - - ## Send Message - return self._request({"urlcomponents": [ - 'publish', - self.publish_key, - self.subscribe_key, - '0', - channel, - '0', - message - ], 'urlparams': {'auth': self.auth_key}}, - callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) - - def presence(self, channel, callback, error=None): - """ - #** - #* 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 - }) - """ - return self.subscribe({ - 'channel': channel + '-pnpres', - 'subscribe_key': self.subscribe_key, - 'callback': self._return_wrapped_callback(callback)}) - - def here_now(self, channel, callback, error=None): - """ - #** - #* 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']) - - """ - - ## Get Presence Here Now - return self._request({"urlcomponents": [ - 'v2', 'presence', - 'sub_key', self.subscribe_key, - 'channel', channel - ], 'urlparams': {'auth': self.auth_key}}, - callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) - - def history(self, channel, count=100, reverse=False, - start=None, end=None, callback=None, error=None): - """ - #** - #* History - #* - #* Load history from a channel. - #* - - ## History Example - history = pubnub.detailedHistory({ - 'channel' : 'hello_world', - 'count' : 5 - }) - print(history) - - """ - - params = dict() - - params['count'] = count - params['reverse'] = reverse - params['start'] = start - params['end'] = end - - ## Get History - return self._request({'urlcomponents': [ - 'v2', - 'history', - 'sub-key', - self.subscribe_key, - 'channel', - channel, - ], 'urlparams': {'auth': self.auth_key}}, - callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) - - def time(self, callback=None): - """ - #** - #* Time - #* - #* Timestamp from PubNub Cloud. - #* - #* @return int timestamp. - #* - - ## PubNub Server Time Example - timestamp = pubnub.time() - print(timestamp) - - """ - - time = self._request({'urlcomponents': [ - 'time', - '0' - ]}, callback) - if time is not 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 ("urlparams" in request): - url = url + '?' + "&".join([x + "=" + str(y) for x, y in request[ - "urlparams"].items() if y is not None]) - return url - - -try: - from hashlib import sha256 - digestmod = sha256 -except ImportError: - import Crypto.Hash.SHA256 as digestmod - sha256 = digestmod.new -import hmac - - -class EmptyLock(): - def __enter__(self): - pass - - def __exit__(self, a, b, c): - pass - -empty_lock = EmptyLock() - - -class PubnubCoreAsync(PubnubBase): - - def start(self): - pass - - def stop(self): - pass - - def __init__( - self, - publish_key, - subscribe_key, - secret_key=False, - cipher_key=False, - auth_key=None, - ssl_on=False, - origin='pubsub.pubnub.com', - uuid=None, - _tt_lock=empty_lock, - _channel_list_lock=empty_lock - ): - """ - #** - #* 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, - auth_key=auth_key, - ssl_on=ssl_on, - origin=origin, - UUID=uuid - ) - - self.subscriptions = {} - self.timetoken = 0 - self.last_timetoken = 0 - self.version = '3.3.4' - self.accept_encoding = 'gzip' - self.SUB_RECEIVER = None - self._connect = None - self._tt_lock = _tt_lock - self._channel_list_lock = _channel_list_lock - self._connect = lambda: None - - def get_channel_list(self, channels): - channel = '' - first = True - with self._channel_list_lock: - for ch in channels: - if not channels[ch]['subscribed']: - continue - if not first: - channel += ',' - else: - first = False - channel += ch - return channel - - def get_channel_array(self): - channels = self.subscriptions - channel = [] - with self._channel_list_lock: - for ch in channels: - if not channels[ch]['subscribed']: - continue - channel.append(ch) - return channel - - def each(l, func): - if func is None: - return - for i in l: - func(i) - - def subscribe(self, channel, callback, error=None, - connect=None, disconnect=None, reconnect=None, sync=False): - """ - #** - #* 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 - }) - - """ - - with self._tt_lock: - self.last_timetoken = self.timetoken if self.timetoken != 0 \ - else self.last_timetoken - self.timetoken = 0 - - if sync is True and self.susbcribe_sync is not None: - self.susbcribe_sync(args) - return - - def _invoke(func, msg=None): - if func is not None: - if msg is not None: - func(msg) - else: - func() - - def _invoke_connect(): - if self._channel_list_lock: - with self._channel_list_lock: - for ch in self.subscriptions: - chobj = self.subscriptions[ch] - if chobj['connected'] is False: - chobj['connected'] = True - _invoke(chobj['connect'], chobj['name']) - - def _invoke_error(channel_list=None, err=None): - if channel_list is None: - for ch in self.subscriptions: - chobj = self.subscriptions[ch] - _invoke(chobj['error'], err) - else: - for ch in channel_list: - chobj = self.subscriptions[ch] - _invoke(chobj['error'], err) - - def _get_channel(): - for ch in self.subscriptions: - chobj = self.subscriptions[ch] - if chobj['subscribed'] is True: - return chobj - - ## New Channel? - if not channel in self.subscriptions or \ - self.subscriptions[channel]['subscribed'] is False: - with self._channel_list_lock: - self.subscriptions[channel] = { - 'name': channel, - 'first': False, - 'connected': False, - 'subscribed': True, - 'callback': callback, - 'connect': connect, - 'disconnect': disconnect, - 'reconnect': reconnect, - 'error': error - } - - ## return if already connected to channel - if channel in self.subscriptions and \ - 'connected' in self.subscriptions[channel] and \ - self.subscriptions[channel]['connected'] is True: - _invoke(error, "Already Connected") - return - - ## SUBSCRIPTION RECURSION - def _connect(): - - self._reset_offline() - - def sub_callback(response): - ## ERROR ? - if not response or \ - ('message' in response and - response['message'] == 'Forbidden'): - _invoke_error(response['payload'][ - 'channels'], response['message']) - _connect() - return - - _invoke_connect() - - with self._tt_lock: - self.timetoken = \ - self.last_timetoken if self.timetoken == 0 and \ - self.last_timetoken != 0 else response[1] - if len(response) > 2: - channel_list = response[2].split(',') - response_list = response[0] - for ch in enumerate(channel_list): - if ch[1] in self.subscriptions: - chobj = self.subscriptions[ch[1]] - _invoke(chobj['callback'], - self.decrypt(response_list[ch[0]])) - else: - response_list = response[0] - chobj = _get_channel() - for r in response_list: - if chobj: - _invoke(chobj['callback'], self.decrypt(r)) - - _connect() - - channel_list = self.get_channel_list(self.subscriptions) - if len(channel_list) <= 0: - return - - ## CONNECT TO PUBNUB SUBSCRIBE SERVERS - #try: - self.SUB_RECEIVER = self._request({"urlcomponents": [ - 'subscribe', - self.subscribe_key, - channel_list, - '0', - str(self.timetoken) - ], "urlparams": {"uuid": self.uuid, "auth": self.auth_key}}, - sub_callback, - sub_callback, - single=True) - ''' - except Exception as e: - print(e) - self.timeout(1, _connect) - return - ''' - - self._connect = _connect - - ## BEGIN SUBSCRIPTION (LISTEN FOR MESSAGES) - _connect() - - def _reset_offline(self): - if self.SUB_RECEIVER is not None: - self.SUB_RECEIVER() - self.SUB_RECEIVER = None - - def CONNECT(self): - self._reset_offline() - self._connect() - - def unsubscribe(self, channel): - - if channel in self.subscriptions is False: - return False - - ## DISCONNECT - with self._channel_list_lock: - if channel in self.subscriptions: - self.subscriptions[channel]['connected'] = 0 - self.subscriptions[channel]['subscribed'] = False - self.subscriptions[channel]['timetoken'] = 0 - self.subscriptions[channel]['first'] = False - self.CONNECT() - - -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, - auth_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, - auth_key=auth_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) - self.id = None - - def _request(self, request, callback=None, error=None, - single=False, read_timeout=5, connect_timeout=5): - - def _invoke(func, data): - if func is not None: - func(data) - - url = self.getUrl(request) - request = tornado.httpclient.HTTPRequest( - url, 'GET', - self.headers, - connect_timeout=connect_timeout, - request_timeout=read_timeout) - if single is True: - id = time.time() - self.id = id - - def responseCallback(response): - if single is True: - if not id == self.id: - return None - - body = response._get_body() - - if body is None: - return - - def handle_exc(*args): - return True - if response.error is not None: - with ExceptionStackContext(handle_exc): - if response.code in [403, 401]: - response.rethrow() - else: - _invoke(error, {"message": response.reason}) - return - - try: - data = json.loads(body) - except TypeError as e: - try: - data = json.loads(body.decode("utf-8")) - except ValueError as ve: - _invoke(error, {'error': 'json decode error'}) - - if 'error' in data and 'status' in data and 'status' != 200: - _invoke(error, data) - else: - _invoke(callback, data) - - self.http.fetch( - request=request, - callback=responseCallback - ) - - def abort(): - pass - - return abort diff --git a/python-tornado/unassembled/Platform.py b/python-tornado/unassembled/Platform.py deleted file mode 100644 index b0e0be9..0000000 --- a/python-tornado/unassembled/Platform.py +++ /dev/null @@ -1,112 +0,0 @@ -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, - auth_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, - auth_key=auth_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) - self.id = None - - def _request(self, request, callback=None, error=None, - single=False, read_timeout=5, connect_timeout=5): - - def _invoke(func, data): - if func is not None: - func(data) - - url = self.getUrl(request) - request = tornado.httpclient.HTTPRequest( - url, 'GET', - self.headers, - connect_timeout=connect_timeout, - request_timeout=read_timeout) - if single is True: - id = time.time() - self.id = id - - def responseCallback(response): - if single is True: - if not id == self.id: - return None - - body = response._get_body() - - if body is None: - return - - def handle_exc(*args): - return True - if response.error is not None: - with ExceptionStackContext(handle_exc): - if response.code in [403, 401]: - response.rethrow() - else: - _invoke(error, {"message": response.reason}) - return - - try: - data = json.loads(body) - except TypeError as e: - try: - data = json.loads(body.decode("utf-8")) - except ValueError as ve: - _invoke(error, {'error': 'json decode error'}) - - if 'error' in data and 'status' in data and 'status' != 200: - _invoke(error, data) - else: - _invoke(callback, data) - - self.http.fetch( - request=request, - callback=responseCallback - ) - - def abort(): - pass - - return abort diff --git a/python-twisted/Makefile b/python-twisted/Makefile deleted file mode 100644 index bf23137..0000000 --- a/python-twisted/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -include ../Makefile.inc - - -.PHONY: all -all: build - -.PHONY: build -build: - cat ../common/LICENSE_HEADER > ./Pubnub.py - echo "\n" >> ./Pubnub.py - cat ../common/PubnubCrypto.py >> ./Pubnub.py - echo "\n" >> ./Pubnub.py - cat ../common/PubnubBase.py >> ./Pubnub.py - echo "\n" >> ./Pubnub.py - cat ../common/PubnubCoreAsync.py >> ./Pubnub.py - echo "\n" >> ./Pubnub.py - cat ./unassembled/Platform.py >> ./Pubnub.py - find -name "Pubnub*py" | xargs sed -i "s/PubNub\ [0-9]\.[0-9]\.[0-9]/PubNub\ $(VERSION)/g" - - -.PHONY: clean -clean: - rm -f Pubnub.py* - -.PHONY: test -test: - python tests/unit-tests.py - diff --git a/python-twisted/Pubnub.py b/python-twisted/Pubnub.py deleted file mode 100644 index efbbfd9..0000000 --- a/python-twisted/Pubnub.py +++ /dev/null @@ -1,994 +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 PubnubCrypto2(): - """ - #** - #* 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)))) - - -class PubnubCrypto3(): - """ - #** - #* 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).encode('utf-8') - - 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.encode("utf-8")).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) - return encodestring( - cipher.encrypt(self.pad(msg.encode('utf-8')))).decode('utf-8') - - 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 (cipher.decrypt( - decodestring(msg.encode('utf-8')))).decode('utf-8') - - -try: - import json -except ImportError: - import simplejson as json - -import time -import hashlib -import uuid -import sys - -try: - from urllib.parse import quote -except ImportError: - from urllib2 import quote - -from base64 import urlsafe_b64encode -from hashlib import sha256 - - -import hmac - - -class PubnubBase(object): - def __init__( - self, - publish_key, - subscribe_key, - secret_key=False, - cipher_key=False, - auth_key=None, - 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.auth_key = auth_key - - if self.ssl: - self.origin = 'https://' + self.origin - else: - self.origin = 'http://' + self.origin - - self.uuid = UUID or str(uuid.uuid4()) - - if type(sys.version_info) is tuple: - self.python_version = 2 - self.pc = PubnubCrypto2() - else: - if sys.version_info.major == 2: - self.python_version = 2 - self.pc = PubnubCrypto2() - else: - self.python_version = 3 - self.pc = PubnubCrypto3() - - if not isinstance(self.uuid, str): - 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 _pam_sign(self, msg): - """Calculate a signature by secret key and message.""" - - return urlsafe_b64encode(hmac.new( - self.secret_key.encode("utf-8"), - msg.encode("utf-8"), - sha256 - ).digest()) - - def _pam_auth(self, query, apicode=0, callback=None): - """Issue an authenticated request.""" - - if 'timestamp' not in query: - query['timestamp'] = int(time.time()) - - ## Global Grant? - if 'auth' in query and not query['auth']: - del query['auth'] - - if 'channel' in query and not query['channel']: - del query['channel'] - - params = "&".join([ - x + "=" + quote( - str(query[x]), safe="" - ) for x in sorted(query) - ]) - sign_input = "{subkey}\n{pubkey}\n{apitype}\n{params}".format( - subkey=self.subscribe_key, - pubkey=self.publish_key, - apitype="audit" if (apicode) else "grant", - params=params - ) - - query['signature'] = self._pam_sign(sign_input) - - return self._request({"urlcomponents": [ - 'v1', 'auth', "audit" if (apicode) else "grant", - 'sub-key', - self.subscribe_key - ], 'urlparams': query}, - self._return_wrapped_callback(callback)) - - def grant(self, channel, authkey=False, read=True, - write=True, ttl=5, callback=None): - """Grant Access on a Channel.""" - - return self._pam_auth({ - "channel": channel, - "auth": authkey, - "r": read and 1 or 0, - "w": write and 1 or 0, - "ttl": ttl - }, callback=callback) - - def revoke(self, channel, authkey=False, ttl=1, callback=None): - """Revoke Access on a Channel.""" - - return self._pam_auth({ - "channel": channel, - "auth": authkey, - "r": 0, - "w": 0, - "ttl": ttl - }, callback=callback) - - def audit(self, channel=False, authkey=False, callback=None): - return self._pam_auth({ - "channel": channel, - "auth": authkey - }, 1, callback=callback) - - 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 _return_wrapped_callback(self, callback=None): - def _new_format_callback(response): - if 'payload' in response: - if (callback is not None): - callback({'message': response['message'], - 'payload': response['payload']}) - else: - if (callback is not None): - callback(response) - if (callback is not None): - return _new_format_callback - else: - return None - - def publish(channel, message, callback=None, error=None): - """ - #** - #* 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) - - """ - - message = self.encrypt(message) - - ## Send Message - return self._request({"urlcomponents": [ - 'publish', - self.publish_key, - self.subscribe_key, - '0', - channel, - '0', - message - ], 'urlparams': {'auth': self.auth_key}}, - callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) - - def presence(self, channel, callback, error=None): - """ - #** - #* 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 - }) - """ - return self.subscribe({ - 'channel': channel + '-pnpres', - 'subscribe_key': self.subscribe_key, - 'callback': self._return_wrapped_callback(callback)}) - - def here_now(self, channel, callback, error=None): - """ - #** - #* 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']) - - """ - - ## Get Presence Here Now - return self._request({"urlcomponents": [ - 'v2', 'presence', - 'sub_key', self.subscribe_key, - 'channel', channel - ], 'urlparams': {'auth': self.auth_key}}, - callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) - - def history(self, channel, count=100, reverse=False, - start=None, end=None, callback=None, error=None): - """ - #** - #* History - #* - #* Load history from a channel. - #* - - ## History Example - history = pubnub.detailedHistory({ - 'channel' : 'hello_world', - 'count' : 5 - }) - print(history) - - """ - - params = dict() - - params['count'] = count - params['reverse'] = reverse - params['start'] = start - params['end'] = end - - ## Get History - return self._request({'urlcomponents': [ - 'v2', - 'history', - 'sub-key', - self.subscribe_key, - 'channel', - channel, - ], 'urlparams': {'auth': self.auth_key}}, - callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) - - def time(self, callback=None): - """ - #** - #* Time - #* - #* Timestamp from PubNub Cloud. - #* - #* @return int timestamp. - #* - - ## PubNub Server Time Example - timestamp = pubnub.time() - print(timestamp) - - """ - - time = self._request({'urlcomponents': [ - 'time', - '0' - ]}, callback) - if time is not 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 ("urlparams" in request): - url = url + '?' + "&".join([x + "=" + str(y) for x, y in request[ - "urlparams"].items() if y is not None]) - return url - - -try: - from hashlib import sha256 - digestmod = sha256 -except ImportError: - import Crypto.Hash.SHA256 as digestmod - sha256 = digestmod.new -import hmac - - -class EmptyLock(): - def __enter__(self): - pass - - def __exit__(self, a, b, c): - pass - -empty_lock = EmptyLock() - - -class PubnubCoreAsync(PubnubBase): - - def start(self): - pass - - def stop(self): - pass - - def __init__( - self, - publish_key, - subscribe_key, - secret_key=False, - cipher_key=False, - auth_key=None, - ssl_on=False, - origin='pubsub.pubnub.com', - uuid=None, - _tt_lock=empty_lock, - _channel_list_lock=empty_lock - ): - """ - #** - #* 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, - auth_key=auth_key, - ssl_on=ssl_on, - origin=origin, - UUID=uuid - ) - - self.subscriptions = {} - self.timetoken = 0 - self.last_timetoken = 0 - self.version = '3.3.4' - self.accept_encoding = 'gzip' - self.SUB_RECEIVER = None - self._connect = None - self._tt_lock = _tt_lock - self._channel_list_lock = _channel_list_lock - self._connect = lambda: None - - def get_channel_list(self, channels): - channel = '' - first = True - with self._channel_list_lock: - for ch in channels: - if not channels[ch]['subscribed']: - continue - if not first: - channel += ',' - else: - first = False - channel += ch - return channel - - def get_channel_array(self): - channels = self.subscriptions - channel = [] - with self._channel_list_lock: - for ch in channels: - if not channels[ch]['subscribed']: - continue - channel.append(ch) - return channel - - def each(l, func): - if func is None: - return - for i in l: - func(i) - - def subscribe(self, channel, callback, error=None, - connect=None, disconnect=None, reconnect=None, sync=False): - """ - #** - #* 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 - }) - - """ - - with self._tt_lock: - self.last_timetoken = self.timetoken if self.timetoken != 0 \ - else self.last_timetoken - self.timetoken = 0 - - if sync is True and self.susbcribe_sync is not None: - self.susbcribe_sync(args) - return - - def _invoke(func, msg=None): - if func is not None: - if msg is not None: - func(msg) - else: - func() - - def _invoke_connect(): - if self._channel_list_lock: - with self._channel_list_lock: - for ch in self.subscriptions: - chobj = self.subscriptions[ch] - if chobj['connected'] is False: - chobj['connected'] = True - _invoke(chobj['connect'], chobj['name']) - - def _invoke_error(channel_list=None, err=None): - if channel_list is None: - for ch in self.subscriptions: - chobj = self.subscriptions[ch] - _invoke(chobj['error'], err) - else: - for ch in channel_list: - chobj = self.subscriptions[ch] - _invoke(chobj['error'], err) - - def _get_channel(): - for ch in self.subscriptions: - chobj = self.subscriptions[ch] - if chobj['subscribed'] is True: - return chobj - - ## New Channel? - if not channel in self.subscriptions or \ - self.subscriptions[channel]['subscribed'] is False: - with self._channel_list_lock: - self.subscriptions[channel] = { - 'name': channel, - 'first': False, - 'connected': False, - 'subscribed': True, - 'callback': callback, - 'connect': connect, - 'disconnect': disconnect, - 'reconnect': reconnect, - 'error': error - } - - ## return if already connected to channel - if channel in self.subscriptions and \ - 'connected' in self.subscriptions[channel] and \ - self.subscriptions[channel]['connected'] is True: - _invoke(error, "Already Connected") - return - - ## SUBSCRIPTION RECURSION - def _connect(): - - self._reset_offline() - - def sub_callback(response): - ## ERROR ? - if not response or \ - ('message' in response and - response['message'] == 'Forbidden'): - _invoke_error(response['payload'][ - 'channels'], response['message']) - _connect() - return - - _invoke_connect() - - with self._tt_lock: - self.timetoken = \ - self.last_timetoken if self.timetoken == 0 and \ - self.last_timetoken != 0 else response[1] - if len(response) > 2: - channel_list = response[2].split(',') - response_list = response[0] - for ch in enumerate(channel_list): - if ch[1] in self.subscriptions: - chobj = self.subscriptions[ch[1]] - _invoke(chobj['callback'], - self.decrypt(response_list[ch[0]])) - else: - response_list = response[0] - chobj = _get_channel() - for r in response_list: - if chobj: - _invoke(chobj['callback'], self.decrypt(r)) - - _connect() - - channel_list = self.get_channel_list(self.subscriptions) - if len(channel_list) <= 0: - return - - ## CONNECT TO PUBNUB SUBSCRIBE SERVERS - #try: - self.SUB_RECEIVER = self._request({"urlcomponents": [ - 'subscribe', - self.subscribe_key, - channel_list, - '0', - str(self.timetoken) - ], "urlparams": {"uuid": self.uuid, "auth": self.auth_key}}, - sub_callback, - sub_callback, - single=True) - ''' - except Exception as e: - print(e) - self.timeout(1, _connect) - return - ''' - - self._connect = _connect - - ## BEGIN SUBSCRIPTION (LISTEN FOR MESSAGES) - _connect() - - def _reset_offline(self): - if self.SUB_RECEIVER is not None: - self.SUB_RECEIVER() - self.SUB_RECEIVER = None - - def CONNECT(self): - self._reset_offline() - self._connect() - - def unsubscribe(self, channel): - - if channel in self.subscriptions is False: - return False - - ## DISCONNECT - with self._channel_list_lock: - if channel in self.subscriptions: - self.subscriptions[channel]['connected'] = 0 - self.subscriptions[channel]['subscribed'] = False - self.subscriptions[channel]['timetoken'] = 0 - self.subscriptions[channel]['first'] = False - self.CONNECT() - - -from twisted.web.client import getPage -from twisted.internet import reactor -from twisted.internet.defer import Deferred -from twisted.internet.protocol import Protocol -from twisted.web.client import Agent, ContentDecoderAgent -from twisted.web.client import RedirectAgent, GzipDecoder -from twisted.web.client import HTTPConnectionPool -from twisted.web.http_headers import Headers -from twisted.internet.ssl import ClientContextFactory -from twisted.internet.task import LoopingCall -import twisted -from hashlib import sha256 -import time -import json - -import traceback - - -from twisted.python.compat import ( - _PY3, unicode, intToBytes, networkString, nativeString) - -pnconn_pool = HTTPConnectionPool(reactor, persistent=True) -pnconn_pool.maxPersistentPerHost = 100000 -pnconn_pool.cachedConnectionTimeout = 15 -pnconn_pool.retryAutomatically = True - -class Pubnub(PubnubCoreAsync): - - def start(self): - reactor.run() - - def stop(self): - reactor.stop() - - def timeout(self, delay, callback): - reactor.callLater(delay, callback) - - def __init__( - self, - publish_key, - subscribe_key, - secret_key=False, - cipher_key=False, - auth_key=None, - 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, - auth_key=auth_key, - ssl_on=ssl_on, - origin=origin, - ) - self.headers = {} - self.headers['User-Agent'] = ['Python-Twisted'] - #self.headers['Accept-Encoding'] = [self.accept_encoding] - self.headers['V'] = [self.version] - - def _request(self, request, callback=None, error=None, single=False): - global pnconn_pool - - def _invoke(func, data): - if func is not None: - func(data) - - ## Build URL - - url = self.getUrl(request) - - agent = ContentDecoderAgent(RedirectAgent(Agent( - reactor, - contextFactory=WebClientContextFactory(), - pool=self.ssl and None or pnconn_pool - )), [('gzip', GzipDecoder)]) - - try: - request = agent.request( - 'GET', url, Headers(self.headers), None) - except TypeError as te: - request = agent.request( - 'GET', url.encode(), Headers(self.headers), None) - - if single is True: - id = time.time() - self.id = id - - def received(response): - if not isinstance(response, twisted.web._newclient.Response): - _invoke(error, {"message" : "Not Found"}) - return - - finished = Deferred() - if response.code in [401,403]: - response.deliverBody(PubNubPamResponse(finished)) - else: - response.deliverBody(PubNubResponse(finished)) - - return finished - - def complete(data): - if single is True: - if id != self.id: - return None - try: - data = json.loads(data) - except ValueError as e: - try: - data = json.loads(data.decode("utf-8")) - except ValueError as e: - _invoke(error, {'error': 'json decode error'}) - - if 'error' in data and 'status' in data and 'status' != 200: - _invoke(error, data) - else: - _invoke(callback, data) - - def abort(): - pass - - request.addCallback(received) - request.addCallback(complete) - - return abort - - -class WebClientContextFactory(ClientContextFactory): - def getContext(self, hostname, port): - return ClientContextFactory.getContext(self) - - -class PubNubPamResponse(Protocol): - def __init__(self, finished): - self.finished = finished - - def dataReceived(self, bytes): - self.finished.callback(bytes) - - -class PubNubResponse(Protocol): - def __init__(self, finished): - self.finished = finished - - def dataReceived(self, bytes): - self.finished.callback(bytes) diff --git a/python-twisted/unassembled/Platform.py b/python-twisted/unassembled/Platform.py deleted file mode 100644 index b220257..0000000 --- a/python-twisted/unassembled/Platform.py +++ /dev/null @@ -1,147 +0,0 @@ -from twisted.web.client import getPage -from twisted.internet import reactor -from twisted.internet.defer import Deferred -from twisted.internet.protocol import Protocol -from twisted.web.client import Agent, ContentDecoderAgent -from twisted.web.client import RedirectAgent, GzipDecoder -from twisted.web.client import HTTPConnectionPool -from twisted.web.http_headers import Headers -from twisted.internet.ssl import ClientContextFactory -from twisted.internet.task import LoopingCall -import twisted -from hashlib import sha256 -import time -import json - -import traceback - - -from twisted.python.compat import ( - _PY3, unicode, intToBytes, networkString, nativeString) - -pnconn_pool = HTTPConnectionPool(reactor, persistent=True) -pnconn_pool.maxPersistentPerHost = 100000 -pnconn_pool.cachedConnectionTimeout = 15 -pnconn_pool.retryAutomatically = True - -class Pubnub(PubnubCoreAsync): - - def start(self): - reactor.run() - - def stop(self): - reactor.stop() - - def timeout(self, delay, callback): - reactor.callLater(delay, callback) - - def __init__( - self, - publish_key, - subscribe_key, - secret_key=False, - cipher_key=False, - auth_key=None, - 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, - auth_key=auth_key, - ssl_on=ssl_on, - origin=origin, - ) - self.headers = {} - self.headers['User-Agent'] = ['Python-Twisted'] - #self.headers['Accept-Encoding'] = [self.accept_encoding] - self.headers['V'] = [self.version] - - def _request(self, request, callback=None, error=None, single=False): - global pnconn_pool - - def _invoke(func, data): - if func is not None: - func(data) - - ## Build URL - - url = self.getUrl(request) - - agent = ContentDecoderAgent(RedirectAgent(Agent( - reactor, - contextFactory=WebClientContextFactory(), - pool=self.ssl and None or pnconn_pool - )), [('gzip', GzipDecoder)]) - - try: - request = agent.request( - 'GET', url, Headers(self.headers), None) - except TypeError as te: - request = agent.request( - 'GET', url.encode(), Headers(self.headers), None) - - if single is True: - id = time.time() - self.id = id - - def received(response): - if not isinstance(response, twisted.web._newclient.Response): - _invoke(error, {"message" : "Not Found"}) - return - - finished = Deferred() - if response.code in [401,403]: - response.deliverBody(PubNubPamResponse(finished)) - else: - response.deliverBody(PubNubResponse(finished)) - - return finished - - def complete(data): - if single is True: - if id != self.id: - return None - try: - data = json.loads(data) - except ValueError as e: - try: - data = json.loads(data.decode("utf-8")) - except ValueError as e: - _invoke(error, {'error': 'json decode error'}) - - if 'error' in data and 'status' in data and 'status' != 200: - _invoke(error, data) - else: - _invoke(callback, data) - - def abort(): - pass - - request.addCallback(received) - request.addCallback(complete) - - return abort - - -class WebClientContextFactory(ClientContextFactory): - def getContext(self, hostname, port): - return ClientContextFactory.getContext(self) - - -class PubNubPamResponse(Protocol): - def __init__(self, finished): - self.finished = finished - - def dataReceived(self, bytes): - self.finished.callback(bytes) - - -class PubNubResponse(Protocol): - def __init__(self, finished): - self.finished = finished - - def dataReceived(self, bytes): - self.finished.callback(bytes) diff --git a/python/Makefile b/python/Makefile deleted file mode 100644 index b693cf8..0000000 --- a/python/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -include ../Makefile.inc - - -.PHONY: all -all: build - -.PHONY: build -build: - cat ../common/LICENSE_HEADER > ./Pubnub.py - echo "\n" >> ./Pubnub.py - cat ../common/PubnubCrypto.py >> ./Pubnub.py - echo "\n" >> ./Pubnub.py - cat ../common/PubnubBase.py >> ./Pubnub.py - echo "\n" >> ./Pubnub.py - cat ../common/PubnubCoreAsync.py >> ./Pubnub.py - echo "\n" >> ./Pubnub.py - cat ./unassembled/Platform.py >> ./Pubnub.py - find -name "Pubnub*py" | xargs sed -i "s/PubNub\ [0-9]\.[0-9]\.[0-9]/PubNub\ $(VERSION)/g" - - -.PHONY: clean -clean: - rm -f Pubnub.py* - -.PHONY: test -test: - python tests/detailed-history-unit-test.py - python tests/unit-test.py - diff --git a/python/Pubnub.py b/python/Pubnub.py deleted file mode 100644 index a52c46e..0000000 --- a/python/Pubnub.py +++ /dev/null @@ -1,1080 +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 PubnubCrypto2(): - """ - #** - #* 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)))) - - -class PubnubCrypto3(): - """ - #** - #* 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).encode('utf-8') - - 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.encode("utf-8")).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) - return encodestring( - cipher.encrypt(self.pad(msg.encode('utf-8')))).decode('utf-8') - - 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 (cipher.decrypt( - decodestring(msg.encode('utf-8')))).decode('utf-8') - - -try: - import json -except ImportError: - import simplejson as json - -import time -import hashlib -import uuid -import sys - -try: - from urllib.parse import quote -except ImportError: - from urllib2 import quote - -from base64 import urlsafe_b64encode -from hashlib import sha256 - - -import hmac - - -class PubnubBase(object): - def __init__( - self, - publish_key, - subscribe_key, - secret_key=False, - cipher_key=False, - auth_key=None, - 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.auth_key = auth_key - - if self.ssl: - self.origin = 'https://' + self.origin - else: - self.origin = 'http://' + self.origin - - self.uuid = UUID or str(uuid.uuid4()) - - if type(sys.version_info) is tuple: - self.python_version = 2 - self.pc = PubnubCrypto2() - else: - if sys.version_info.major == 2: - self.python_version = 2 - self.pc = PubnubCrypto2() - else: - self.python_version = 3 - self.pc = PubnubCrypto3() - - if not isinstance(self.uuid, str): - 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 _pam_sign(self, msg): - """Calculate a signature by secret key and message.""" - - return urlsafe_b64encode(hmac.new( - self.secret_key.encode("utf-8"), - msg.encode("utf-8"), - sha256 - ).digest()) - - def _pam_auth(self, query, apicode=0, callback=None): - """Issue an authenticated request.""" - - if 'timestamp' not in query: - query['timestamp'] = int(time.time()) - - ## Global Grant? - if 'auth' in query and not query['auth']: - del query['auth'] - - if 'channel' in query and not query['channel']: - del query['channel'] - - params = "&".join([ - x + "=" + quote( - str(query[x]), safe="" - ) for x in sorted(query) - ]) - sign_input = "{subkey}\n{pubkey}\n{apitype}\n{params}".format( - subkey=self.subscribe_key, - pubkey=self.publish_key, - apitype="audit" if (apicode) else "grant", - params=params - ) - - query['signature'] = self._pam_sign(sign_input) - - return self._request({"urlcomponents": [ - 'v1', 'auth', "audit" if (apicode) else "grant", - 'sub-key', - self.subscribe_key - ], 'urlparams': query}, - self._return_wrapped_callback(callback)) - - def grant(self, channel, authkey=False, read=True, - write=True, ttl=5, callback=None): - """Grant Access on a Channel.""" - - return self._pam_auth({ - "channel": channel, - "auth": authkey, - "r": read and 1 or 0, - "w": write and 1 or 0, - "ttl": ttl - }, callback=callback) - - def revoke(self, channel, authkey=False, ttl=1, callback=None): - """Revoke Access on a Channel.""" - - return self._pam_auth({ - "channel": channel, - "auth": authkey, - "r": 0, - "w": 0, - "ttl": ttl - }, callback=callback) - - def audit(self, channel=False, authkey=False, callback=None): - return self._pam_auth({ - "channel": channel, - "auth": authkey - }, 1, callback=callback) - - 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 _return_wrapped_callback(self, callback=None): - def _new_format_callback(response): - if 'payload' in response: - if (callback is not None): - callback({'message': response['message'], - 'payload': response['payload']}) - else: - if (callback is not None): - callback(response) - if (callback is not None): - return _new_format_callback - else: - return None - - def publish(channel, message, callback=None, error=None): - """ - #** - #* 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) - - """ - - message = self.encrypt(message) - - ## Send Message - return self._request({"urlcomponents": [ - 'publish', - self.publish_key, - self.subscribe_key, - '0', - channel, - '0', - message - ], 'urlparams': {'auth': self.auth_key}}, - callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) - - def presence(self, channel, callback, error=None): - """ - #** - #* 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 - }) - """ - return self.subscribe({ - 'channel': channel + '-pnpres', - 'subscribe_key': self.subscribe_key, - 'callback': self._return_wrapped_callback(callback)}) - - def here_now(self, channel, callback, error=None): - """ - #** - #* 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']) - - """ - - ## Get Presence Here Now - return self._request({"urlcomponents": [ - 'v2', 'presence', - 'sub_key', self.subscribe_key, - 'channel', channel - ], 'urlparams': {'auth': self.auth_key}}, - callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) - - def history(self, channel, count=100, reverse=False, - start=None, end=None, callback=None, error=None): - """ - #** - #* History - #* - #* Load history from a channel. - #* - - ## History Example - history = pubnub.detailedHistory({ - 'channel' : 'hello_world', - 'count' : 5 - }) - print(history) - - """ - - params = dict() - - params['count'] = count - params['reverse'] = reverse - params['start'] = start - params['end'] = end - - ## Get History - return self._request({'urlcomponents': [ - 'v2', - 'history', - 'sub-key', - self.subscribe_key, - 'channel', - channel, - ], 'urlparams': {'auth': self.auth_key}}, - callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) - - def time(self, callback=None): - """ - #** - #* Time - #* - #* Timestamp from PubNub Cloud. - #* - #* @return int timestamp. - #* - - ## PubNub Server Time Example - timestamp = pubnub.time() - print(timestamp) - - """ - - time = self._request({'urlcomponents': [ - 'time', - '0' - ]}, callback) - if time is not 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 ("urlparams" in request): - url = url + '?' + "&".join([x + "=" + str(y) for x, y in request[ - "urlparams"].items() if y is not None]) - return url - - -try: - from hashlib import sha256 - digestmod = sha256 -except ImportError: - import Crypto.Hash.SHA256 as digestmod - sha256 = digestmod.new -import hmac - - -class EmptyLock(): - def __enter__(self): - pass - - def __exit__(self, a, b, c): - pass - -empty_lock = EmptyLock() - - -class PubnubCoreAsync(PubnubBase): - - def start(self): - pass - - def stop(self): - pass - - def __init__( - self, - publish_key, - subscribe_key, - secret_key=False, - cipher_key=False, - auth_key=None, - ssl_on=False, - origin='pubsub.pubnub.com', - uuid=None, - _tt_lock=empty_lock, - _channel_list_lock=empty_lock - ): - """ - #** - #* 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, - auth_key=auth_key, - ssl_on=ssl_on, - origin=origin, - UUID=uuid - ) - - self.subscriptions = {} - self.timetoken = 0 - self.last_timetoken = 0 - self.version = '3.3.4' - self.accept_encoding = 'gzip' - self.SUB_RECEIVER = None - self._connect = None - self._tt_lock = _tt_lock - self._channel_list_lock = _channel_list_lock - self._connect = lambda: None - - def get_channel_list(self, channels): - channel = '' - first = True - with self._channel_list_lock: - for ch in channels: - if not channels[ch]['subscribed']: - continue - if not first: - channel += ',' - else: - first = False - channel += ch - return channel - - def get_channel_array(self): - channels = self.subscriptions - channel = [] - with self._channel_list_lock: - for ch in channels: - if not channels[ch]['subscribed']: - continue - channel.append(ch) - return channel - - def each(l, func): - if func is None: - return - for i in l: - func(i) - - def subscribe(self, channel, callback, error=None, - connect=None, disconnect=None, reconnect=None, sync=False): - """ - #** - #* 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 - }) - - """ - - with self._tt_lock: - self.last_timetoken = self.timetoken if self.timetoken != 0 \ - else self.last_timetoken - self.timetoken = 0 - - if sync is True and self.susbcribe_sync is not None: - self.susbcribe_sync(args) - return - - def _invoke(func, msg=None): - if func is not None: - if msg is not None: - func(msg) - else: - func() - - def _invoke_connect(): - if self._channel_list_lock: - with self._channel_list_lock: - for ch in self.subscriptions: - chobj = self.subscriptions[ch] - if chobj['connected'] is False: - chobj['connected'] = True - _invoke(chobj['connect'], chobj['name']) - - def _invoke_error(channel_list=None, err=None): - if channel_list is None: - for ch in self.subscriptions: - chobj = self.subscriptions[ch] - _invoke(chobj['error'], err) - else: - for ch in channel_list: - chobj = self.subscriptions[ch] - _invoke(chobj['error'], err) - - def _get_channel(): - for ch in self.subscriptions: - chobj = self.subscriptions[ch] - if chobj['subscribed'] is True: - return chobj - - ## New Channel? - if not channel in self.subscriptions or \ - self.subscriptions[channel]['subscribed'] is False: - with self._channel_list_lock: - self.subscriptions[channel] = { - 'name': channel, - 'first': False, - 'connected': False, - 'subscribed': True, - 'callback': callback, - 'connect': connect, - 'disconnect': disconnect, - 'reconnect': reconnect, - 'error': error - } - - ## return if already connected to channel - if channel in self.subscriptions and \ - 'connected' in self.subscriptions[channel] and \ - self.subscriptions[channel]['connected'] is True: - _invoke(error, "Already Connected") - return - - ## SUBSCRIPTION RECURSION - def _connect(): - - self._reset_offline() - - def error_callback(response): - ## ERROR ? - if not response or \ - ('message' in response and - response['message'] == 'Forbidden'): - _invoke_error(response['payload'][ - 'channels'], response['message']) - _connect() - return - if 'message' in response: - _invoke_error(err=response['message']) - - - def sub_callback(response): - ## ERROR ? - if not response or \ - ('message' in response and - response['message'] == 'Forbidden'): - _invoke_error(response['payload'][ - 'channels'], response['message']) - _connect() - return - - _invoke_connect() - - with self._tt_lock: - self.timetoken = \ - self.last_timetoken if self.timetoken == 0 and \ - self.last_timetoken != 0 else response[1] - if len(response) > 2: - channel_list = response[2].split(',') - response_list = response[0] - for ch in enumerate(channel_list): - if ch[1] in self.subscriptions: - chobj = self.subscriptions[ch[1]] - _invoke(chobj['callback'], - self.decrypt(response_list[ch[0]])) - else: - response_list = response[0] - chobj = _get_channel() - for r in response_list: - if chobj: - _invoke(chobj['callback'], self.decrypt(r)) - - _connect() - - channel_list = self.get_channel_list(self.subscriptions) - if len(channel_list) <= 0: - return - - ## CONNECT TO PUBNUB SUBSCRIBE SERVERS - #try: - self.SUB_RECEIVER = self._request({"urlcomponents": [ - 'subscribe', - self.subscribe_key, - channel_list, - '0', - str(self.timetoken) - ], "urlparams": {"uuid": self.uuid, "auth": self.auth_key}}, - sub_callback, - error_callback, - single=True) - ''' - except Exception as e: - print(e) - self.timeout(1, _connect) - return - ''' - - self._connect = _connect - - ## BEGIN SUBSCRIPTION (LISTEN FOR MESSAGES) - _connect() - - def _reset_offline(self): - if self.SUB_RECEIVER is not None: - self.SUB_RECEIVER() - self.SUB_RECEIVER = None - - def CONNECT(self): - self._reset_offline() - self._connect() - - def unsubscribe(self, channel): - - if channel in self.subscriptions is False: - return False - - ## DISCONNECT - with self._channel_list_lock: - if channel in self.subscriptions: - self.subscriptions[channel]['connected'] = 0 - self.subscriptions[channel]['subscribed'] = False - self.subscriptions[channel]['timetoken'] = 0 - self.subscriptions[channel]['first'] = False - self.CONNECT() - - -try: - import urllib.request -except ImportError: - import urllib2 - -import threading -import json -import time -import threading -from threading import current_thread - -latest_sub_callback_lock = threading.RLock() -latest_sub_callback = {'id': None, 'callback': None} - - -class HTTPClient: - def __init__(self, url, urllib_func=None, - callback=None, error=None, id=None): - self.url = url - self.id = id - self.callback = callback - self.error = error - self.stop = False - self._urllib_func = urllib_func - - def cancel(self): - self.stop = True - self.callback = None - self.error = None - - def run(self): - - def _invoke(func, data): - if func is not None: - func(data) - - if self._urllib_func is None: - return - - ''' - try: - resp = urllib2.urlopen(self.url, timeout=320) - except urllib2.HTTPError as http_error: - resp = http_error - ''' - resp = self._urllib_func(self.url, timeout=320) - data = resp[0] - code = resp[1] - - if self.stop is True: - return - if self.callback is None: - global latest_sub_callback - global latest_sub_callback_lock - with latest_sub_callback_lock: - if latest_sub_callback['id'] != self.id: - return - else: - if latest_sub_callback['callback'] is not None: - latest_sub_callback['id'] = 0 - print data - try: - data = json.loads(data) - except ValueError as e: - _invoke(latest_sub_callback['error'], - {'error': 'json decoding error'}) - return - print code - if code != 200: - print 'ERROR' - _invoke(latest_sub_callback['error'], data) - else: - print 'CALLBACK' - _invoke(latest_sub_callback['callback'], data) - else: - try: - data = json.loads(data) - except ValueError: - _invoke(self.error, {'error': 'json decoding error'}) - return - - if code != 200: - _invoke(self.error, data) - else: - _invoke(self.callback, data) - - -def _urllib_request_2(url, timeout=320): - try: - resp = urllib2.urlopen(url, timeout=timeout) - except urllib2.HTTPError as http_error: - resp = http_error - except urllib2.URLError as error: - #print error.reason - msg = { "message" : str(error.reason)} - #print str(msg) - return (json.dumps(msg),0) - - return (resp.read(), resp.code) - - -def _urllib_request_3(url, timeout=320): - #print(url) - try: - resp = urllib.request.urlopen(url, timeout=timeout) - except (urllib.request.HTTPError, urllib.request.URLError) as http_error: - resp = http_error - r = resp.read().decode("utf-8") - #print(r) - return (r, resp.code) - -_urllib_request = None - - -class Pubnub(PubnubCoreAsync): - def __init__( - self, - publish_key, - subscribe_key, - secret_key=False, - cipher_key=False, - auth_key=None, - ssl_on=False, - origin='pubsub.pubnub.com', - pres_uuid=None - ): - super(Pubnub, self).__init__( - publish_key=publish_key, - subscribe_key=subscribe_key, - secret_key=secret_key, - cipher_key=cipher_key, - auth_key=auth_key, - ssl_on=ssl_on, - origin=origin, - uuid=pres_uuid, - _tt_lock=threading.RLock(), - _channel_list_lock=threading.RLock() - ) - global _urllib_request - if self.python_version == 2: - _urllib_request = _urllib_request_2 - else: - _urllib_request = _urllib_request_3 - - def timeout(self, interval, func): - def cb(): - time.sleep(interval) - func() - thread = threading.Thread(target=cb) - thread.start() - - def _request_async(self, request, callback=None, error=None, single=False): - global _urllib_request - ## Build URL - url = self.getUrl(request) - if single is True: - id = time.time() - client = HTTPClient(url=url, urllib_func=_urllib_request, - callback=None, error=None, id=id) - with latest_sub_callback_lock: - latest_sub_callback['id'] = id - latest_sub_callback['callback'] = callback - latest_sub_callback['error'] = error - else: - client = HTTPClient(url=url, urllib_func=_urllib_request, - callback=callback, error=error) - - thread = threading.Thread(target=client.run) - thread.start() - - def abort(): - client.cancel() - return abort - - def _request_sync(self, request): - global _urllib_request - ## Build URL - url = self.getUrl(request) - ## Send Request Expecting JSONP Response - response = _urllib_request(url, timeout=320) - try: - resp_json = json.loads(response[0]) - except ValueError: - return [0, "JSON Error"] - - if response[1] != 200 and 'status' in resp_json: - return {'message': resp_json['message'], - 'payload': resp_json['payload']} - - return resp_json - - def _request(self, request, callback=None, error=None, single=False): - if callback is None: - return self._request_sync(request) - else: - self._request_async(request, callback, error, single=single) - -''' - - def _request3_sync( self, request) : - ## Build URL - url = self.getUrl(request) - ## Send Request Expecting JSONP Response - try: - response = urllib.request.urlopen(url,timeout=310) - resp_json = json.loads(response.read().decode("utf-8")) - except Exception as e: - return None - - return resp_json - - def _request3_async( self, request, callback, single=False ) : - pass - - def _request3(self, request, callback=None, single=False): - if callback is None: - return self._request3_sync(request,single=single) - else: - self._request3_async(request, callback, single=single) - ''' diff --git a/python/unassembled/Platform.py b/python/unassembled/Platform.py deleted file mode 100644 index 17180fa..0000000 --- a/python/unassembled/Platform.py +++ /dev/null @@ -1,220 +0,0 @@ -try: - import urllib.request -except ImportError: - import urllib2 - -import threading -import json -import time -import threading -from threading import current_thread - -latest_sub_callback_lock = threading.RLock() -latest_sub_callback = {'id': None, 'callback': None} - - -class HTTPClient: - def __init__(self, url, urllib_func=None, - callback=None, error=None, id=None): - self.url = url - self.id = id - self.callback = callback - self.error = error - self.stop = False - self._urllib_func = urllib_func - - def cancel(self): - self.stop = True - self.callback = None - self.error = None - - def run(self): - - def _invoke(func, data): - if func is not None: - func(data) - - if self._urllib_func is None: - return - - ''' - try: - resp = urllib2.urlopen(self.url, timeout=320) - except urllib2.HTTPError as http_error: - resp = http_error - ''' - resp = self._urllib_func(self.url, timeout=320) - data = resp[0] - code = resp[1] - - if self.stop is True: - return - if self.callback is None: - global latest_sub_callback - global latest_sub_callback_lock - with latest_sub_callback_lock: - if latest_sub_callback['id'] != self.id: - return - else: - if latest_sub_callback['callback'] is not None: - latest_sub_callback['id'] = 0 - print data - try: - data = json.loads(data) - except ValueError as e: - _invoke(latest_sub_callback['error'], - {'error': 'json decoding error'}) - return - print code - if code != 200: - print 'ERROR' - _invoke(latest_sub_callback['error'], data) - else: - print 'CALLBACK' - _invoke(latest_sub_callback['callback'], data) - else: - try: - data = json.loads(data) - except ValueError: - _invoke(self.error, {'error': 'json decoding error'}) - return - - if code != 200: - _invoke(self.error, data) - else: - _invoke(self.callback, data) - - -def _urllib_request_2(url, timeout=320): - try: - resp = urllib2.urlopen(url, timeout=timeout) - except urllib2.HTTPError as http_error: - resp = http_error - except urllib2.URLError as error: - #print error.reason - msg = { "message" : str(error.reason)} - #print str(msg) - return (json.dumps(msg),0) - - return (resp.read(), resp.code) - - -def _urllib_request_3(url, timeout=320): - #print(url) - try: - resp = urllib.request.urlopen(url, timeout=timeout) - except (urllib.request.HTTPError, urllib.request.URLError) as http_error: - resp = http_error - r = resp.read().decode("utf-8") - #print(r) - return (r, resp.code) - -_urllib_request = None - - -class Pubnub(PubnubCoreAsync): - def __init__( - self, - publish_key, - subscribe_key, - secret_key=False, - cipher_key=False, - auth_key=None, - ssl_on=False, - origin='pubsub.pubnub.com', - pres_uuid=None - ): - super(Pubnub, self).__init__( - publish_key=publish_key, - subscribe_key=subscribe_key, - secret_key=secret_key, - cipher_key=cipher_key, - auth_key=auth_key, - ssl_on=ssl_on, - origin=origin, - uuid=pres_uuid, - _tt_lock=threading.RLock(), - _channel_list_lock=threading.RLock() - ) - global _urllib_request - if self.python_version == 2: - _urllib_request = _urllib_request_2 - else: - _urllib_request = _urllib_request_3 - - def timeout(self, interval, func): - def cb(): - time.sleep(interval) - func() - thread = threading.Thread(target=cb) - thread.start() - - def _request_async(self, request, callback=None, error=None, single=False): - global _urllib_request - ## Build URL - url = self.getUrl(request) - if single is True: - id = time.time() - client = HTTPClient(url=url, urllib_func=_urllib_request, - callback=None, error=None, id=id) - with latest_sub_callback_lock: - latest_sub_callback['id'] = id - latest_sub_callback['callback'] = callback - latest_sub_callback['error'] = error - else: - client = HTTPClient(url=url, urllib_func=_urllib_request, - callback=callback, error=error) - - thread = threading.Thread(target=client.run) - thread.start() - - def abort(): - client.cancel() - return abort - - def _request_sync(self, request): - global _urllib_request - ## Build URL - url = self.getUrl(request) - ## Send Request Expecting JSONP Response - response = _urllib_request(url, timeout=320) - try: - resp_json = json.loads(response[0]) - except ValueError: - return [0, "JSON Error"] - - if response[1] != 200 and 'status' in resp_json: - return {'message': resp_json['message'], - 'payload': resp_json['payload']} - - return resp_json - - def _request(self, request, callback=None, error=None, single=False): - if callback is None: - return self._request_sync(request) - else: - self._request_async(request, callback, error, single=single) - -''' - - def _request3_sync( self, request) : - ## Build URL - url = self.getUrl(request) - ## Send Request Expecting JSONP Response - try: - response = urllib.request.urlopen(url,timeout=310) - resp_json = json.loads(response.read().decode("utf-8")) - except Exception as e: - return None - - return resp_json - - def _request3_async( self, request, callback, single=False ) : - pass - - def _request3(self, request, callback=None, single=False): - if callback is None: - return self._request3_sync(request,single=single) - else: - self._request3_async(request, callback, single=single) - ''' -- cgit v1.2.3 From c98286f500b77dcf426367df0b688f536b77ea9b Mon Sep 17 00:00:00 2001 From: Devendra Date: Thu, 24 Apr 2014 01:33:45 +0530 Subject: fixing imports --- Pubnub.py | 853 +-------------------------- python-tornado/examples/history-example.py | 30 +- python-tornado/examples/publish-example.py | 6 +- python-tornado/examples/subscribe-example.py | 2 +- python-tornado/examples/uuid-example.py | 2 +- python-tornado/tests/benchmark.py | 2 +- python-tornado/tests/delivery.py | 2 +- python-tornado/tests/subscribe-test.py | 2 +- python-tornado/tests/unit-tests.py | 2 +- python-twisted/examples/here-now-example.py | 2 +- python-twisted/examples/history-example.py | 2 +- python-twisted/examples/publish-example.py | 2 +- python-twisted/examples/subscribe-example.py | 2 +- python-twisted/examples/uuid-example.py | 2 +- python-twisted/tests/benchmark.py | 2 +- python-twisted/tests/delivery.py | 2 +- python-twisted/tests/subscribe-test.py | 2 +- python-twisted/tests/unit-test-full.py | 2 +- python-twisted/tests/unit-tests.py | 2 +- python/examples/dev-console.py | 6 +- python/examples/here-now-example.py | 5 +- python/examples/history-example.py | 2 +- python/examples/publish-example.py | 7 +- python/examples/subscribe-example.py | 2 +- python/tests/detailed-history-unit-test.py | 2 +- python/tests/subscribe-test.py | 2 +- python/tests/unit-test.py | 2 +- 27 files changed, 36 insertions(+), 913 deletions(-) diff --git a/Pubnub.py b/Pubnub.py index bd00709..92a6822 100644 --- a/Pubnub.py +++ b/Pubnub.py @@ -1077,7 +1077,7 @@ class PubnubAsync(PubnubCoreAsync): origin='pubsub.pubnub.com', pres_uuid=None ): - super(Pubnub, self).__init__( + super(PubnubAsync, self).__init__( publish_key=publish_key, subscribe_key=subscribe_key, secret_key=secret_key, @@ -1210,7 +1210,7 @@ class PubnubTornado(PubnubCoreAsync): ssl_on=False, origin='pubsub.pubnub.com' ): - super(Pubnub, self).__init__( + super(PubnubTornado, self).__init__( publish_key=publish_key, subscribe_key=subscribe_key, secret_key=secret_key, @@ -1286,853 +1286,6 @@ class PubnubTornado(PubnubCoreAsync): return abort -## 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 PubnubCrypto2(): - """ - #** - #* 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)))) - - -class PubnubCrypto3(): - """ - #** - #* 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).encode('utf-8') - - 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.encode("utf-8")).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) - return encodestring( - cipher.encrypt(self.pad(msg.encode('utf-8')))).decode('utf-8') - - 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 (cipher.decrypt( - decodestring(msg.encode('utf-8')))).decode('utf-8') - - -try: - import json -except ImportError: - import simplejson as json - -import time -import hashlib -import uuid -import sys - -try: - from urllib.parse import quote -except ImportError: - from urllib2 import quote - -from base64 import urlsafe_b64encode -from hashlib import sha256 - - -import hmac - - -class PubnubBase(object): - def __init__( - self, - publish_key, - subscribe_key, - secret_key=False, - cipher_key=False, - auth_key=None, - 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.auth_key = auth_key - - if self.ssl: - self.origin = 'https://' + self.origin - else: - self.origin = 'http://' + self.origin - - self.uuid = UUID or str(uuid.uuid4()) - - if type(sys.version_info) is tuple: - self.python_version = 2 - self.pc = PubnubCrypto2() - else: - if sys.version_info.major == 2: - self.python_version = 2 - self.pc = PubnubCrypto2() - else: - self.python_version = 3 - self.pc = PubnubCrypto3() - - if not isinstance(self.uuid, str): - 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 _pam_sign(self, msg): - """Calculate a signature by secret key and message.""" - - return urlsafe_b64encode(hmac.new( - self.secret_key.encode("utf-8"), - msg.encode("utf-8"), - sha256 - ).digest()) - - def _pam_auth(self, query, apicode=0, callback=None): - """Issue an authenticated request.""" - - if 'timestamp' not in query: - query['timestamp'] = int(time.time()) - - ## Global Grant? - if 'auth' in query and not query['auth']: - del query['auth'] - - if 'channel' in query and not query['channel']: - del query['channel'] - - params = "&".join([ - x + "=" + quote( - str(query[x]), safe="" - ) for x in sorted(query) - ]) - sign_input = "{subkey}\n{pubkey}\n{apitype}\n{params}".format( - subkey=self.subscribe_key, - pubkey=self.publish_key, - apitype="audit" if (apicode) else "grant", - params=params - ) - - query['signature'] = self._pam_sign(sign_input) - - return self._request({"urlcomponents": [ - 'v1', 'auth', "audit" if (apicode) else "grant", - 'sub-key', - self.subscribe_key - ], 'urlparams': query}, - self._return_wrapped_callback(callback)) - - def grant(self, channel, authkey=False, read=True, - write=True, ttl=5, callback=None): - """Grant Access on a Channel.""" - - return self._pam_auth({ - "channel": channel, - "auth": authkey, - "r": read and 1 or 0, - "w": write and 1 or 0, - "ttl": ttl - }, callback=callback) - - def revoke(self, channel, authkey=False, ttl=1, callback=None): - """Revoke Access on a Channel.""" - - return self._pam_auth({ - "channel": channel, - "auth": authkey, - "r": 0, - "w": 0, - "ttl": ttl - }, callback=callback) - - def audit(self, channel=False, authkey=False, callback=None): - return self._pam_auth({ - "channel": channel, - "auth": authkey - }, 1, callback=callback) - - 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 _return_wrapped_callback(self, callback=None): - def _new_format_callback(response): - if 'payload' in response: - if (callback is not None): - callback({'message': response['message'], - 'payload': response['payload']}) - else: - if (callback is not None): - callback(response) - if (callback is not None): - return _new_format_callback - else: - return None - - def publish(channel, message, callback=None, error=None): - """ - #** - #* 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) - - """ - - message = self.encrypt(message) - - ## Send Message - return self._request({"urlcomponents": [ - 'publish', - self.publish_key, - self.subscribe_key, - '0', - channel, - '0', - message - ], 'urlparams': {'auth': self.auth_key}}, - callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) - - def presence(self, channel, callback, error=None): - """ - #** - #* 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 - }) - """ - return self.subscribe({ - 'channel': channel + '-pnpres', - 'subscribe_key': self.subscribe_key, - 'callback': self._return_wrapped_callback(callback)}) - - def here_now(self, channel, callback, error=None): - """ - #** - #* 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']) - - """ - - ## Get Presence Here Now - return self._request({"urlcomponents": [ - 'v2', 'presence', - 'sub_key', self.subscribe_key, - 'channel', channel - ], 'urlparams': {'auth': self.auth_key}}, - callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) - - def history(self, channel, count=100, reverse=False, - start=None, end=None, callback=None, error=None): - """ - #** - #* History - #* - #* Load history from a channel. - #* - - ## History Example - history = pubnub.detailedHistory({ - 'channel' : 'hello_world', - 'count' : 5 - }) - print(history) - - """ - - params = dict() - - params['count'] = count - params['reverse'] = reverse - params['start'] = start - params['end'] = end - - ## Get History - return self._request({'urlcomponents': [ - 'v2', - 'history', - 'sub-key', - self.subscribe_key, - 'channel', - channel, - ], 'urlparams': {'auth': self.auth_key}}, - callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) - - def time(self, callback=None): - """ - #** - #* Time - #* - #* Timestamp from PubNub Cloud. - #* - #* @return int timestamp. - #* - - ## PubNub Server Time Example - timestamp = pubnub.time() - print(timestamp) - - """ - - time = self._request({'urlcomponents': [ - 'time', - '0' - ]}, callback) - if time is not 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 ("urlparams" in request): - url = url + '?' + "&".join([x + "=" + str(y) for x, y in request[ - "urlparams"].items() if y is not None]) - return url - - -try: - from hashlib import sha256 - digestmod = sha256 -except ImportError: - import Crypto.Hash.SHA256 as digestmod - sha256 = digestmod.new -import hmac - - -class EmptyLock(): - def __enter__(self): - pass - - def __exit__(self, a, b, c): - pass - -empty_lock = EmptyLock() - - -class PubnubCoreAsync(PubnubBase): - - def start(self): - pass - - def stop(self): - pass - - def __init__( - self, - publish_key, - subscribe_key, - secret_key=False, - cipher_key=False, - auth_key=None, - ssl_on=False, - origin='pubsub.pubnub.com', - uuid=None, - _tt_lock=empty_lock, - _channel_list_lock=empty_lock - ): - """ - #** - #* 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, - auth_key=auth_key, - ssl_on=ssl_on, - origin=origin, - UUID=uuid - ) - - self.subscriptions = {} - self.timetoken = 0 - self.last_timetoken = 0 - self.version = '3.3.4' - self.accept_encoding = 'gzip' - self.SUB_RECEIVER = None - self._connect = None - self._tt_lock = _tt_lock - self._channel_list_lock = _channel_list_lock - self._connect = lambda: None - - def get_channel_list(self, channels): - channel = '' - first = True - with self._channel_list_lock: - for ch in channels: - if not channels[ch]['subscribed']: - continue - if not first: - channel += ',' - else: - first = False - channel += ch - return channel - - def get_channel_array(self): - channels = self.subscriptions - channel = [] - with self._channel_list_lock: - for ch in channels: - if not channels[ch]['subscribed']: - continue - channel.append(ch) - return channel - - def each(l, func): - if func is None: - return - for i in l: - func(i) - - def subscribe(self, channel, callback, error=None, - connect=None, disconnect=None, reconnect=None, sync=False): - """ - #** - #* 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 - }) - - """ - - with self._tt_lock: - self.last_timetoken = self.timetoken if self.timetoken != 0 \ - else self.last_timetoken - self.timetoken = 0 - - if sync is True and self.susbcribe_sync is not None: - self.susbcribe_sync(args) - return - - def _invoke(func, msg=None): - if func is not None: - if msg is not None: - func(msg) - else: - func() - - def _invoke_connect(): - if self._channel_list_lock: - with self._channel_list_lock: - for ch in self.subscriptions: - chobj = self.subscriptions[ch] - if chobj['connected'] is False: - chobj['connected'] = True - _invoke(chobj['connect'], chobj['name']) - - def _invoke_error(channel_list=None, err=None): - if channel_list is None: - for ch in self.subscriptions: - chobj = self.subscriptions[ch] - _invoke(chobj['error'], err) - else: - for ch in channel_list: - chobj = self.subscriptions[ch] - _invoke(chobj['error'], err) - - def _get_channel(): - for ch in self.subscriptions: - chobj = self.subscriptions[ch] - if chobj['subscribed'] is True: - return chobj - - ## New Channel? - if not channel in self.subscriptions or \ - self.subscriptions[channel]['subscribed'] is False: - with self._channel_list_lock: - self.subscriptions[channel] = { - 'name': channel, - 'first': False, - 'connected': False, - 'subscribed': True, - 'callback': callback, - 'connect': connect, - 'disconnect': disconnect, - 'reconnect': reconnect, - 'error': error - } - - ## return if already connected to channel - if channel in self.subscriptions and \ - 'connected' in self.subscriptions[channel] and \ - self.subscriptions[channel]['connected'] is True: - _invoke(error, "Already Connected") - return - - ## SUBSCRIPTION RECURSION - def _connect(): - - self._reset_offline() - - def sub_callback(response): - ## ERROR ? - if not response or \ - ('message' in response and - response['message'] == 'Forbidden'): - _invoke_error(response['payload'][ - 'channels'], response['message']) - _connect() - return - - _invoke_connect() - - with self._tt_lock: - self.timetoken = \ - self.last_timetoken if self.timetoken == 0 and \ - self.last_timetoken != 0 else response[1] - if len(response) > 2: - channel_list = response[2].split(',') - response_list = response[0] - for ch in enumerate(channel_list): - if ch[1] in self.subscriptions: - chobj = self.subscriptions[ch[1]] - _invoke(chobj['callback'], - self.decrypt(response_list[ch[0]])) - else: - response_list = response[0] - chobj = _get_channel() - for r in response_list: - if chobj: - _invoke(chobj['callback'], self.decrypt(r)) - - _connect() - - channel_list = self.get_channel_list(self.subscriptions) - if len(channel_list) <= 0: - return - - ## CONNECT TO PUBNUB SUBSCRIBE SERVERS - #try: - self.SUB_RECEIVER = self._request({"urlcomponents": [ - 'subscribe', - self.subscribe_key, - channel_list, - '0', - str(self.timetoken) - ], "urlparams": {"uuid": self.uuid, "auth": self.auth_key}}, - sub_callback, - sub_callback, - single=True) - ''' - except Exception as e: - print(e) - self.timeout(1, _connect) - return - ''' - - self._connect = _connect - - ## BEGIN SUBSCRIPTION (LISTEN FOR MESSAGES) - _connect() - - def _reset_offline(self): - if self.SUB_RECEIVER is not None: - self.SUB_RECEIVER() - self.SUB_RECEIVER = None - - def CONNECT(self): - self._reset_offline() - self._connect() - - def unsubscribe(self, channel): - - if channel in self.subscriptions is False: - return False - - ## DISCONNECT - with self._channel_list_lock: - if channel in self.subscriptions: - self.subscriptions[channel]['connected'] = 0 - self.subscriptions[channel]['subscribed'] = False - self.subscriptions[channel]['timetoken'] = 0 - self.subscriptions[channel]['first'] = False - self.CONNECT() - - try: from twisted.web.client import getPage from twisted.internet import reactor @@ -2186,7 +1339,7 @@ class PubnubTwisted(PubnubCoreAsync): ssl_on=False, origin='pubsub.pubnub.com' ): - super(Pubnub, self).__init__( + super(PubnubTwisted, self).__init__( publish_key=publish_key, subscribe_key=subscribe_key, secret_key=secret_key, diff --git a/python-tornado/examples/history-example.py b/python-tornado/examples/history-example.py index 00bdaf3..879568b 100644 --- a/python-tornado/examples/history-example.py +++ b/python-tornado/examples/history-example.py @@ -10,8 +10,7 @@ ## ----------------------------------- import sys -import tornado -from Pubnub import Pubnub +from Pubnub import PubnubTornado as Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' @@ -19,28 +18,13 @@ secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False -## ----------------------------------------------------------------------- -## Initiate Pubnub State -## ----------------------------------------------------------------------- pubnub = Pubnub(publish_key, subscribe_key, secret_key, cipher_key, ssl_on) -crazy = 'hello_world' - -## ----------------------------------------------------------------------- -## History Example -## ----------------------------------------------------------------------- - +channel = 'hello_world' def history_complete(messages): print(messages) - tornado.ioloop.IOLoop.instance().stop() - -pubnub.history({ - 'channel': crazy, - 'limit': 10, - 'callback': history_complete - }) - -## ----------------------------------------------------------------------- -## IO Event Loop -## ----------------------------------------------------------------------- -tornado.ioloop.IOLoop.instance().start() + pubnub.stop() + +pubnub.history(channel=channel, count=10, callback=history_complete) + +pubnub.start() diff --git a/python-tornado/examples/publish-example.py b/python-tornado/examples/publish-example.py index b02c41f..5da6485 100644 --- a/python-tornado/examples/publish-example.py +++ b/python-tornado/examples/publish-example.py @@ -10,14 +10,12 @@ ## ----------------------------------- import sys -from twisted.internet import reactor -from Pubnub import Pubnub +from Pubnub import PubnubTwisted as Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len( - sys.argv) > 4 and sys.argv[4] or '' # (Cipher key is Optional) +cipher_key = len( sys.argv) > 4 and sys.argv[4] or '' ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- diff --git a/python-tornado/examples/subscribe-example.py b/python-tornado/examples/subscribe-example.py index 0724fa9..26be1fd 100644 --- a/python-tornado/examples/subscribe-example.py +++ b/python-tornado/examples/subscribe-example.py @@ -11,7 +11,7 @@ import sys import tornado -from Pubnub import Pubnub +from Pubnub import PubnubTwisted as Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' diff --git a/python-tornado/examples/uuid-example.py b/python-tornado/examples/uuid-example.py index a1cabf6..e5521ab 100644 --- a/python-tornado/examples/uuid-example.py +++ b/python-tornado/examples/uuid-example.py @@ -11,7 +11,7 @@ import sys import tornado -from Pubnub import Pubnub +from Pubnub import PubnubTwisted as Pubnub ## ----------------------------------------------------------------------- ## Initiate Pubnub State diff --git a/python-tornado/tests/benchmark.py b/python-tornado/tests/benchmark.py index 636a87a..748fe3b 100644 --- a/python-tornado/tests/benchmark.py +++ b/python-tornado/tests/benchmark.py @@ -12,7 +12,7 @@ import sys import datetime import tornado -from Pubnub import Pubnub +from Pubnub import PubnubTwisted as Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' diff --git a/python-tornado/tests/delivery.py b/python-tornado/tests/delivery.py index d0eb9f9..0181403 100644 --- a/python-tornado/tests/delivery.py +++ b/python-tornado/tests/delivery.py @@ -14,7 +14,7 @@ import datetime import time import math -from Pubnub import Pubnub +from Pubnub import PubnubTwisted as Pubnub ## ----------------------------------------------------------------------- ## Configuration diff --git a/python-tornado/tests/subscribe-test.py b/python-tornado/tests/subscribe-test.py index a2bafde..bcbbc7e 100755 --- a/python-tornado/tests/subscribe-test.py +++ b/python-tornado/tests/subscribe-test.py @@ -11,7 +11,7 @@ import sys import datetime -from Pubnub import Pubnub +from Pubnub import PubnubTwisted as Pubnub from functools import partial from threading import current_thread import threading diff --git a/python-tornado/tests/unit-tests.py b/python-tornado/tests/unit-tests.py index 0069a5c..b00f2b7 100644 --- a/python-tornado/tests/unit-tests.py +++ b/python-tornado/tests/unit-tests.py @@ -3,7 +3,7 @@ import sys from PubnubUnitTest import Suite -from Pubnub import Pubnub +from Pubnub import PubnubTwisted as Pubnub pubnub = Pubnub("demo", "demo") diff --git a/python-twisted/examples/here-now-example.py b/python-twisted/examples/here-now-example.py index 0f34f36..4b2965b 100644 --- a/python-twisted/examples/here-now-example.py +++ b/python-twisted/examples/here-now-example.py @@ -10,7 +10,7 @@ ## ----------------------------------- import sys -from Pubnub import Pubnub +from Pubnub import PubnubTwisted as Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' diff --git a/python-twisted/examples/history-example.py b/python-twisted/examples/history-example.py index 72c7445..f867a36 100644 --- a/python-twisted/examples/history-example.py +++ b/python-twisted/examples/history-example.py @@ -11,7 +11,7 @@ import sys from twisted.internet import reactor -from Pubnub import Pubnub +from Pubnub import PubnubTwisted as Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' diff --git a/python-twisted/examples/publish-example.py b/python-twisted/examples/publish-example.py index 5d6cc29..d5af6a5 100644 --- a/python-twisted/examples/publish-example.py +++ b/python-twisted/examples/publish-example.py @@ -11,7 +11,7 @@ import sys from twisted.internet import reactor -from Pubnub import Pubnub +from Pubnub import PubnubTwisted as Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' diff --git a/python-twisted/examples/subscribe-example.py b/python-twisted/examples/subscribe-example.py index b261b0d..3bca615 100644 --- a/python-twisted/examples/subscribe-example.py +++ b/python-twisted/examples/subscribe-example.py @@ -11,7 +11,7 @@ import sys from twisted.internet import reactor -from Pubnub import Pubnub +from Pubnub import PubnubTwisted as Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' diff --git a/python-twisted/examples/uuid-example.py b/python-twisted/examples/uuid-example.py index 840f48c..a745088 100644 --- a/python-twisted/examples/uuid-example.py +++ b/python-twisted/examples/uuid-example.py @@ -11,7 +11,7 @@ import sys from twisted.internet import reactor -from Pubnub import Pubnub +from Pubnub import PubnubTwisted as Pubnub ## ----------------------------------------------------------------------- ## Initiate Pubnub State diff --git a/python-twisted/tests/benchmark.py b/python-twisted/tests/benchmark.py index 0e7b809..b6477c0 100644 --- a/python-twisted/tests/benchmark.py +++ b/python-twisted/tests/benchmark.py @@ -12,7 +12,7 @@ import sys import datetime from twisted.internet import reactor -from Pubnub import Pubnub +from Pubnub import PubnubTwisted as Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' diff --git a/python-twisted/tests/delivery.py b/python-twisted/tests/delivery.py index d36e895..30ce55f 100644 --- a/python-twisted/tests/delivery.py +++ b/python-twisted/tests/delivery.py @@ -14,7 +14,7 @@ import datetime import time import math -from Pubnub import Pubnub +from Pubnub import PubnubTwisted as Pubnub ## ----------------------------------------------------------------------- ## Configuration diff --git a/python-twisted/tests/subscribe-test.py b/python-twisted/tests/subscribe-test.py index aca63ba..ba74992 100755 --- a/python-twisted/tests/subscribe-test.py +++ b/python-twisted/tests/subscribe-test.py @@ -11,7 +11,7 @@ import sys import datetime -from Pubnub import Pubnub +from Pubnub import PubnubTwisted as Pubnub from functools import partial from threading import current_thread import threading diff --git a/python-twisted/tests/unit-test-full.py b/python-twisted/tests/unit-test-full.py index 374772f..3aecf12 100644 --- a/python-twisted/tests/unit-test-full.py +++ b/python-twisted/tests/unit-test-full.py @@ -18,7 +18,7 @@ ## ----------------------------------- import sys -from Pubnub import Pubnub +from Pubnub import PubnubTwisted as Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' diff --git a/python-twisted/tests/unit-tests.py b/python-twisted/tests/unit-tests.py index 169e1f1..70c373b 100644 --- a/python-twisted/tests/unit-tests.py +++ b/python-twisted/tests/unit-tests.py @@ -4,7 +4,7 @@ import time from PubnubUnitTest import Suite -from Pubnub import Pubnub +from Pubnub import PubnubTwisted as Pubnub pubnub = Pubnub("demo", "demo") diff --git a/python/examples/dev-console.py b/python/examples/dev-console.py index 6ff5209..5bdbe8c 100755 --- a/python/examples/dev-console.py +++ b/python/examples/dev-console.py @@ -5,12 +5,8 @@ ## Copyright (c) 2010 Stephen Blum ## http://www.pubnub.com/ -## ----------------------------------- -## PubNub 3.1 Real-time Push Cloud API -## ----------------------------------- - import sys -from Pubnub import Pubnub +from Pubnub import PubnubAsync as Pubnub from optparse import OptionParser diff --git a/python/examples/here-now-example.py b/python/examples/here-now-example.py index 9bb448c..0bc3015 100644 --- a/python/examples/here-now-example.py +++ b/python/examples/here-now-example.py @@ -5,12 +5,9 @@ ## Copyright (c) 2010 Stephen Blum ## http://www.pubnub.com/ -## ----------------------------------- -## PubNub 3.1 Real-time Push Cloud API -## ----------------------------------- import sys -from Pubnub import Pubnub +from Pubnub import PubnubAsync as Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' diff --git a/python/examples/history-example.py b/python/examples/history-example.py index 092c929..793c612 100755 --- a/python/examples/history-example.py +++ b/python/examples/history-example.py @@ -1,5 +1,5 @@ import sys -from Pubnub import Pubnub +from Pubnub import PubnubAsync as Pubnub ## Initiat Class pubnub = Pubnub('demo', 'demo', None, False) diff --git a/python/examples/publish-example.py b/python/examples/publish-example.py index 69ea053..1c57e4b 100755 --- a/python/examples/publish-example.py +++ b/python/examples/publish-example.py @@ -5,13 +5,8 @@ ## Copyright (c) 2010 Stephen Blum ## http://www.pubnub.com/ -## ----------------------------------- -## PubNub 3.1 Real-time Push Cloud API -## ----------------------------------- - import sys -from twisted.internet import reactor -from Pubnub import Pubnub +from Pubnub import PubnubAsync as Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' diff --git a/python/examples/subscribe-example.py b/python/examples/subscribe-example.py index 0b1c949..9c16bbe 100755 --- a/python/examples/subscribe-example.py +++ b/python/examples/subscribe-example.py @@ -3,7 +3,7 @@ import threading import time import random import string -from Pubnub import Pubnub +from Pubnub import PubnubAsync as Pubnub ## Initiate Class pubnub = Pubnub('demo', 'demo', None, False) diff --git a/python/tests/detailed-history-unit-test.py b/python/tests/detailed-history-unit-test.py index 9663de9..fd2c81a 100755 --- a/python/tests/detailed-history-unit-test.py +++ b/python/tests/detailed-history-unit-test.py @@ -10,7 +10,7 @@ ## ----------------------------------- import sys -from Pubnub import Pubnub +from Pubnub import PubnubAsync as Pubnub import unittest as unittest diff --git a/python/tests/subscribe-test.py b/python/tests/subscribe-test.py index a2bafde..a1b1826 100755 --- a/python/tests/subscribe-test.py +++ b/python/tests/subscribe-test.py @@ -11,7 +11,7 @@ import sys import datetime -from Pubnub import Pubnub +from Pubnub import PubnubAsync as Pubnub from functools import partial from threading import current_thread import threading diff --git a/python/tests/unit-test.py b/python/tests/unit-test.py index a9a462c..a48cbd3 100755 --- a/python/tests/unit-test.py +++ b/python/tests/unit-test.py @@ -10,7 +10,7 @@ ## ----------------------------------- import sys -from Pubnub import Pubnub +from Pubnub import PubnubAsync as Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -- cgit v1.2.3 From 98242257846e9276dd83adbea950f83e25a4f2b6 Mon Sep 17 00:00:00 2001 From: Devendra Date: Thu, 24 Apr 2014 02:07:56 +0530 Subject: pep8 compliance, removing redundant files --- Pubnub.py | 295 +++++++---------------- common/LICENSE_HEADER | 10 - common/Makefile | 16 -- common/PubnubBase.py | 372 ----------------------------- common/PubnubCore.py | 102 -------- common/PubnubCoreAsync.py | 308 ------------------------ common/PubnubCrypto.py | 162 ------------- python-tornado/examples/history-example.py | 1 + python-tornado/examples/publish-example.py | 2 +- 9 files changed, 83 insertions(+), 1185 deletions(-) delete mode 100644 common/LICENSE_HEADER delete mode 100644 common/Makefile delete mode 100644 common/PubnubBase.py delete mode 100644 common/PubnubCore.py delete mode 100644 common/PubnubCoreAsync.py delete mode 100644 common/PubnubCrypto.py diff --git a/Pubnub.py b/Pubnub.py index 92a6822..1802774 100644 --- a/Pubnub.py +++ b/Pubnub.py @@ -1,3 +1,17 @@ + +## 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.4 Real-time Push Cloud API +## ----------------------------------- + + + try: import json except ImportError: @@ -7,25 +21,75 @@ import time import hashlib import uuid import sys +from base64 import urlsafe_b64encode +import hmac +from Crypto.Cipher import AES +from Crypto.Hash import MD5 + +try: + from hashlib import sha256 + digestmod = sha256 +except ImportError: + import Crypto.Hash.SHA256 as digestmod + sha256 = digestmod.new + + +##### vanilla python imports ##### try: from urllib.parse import quote except ImportError: from urllib2 import quote +try: + import urllib.request +except ImportError: + import urllib2 -from base64 import urlsafe_b64encode -from hashlib import sha256 +import threading +from threading import current_thread -import hmac +################################## +##### Tornado imports and globals ##### +try: + import tornado.httpclient + import tornado.ioloop + from tornado.stack_context import ExceptionStackContext + ioloop = tornado.ioloop.IOLoop.instance() +except ImportError: + pass -from Crypto.Cipher import AES -from Crypto.Hash import MD5 -from base64 import encodestring, decodestring -import hashlib -import hmac +####################################### + + +##### Twisted imports and globals ##### +try: + from twisted.web.client import getPage + from twisted.internet import reactor + from twisted.internet.defer import Deferred + from twisted.internet.protocol import Protocol + from twisted.web.client import Agent, ContentDecoderAgent + from twisted.web.client import RedirectAgent, GzipDecoder + from twisted.web.client import HTTPConnectionPool + from twisted.web.http_headers import Headers + from twisted.internet.ssl import ClientContextFactory + from twisted.internet.task import LoopingCall + import twisted + + from twisted.python.compat import ( + _PY3, unicode, intToBytes, networkString, nativeString) + + pnconn_pool = HTTPConnectionPool(reactor, persistent=True) + pnconn_pool.maxPersistentPerHost = 100000 + pnconn_pool.cachedConnectionTimeout = 15 + pnconn_pool.retryAutomatically = True +except ImportError: + pass + + +####################################### class PubnubCrypto2(): @@ -246,23 +310,6 @@ class PubnubBase(object): if not isinstance(self.uuid, str): 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 _pam_sign(self, msg): """Calculate a signature by secret key and message.""" @@ -537,15 +584,6 @@ class PubnubBase(object): return url -try: - from hashlib import sha256 - digestmod = sha256 -except ImportError: - import Crypto.Hash.SHA256 as digestmod - sha256 = digestmod.new -import hmac - - class EmptyLock(): def __enter__(self): pass @@ -760,7 +798,6 @@ class PubnubCoreAsync(PubnubBase): return if 'message' in response: _invoke_error(err=response['message']) - def sub_callback(response): ## ERROR ? @@ -951,17 +988,6 @@ class PubnubCore(PubnubCoreAsync): return True -try: - import urllib.request -except ImportError: - import urllib2 - -import threading -import json -import time -import threading -from threading import current_thread - latest_sub_callback_lock = threading.RLock() latest_sub_callback = {'id': None, 'callback': None} @@ -1045,10 +1071,10 @@ def _urllib_request_2(url, timeout=320): resp = http_error except urllib2.URLError as error: #print error.reason - msg = { "message" : str(error.reason)} + msg = {"message": str(error.reason)} #print str(msg) - return (json.dumps(msg),0) - + return (json.dumps(msg), 0) + return (resp.read(), resp.code) @@ -1065,6 +1091,8 @@ def _urllib_request_3(url, timeout=320): _urllib_request = None +# PubnubAsync + class PubnubAsync(PubnubCoreAsync): def __init__( self, @@ -1173,150 +1201,7 @@ class PubnubAsync(PubnubCoreAsync): ''' -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 PubnubTornado(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, - auth_key=False, - ssl_on=False, - origin='pubsub.pubnub.com' - ): - super(PubnubTornado, self).__init__( - publish_key=publish_key, - subscribe_key=subscribe_key, - secret_key=secret_key, - cipher_key=cipher_key, - auth_key=auth_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) - self.id = None - - def _request(self, request, callback=None, error=None, - single=False, read_timeout=5, connect_timeout=5): - - def _invoke(func, data): - if func is not None: - func(data) - - url = self.getUrl(request) - request = tornado.httpclient.HTTPRequest( - url, 'GET', - self.headers, - connect_timeout=connect_timeout, - request_timeout=read_timeout) - if single is True: - id = time.time() - self.id = id - - def responseCallback(response): - if single is True: - if not id == self.id: - return None - - body = response._get_body() - - if body is None: - return - - def handle_exc(*args): - return True - if response.error is not None: - with ExceptionStackContext(handle_exc): - if response.code in [403, 401]: - response.rethrow() - else: - _invoke(error, {"message": response.reason}) - return - - try: - data = json.loads(body) - except TypeError as e: - try: - data = json.loads(body.decode("utf-8")) - except ValueError as ve: - _invoke(error, {'error': 'json decode error'}) - - if 'error' in data and 'status' in data and 'status' != 200: - _invoke(error, data) - else: - _invoke(callback, data) - - self.http.fetch( - request=request, - callback=responseCallback - ) - - def abort(): - pass - - return abort - -try: - from twisted.web.client import getPage - from twisted.internet import reactor - from twisted.internet.defer import Deferred - from twisted.internet.protocol import Protocol - from twisted.web.client import Agent, ContentDecoderAgent - from twisted.web.client import RedirectAgent, GzipDecoder - from twisted.web.client import HTTPConnectionPool - from twisted.web.http_headers import Headers - from twisted.internet.ssl import ClientContextFactory - from twisted.internet.task import LoopingCall - import twisted - - from twisted.python.compat import ( - _PY3, unicode, intToBytes, networkString, nativeString) - - pnconn_pool = HTTPConnectionPool(reactor, persistent=True) - pnconn_pool.maxPersistentPerHost = 100000 - pnconn_pool.cachedConnectionTimeout = 15 - pnconn_pool.retryAutomatically = True -except ImportError: - pass - -from hashlib import sha256 -import time -import json - -import traceback - - - +# Pubnub Twisted class PubnubTwisted(PubnubCoreAsync): @@ -1383,11 +1268,11 @@ class PubnubTwisted(PubnubCoreAsync): def received(response): if not isinstance(response, twisted.web._newclient.Response): - _invoke(error, {"message" : "Not Found"}) + _invoke(error, {"message": "Not Found"}) return finished = Deferred() - if response.code in [401,403]: + if response.code in [401, 403]: response.deliverBody(PubNubPamResponse(finished)) else: response.deliverBody(PubNubResponse(finished)) @@ -1441,24 +1326,7 @@ class PubNubResponse(Protocol): self.finished.callback(bytes) -import tornado.httpclient - -try: - from hashlib import sha256 - digestmod = sha256 -except ImportError: - import Crypto.Hash.SHA256 as digestmod - sha256 = digestmod.new - -try: - import hmac - import tornado.ioloop - from tornado.stack_context import ExceptionStackContext - ioloop = tornado.ioloop.IOLoop.instance() -except ImportError: - pass - - +# PubnubTornado class PubnubTornado(PubnubCoreAsync): def stop(self): @@ -1555,4 +1423,3 @@ class PubnubTornado(PubnubCoreAsync): pass return abort - diff --git a/common/LICENSE_HEADER b/common/LICENSE_HEADER deleted file mode 100644 index a83793d..0000000 --- a/common/LICENSE_HEADER +++ /dev/null @@ -1,10 +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.4 Real-time Push Cloud API -## ----------------------------------- diff --git a/common/Makefile b/common/Makefile deleted file mode 100644 index 1be6f8c..0000000 --- a/common/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -include ../Makefile.inc - - -.PHONY: all -all: build - -.PHONY: build -build: - find -name "Pubnub*py" | xargs sed -i "s/PubNub\ [0-9]\.[0-9]\.[0-9]/PubNub\ $(VERSION)/g" - - -.PHONY: clean -clean: - -.PHONY: test -test: diff --git a/common/PubnubBase.py b/common/PubnubBase.py deleted file mode 100644 index 9a20034..0000000 --- a/common/PubnubBase.py +++ /dev/null @@ -1,372 +0,0 @@ -try: - import json -except ImportError: - import simplejson as json - -import time -import hashlib -import uuid -import sys - -try: - from urllib.parse import quote -except ImportError: - from urllib2 import quote - -from base64 import urlsafe_b64encode -from hashlib import sha256 - - -import hmac - - -class PubnubBase(object): - def __init__( - self, - publish_key, - subscribe_key, - secret_key=False, - cipher_key=False, - auth_key=None, - 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.auth_key = auth_key - - if self.ssl: - self.origin = 'https://' + self.origin - else: - self.origin = 'http://' + self.origin - - self.uuid = UUID or str(uuid.uuid4()) - - if type(sys.version_info) is tuple: - self.python_version = 2 - self.pc = PubnubCrypto2() - else: - if sys.version_info.major == 2: - self.python_version = 2 - self.pc = PubnubCrypto2() - else: - self.python_version = 3 - self.pc = PubnubCrypto3() - - if not isinstance(self.uuid, str): - 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 _pam_sign(self, msg): - """Calculate a signature by secret key and message.""" - - return urlsafe_b64encode(hmac.new( - self.secret_key.encode("utf-8"), - msg.encode("utf-8"), - sha256 - ).digest()) - - def _pam_auth(self, query, apicode=0, callback=None): - """Issue an authenticated request.""" - - if 'timestamp' not in query: - query['timestamp'] = int(time.time()) - - ## Global Grant? - if 'auth' in query and not query['auth']: - del query['auth'] - - if 'channel' in query and not query['channel']: - del query['channel'] - - params = "&".join([ - x + "=" + quote( - str(query[x]), safe="" - ) for x in sorted(query) - ]) - sign_input = "{subkey}\n{pubkey}\n{apitype}\n{params}".format( - subkey=self.subscribe_key, - pubkey=self.publish_key, - apitype="audit" if (apicode) else "grant", - params=params - ) - - query['signature'] = self._pam_sign(sign_input) - - return self._request({"urlcomponents": [ - 'v1', 'auth', "audit" if (apicode) else "grant", - 'sub-key', - self.subscribe_key - ], 'urlparams': query}, - self._return_wrapped_callback(callback)) - - def grant(self, channel, authkey=False, read=True, - write=True, ttl=5, callback=None): - """Grant Access on a Channel.""" - - return self._pam_auth({ - "channel": channel, - "auth": authkey, - "r": read and 1 or 0, - "w": write and 1 or 0, - "ttl": ttl - }, callback=callback) - - def revoke(self, channel, authkey=False, ttl=1, callback=None): - """Revoke Access on a Channel.""" - - return self._pam_auth({ - "channel": channel, - "auth": authkey, - "r": 0, - "w": 0, - "ttl": ttl - }, callback=callback) - - def audit(self, channel=False, authkey=False, callback=None): - return self._pam_auth({ - "channel": channel, - "auth": authkey - }, 1, callback=callback) - - 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 _return_wrapped_callback(self, callback=None): - def _new_format_callback(response): - if 'payload' in response: - if (callback is not None): - callback({'message': response['message'], - 'payload': response['payload']}) - else: - if (callback is not None): - callback(response) - if (callback is not None): - return _new_format_callback - else: - return None - - def publish(channel, message, callback=None, error=None): - """ - #** - #* 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) - - """ - - message = self.encrypt(message) - - ## Send Message - return self._request({"urlcomponents": [ - 'publish', - self.publish_key, - self.subscribe_key, - '0', - channel, - '0', - message - ], 'urlparams': {'auth': self.auth_key}}, - callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) - - def presence(self, channel, callback, error=None): - """ - #** - #* 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 - }) - """ - return self.subscribe({ - 'channel': channel + '-pnpres', - 'subscribe_key': self.subscribe_key, - 'callback': self._return_wrapped_callback(callback)}) - - def here_now(self, channel, callback, error=None): - """ - #** - #* 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']) - - """ - - ## Get Presence Here Now - return self._request({"urlcomponents": [ - 'v2', 'presence', - 'sub_key', self.subscribe_key, - 'channel', channel - ], 'urlparams': {'auth': self.auth_key}}, - callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) - - def history(self, channel, count=100, reverse=False, - start=None, end=None, callback=None, error=None): - """ - #** - #* History - #* - #* Load history from a channel. - #* - - ## History Example - history = pubnub.detailedHistory({ - 'channel' : 'hello_world', - 'count' : 5 - }) - print(history) - - """ - - params = dict() - - params['count'] = count - params['reverse'] = reverse - params['start'] = start - params['end'] = end - - ## Get History - return self._request({'urlcomponents': [ - 'v2', - 'history', - 'sub-key', - self.subscribe_key, - 'channel', - channel, - ], 'urlparams': {'auth': self.auth_key}}, - callback=self._return_wrapped_callback(callback), - error=self._return_wrapped_callback(error)) - - def time(self, callback=None): - """ - #** - #* Time - #* - #* Timestamp from PubNub Cloud. - #* - #* @return int timestamp. - #* - - ## PubNub Server Time Example - timestamp = pubnub.time() - print(timestamp) - - """ - - time = self._request({'urlcomponents': [ - 'time', - '0' - ]}, callback) - if time is not 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 ("urlparams" in request): - url = url + '?' + "&".join([x + "=" + str(y) for x, y in request[ - "urlparams"].items() if y is not None]) - return url diff --git a/common/PubnubCore.py b/common/PubnubCore.py deleted file mode 100644 index 8454797..0000000 --- a/common/PubnubCore.py +++ /dev/null @@ -1,102 +0,0 @@ -class PubnubCore(PubnubCoreAsync): - def __init__( - self, - publish_key, - subscribe_key, - secret_key=False, - cipher_key=False, - auth_key=None, - 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 ) - - """ - super(PubnubCore, self).__init__( - publish_key=publish_key, - subscribe_key=subscribe_key, - secret_key=secret_key, - cipher_key=cipher_key, - auth_key=auth_key, - ssl_on=ssl_on, - origin=origin, - UUID=uuid - ) - - self.subscriptions = {} - self.timetoken = 0 - self.version = '3.4' - self.accept_encoding = 'gzip' - - def subscribe_sync(self, channel, callback, timetoken=0): - """ - #** - #* Subscribe - #* - #* This is BLOCKING. - #* Listen for a message on a channel. - #* - #* @param array args with channel and callback. - #* @return false on fail, array on success. - #** - - ## Subscribe Example - def receive(message) : - print(message) - return True - - pubnub.subscribe({ - 'channel' : 'hello_world', - 'callback' : receive - }) - - """ - - subscribe_key = self.subscribe_key - - ## Begin Subscribe - while True: - - try: - ## Wait for Message - response = self._request({"urlcomponents": [ - 'subscribe', - subscribe_key, - channel, - '0', - str(timetoken) - ], "urlparams": {"uuid": self.uuid}}) - - messages = response[0] - timetoken = response[1] - - ## If it was a timeout - if not len(messages): - continue - - ## Run user Callback and Reconnect if user permits. - for message in messages: - if not callback(self.decrypt(message)): - return - - except Exception: - time.sleep(1) - - return True diff --git a/common/PubnubCoreAsync.py b/common/PubnubCoreAsync.py deleted file mode 100644 index c9a44c3..0000000 --- a/common/PubnubCoreAsync.py +++ /dev/null @@ -1,308 +0,0 @@ -try: - from hashlib import sha256 - digestmod = sha256 -except ImportError: - import Crypto.Hash.SHA256 as digestmod - sha256 = digestmod.new -import hmac - - -class EmptyLock(): - def __enter__(self): - pass - - def __exit__(self, a, b, c): - pass - -empty_lock = EmptyLock() - - -class PubnubCoreAsync(PubnubBase): - - def start(self): - pass - - def stop(self): - pass - - def __init__( - self, - publish_key, - subscribe_key, - secret_key=False, - cipher_key=False, - auth_key=None, - ssl_on=False, - origin='pubsub.pubnub.com', - uuid=None, - _tt_lock=empty_lock, - _channel_list_lock=empty_lock - ): - """ - #** - #* 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, - auth_key=auth_key, - ssl_on=ssl_on, - origin=origin, - UUID=uuid - ) - - self.subscriptions = {} - self.timetoken = 0 - self.last_timetoken = 0 - self.version = '3.3.4' - self.accept_encoding = 'gzip' - self.SUB_RECEIVER = None - self._connect = None - self._tt_lock = _tt_lock - self._channel_list_lock = _channel_list_lock - self._connect = lambda: None - - def get_channel_list(self, channels): - channel = '' - first = True - with self._channel_list_lock: - for ch in channels: - if not channels[ch]['subscribed']: - continue - if not first: - channel += ',' - else: - first = False - channel += ch - return channel - - def get_channel_array(self): - channels = self.subscriptions - channel = [] - with self._channel_list_lock: - for ch in channels: - if not channels[ch]['subscribed']: - continue - channel.append(ch) - return channel - - def each(l, func): - if func is None: - return - for i in l: - func(i) - - def subscribe(self, channel, callback, error=None, - connect=None, disconnect=None, reconnect=None, sync=False): - """ - #** - #* 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 - }) - - """ - - with self._tt_lock: - self.last_timetoken = self.timetoken if self.timetoken != 0 \ - else self.last_timetoken - self.timetoken = 0 - - if sync is True and self.susbcribe_sync is not None: - self.susbcribe_sync(args) - return - - def _invoke(func, msg=None): - if func is not None: - if msg is not None: - func(msg) - else: - func() - - def _invoke_connect(): - if self._channel_list_lock: - with self._channel_list_lock: - for ch in self.subscriptions: - chobj = self.subscriptions[ch] - if chobj['connected'] is False: - chobj['connected'] = True - _invoke(chobj['connect'], chobj['name']) - - def _invoke_error(channel_list=None, err=None): - if channel_list is None: - for ch in self.subscriptions: - chobj = self.subscriptions[ch] - _invoke(chobj['error'], err) - else: - for ch in channel_list: - chobj = self.subscriptions[ch] - _invoke(chobj['error'], err) - - def _get_channel(): - for ch in self.subscriptions: - chobj = self.subscriptions[ch] - if chobj['subscribed'] is True: - return chobj - - ## New Channel? - if not channel in self.subscriptions or \ - self.subscriptions[channel]['subscribed'] is False: - with self._channel_list_lock: - self.subscriptions[channel] = { - 'name': channel, - 'first': False, - 'connected': False, - 'subscribed': True, - 'callback': callback, - 'connect': connect, - 'disconnect': disconnect, - 'reconnect': reconnect, - 'error': error - } - - ## return if already connected to channel - if channel in self.subscriptions and \ - 'connected' in self.subscriptions[channel] and \ - self.subscriptions[channel]['connected'] is True: - _invoke(error, "Already Connected") - return - - ## SUBSCRIPTION RECURSION - def _connect(): - - self._reset_offline() - - def error_callback(response): - ## ERROR ? - if not response or \ - ('message' in response and - response['message'] == 'Forbidden'): - _invoke_error(response['payload'][ - 'channels'], response['message']) - _connect() - return - if 'message' in response: - _invoke_error(err=response['message']) - - - def sub_callback(response): - ## ERROR ? - if not response or \ - ('message' in response and - response['message'] == 'Forbidden'): - _invoke_error(response['payload'][ - 'channels'], response['message']) - _connect() - return - - _invoke_connect() - - with self._tt_lock: - self.timetoken = \ - self.last_timetoken if self.timetoken == 0 and \ - self.last_timetoken != 0 else response[1] - if len(response) > 2: - channel_list = response[2].split(',') - response_list = response[0] - for ch in enumerate(channel_list): - if ch[1] in self.subscriptions: - chobj = self.subscriptions[ch[1]] - _invoke(chobj['callback'], - self.decrypt(response_list[ch[0]])) - else: - response_list = response[0] - chobj = _get_channel() - for r in response_list: - if chobj: - _invoke(chobj['callback'], self.decrypt(r)) - - _connect() - - channel_list = self.get_channel_list(self.subscriptions) - if len(channel_list) <= 0: - return - - ## CONNECT TO PUBNUB SUBSCRIBE SERVERS - #try: - self.SUB_RECEIVER = self._request({"urlcomponents": [ - 'subscribe', - self.subscribe_key, - channel_list, - '0', - str(self.timetoken) - ], "urlparams": {"uuid": self.uuid, "auth": self.auth_key}}, - sub_callback, - error_callback, - single=True) - ''' - except Exception as e: - print(e) - self.timeout(1, _connect) - return - ''' - - self._connect = _connect - - ## BEGIN SUBSCRIPTION (LISTEN FOR MESSAGES) - _connect() - - def _reset_offline(self): - if self.SUB_RECEIVER is not None: - self.SUB_RECEIVER() - self.SUB_RECEIVER = None - - def CONNECT(self): - self._reset_offline() - self._connect() - - def unsubscribe(self, channel): - - if channel in self.subscriptions is False: - return False - - ## DISCONNECT - with self._channel_list_lock: - if channel in self.subscriptions: - self.subscriptions[channel]['connected'] = 0 - self.subscriptions[channel]['subscribed'] = False - self.subscriptions[channel]['timetoken'] = 0 - self.subscriptions[channel]['first'] = False - self.CONNECT() diff --git a/common/PubnubCrypto.py b/common/PubnubCrypto.py deleted file mode 100644 index 295a76e..0000000 --- a/common/PubnubCrypto.py +++ /dev/null @@ -1,162 +0,0 @@ -from Crypto.Cipher import AES -from Crypto.Hash import MD5 -from base64 import encodestring, decodestring -import hashlib -import hmac - - -class PubnubCrypto2(): - """ - #** - #* 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)))) - - -class PubnubCrypto3(): - """ - #** - #* 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).encode('utf-8') - - 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.encode("utf-8")).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) - return encodestring( - cipher.encrypt(self.pad(msg.encode('utf-8')))).decode('utf-8') - - 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 (cipher.decrypt( - decodestring(msg.encode('utf-8')))).decode('utf-8') diff --git a/python-tornado/examples/history-example.py b/python-tornado/examples/history-example.py index 879568b..3a5fd88 100644 --- a/python-tornado/examples/history-example.py +++ b/python-tornado/examples/history-example.py @@ -21,6 +21,7 @@ ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False pubnub = Pubnub(publish_key, subscribe_key, secret_key, cipher_key, ssl_on) channel = 'hello_world' + def history_complete(messages): print(messages) pubnub.stop() diff --git a/python-tornado/examples/publish-example.py b/python-tornado/examples/publish-example.py index 5da6485..456dbf9 100644 --- a/python-tornado/examples/publish-example.py +++ b/python-tornado/examples/publish-example.py @@ -15,7 +15,7 @@ from Pubnub import PubnubTwisted as Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len( sys.argv) > 4 and sys.argv[4] or '' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- -- cgit v1.2.3 From ad6a453a0f00d20f0668b17b61668cb7fa5ee4e4 Mon Sep 17 00:00:00 2001 From: Devendra Date: Fri, 25 Apr 2014 03:26:09 +0530 Subject: v1 of console --- Pubnub.py | 10 +- python/examples/console.py | 326 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 327 insertions(+), 9 deletions(-) create mode 100644 python/examples/console.py diff --git a/Pubnub.py b/Pubnub.py index 1802774..62a401d 100644 --- a/Pubnub.py +++ b/Pubnub.py @@ -411,7 +411,7 @@ class PubnubBase(object): else: return None - def publish(channel, message, callback=None, error=None): + def publish(self, channel, message, callback=None, error=None): """ #** #* Publish @@ -1037,19 +1037,15 @@ class HTTPClient: else: if latest_sub_callback['callback'] is not None: latest_sub_callback['id'] = 0 - print data try: data = json.loads(data) except ValueError as e: _invoke(latest_sub_callback['error'], {'error': 'json decoding error'}) return - print code if code != 200: - print 'ERROR' _invoke(latest_sub_callback['error'], data) else: - print 'CALLBACK' _invoke(latest_sub_callback['callback'], data) else: try: @@ -1070,22 +1066,18 @@ def _urllib_request_2(url, timeout=320): except urllib2.HTTPError as http_error: resp = http_error except urllib2.URLError as error: - #print error.reason msg = {"message": str(error.reason)} - #print str(msg) return (json.dumps(msg), 0) return (resp.read(), resp.code) def _urllib_request_3(url, timeout=320): - #print(url) try: resp = urllib.request.urlopen(url, timeout=timeout) except (urllib.request.HTTPError, urllib.request.URLError) as http_error: resp = http_error r = resp.read().decode("utf-8") - #print(r) return (r, resp.code) _urllib_request = None diff --git a/python/examples/console.py b/python/examples/console.py new file mode 100644 index 0000000..bd364f7 --- /dev/null +++ b/python/examples/console.py @@ -0,0 +1,326 @@ +## 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/ + +import sys +from Pubnub import PubnubAsync as Pubnub +import threading +from datetime import datetime + +from cmd2 import Cmd, make_option, options, Cmd2TestCase +import optparse + + +of=sys.stdout + + +class color(object): + PURPLE = '\033[95m' + CYAN = '\033[96m' + DARKCYAN = '\033[36m' + BLUE = '\033[94m' + GREEN = '\033[92m' + YELLOW = '\033[93m' + RED = '\033[91m' + BOLD = '\033[1m' + UNDERLINE = '\033[4m' + END = '\033[0m' + +def print_ok(msg, channel=None): + chstr = color.PURPLE + "[" + datetime.now().strftime( + '%Y-%m-%d %H:%M:%S') + "] " + color.END + chstr += color.CYAN + "[Channel : " + channel + \ + "] " if channel is not None else "" + color.END + try: + print >>of, ("\n") + print >>of, (chstr + color.GREEN + str(msg) + color.END) + except UnicodeEncodeError as e: + print >>of, (msg) + +def print_error(msg, channel=None): + chstr = color.PURPLE + "[" + datetime.now().strftime( + '%Y-%m-%d %H:%M:%S') + "] " + color.END + chstr += color.CYAN + "[Channel : " + channel + \ + "] " if channel is not None else "" + color.END + try: + print >>of, ("\n") + print >>of, (chstr + color.RED + color.BOLD + str(msg) + color.END) + except UnicodeEncodeError as e: + print >>of, (msg) + +class DefaultPubnub(object): + def handlerFunctionClosure(self,name): + def handlerFunction(*args,**kwargs): + print_error("Pubnub not initialized. Use init command to initialize") + return handlerFunction + def __getattr__(self,name): + return self.handlerFunctionClosure(name) + +pubnub=DefaultPubnub() + + + +def kill_all_threads(): + for thread in threading.enumerate(): + if thread.isAlive(): + thread._Thread__stop() + +def get_input(message, t=None): + while True: + try: + try: + command = raw_input(message) + except NameError: + command = input(message) + except KeyboardInterrupt: + return None + + command = command.strip() + + if command is None or len(command) == 0: + raise ValueError + + if t is not None and t == bool: + valid = ["True", "true", "1", 1, "y", "Y", "yes", "Yes", "YES"] + if command in valid: + return True + else: + return False + if t is not None: + command = t(command) + else: + command = eval("'" + command + "'") + + return command + except ValueError: + print_error("Invalid input : " + command) + +def _publish_command_handler(channel, message): + def _callback(r): + print_ok(r) + + def _error(r): + print_error(r) + pubnub.publish(channel, message, _callback, _error) + + +def _subscribe_command_handler(channel): + + def _callback(r): + print_ok(r, channel) + + def _error(r): + print_error(r, channel) + pubnub.subscribe(channel, _callback, _error) + + +def _unsubscribe_command_handler(channel): + + def _callback(r): + print_ok(r) + + def _error(r): + print_error(r) + pubnub.unsubscribe(channel) + + +def _grant_command_handler(channel, auth_key, read, write, ttl): + def _callback(r): + print_ok(r) + + def _error(r): + print_error(r) + + pubnub.grant(channel, auth_key, read, write, ttl, _callback) + + +def _revoke_command_handler(channel, auth_key, ttl): + def _callback(r): + print_ok(r) + + def _error(r): + print_error(r) + + pubnub.revoke(channel, auth_key, ttl, _callback) + + +def _audit_command_handler(channel, auth_key): + def _callback(r): + print_ok(r) + + def _error(r): + print_error(r) + + pubnub.audit(channel, auth_key, _callback) + + +def _history_command_handler(channel, count): + def _callback(r): + print_ok(r) + + def _error(r): + print_error(r) + + pubnub.history(channel, count, callback=_callback, error=_error) + + +def _here_now_command_handler(channel): + def _callback(r): + print_ok(r) + + def _error(r): + print_error(r) + + pubnub.here_now(channel, callback=_callback, error=_error) + + +class DevConsole(Cmd): + multilineCommands = ['orate'] + Cmd.shortcuts.update({'&': 'speak'}) + maxrepeats = 3 + Cmd.settable.append('maxrepeats') + + def __init__(self): + Cmd.__init__(self) + self.prompt = "(PubNub Console) > " + self.intro = "Welcome to PubNub Developer Console!" ## defaults to None + + def cmdloop(self): + try: + Cmd.cmdloop(self) + except KeyboardInterrupt as e: + self.cmdloop() + + + @options([make_option('-p', '--publish-key', action="store", default="demo", help="Publish Key"), + make_option('-s', '--subscribe-key', action="store", default="demo", help="Subscribe Key"), + make_option('-k', '--secret-key', action="store", default="demo", help="cipher Key"), + make_option('-c', '--cipher-key', action="store", default="", help="Secret Key"), + make_option('-a', '--auth-key', action="store", default=None, help="Auth Key"), + make_option('--ssl-on', dest='ssl', action='store_true', default=False, help="SSL Enabled ?"), + make_option('-o', '--origin', action="store", default="pubsub.pubnub.com", help="Origin"), + make_option('-u', '--uuid', action="store", default=None, help="UUID") + ]) + def do_init(self, command, opts): + global pubnub + pubnub = Pubnub(opts.publish_key, + opts.subscribe_key, + opts.secret_key, + opts.cipher_key, + opts.auth_key, + opts.ssl, + opts.origin, + opts.uuid) + + @options([make_option('-c', '--channel', action="store", help="Channel for here now data") + ]) + def do_here_now(self, command, opts): + + if opts.channel is None: + print_error("Missing channel") + return + + _here_now_command_handler(opts.channel) + + @options([make_option('-c', '--channel', action="store", help="Channel for history data"), + make_option('-n', '--count', action="store", default=5, help="Number of messages") + ]) + def do_history(self, command, opts): + + if opts.channel is None: + print_error("Missing channel") + return + + _history_command_handler(opts.channel, opts.count) + + + @options([make_option('-c', '--channel', action="store", help="Channel on which to publish"), + make_option('-m', '--message', action="store", help="Message to be published") + ]) + def do_publish(self, command, opts): + + if opts.channel is None: + print_error("Missing channel") + return + + if opts.message is None: + print_error("Missing message") + return + + _publish_command_handler(opts.channel,opts.message) + + @options([make_option('-c', '--channel', action="store", help="Channel on which to grant"), + make_option('-a', '--auth-key', dest="auth_key", action="store", + help="Auth Key"), + make_option('-r', '--read-enabled', dest='read', action='store_true', default=False, help="Read ?"), + make_option('-w', '--write-enabled', dest='write', action='store_true', default=False, help="Write ?"), + make_option('-t', '--ttl', action="store", default=5, help="TTL") + ]) + def do_grant(self, command, opts): + if opts.channel is None: + print_error("Missing channel") + return + + opts.auth_key = pubnub.auth_key if opts.auth_key is None else opts.auth_key + + _grant_command_handler(opts.channel,opts.auth_key, opts.read, opts.write, opts.ttl) + + @options([make_option('-c', '--channel', action="store", help="Channel on which to revoke"), + make_option('-a', '--auth-key', dest="auth_key", action="store", + help="Auth Key"), + make_option('-t', '--ttl', action="store", default=5, help="TTL") + ]) + def do_revoke(self, command, opts): + if opts.channel is None: + print_error("Missing channel") + return + + opts.auth_key = pubnub.auth_key if opts.auth_key is None else opts.auth_key + + _revoke_command_handler(opts.channel,opts.auth_key, opts.ttl) + + @options([make_option('-a', '--auth-key', dest="auth_key", action="store", + help="Auth Key") + ]) + def do_audit(self, command, opts): + + opts.auth_key = pubnub.auth_key if opts.auth_key is None else opts.auth_key + + _audit_command_handler(opts.auth_key) + + + @options([make_option('-c', '--channel', action="store", help="Channel for unsubscribe") + ]) + def do_unsubscribe(self, command, opts): + if opts.channel is None: + print_error("Missing channel") + return + _unsubscribe_command_handler(opts.channel) + + + @options([make_option('-c', '--channel', action="store", help="Channel for subscribe") + ]) + def do_subscribe(self, command, opts): + + if opts is None: + print_error("Missing argument") + return + + if opts.channel is None: + print_error("Missing channel") + return + + _subscribe_command_handler(opts.channel) + + + +def main(): + app = DevConsole() + app.cmdloop() + +if __name__ == "__main__": + main() + -- cgit v1.2.3 From 9e4032331721539d2b1e74b87b86ac5c66ccc4af Mon Sep 17 00:00:00 2001 From: Devendra Date: Fri, 25 Apr 2014 10:54:36 +0530 Subject: more changes to new console --- python/examples/console.py | 78 ++++++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 33 deletions(-) diff --git a/python/examples/console.py b/python/examples/console.py index bd364f7..4dfd891 100644 --- a/python/examples/console.py +++ b/python/examples/console.py @@ -16,40 +16,29 @@ import optparse of=sys.stdout - -class color(object): - PURPLE = '\033[95m' - CYAN = '\033[96m' - DARKCYAN = '\033[36m' - BLUE = '\033[94m' - GREEN = '\033[92m' - YELLOW = '\033[93m' - RED = '\033[91m' - BOLD = '\033[1m' - UNDERLINE = '\033[4m' - END = '\033[0m' +color = Cmd() def print_ok(msg, channel=None): - chstr = color.PURPLE + "[" + datetime.now().strftime( - '%Y-%m-%d %H:%M:%S') + "] " + color.END - chstr += color.CYAN + "[Channel : " + channel + \ - "] " if channel is not None else "" + color.END + chstr = color.colorize("[" + datetime.now().strftime( + '%Y-%m-%d %H:%M:%S') + "] ","magenta") + chstr += color.colorize("[Channel : " + channel + \ + "] " if channel is not None else "", "cyan") try: - print >>of, ("\n") - print >>of, (chstr + color.GREEN + str(msg) + color.END) + print >>of, (chstr + color.colorize(str(msg),"green")) except UnicodeEncodeError as e: print >>of, (msg) + of.flush() def print_error(msg, channel=None): - chstr = color.PURPLE + "[" + datetime.now().strftime( - '%Y-%m-%d %H:%M:%S') + "] " + color.END - chstr += color.CYAN + "[Channel : " + channel + \ - "] " if channel is not None else "" + color.END + chstr = color.colorize("[" + datetime.now().strftime( + '%Y-%m-%d %H:%M:%S') + "] ", "magenta") + chstr += color.colorize("[Channel : " + channel + \ + "] " if channel is not None else "", "cyan") try: - print >>of, ("\n") - print >>of, (chstr + color.RED + color.BOLD + str(msg) + color.END) + print >>of, (chstr + color.colorize(color.colorize(str(msg),"red"),"bold")) except UnicodeEncodeError as e: print >>of, (msg) + of.flush() class DefaultPubnub(object): def handlerFunctionClosure(self,name): @@ -177,16 +166,16 @@ def _here_now_command_handler(channel): pubnub.here_now(channel, callback=_callback, error=_error) -class DevConsole(Cmd): - multilineCommands = ['orate'] - Cmd.shortcuts.update({'&': 'speak'}) - maxrepeats = 3 - Cmd.settable.append('maxrepeats') +class DevConsole(Cmd): + def __init__(self): Cmd.__init__(self) + global pubnub self.prompt = "(PubNub Console) > " self.intro = "Welcome to PubNub Developer Console!" ## defaults to None + self.default_channel = None + pubnub = Pubnub("demo", "demo") def cmdloop(self): try: @@ -215,10 +204,30 @@ class DevConsole(Cmd): opts.origin, opts.uuid) + + @options([make_option('-c', '--channel', action="store", help="Default Channel") + ]) + def do_set_default_channel(self, command, opts): + + if opts.channel is None: + print_error("Missing channel") + return + self.default_channel = opts.channel + + @options([make_option('-f', '--file', action="store", default="./pubnub-console.log", help="Output file") + ]) + def do_set_output_file(self, command, opts): + global of + try: + of = file(opts.file,'w+') + except IOError as e: + print_error("Could not set output file. " + e.reason) + + @options([make_option('-c', '--channel', action="store", help="Channel for here now data") ]) def do_here_now(self, command, opts): - + opts.channel = self.default_channel if opts.channel is None else opts.channel if opts.channel is None: print_error("Missing channel") return @@ -229,7 +238,7 @@ class DevConsole(Cmd): make_option('-n', '--count', action="store", default=5, help="Number of messages") ]) def do_history(self, command, opts): - + opts.channel = self.default_channel if opts.channel is None else opts.channel if opts.channel is None: print_error("Missing channel") return @@ -241,7 +250,7 @@ class DevConsole(Cmd): make_option('-m', '--message', action="store", help="Message to be published") ]) def do_publish(self, command, opts): - + opts.channel = self.default_channel if opts.channel is None else opts.channel if opts.channel is None: print_error("Missing channel") return @@ -260,6 +269,7 @@ class DevConsole(Cmd): make_option('-t', '--ttl', action="store", default=5, help="TTL") ]) def do_grant(self, command, opts): + opts.channel = self.default_channel if opts.channel is None else opts.channel if opts.channel is None: print_error("Missing channel") return @@ -274,6 +284,7 @@ class DevConsole(Cmd): make_option('-t', '--ttl', action="store", default=5, help="TTL") ]) def do_revoke(self, command, opts): + opts.channel = self.default_channel if opts.channel is None else opts.channel if opts.channel is None: print_error("Missing channel") return @@ -295,6 +306,7 @@ class DevConsole(Cmd): @options([make_option('-c', '--channel', action="store", help="Channel for unsubscribe") ]) def do_unsubscribe(self, command, opts): + opts.channel = self.default_channel if opts.channel is None else opts.channel if opts.channel is None: print_error("Missing channel") return @@ -304,7 +316,7 @@ class DevConsole(Cmd): @options([make_option('-c', '--channel', action="store", help="Channel for subscribe") ]) def do_subscribe(self, command, opts): - + opts.channel = self.default_channel if opts.channel is None else opts.channel if opts is None: print_error("Missing argument") return -- cgit v1.2.3 From 44aee82f3eadea1241ac4350b4f9f34daf58eb87 Mon Sep 17 00:00:00 2001 From: Devendra Date: Fri, 25 Apr 2014 19:42:21 +0530 Subject: improvements to console --- Pubnub.py | 41 +++++++++++++++++++++-------------------- python/examples/console.py | 16 +++++++++------- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/Pubnub.py b/Pubnub.py index 62a401d..cefe50b 100644 --- a/Pubnub.py +++ b/Pubnub.py @@ -22,6 +22,7 @@ import hashlib import uuid import sys from base64 import urlsafe_b64encode +from base64 import encodestring, decodestring import hmac from Crypto.Cipher import AES from Crypto.Hash import MD5 @@ -85,6 +86,26 @@ try: pnconn_pool.maxPersistentPerHost = 100000 pnconn_pool.cachedConnectionTimeout = 15 pnconn_pool.retryAutomatically = True + + class WebClientContextFactory(ClientContextFactory): + def getContext(self, hostname, port): + return ClientContextFactory.getContext(self) + + + class PubNubPamResponse(Protocol): + def __init__(self, finished): + self.finished = finished + + def dataReceived(self, bytes): + self.finished.callback(bytes) + + + class PubNubResponse(Protocol): + def __init__(self, finished): + self.finished = finished + + def dataReceived(self, bytes): + self.finished.callback(bytes) except ImportError: pass @@ -1297,26 +1318,6 @@ class PubnubTwisted(PubnubCoreAsync): return abort -class WebClientContextFactory(ClientContextFactory): - def getContext(self, hostname, port): - return ClientContextFactory.getContext(self) - - -class PubNubPamResponse(Protocol): - def __init__(self, finished): - self.finished = finished - - def dataReceived(self, bytes): - self.finished.callback(bytes) - - -class PubNubResponse(Protocol): - def __init__(self, finished): - self.finished = finished - - def dataReceived(self, bytes): - self.finished.callback(bytes) - # PubnubTornado class PubnubTornado(PubnubCoreAsync): diff --git a/python/examples/console.py b/python/examples/console.py index 4dfd891..aa6fff3 100644 --- a/python/examples/console.py +++ b/python/examples/console.py @@ -12,7 +12,7 @@ from datetime import datetime from cmd2 import Cmd, make_option, options, Cmd2TestCase import optparse - +import json of=sys.stdout @@ -246,8 +246,7 @@ class DevConsole(Cmd): _history_command_handler(opts.channel, opts.count) - @options([make_option('-c', '--channel', action="store", help="Channel on which to publish"), - make_option('-m', '--message', action="store", help="Message to be published") + @options([make_option('-c', '--channel', action="store", help="Channel on which to publish") ]) def do_publish(self, command, opts): opts.channel = self.default_channel if opts.channel is None else opts.channel @@ -255,11 +254,16 @@ class DevConsole(Cmd): print_error("Missing channel") return - if opts.message is None: + if command is None: print_error("Missing message") return - _publish_command_handler(opts.channel,opts.message) + try: + message = json.loads(str(command)) + except ValueError as ve: + message = str(command) + + _publish_command_handler(opts.channel,message) @options([make_option('-c', '--channel', action="store", help="Channel on which to grant"), make_option('-a', '--auth-key', dest="auth_key", action="store", @@ -327,8 +331,6 @@ class DevConsole(Cmd): _subscribe_command_handler(opts.channel) - - def main(): app = DevConsole() app.cmdloop() -- cgit v1.2.3 From 2b72900bab9af06f37bd024c4aad8da3513a2430 Mon Sep 17 00:00:00 2001 From: Devendra Date: Fri, 25 Apr 2014 20:15:55 +0530 Subject: clean exit on typing exit --- python/examples/console.py | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/python/examples/console.py b/python/examples/console.py index aa6fff3..1694ba5 100644 --- a/python/examples/console.py +++ b/python/examples/console.py @@ -166,6 +166,12 @@ def _here_now_command_handler(channel): pubnub.here_now(channel, callback=_callback, error=_error) +def kill_all_threads(): + for thread in threading.enumerate(): + if thread.isAlive(): + thread._Thread__stop() + + class DevConsole(Cmd): @@ -177,11 +183,13 @@ class DevConsole(Cmd): self.default_channel = None pubnub = Pubnub("demo", "demo") - def cmdloop(self): + def cmdloop_with_keyboard_interrupt(self): try: - Cmd.cmdloop(self) - except KeyboardInterrupt as e: self.cmdloop() + except KeyboardInterrupt: + print 'KB KeyboardInterrupt' + sys.stdout.write('\n') + kill_all_threads() @options([make_option('-p', '--publish-key', action="store", default="demo", help="Publish Key"), @@ -331,9 +339,20 @@ class DevConsole(Cmd): _subscribe_command_handler(opts.channel) + def do_exit(self, args): + kill_all_threads() + return -1 + + def do_EOF(self, args): + kill_all_threads() + return self.do_exit(args) + + def handler(self, signum, frame): + kill_all_threads() + def main(): app = DevConsole() - app.cmdloop() + app.cmdloop_with_keyboard_interrupt() if __name__ == "__main__": main() -- cgit v1.2.3 From 7568c30242ae3a9f4163248a29a596fab5902601 Mon Sep 17 00:00:00 2001 From: Devendra Date: Fri, 25 Apr 2014 23:46:57 +0530 Subject: adding sync async mode to console --- Pubnub.py | 34 ++++++++++++++-------------- python/examples/console.py | 56 +++++++++++++++++++++++++++++----------------- 2 files changed, 53 insertions(+), 37 deletions(-) diff --git a/Pubnub.py b/Pubnub.py index cefe50b..6c082dc 100644 --- a/Pubnub.py +++ b/Pubnub.py @@ -340,7 +340,7 @@ class PubnubBase(object): sha256 ).digest()) - def _pam_auth(self, query, apicode=0, callback=None): + def _pam_auth(self, query, apicode=0, callback=None, error=None): """Issue an authenticated request.""" if 'timestamp' not in query: @@ -364,7 +364,6 @@ class PubnubBase(object): apitype="audit" if (apicode) else "grant", params=params ) - query['signature'] = self._pam_sign(sign_input) return self._request({"urlcomponents": [ @@ -372,10 +371,11 @@ class PubnubBase(object): 'sub-key', self.subscribe_key ], 'urlparams': query}, - self._return_wrapped_callback(callback)) + self._return_wrapped_callback(callback), + self._return_wrapped_callback(error)) def grant(self, channel, authkey=False, read=True, - write=True, ttl=5, callback=None): + write=True, ttl=5, callback=None, error=None): """Grant Access on a Channel.""" return self._pam_auth({ @@ -384,9 +384,9 @@ class PubnubBase(object): "r": read and 1 or 0, "w": write and 1 or 0, "ttl": ttl - }, callback=callback) + }, callback=callback, error=error) - def revoke(self, channel, authkey=False, ttl=1, callback=None): + def revoke(self, channel, authkey=False, ttl=1, callback=None, error=None): """Revoke Access on a Channel.""" return self._pam_auth({ @@ -395,13 +395,13 @@ class PubnubBase(object): "r": 0, "w": 0, "ttl": ttl - }, callback=callback) + }, callback=callback, error=error) - def audit(self, channel=False, authkey=False, callback=None): + def audit(self, channel=False, authkey=False, callback=None, error=None): return self._pam_auth({ "channel": channel, "auth": authkey - }, 1, callback=callback) + }, 1, callback=callback, error=error) def encrypt(self, message): if self.cipher_key: @@ -627,8 +627,8 @@ class PubnubCoreAsync(PubnubBase): self, publish_key, subscribe_key, - secret_key=False, - cipher_key=False, + secret_key=None, + cipher_key=None, auth_key=None, ssl_on=False, origin='pubsub.pubnub.com', @@ -910,8 +910,8 @@ class PubnubCore(PubnubCoreAsync): self, publish_key, subscribe_key, - secret_key=False, - cipher_key=False, + secret_key=None, + cipher_key=None, auth_key=None, ssl_on=False, origin='pubsub.pubnub.com', @@ -1111,8 +1111,8 @@ class PubnubAsync(PubnubCoreAsync): self, publish_key, subscribe_key, - secret_key=False, - cipher_key=False, + secret_key=None, + cipher_key=None, auth_key=None, ssl_on=False, origin='pubsub.pubnub.com', @@ -1231,8 +1231,8 @@ class PubnubTwisted(PubnubCoreAsync): self, publish_key, subscribe_key, - secret_key=False, - cipher_key=False, + secret_key=None, + cipher_key=None, auth_key=None, ssl_on=False, origin='pubsub.pubnub.com' diff --git a/python/examples/console.py b/python/examples/console.py index 1694ba5..dd499c5 100644 --- a/python/examples/console.py +++ b/python/examples/console.py @@ -19,6 +19,8 @@ of=sys.stdout color = Cmd() def print_ok(msg, channel=None): + if msg is None: + return chstr = color.colorize("[" + datetime.now().strftime( '%Y-%m-%d %H:%M:%S') + "] ","magenta") chstr += color.colorize("[Channel : " + channel + \ @@ -30,6 +32,8 @@ def print_ok(msg, channel=None): of.flush() def print_error(msg, channel=None): + if msg is None: + return chstr = color.colorize("[" + datetime.now().strftime( '%Y-%m-%d %H:%M:%S') + "] ", "magenta") chstr += color.colorize("[Channel : " + channel + \ @@ -87,13 +91,13 @@ def get_input(message, t=None): except ValueError: print_error("Invalid input : " + command) -def _publish_command_handler(channel, message): +def _publish_command_handler(channel, message,async=False): def _callback(r): print_ok(r) def _error(r): print_error(r) - pubnub.publish(channel, message, _callback, _error) + print_ok(pubnub.publish(channel, message, _callback if async is True else None, _error if async is True else None)) def _subscribe_command_handler(channel): @@ -116,54 +120,54 @@ def _unsubscribe_command_handler(channel): pubnub.unsubscribe(channel) -def _grant_command_handler(channel, auth_key, read, write, ttl): +def _grant_command_handler(channel, auth_key, read, write, ttl,async=False): def _callback(r): print_ok(r) def _error(r): print_error(r) - pubnub.grant(channel, auth_key, read, write, ttl, _callback) + print_ok(pubnub.grant(channel, auth_key, read, write, ttl, _callback if async is True else None, _error if async is True else None)) -def _revoke_command_handler(channel, auth_key, ttl): +def _revoke_command_handler(channel, auth_key, ttl,async=False): def _callback(r): print_ok(r) def _error(r): print_error(r) - pubnub.revoke(channel, auth_key, ttl, _callback) + print_ok(pubnub.revoke(channel, auth_key, ttl, _callback if async is True else None, _error if async is True else None)) -def _audit_command_handler(channel, auth_key): +def _audit_command_handler(channel, auth_key,async=False): def _callback(r): print_ok(r) def _error(r): print_error(r) - pubnub.audit(channel, auth_key, _callback) + print_ok(pubnub.audit(channel, auth_key, _callback if async is True else None, _error if async is True else None)) -def _history_command_handler(channel, count): +def _history_command_handler(channel, count,async=False): def _callback(r): print_ok(r) def _error(r): print_error(r) - pubnub.history(channel, count, callback=_callback, error=_error) + print_ok(pubnub.history(channel, count, _callback if async is True else None, _error if async is True else None)) -def _here_now_command_handler(channel): +def _here_now_command_handler(channel,async=False): def _callback(r): print_ok(r) def _error(r): print_error(r) - pubnub.here_now(channel, callback=_callback, error=_error) + print_ok(pubnub.here_now(channel, _callback if async is True else None, _error if async is True else None)) def kill_all_threads(): @@ -181,13 +185,13 @@ class DevConsole(Cmd): self.prompt = "(PubNub Console) > " self.intro = "Welcome to PubNub Developer Console!" ## defaults to None self.default_channel = None + self.async = False pubnub = Pubnub("demo", "demo") def cmdloop_with_keyboard_interrupt(self): try: self.cmdloop() except KeyboardInterrupt: - print 'KB KeyboardInterrupt' sys.stdout.write('\n') kill_all_threads() @@ -213,6 +217,13 @@ class DevConsole(Cmd): opts.uuid) + def do_set_sync(self, command): + self.async = False + + def do_set_async(self, command): + self.async = True + + @options([make_option('-c', '--channel', action="store", help="Default Channel") ]) def do_set_default_channel(self, command, opts): @@ -240,7 +251,7 @@ class DevConsole(Cmd): print_error("Missing channel") return - _here_now_command_handler(opts.channel) + _here_now_command_handler(opts.channel,async=self.async) @options([make_option('-c', '--channel', action="store", help="Channel for history data"), make_option('-n', '--count', action="store", default=5, help="Number of messages") @@ -251,7 +262,7 @@ class DevConsole(Cmd): print_error("Missing channel") return - _history_command_handler(opts.channel, opts.count) + _history_command_handler(opts.channel, opts.count,async=self.async) @options([make_option('-c', '--channel', action="store", help="Channel on which to publish") @@ -271,7 +282,7 @@ class DevConsole(Cmd): except ValueError as ve: message = str(command) - _publish_command_handler(opts.channel,message) + _publish_command_handler(opts.channel,message,async=self.async) @options([make_option('-c', '--channel', action="store", help="Channel on which to grant"), make_option('-a', '--auth-key', dest="auth_key", action="store", @@ -288,7 +299,7 @@ class DevConsole(Cmd): opts.auth_key = pubnub.auth_key if opts.auth_key is None else opts.auth_key - _grant_command_handler(opts.channel,opts.auth_key, opts.read, opts.write, opts.ttl) + _grant_command_handler(opts.channel,opts.auth_key, opts.read, opts.write, opts.ttl,async=self.async) @options([make_option('-c', '--channel', action="store", help="Channel on which to revoke"), make_option('-a', '--auth-key', dest="auth_key", action="store", @@ -303,16 +314,21 @@ class DevConsole(Cmd): opts.auth_key = pubnub.auth_key if opts.auth_key is None else opts.auth_key - _revoke_command_handler(opts.channel,opts.auth_key, opts.ttl) + _revoke_command_handler(opts.channel,opts.auth_key, opts.ttl,async=self.async) - @options([make_option('-a', '--auth-key', dest="auth_key", action="store", + @options([make_option('-c', '--channel', action="store", help="Channel on which to revoke"), + make_option('-a', '--auth-key', dest="auth_key", action="store", help="Auth Key") ]) def do_audit(self, command, opts): + opts.channel = self.default_channel if opts.channel is None else opts.channel + if opts.channel is None: + print_error("Missing channel") + return opts.auth_key = pubnub.auth_key if opts.auth_key is None else opts.auth_key - _audit_command_handler(opts.auth_key) + _audit_command_handler(opts.channel, opts.auth_key,async=self.async) @options([make_option('-c', '--channel', action="store", help="Channel for unsubscribe") -- cgit v1.2.3 From 03eedf317ae660893f61bb919b48289b0bf971f3 Mon Sep 17 00:00:00 2001 From: Devendra Date: Fri, 25 Apr 2014 23:56:15 +0530 Subject: changing history to get_history --- python/examples/console.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/examples/console.py b/python/examples/console.py index dd499c5..225c7eb 100644 --- a/python/examples/console.py +++ b/python/examples/console.py @@ -256,7 +256,7 @@ class DevConsole(Cmd): @options([make_option('-c', '--channel', action="store", help="Channel for history data"), make_option('-n', '--count', action="store", default=5, help="Number of messages") ]) - def do_history(self, command, opts): + def do_get_history(self, command, opts): opts.channel = self.default_channel if opts.channel is None else opts.channel if opts.channel is None: print_error("Missing channel") -- cgit v1.2.3 From 769c3a908890a15c8f5e08cd651e1120194c2e74 Mon Sep 17 00:00:00 2001 From: Devendra Date: Sat, 26 Apr 2014 00:23:30 +0530 Subject: save history to file --- python/examples/console.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/python/examples/console.py b/python/examples/console.py index 225c7eb..8a3ab3b 100644 --- a/python/examples/console.py +++ b/python/examples/console.py @@ -14,6 +14,22 @@ from cmd2 import Cmd, make_option, options, Cmd2TestCase import optparse import json +import atexit +import os +import readline +import rlcompleter + +historyPath = os.path.expanduser("~/.pubnub_console_history") + +def save_history(historyPath=historyPath): + import readline + readline.write_history_file(historyPath) + +if os.path.exists(historyPath): + readline.read_history_file(historyPath) + +atexit.register(save_history) + of=sys.stdout color = Cmd() -- cgit v1.2.3 From d703c34d918a75a4d5a984143c8fbd5049931b1a Mon Sep 17 00:00:00 2001 From: Devendra Date: Tue, 29 Apr 2014 03:11:45 +0530 Subject: adding start console script and helper files --- python/examples/config | 9 +++++++++ python/examples/console-help.txt | 34 ++++++++++++++++++++++++++++++++++ python/examples/console.py | 4 ++++ python/examples/start-console.sh | 8 ++++++++ 4 files changed, 55 insertions(+) create mode 100644 python/examples/config create mode 100644 python/examples/console-help.txt create mode 100644 python/examples/start-console.sh diff --git a/python/examples/config b/python/examples/config new file mode 100644 index 0000000..1c73645 --- /dev/null +++ b/python/examples/config @@ -0,0 +1,9 @@ +sessionname pubnub-console +screen -t output tail -f ./pubnub-console.log +split +focus down +screen -t console python console.py "set_output_file" +split -v +focus down +screen -t help vi ./console-help.txt +focus up diff --git a/python/examples/console-help.txt b/python/examples/console-help.txt new file mode 100644 index 0000000..55debd2 --- /dev/null +++ b/python/examples/console-help.txt @@ -0,0 +1,34 @@ +********************** HELP ****************************** + +TO EXIT . Ctrl-A \ followed by y +TO MOVE BETWEEN PANES . Ctrl-A TAB + +********************************************************** + +PUBLISH + +Usage: publish [options] arg + +Options: + -h, --help show this help message and exit + -c CHANNEL, --channel=CHANNEL + Channel on which to publish + +Examples: + (1) publish -c hello_world hi how r u + (2) pub -c hello_world [1,2] + + + +SUBSCRIBE + +Usage: subscribe [options] arg + +Options: + -h, --help show this help message and exit + -c CHANNEL, --channel=CHANNEL + Channel for subscribe + +Examples: + (1) subscribe -c hello_world + (2) sub -c hello_world \ No newline at end of file diff --git a/python/examples/console.py b/python/examples/console.py index 8a3ab3b..e96b4e5 100644 --- a/python/examples/console.py +++ b/python/examples/console.py @@ -5,6 +5,7 @@ ## Copyright (c) 2010 Stephen Blum ## http://www.pubnub.com/ + import sys from Pubnub import PubnubAsync as Pubnub import threading @@ -19,6 +20,9 @@ import os import readline import rlcompleter +if sys.argv[0] == "screen": + print "screen" + historyPath = os.path.expanduser("~/.pubnub_console_history") def save_history(historyPath=historyPath): diff --git a/python/examples/start-console.sh b/python/examples/start-console.sh new file mode 100644 index 0000000..df4fd6e --- /dev/null +++ b/python/examples/start-console.sh @@ -0,0 +1,8 @@ +if ! type "screen" > /dev/null; then + echo "[ERROR] Screen is not installed. Please install screen to use this utility ." + exit +fi +rm ./pubnub-console.log +touch ./pubnub-console.log +set PYTHONPATH=../.. +screen -c config -- cgit v1.2.3 From 8395a9a3922e345608aa1e49b4aa27b9d5927a0d Mon Sep 17 00:00:00 2001 From: Devendra Date: Wed, 30 Apr 2014 00:43:56 +0530 Subject: making tweaks to run on osx --- python/examples/config | 2 +- python/examples/config_osx | 8 ++++++++ python/examples/start-console.sh | 10 +++++++++- 3 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 python/examples/config_osx diff --git a/python/examples/config b/python/examples/config index 1c73645..f35134f 100644 --- a/python/examples/config +++ b/python/examples/config @@ -5,5 +5,5 @@ focus down screen -t console python console.py "set_output_file" split -v focus down -screen -t help vi ./console-help.txt +screen -t help vi -R ./console-help.txt focus up diff --git a/python/examples/config_osx b/python/examples/config_osx new file mode 100644 index 0000000..cdb186c --- /dev/null +++ b/python/examples/config_osx @@ -0,0 +1,8 @@ +sessionname pubnub-console +screen -t help vi -R ./console-help.txt +split +focus down +screen -t output tail -f ./pubnub-console.log +split +focus down +screen -t console python console.py "set_output_file" diff --git a/python/examples/start-console.sh b/python/examples/start-console.sh index df4fd6e..e842427 100644 --- a/python/examples/start-console.sh +++ b/python/examples/start-console.sh @@ -1,3 +1,4 @@ +#!/bin/bash if ! type "screen" > /dev/null; then echo "[ERROR] Screen is not installed. Please install screen to use this utility ." exit @@ -5,4 +6,11 @@ fi rm ./pubnub-console.log touch ./pubnub-console.log set PYTHONPATH=../.. -screen -c config +screen -X -S pubnub-console quit 2>&1 > /dev/null +OS="`uname`" +case $OS in + 'darwin') + screen -c config_osx + ;; + *) screen -c config;; +esac -- cgit v1.2.3 From e2ccbc05b6ed2696dd8d2d2134b2023c528e1b70 Mon Sep 17 00:00:00 2001 From: Devendra Date: Wed, 30 Apr 2014 00:59:26 +0530 Subject: fixing start script for osx --- python/examples/start-console.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/examples/start-console.sh b/python/examples/start-console.sh index e842427..2df3f77 100644 --- a/python/examples/start-console.sh +++ b/python/examples/start-console.sh @@ -9,8 +9,8 @@ set PYTHONPATH=../.. screen -X -S pubnub-console quit 2>&1 > /dev/null OS="`uname`" case $OS in - 'darwin') + [dD]'arwin') screen -c config_osx ;; - *) screen -c config;; + *) screen -c config ;; esac -- cgit v1.2.3 From 10f345fcf4edb489cf9b86039c030baa62a6881c Mon Sep 17 00:00:00 2001 From: Devendra Date: Wed, 30 Apr 2014 17:14:09 +0530 Subject: adding persistent connectino support --- Pubnub.py | 23 +++++++++++++++++++++- python/examples/publish-example.py | 40 +++++++------------------------------- 2 files changed, 29 insertions(+), 34 deletions(-) diff --git a/Pubnub.py b/Pubnub.py index 6c082dc..06a594b 100644 --- a/Pubnub.py +++ b/Pubnub.py @@ -46,6 +46,11 @@ try: except ImportError: import urllib2 +try: + import requests +except ImportError: + pass + import threading from threading import current_thread @@ -1092,6 +1097,18 @@ def _urllib_request_2(url, timeout=320): return (resp.read(), resp.code) +s = requests.Session() +def _requests_request(url, timeout=320): + try: + resp = s.get(url) + except requests.exceptions.HTTPError as http_error: + resp = http_error + except requests.exceptions.ConnectionError as error: + msg = {"message": str(error.reason)} + return (json.dumps(msg), 0) + + return (resp.text, resp.status_code) + def _urllib_request_3(url, timeout=320): try: @@ -1116,7 +1133,8 @@ class PubnubAsync(PubnubCoreAsync): auth_key=None, ssl_on=False, origin='pubsub.pubnub.com', - pres_uuid=None + pres_uuid=None, + pooling=True ): super(PubnubAsync, self).__init__( publish_key=publish_key, @@ -1136,6 +1154,9 @@ class PubnubAsync(PubnubCoreAsync): else: _urllib_request = _urllib_request_3 + if pooling is True: + _urllib_request = _requests_request + def timeout(self, interval, func): def cb(): time.sleep(interval) diff --git a/python/examples/publish-example.py b/python/examples/publish-example.py index 1c57e4b..78b7f36 100755 --- a/python/examples/publish-example.py +++ b/python/examples/publish-example.py @@ -21,7 +21,7 @@ ssl_on = len(sys.argv) > 6 and bool(sys.argv[5]) or False ## Initiate Pubnub State ## ----------------------------------------------------------------------- pubnub = Pubnub( - publish_key, subscribe_key, secret_key, cipher_key, auth_key, ssl_on) + publish_key, subscribe_key, secret_key, cipher_key, auth_key, ssl_on, pooling=True) crazy = 'hello_world' ## ----------------------------------------------------------------------- @@ -36,35 +36,9 @@ def publish_complete(info): def publish_error(info): print('ERROR : ' + str(info)) -## Publish string -pubnub.publish({ - 'channel': crazy, - 'message': 'Hello World!', - 'callback': publish_complete, - 'error': publish_error -}) - -## Publish list -li = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', - 'Saturday'] - -pubnub.publish({ - 'channel': crazy, - 'message': li, - 'callback': publish_complete, - 'error': publish_error -}) - - -def done_cb(info): - publish_complete(info) - -pubnub.publish({ - 'channel': crazy, - 'message': {'some_key': 'some_val'}, - 'callback': done_cb, - 'error': publish_error -}) - - -pubnub.start() +import time +start = time.time() +for i in range(1,100): + print pubnub.publish(crazy, 'hello world-' + str(i)) +end = time.time() +print(end - start); -- cgit v1.2.3 From 06511b3849e80cb5692ed92f7da31043c85556a0 Mon Sep 17 00:00:00 2001 From: Devendra Date: Thu, 1 May 2014 00:14:25 +0530 Subject: more chagnes to console --- Pubnub.py | 3 +++ python/examples/console.py | 22 +++++++++++++++------- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/Pubnub.py b/Pubnub.py index 06a594b..1bf31e9 100644 --- a/Pubnub.py +++ b/Pubnub.py @@ -379,6 +379,9 @@ class PubnubBase(object): self._return_wrapped_callback(callback), self._return_wrapped_callback(error)) + def get_origin(self): + return self.origin + def grant(self, channel, authkey=False, read=True, write=True, ttl=5, callback=None, error=None): """Grant Access on a Channel.""" diff --git a/python/examples/console.py b/python/examples/console.py index e96b4e5..240e5c0 100644 --- a/python/examples/console.py +++ b/python/examples/console.py @@ -202,11 +202,12 @@ class DevConsole(Cmd): def __init__(self): Cmd.__init__(self) global pubnub - self.prompt = "(PubNub Console) > " - self.intro = "Welcome to PubNub Developer Console!" ## defaults to None + self.intro = "For Help type ? or help . To quit/exit type exit" ## defaults to None self.default_channel = None self.async = False pubnub = Pubnub("demo", "demo") + self.prompt = "(PubNub Console) [" + color.colorize(pubnub.get_origin(),"blue") + "] > " + def cmdloop_with_keyboard_interrupt(self): try: @@ -235,12 +236,17 @@ class DevConsole(Cmd): opts.ssl, opts.origin, opts.uuid) + self.prompt = "(PubNub Console) [" + color.colorize(pubnub.get_origin(),"blue") + "] > " def do_set_sync(self, command): + """unset_async + Unset Async mode""" self.async = False def do_set_async(self, command): + """set_async + Set Async mode""" self.async = True @@ -361,7 +367,9 @@ class DevConsole(Cmd): _unsubscribe_command_handler(opts.channel) - @options([make_option('-c', '--channel', action="store", help="Channel for subscribe") + @options([make_option('-c', '--channel', action="store", help="Channel for subscribe"), + make_option('-g', '--get-channel-list', action="store_true", dest="get", + default=False, help="Get susbcribed channel list") ]) def do_subscribe(self, command, opts): opts.channel = self.default_channel if opts.channel is None else opts.channel @@ -369,11 +377,11 @@ class DevConsole(Cmd): print_error("Missing argument") return - if opts.channel is None: - print_error("Missing channel") - return + if opts.channel is not None: + _subscribe_command_handler(opts.channel) - _subscribe_command_handler(opts.channel) + if opts.get is True: + print_ok(pubnub.get_channel_array()) def do_exit(self, args): kill_all_threads() -- cgit v1.2.3 From 8a642ab92c537c84960ef3943b34aac95bc39121 Mon Sep 17 00:00:00 2001 From: Devendra Date: Fri, 2 May 2014 01:58:21 +0530 Subject: modifications for susbcribe loop events, connect, disconnect, reconnect --- Pubnub.py | 32 ++++++++++++++++++++++++++++---- python/examples/console.py | 12 +++++++++++- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/Pubnub.py b/Pubnub.py index 1bf31e9..3e8fd64 100644 --- a/Pubnub.py +++ b/Pubnub.py @@ -381,7 +381,7 @@ class PubnubBase(object): def get_origin(self): return self.origin - + def grant(self, channel, authkey=False, read=True, write=True, ttl=5, callback=None, error=None): """Grant Access on a Channel.""" @@ -770,7 +770,22 @@ class PubnubCoreAsync(PubnubBase): chobj = self.subscriptions[ch] if chobj['connected'] is False: chobj['connected'] = True + chobj['disconnected'] = False _invoke(chobj['connect'], chobj['name']) + else: + if chobj['disconnected'] is True: + chobj['disconnected'] = False + _invoke(chobj['reconnect'], chobj['name']) + + def _invoke_disconnect(): + if self._channel_list_lock: + with self._channel_list_lock: + for ch in self.subscriptions: + chobj = self.subscriptions[ch] + if chobj['connected'] is True: + if chobj['disconnected'] is False: + chobj['disconnected'] = True + _invoke(chobj['disconnect'], chobj['name']) def _invoke_error(channel_list=None, err=None): if channel_list is None: @@ -796,6 +811,7 @@ class PubnubCoreAsync(PubnubBase): 'name': channel, 'first': False, 'connected': False, + 'disconnected': True, 'subscribed': True, 'callback': callback, 'connect': connect, @@ -823,10 +839,13 @@ class PubnubCoreAsync(PubnubBase): response['message'] == 'Forbidden'): _invoke_error(response['payload'][ 'channels'], response['message']) - _connect() + self.timeout(1, _connect) return if 'message' in response: _invoke_error(err=response['message']) + else: + _invoke_disconnect() + self.timeout(1, _connect) def sub_callback(response): ## ERROR ? @@ -1103,11 +1122,16 @@ def _urllib_request_2(url, timeout=320): s = requests.Session() def _requests_request(url, timeout=320): try: - resp = s.get(url) + resp = s.get(url, timeout=timeout) except requests.exceptions.HTTPError as http_error: resp = http_error except requests.exceptions.ConnectionError as error: - msg = {"message": str(error.reason)} + msg = str(error) + return (json.dumps(msg), 0) + except requests.exceptions.Timeout as error: + #print(error); + #print('timeout'); + msg = str(error) return (json.dumps(msg), 0) return (resp.text, resp.status_code) diff --git a/python/examples/console.py b/python/examples/console.py index 240e5c0..fd9ebf4 100644 --- a/python/examples/console.py +++ b/python/examples/console.py @@ -127,7 +127,17 @@ def _subscribe_command_handler(channel): def _error(r): print_error(r, channel) - pubnub.subscribe(channel, _callback, _error) + + def _disconnect(r): + print_error("DISCONNECTED", channel) + + def _reconnect(r): + print_error("RECONNECTED", channel) + + def _connect(r): + print_error("CONNECTED", channel) + + pubnub.subscribe(channel, _callback, _error,connect=_connect, disconnect=_disconnect, reconnect=_reconnect) def _unsubscribe_command_handler(channel): -- cgit v1.2.3 From ca29b41c781c3a9861141811b208432fbda8aa0a Mon Sep 17 00:00:00 2001 From: Devendra Date: Fri, 2 May 2014 20:19:57 +0530 Subject: enahancements to dev console --- Pubnub.py | 52 ++++++++++++++++++++++++---------------------- python/examples/console.py | 50 +++++++++++++++++++++++++++++++++++++------- 2 files changed, 69 insertions(+), 33 deletions(-) diff --git a/Pubnub.py b/Pubnub.py index 3e8fd64..fc822f7 100644 --- a/Pubnub.py +++ b/Pubnub.py @@ -713,7 +713,7 @@ class PubnubCoreAsync(PubnubBase): for i in l: func(i) - def subscribe(self, channel, callback, error=None, + def subscribe(self, channels, callback, error=None, connect=None, disconnect=None, reconnect=None, sync=False): """ #** @@ -756,11 +756,13 @@ class PubnubCoreAsync(PubnubBase): self.susbcribe_sync(args) return - def _invoke(func, msg=None): + def _invoke(func, msg=None, channel=None): if func is not None: - if msg is not None: + if msg is not None and channel is not None: + func(msg,channel) + elif msg is not None: func(msg) - else: + else : func() def _invoke_connect(): @@ -802,31 +804,32 @@ class PubnubCoreAsync(PubnubBase): chobj = self.subscriptions[ch] if chobj['subscribed'] is True: return chobj - - ## New Channel? - if not channel in self.subscriptions or \ - self.subscriptions[channel]['subscribed'] is False: - with self._channel_list_lock: - self.subscriptions[channel] = { - 'name': channel, - 'first': False, - 'connected': False, - 'disconnected': True, - 'subscribed': True, - 'callback': callback, - 'connect': connect, - 'disconnect': disconnect, - 'reconnect': reconnect, - 'error': error - } - + channels = channels if isinstance(channels,list) else channels.split(",") + for channel in channels: + ## New Channel? + if not channel in self.subscriptions or \ + self.subscriptions[channel]['subscribed'] is False: + with self._channel_list_lock: + self.subscriptions[channel] = { + 'name': channel, + 'first': False, + 'connected': False, + 'disconnected': True, + 'subscribed': True, + 'callback': callback, + 'connect': connect, + 'disconnect': disconnect, + 'reconnect': reconnect, + 'error': error + } + ''' ## return if already connected to channel if channel in self.subscriptions and \ 'connected' in self.subscriptions[channel] and \ self.subscriptions[channel]['connected'] is True: _invoke(error, "Already Connected") return - + ''' ## SUBSCRIPTION RECURSION def _connect(): @@ -845,6 +848,7 @@ class PubnubCoreAsync(PubnubBase): _invoke_error(err=response['message']) else: _invoke_disconnect() + self.timetoken = 0 self.timeout(1, _connect) def sub_callback(response): @@ -1129,8 +1133,6 @@ def _requests_request(url, timeout=320): msg = str(error) return (json.dumps(msg), 0) except requests.exceptions.Timeout as error: - #print(error); - #print('timeout'); msg = str(error) return (json.dumps(msg), 0) diff --git a/python/examples/console.py b/python/examples/console.py index fd9ebf4..d43ee80 100644 --- a/python/examples/console.py +++ b/python/examples/console.py @@ -129,13 +129,13 @@ def _subscribe_command_handler(channel): print_error(r, channel) def _disconnect(r): - print_error("DISCONNECTED", channel) + print_error("DISCONNECTED", r) def _reconnect(r): - print_error("RECONNECTED", channel) + print_error("RECONNECTED", r) def _connect(r): - print_error("CONNECTED", channel) + print_error("CONNECTED", r) pubnub.subscribe(channel, _callback, _error,connect=_connect, disconnect=_disconnect, reconnect=_reconnect) @@ -216,16 +216,47 @@ class DevConsole(Cmd): self.default_channel = None self.async = False pubnub = Pubnub("demo", "demo") - self.prompt = "(PubNub Console) [" + color.colorize(pubnub.get_origin(),"blue") + "] > " + self.prompt = self.get_prompt() + + def get_channel_origin(self): + cho = " [" + channels = pubnub.get_channel_array() + channels_str = ",".join(channels) + if len(channels) > 3: + cho += ",".join(channels[:3]) + " " + str(len(channels) - 3) + " more..." + else: + cho += ",".join(channels) + + if len(channels) > 0: + cho = color.colorize(cho,"bold") + "@" + + return cho + color.colorize(pubnub.get_origin(),"blue") + "] > " + + def get_prompt(self): + prompt = color.colorize("[" + datetime.now().strftime( + '%Y-%m-%d %H:%M:%S') + "] ", "magenta") + if self.default_channel is not None and len(self.default_channel) > 0: + prompt += " [default channel: " + color.colorize(self.default_channel,"bold") + "]" + + prompt += self.get_channel_origin() + return prompt + + def precmd(self, line): + self.prompt = self.get_prompt() + return line + + def emptyline(self): + print('empty line') + self.prompt = get_date() + " [" + color.colorize(pubnub.get_origin(),"blue") + "] > " def cmdloop_with_keyboard_interrupt(self): try: self.cmdloop() - except KeyboardInterrupt: - sys.stdout.write('\n') - kill_all_threads() - + except KeyboardInterrupt as e: + pass + sys.stdout.write('\n') + kill_all_threads() @options([make_option('-p', '--publish-key', action="store", default="demo", help="Publish Key"), make_option('-s', '--subscribe-key', action="store", default="demo", help="Subscribe Key"), @@ -268,6 +299,7 @@ class DevConsole(Cmd): print_error("Missing channel") return self.default_channel = opts.channel + self.prompt = self.get_prompt() @options([make_option('-f', '--file', action="store", default="./pubnub-console.log", help="Output file") ]) @@ -375,6 +407,7 @@ class DevConsole(Cmd): print_error("Missing channel") return _unsubscribe_command_handler(opts.channel) + self.prompt = self.get_prompt() @options([make_option('-c', '--channel', action="store", help="Channel for subscribe"), @@ -392,6 +425,7 @@ class DevConsole(Cmd): if opts.get is True: print_ok(pubnub.get_channel_array()) + self.prompt = self.get_prompt() def do_exit(self, args): kill_all_threads() -- cgit v1.2.3 From e0207efea24574bc6dac3e0aadb2d53cebe2a307 Mon Sep 17 00:00:00 2001 From: Devendra Date: Fri, 2 May 2014 22:45:17 +0530 Subject: console enhancements --- Pubnub.py | 6 ++++-- python/examples/console.py | 8 ++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Pubnub.py b/Pubnub.py index fc822f7..75e2243 100644 --- a/Pubnub.py +++ b/Pubnub.py @@ -874,13 +874,13 @@ class PubnubCoreAsync(PubnubBase): if ch[1] in self.subscriptions: chobj = self.subscriptions[ch[1]] _invoke(chobj['callback'], - self.decrypt(response_list[ch[0]])) + self.decrypt(response_list[ch[0]]), chobj['name']) else: response_list = response[0] chobj = _get_channel() for r in response_list: if chobj: - _invoke(chobj['callback'], self.decrypt(r)) + _invoke(chobj['callback'], self.decrypt(r), chobj['name']) _connect() @@ -1133,6 +1133,8 @@ def _requests_request(url, timeout=320): msg = str(error) return (json.dumps(msg), 0) except requests.exceptions.Timeout as error: + #print(error); + #print('timeout'); msg = str(error) return (json.dumps(msg), 0) diff --git a/python/examples/console.py b/python/examples/console.py index d43ee80..3041a02 100644 --- a/python/examples/console.py +++ b/python/examples/console.py @@ -122,11 +122,11 @@ def _publish_command_handler(channel, message,async=False): def _subscribe_command_handler(channel): - def _callback(r): - print_ok(r, channel) + def _callback(r,ch): + print_ok(r, ch) - def _error(r): - print_error(r, channel) + def _error(r,ch=None): + print_error(r, ch if ch is not None else channel) def _disconnect(r): print_error("DISCONNECTED", r) -- cgit v1.2.3 From 57d27fe29751f9cbd14a26d2a4ee8402168bfe8b Mon Sep 17 00:00:00 2001 From: Devendra Date: Fri, 2 May 2014 23:14:10 +0530 Subject: fixing start-console.sh --- python/examples/start-console.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/examples/start-console.sh b/python/examples/start-console.sh index 2df3f77..128a20e 100644 --- a/python/examples/start-console.sh +++ b/python/examples/start-console.sh @@ -5,7 +5,7 @@ if ! type "screen" > /dev/null; then fi rm ./pubnub-console.log touch ./pubnub-console.log -set PYTHONPATH=../.. +export PYTHONPATH=../.. screen -X -S pubnub-console quit 2>&1 > /dev/null OS="`uname`" case $OS in -- cgit v1.2.3 From fc9ef45293540a2a5ff8f6dde5481442f4349f0c Mon Sep 17 00:00:00 2001 From: Devendra Date: Sat, 3 May 2014 00:23:55 +0530 Subject: adding virtualenv creation and installation of dependencies to start-console --- python/examples/start-console.sh | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) mode change 100644 => 100755 python/examples/start-console.sh diff --git a/python/examples/start-console.sh b/python/examples/start-console.sh old mode 100644 new mode 100755 index 128a20e..a928cb3 --- a/python/examples/start-console.sh +++ b/python/examples/start-console.sh @@ -1,4 +1,26 @@ #!/bin/bash + +#!/bin/bash -e + +BASEDIR=. + +if [ ! -d "$BASEDIR/ve" ]; then + virtualenv -q $BASEDIR/ve --no-site-packages + $BASEDIR/ve/bin/activate + echo "Virtualenv created." +fi + +chmod 755 $BASEDIR/ve/bin/activate +$BASEDIR/ve/bin/activate + +if [ ! -f "$BASEDIR/ve/updated" -o $BASEDIR/requirements.pip -nt $BASEDIR/ve/updated ]; then + pip install -r $BASEDIR/requirements.pip -E $BASEDIR/ve + touch $BASEDIR/ve/updated + echo "Requirements installed." +fi + + + if ! type "screen" > /dev/null; then echo "[ERROR] Screen is not installed. Please install screen to use this utility ." exit -- cgit v1.2.3 From ab0597888580855ae8b75ad346a9d20b76027af9 Mon Sep 17 00:00:00 2001 From: Devendra Date: Sat, 3 May 2014 00:29:22 +0530 Subject: adding requirements.pip --- python/examples/requirements.pip | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 python/examples/requirements.pip diff --git a/python/examples/requirements.pip b/python/examples/requirements.pip new file mode 100644 index 0000000..738c606 --- /dev/null +++ b/python/examples/requirements.pip @@ -0,0 +1,3 @@ +pycrypto==2.6.1 +cmd2==0.6.7 +requests==2.2.1 -- cgit v1.2.3 From 2c4281c1ac254bd3915b44820f7d39c0ab0b1721 Mon Sep 17 00:00:00 2001 From: Devendra Date: Sun, 4 May 2014 23:25:22 +0530 Subject: adding help message --- python/examples/console-help.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python/examples/console-help.txt b/python/examples/console-help.txt index 55debd2..abe92c8 100644 --- a/python/examples/console-help.txt +++ b/python/examples/console-help.txt @@ -1,6 +1,9 @@ ********************** HELP ****************************** -TO EXIT . Ctrl-A \ followed by y +TO EXIT : +Ctrl-A \ followed by y ( on linux ) +Ctrl-A Ctrl-\ followed by y ( on mac osx ) + TO MOVE BETWEEN PANES . Ctrl-A TAB ********************************************************** -- cgit v1.2.3 From 3b60b175b085fbf474ca34069025f04633aa072e Mon Sep 17 00:00:00 2001 From: Devendra Date: Tue, 6 May 2014 14:20:16 +0530 Subject: console.py --- python/examples/console.py | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/python/examples/console.py b/python/examples/console.py index 3041a02..8f87a31 100644 --- a/python/examples/console.py +++ b/python/examples/console.py @@ -140,14 +140,20 @@ def _subscribe_command_handler(channel): pubnub.subscribe(channel, _callback, _error,connect=_connect, disconnect=_disconnect, reconnect=_reconnect) -def _unsubscribe_command_handler(channel): +def _unsubscribe_command_handler(channels): def _callback(r): print_ok(r) def _error(r): print_error(r) - pubnub.unsubscribe(channel) + if not isinstance(channels,list): + ch = [] + ch.append(channels) + channels = ch + + for channel in channels: + pubnub.unsubscribe(channel) def _grant_command_handler(channel, auth_key, read, write, ttl,async=False): @@ -230,7 +236,9 @@ class DevConsole(Cmd): if len(channels) > 0: cho = color.colorize(cho,"bold") + "@" - return cho + color.colorize(pubnub.get_origin(),"blue") + "] > " + origin = pubnub.get_origin().split("://")[1] + origin += color.colorize(" (SSL)","green") if pubnub.get_origin().split("://")[0] == "https" else "" + return cho + color.colorize(origin,"blue") + "] > " def get_prompt(self): @@ -277,7 +285,7 @@ class DevConsole(Cmd): opts.ssl, opts.origin, opts.uuid) - self.prompt = "(PubNub Console) [" + color.colorize(pubnub.get_origin(),"blue") + "] > " + self.prompt = self.get_prompt() def do_set_sync(self, command): @@ -399,10 +407,14 @@ class DevConsole(Cmd): _audit_command_handler(opts.channel, opts.auth_key,async=self.async) - @options([make_option('-c', '--channel', action="store", help="Channel for unsubscribe") + @options([make_option('-c', '--channel', action="store", help="Channel for unsubscribe"), + make_option('-a', '--all', action="store_true", dest="all", + default=False, help="Unsubscribe from all channels") ]) def do_unsubscribe(self, command, opts): opts.channel = self.default_channel if opts.channel is None else opts.channel + if (opts.all is True): + opts.channel = pubnub.get_channel_array() if opts.channel is None: print_error("Missing channel") return -- cgit v1.2.3 From cc39ff042c3c7c7d35819e33a5d4d58acdf89b67 Mon Sep 17 00:00:00 2001 From: Devendra Date: Tue, 6 May 2014 15:03:54 +0530 Subject: additions to console --- python/examples/console.py | 47 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/python/examples/console.py b/python/examples/console.py index 8f87a31..1f25eb6 100644 --- a/python/examples/console.py +++ b/python/examples/console.py @@ -212,6 +212,14 @@ def kill_all_threads(): thread._Thread__stop() +def get_date(full=False): + if full is True: + return color.colorize("[" + datetime.now().strftime( + '%Y-%m-%d %H:%M:%S') + "] ", "magenta") + else: + return color.colorize("[" + datetime.now().strftime( + '%H:%M:%S') + "] ", "magenta") + class DevConsole(Cmd): @@ -222,14 +230,18 @@ class DevConsole(Cmd): self.default_channel = None self.async = False pubnub = Pubnub("demo", "demo") + self.full_date = False + self.channel_truncation = 3 self.prompt = self.get_prompt() + def get_channel_origin(self): cho = " [" channels = pubnub.get_channel_array() channels_str = ",".join(channels) - if len(channels) > 3: - cho += ",".join(channels[:3]) + " " + str(len(channels) - 3) + " more..." + sl = self.channel_truncation + if len(channels) > 0 and sl > 0: + cho += ",".join(channels[:int(sl)]) + " " + str(len(channels) - int(sl)) + " more..." else: cho += ",".join(channels) @@ -242,8 +254,8 @@ class DevConsole(Cmd): def get_prompt(self): - prompt = color.colorize("[" + datetime.now().strftime( - '%Y-%m-%d %H:%M:%S') + "] ", "magenta") + prompt = get_date(self.full_date) + if self.default_channel is not None and len(self.default_channel) > 0: prompt += " [default channel: " + color.colorize(self.default_channel,"bold") + "]" @@ -298,6 +310,33 @@ class DevConsole(Cmd): Set Async mode""" self.async = True + @options([make_option('-n', '--count', action="store", default=3, help="Number of channels on prompt") + ]) + def do_set_channel_truncation(self, command, opts): + """set_channel_truncation + Set Channel Truncation""" + + self.channel_truncation = opts.count + + self.prompt = self.get_prompt() + + def do_unset_channel_truncation(self, command): + """unset_channel_truncation + Unset Channel Truncation""" + self.channel_truncation = 0 + self.prompt = self.get_prompt() + + def do_set_full_date(self, command): + """do_set_full_date + Set Full Date""" + self.full_date = True + self.prompt = self.get_prompt() + + def do_unset_full_date(self, command): + """do_unset_full_date + Unset Full Date""" + self.full_date = False + self.prompt = self.get_prompt() @options([make_option('-c', '--channel', action="store", help="Default Channel") ]) -- cgit v1.2.3 From cf1021b3671fb7537ad7b3a4d577ef0fcace694a Mon Sep 17 00:00:00 2001 From: Devendra Date: Tue, 6 May 2014 16:43:09 +0530 Subject: modifying examples --- python-tornado/examples/here-now-example.py | 43 ---------------- python-tornado/examples/here-now.py | 33 ++++++++++++ python-tornado/examples/history-example.py | 31 ----------- python-tornado/examples/history.py | 32 ++++++++++++ python-tornado/examples/publish-example.py | 70 ------------------------- python-tornado/examples/publish.py | 33 ++++++++++++ python-tornado/examples/subscribe-example.py | 77 ---------------------------- python-tornado/examples/subscribe.py | 48 +++++++++++++++++ python-tornado/examples/uuid-example.py | 26 ---------- python-twisted/examples/here-now-example.py | 42 --------------- python-twisted/examples/here-now.py | 33 ++++++++++++ python-twisted/examples/history-example.py | 46 ----------------- python-twisted/examples/history.py | 32 ++++++++++++ python-twisted/examples/publish-example.py | 75 --------------------------- python-twisted/examples/publish.py | 33 ++++++++++++ python-twisted/examples/subscribe-example.py | 50 ------------------ python-twisted/examples/subscribe.py | 48 +++++++++++++++++ python-twisted/examples/uuid-example.py | 27 ---------- python/examples/here-now-example.py | 32 ------------ python/examples/here-now.py | 36 +++++++++++++ python/examples/history-example.py | 12 ----- python/examples/history.py | 34 ++++++++++++ python/examples/publish-example.py | 44 ---------------- python/examples/publish.py | 37 +++++++++++++ python/examples/subscribe-example.py | 70 ------------------------- python/examples/subscribe.py | 46 +++++++++++++++++ 26 files changed, 445 insertions(+), 645 deletions(-) delete mode 100644 python-tornado/examples/here-now-example.py create mode 100644 python-tornado/examples/here-now.py delete mode 100644 python-tornado/examples/history-example.py create mode 100644 python-tornado/examples/history.py delete mode 100644 python-tornado/examples/publish-example.py create mode 100644 python-tornado/examples/publish.py delete mode 100644 python-tornado/examples/subscribe-example.py create mode 100644 python-tornado/examples/subscribe.py delete mode 100644 python-tornado/examples/uuid-example.py delete mode 100644 python-twisted/examples/here-now-example.py create mode 100644 python-twisted/examples/here-now.py delete mode 100644 python-twisted/examples/history-example.py create mode 100644 python-twisted/examples/history.py delete mode 100644 python-twisted/examples/publish-example.py create mode 100644 python-twisted/examples/publish.py delete mode 100644 python-twisted/examples/subscribe-example.py create mode 100644 python-twisted/examples/subscribe.py delete mode 100644 python-twisted/examples/uuid-example.py delete mode 100644 python/examples/here-now-example.py create mode 100644 python/examples/here-now.py delete mode 100755 python/examples/history-example.py create mode 100644 python/examples/history.py delete mode 100755 python/examples/publish-example.py create mode 100644 python/examples/publish.py delete mode 100755 python/examples/subscribe-example.py create mode 100644 python/examples/subscribe.py diff --git a/python-tornado/examples/here-now-example.py b/python-tornado/examples/here-now-example.py deleted file mode 100644 index c701daf..0000000 --- a/python-tornado/examples/here-now-example.py +++ /dev/null @@ -1,43 +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.1 Real-time Push Cloud API -## ----------------------------------- - -import sys -from Pubnub import PubnubTornado as Pubnub - -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' -subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False - -## ----------------------------------------------------------------------- -## Initiate Pubnub State -## ----------------------------------------------------------------------- -pubnub = Pubnub(publish_key, subscribe_key, secret_key, cipher_key, ssl_on) -crazy = 'hello_world' - -## ----------------------------------------------------------------------- -## History Example -## ----------------------------------------------------------------------- - - -def here_now_complete(messages): - print(messages) - print(type(messages)) - pubnub.stop() - -pubnub.here_now( - channel=crazy, callback=here_now_complete, error=here_now_complete) - -## ----------------------------------------------------------------------- -## IO Event Loop -## ----------------------------------------------------------------------- -pubnub.start() diff --git a/python-tornado/examples/here-now.py b/python-tornado/examples/here-now.py new file mode 100644 index 0000000..5c195f1 --- /dev/null +++ b/python-tornado/examples/here-now.py @@ -0,0 +1,33 @@ +## 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/ + + +import sys +from Pubnub import PubnubTornado as Pubnub + +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False + +## ----------------------------------------------------------------------- +## Initiate Pubnub State +## ----------------------------------------------------------------------- +pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, + secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) +channel = 'hello_world' + + +# Asynchronous usage + +def callback(message): + print(message) + +pubnub.here_now(channel, callback=callback, error=callback) + +pubnub.start() diff --git a/python-tornado/examples/history-example.py b/python-tornado/examples/history-example.py deleted file mode 100644 index 3a5fd88..0000000 --- a/python-tornado/examples/history-example.py +++ /dev/null @@ -1,31 +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.0 Real-time Push Cloud API -## ----------------------------------- - -import sys -from Pubnub import PubnubTornado as Pubnub - -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' -subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False - -pubnub = Pubnub(publish_key, subscribe_key, secret_key, cipher_key, ssl_on) -channel = 'hello_world' - - -def history_complete(messages): - print(messages) - pubnub.stop() - -pubnub.history(channel=channel, count=10, callback=history_complete) - -pubnub.start() diff --git a/python-tornado/examples/history.py b/python-tornado/examples/history.py new file mode 100644 index 0000000..da3d6a5 --- /dev/null +++ b/python-tornado/examples/history.py @@ -0,0 +1,32 @@ +## 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/ + + +import sys +from Pubnub import PubnubTornado as Pubnub + +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False + +## ----------------------------------------------------------------------- +## Initiate Pubnub State +## ----------------------------------------------------------------------- +pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, + secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) +channel = 'a' + +# Asynchronous usage + +def callback(message): + print(message) + +pubnub.history(channel, count=2 , callback=callback, error=callback) + +pubnub.start() diff --git a/python-tornado/examples/publish-example.py b/python-tornado/examples/publish-example.py deleted file mode 100644 index 456dbf9..0000000 --- a/python-tornado/examples/publish-example.py +++ /dev/null @@ -1,70 +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.1 Real-time Push Cloud API -## ----------------------------------- - -import sys -from Pubnub import PubnubTwisted as Pubnub - -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' -subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False - -## ----------------------------------------------------------------------- -## Initiate Pubnub State -## ----------------------------------------------------------------------- -pubnub = Pubnub(publish_key, subscribe_key, secret_key, cipher_key, ssl_on) -crazy = 'hello_world' - -## ----------------------------------------------------------------------- -## Publish Example -## ----------------------------------------------------------------------- - - -def publish_complete(info): - print(info) - - -def publish_error(info): - print('ERROR : ' + str(info)) - -## Publish string -pubnub.publish({ - 'channel': crazy, - 'message': 'Hello World!', - 'callback': publish_complete, - 'error': publish_error -}) - -## Publish list -li = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', - 'Saturday'] - -pubnub.publish({ - 'channel': crazy, - 'message': li, - 'callback': publish_complete, - 'error': publish_error -}) - - -def done_cb(info): - publish_complete(info) - -pubnub.publish({ - 'channel': crazy, - 'message': {'some_key': 'some_val'}, - 'callback': done_cb, - 'error': publish_error -}) - - -pubnub.start() diff --git a/python-tornado/examples/publish.py b/python-tornado/examples/publish.py new file mode 100644 index 0000000..4e662fd --- /dev/null +++ b/python-tornado/examples/publish.py @@ -0,0 +1,33 @@ +## 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/ + + +import sys +from Pubnub import PubnubTornado as Pubnub + +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False + +## ----------------------------------------------------------------------- +## Initiate Pubnub State +## ----------------------------------------------------------------------- +pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, + secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) +channel = 'hello_world' +message = 'Hello World !!!' + +# Asynchronous usage + +def callback(message): + print(message) + +pubnub.publish(channel, message, callback=callback, error=callback) + +pubnub.start() diff --git a/python-tornado/examples/subscribe-example.py b/python-tornado/examples/subscribe-example.py deleted file mode 100644 index 26be1fd..0000000 --- a/python-tornado/examples/subscribe-example.py +++ /dev/null @@ -1,77 +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.1 Real-time Push Cloud API -## ----------------------------------- - -import sys -import tornado -from Pubnub import PubnubTwisted as Pubnub - -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' -subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len( - sys.argv) > 4 and sys.argv[4] or 'demo' # (Cipher key is Optional) -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False - -## ----------------------------------------------------------------------- -## Initiate Pubnub State -## ----------------------------------------------------------------------- -pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, - secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) -#pubnub = Pubnub( publish_key, subscribe_key, secret_key, ssl_on ) -crazy = 'hello_world' - - -def connect_cb(): - print 'Connect' - - -def subscribe_result(response): - print response - -pubnub.subscribe({ - 'channel': crazy, - 'callback': subscribe_result, - 'connect': connect_cb -}) -## ----------------------------------------------------------------------- -## Publish Example -## ----------------------------------------------------------------------- -''' -def publish_complete(info): - print(info) - -## Publish string -pubnub.publish({ - 'channel' : crazy, - 'message' : 'Hello World!', - 'callback' : publish_complete -}) - -## Publish list -li = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', - 'Saturday'] -pubnub.publish({ - 'channel' : crazy, - 'message' : li, - 'callback' : publish_complete -}) - -## Publish Dictionary Object -pubnub.publish({ - 'channel' : crazy, - 'message' : { 'some_key' : 'some_val' }, - 'callback' : publish_complete -}) -''' -## ----------------------------------------------------------------------- -## IO Event Loop -## ----------------------------------------------------------------------- -tornado.ioloop.IOLoop.instance().start() diff --git a/python-tornado/examples/subscribe.py b/python-tornado/examples/subscribe.py new file mode 100644 index 0000000..9288836 --- /dev/null +++ b/python-tornado/examples/subscribe.py @@ -0,0 +1,48 @@ +## 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/ + + +import sys +from Pubnub import PubnubTornado as Pubnub + +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False + +## ----------------------------------------------------------------------- +## Initiate Pubnub State +## ----------------------------------------------------------------------- +pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, + secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) + +channel = 'a' + + + +# Asynchronous usage + +def callback(message, channel): + print(message) + +def error(message): + print("ERROR : " + str(message)) + +def connect(message): + print("CONNECTED") + +def reconnect(message): + print("RECONNECTED") + +def disconnect(message): + print("DISCONNECTED") + + +pubnub.subscribe(channel, callback=callback, error=callback, connect=connect, reconnect=reconnect, disconnect=disconnect) + +pubnub.start() diff --git a/python-tornado/examples/uuid-example.py b/python-tornado/examples/uuid-example.py deleted file mode 100644 index e5521ab..0000000 --- a/python-tornado/examples/uuid-example.py +++ /dev/null @@ -1,26 +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.1 Real-time Push Cloud API -## ----------------------------------- - -import sys -import tornado -from Pubnub import PubnubTwisted as Pubnub - -## ----------------------------------------------------------------------- -## Initiate Pubnub State -## ----------------------------------------------------------------------- -pubnub = Pubnub("", "", "", False) - -## ----------------------------------------------------------------------- -## UUID Example -## ----------------------------------------------------------------------- -uuid = pubnub.uuid() -print "UUID: " -print uuid diff --git a/python-twisted/examples/here-now-example.py b/python-twisted/examples/here-now-example.py deleted file mode 100644 index 4b2965b..0000000 --- a/python-twisted/examples/here-now-example.py +++ /dev/null @@ -1,42 +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.1 Real-time Push Cloud API -## ----------------------------------- - -import sys -from Pubnub import PubnubTwisted as Pubnub - -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' -subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False - -## ----------------------------------------------------------------------- -## Initiate Pubnub State -## ----------------------------------------------------------------------- -pubnub = Pubnub(publish_key, subscribe_key, secret_key, cipher_key, ssl_on) -crazy = 'hello_world' - -## ----------------------------------------------------------------------- -## History Example -## ----------------------------------------------------------------------- - - -def here_now_complete(messages): - print(messages) - pubnub.stop() - -pubnub.here_now( - channel=crazy, callback=here_now_complete, error=here_now_complete) - -## ----------------------------------------------------------------------- -## IO Event Loop -## ----------------------------------------------------------------------- -pubnub.start() diff --git a/python-twisted/examples/here-now.py b/python-twisted/examples/here-now.py new file mode 100644 index 0000000..38b79f8 --- /dev/null +++ b/python-twisted/examples/here-now.py @@ -0,0 +1,33 @@ +## 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/ + + +import sys +from Pubnub import PubnubTwisted as Pubnub + +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False + +## ----------------------------------------------------------------------- +## Initiate Pubnub State +## ----------------------------------------------------------------------- +pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, + secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) +channel = 'hello_world' + + +# Asynchronous usage + +def callback(message): + print(message) + +pubnub.here_now(channel, callback=callback, error=callback) + +pubnub.start() diff --git a/python-twisted/examples/history-example.py b/python-twisted/examples/history-example.py deleted file mode 100644 index f867a36..0000000 --- a/python-twisted/examples/history-example.py +++ /dev/null @@ -1,46 +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.1 Real-time Push Cloud API -## ----------------------------------- - -import sys -from twisted.internet import reactor -from Pubnub import PubnubTwisted as Pubnub - -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' -subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False - -## ----------------------------------------------------------------------- -## Initiate Pubnub State -## ----------------------------------------------------------------------- -pubnub = Pubnub(publish_key, subscribe_key, secret_key, cipher_key, ssl_on) -crazy = 'hello_world' - -## ----------------------------------------------------------------------- -## History Example -## ----------------------------------------------------------------------- - - -def history_complete(messages): - print(messages) - reactor.stop() - -pubnub.history({ - 'channel': crazy, - 'limit': 10, - 'callback': history_complete -}) - -## ----------------------------------------------------------------------- -## IO Event Loop -## ----------------------------------------------------------------------- -reactor.run() diff --git a/python-twisted/examples/history.py b/python-twisted/examples/history.py new file mode 100644 index 0000000..10e86b3 --- /dev/null +++ b/python-twisted/examples/history.py @@ -0,0 +1,32 @@ +## 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/ + + +import sys +from Pubnub import PubnubTwisted as Pubnub + +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False + +## ----------------------------------------------------------------------- +## Initiate Pubnub State +## ----------------------------------------------------------------------- +pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, + secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) +channel = 'a' + +# Asynchronous usage + +def callback(message): + print(message) + +pubnub.history(channel, count=2 , callback=callback, error=callback) + +pubnub.start() diff --git a/python-twisted/examples/publish-example.py b/python-twisted/examples/publish-example.py deleted file mode 100644 index d5af6a5..0000000 --- a/python-twisted/examples/publish-example.py +++ /dev/null @@ -1,75 +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.1 Real-time Push Cloud API -## ----------------------------------- - -import sys -from twisted.internet import reactor -from Pubnub import PubnubTwisted as Pubnub - -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' -subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len( - sys.argv) > 4 and sys.argv[4] or '' # (Cipher key is Optional) -auth_key = len( - sys.argv) > 5 and sys.argv[5] or 'abcd' # (Cipher key is Optional) -ssl_on = len(sys.argv) > 6 and bool(sys.argv[5]) or False - -## ----------------------------------------------------------------------- -## Initiate Pubnub State -## ----------------------------------------------------------------------- -pubnub = Pubnub( - publish_key, subscribe_key, secret_key, cipher_key, auth_key, ssl_on) -crazy = 'hello_world' - -## ----------------------------------------------------------------------- -## Publish Example -## ----------------------------------------------------------------------- - - -def publish_complete(info): - print(info) - - -def publish_error(info): - print('ERROR : ' + str(info)) - -## Publish string -pubnub.publish({ - 'channel': crazy, - 'message': 'Hello World!', - 'callback': publish_complete, - 'error': publish_error -}) - -## Publish list -li = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', - 'Saturday'] - -pubnub.publish({ - 'channel': crazy, - 'message': li, - 'callback': publish_complete, - 'error': publish_error -}) - - -def done_cb(info): - publish_complete(info) - -pubnub.publish({ - 'channel': crazy, - 'message': {'some_key': 'some_val'}, - 'callback': done_cb, - 'error': publish_error -}) - - -pubnub.start() diff --git a/python-twisted/examples/publish.py b/python-twisted/examples/publish.py new file mode 100644 index 0000000..f7b746f --- /dev/null +++ b/python-twisted/examples/publish.py @@ -0,0 +1,33 @@ +## 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/ + + +import sys +from Pubnub import PubnubTwisted as Pubnub + +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False + +## ----------------------------------------------------------------------- +## Initiate Pubnub State +## ----------------------------------------------------------------------- +pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, + secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) +channel = 'hello_world' +message = 'Hello World !!!' + +# Asynchronous usage + +def callback(message): + print(message) + +pubnub.publish(channel, message, callback=callback, error=callback) + +pubnub.start() diff --git a/python-twisted/examples/subscribe-example.py b/python-twisted/examples/subscribe-example.py deleted file mode 100644 index 3bca615..0000000 --- a/python-twisted/examples/subscribe-example.py +++ /dev/null @@ -1,50 +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.1 Real-time Push Cloud API -## ----------------------------------- - -import sys -from twisted.internet import reactor -from Pubnub import PubnubTwisted as Pubnub - -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' -subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len(sys.argv) > 4 and sys.argv[4] or None -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False - -## ----------------------------------------------------------------------- -## Initiate Pubnub State -## ----------------------------------------------------------------------- -#pubnub = Pubnub( publish_key, subscribe_key, secret_key, cipher_key, ssl_on ) -pubnub = Pubnub(publish_key, subscribe_key, secret_key, ssl_on) -crazy = 'hello_world' - -## ----------------------------------------------------------------------- -## Subscribe Example -## ----------------------------------------------------------------------- - - -def message_received(message): - print(message) - - -def connected(): - print 'Connected' - -pubnub.subscribe({ - 'channel': crazy, - 'connect': connected, - 'callback': message_received -}) - -## ----------------------------------------------------------------------- -## IO Event Loop -## ----------------------------------------------------------------------- -reactor.run() diff --git a/python-twisted/examples/subscribe.py b/python-twisted/examples/subscribe.py new file mode 100644 index 0000000..1462a69 --- /dev/null +++ b/python-twisted/examples/subscribe.py @@ -0,0 +1,48 @@ +## 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/ + + +import sys +from Pubnub import PubnubTwisted as Pubnub + +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False + +## ----------------------------------------------------------------------- +## Initiate Pubnub State +## ----------------------------------------------------------------------- +pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, + secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) + +channel = 'a' + + + +# Asynchronous usage + +def callback(message, channel): + print(message) + +def error(message): + print("ERROR : " + str(message)) + +def connect(message): + print("CONNECTED") + +def reconnect(message): + print("RECONNECTED") + +def disconnect(message): + print("DISCONNECTED") + + +pubnub.subscribe(channel, callback=callback, error=callback, connect=connect, reconnect=reconnect, disconnect=disconnect) + +pubnub.start() diff --git a/python-twisted/examples/uuid-example.py b/python-twisted/examples/uuid-example.py deleted file mode 100644 index a745088..0000000 --- a/python-twisted/examples/uuid-example.py +++ /dev/null @@ -1,27 +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.1 Real-time Push Cloud API -## ----------------------------------- - -import sys -from twisted.internet import reactor -from Pubnub import PubnubTwisted as Pubnub - -## ----------------------------------------------------------------------- -## Initiate Pubnub State -## ----------------------------------------------------------------------- -pubnub = Pubnub("", "", "", False) - -## ----------------------------------------------------------------------- -## UUID Example -## ----------------------------------------------------------------------- - -uuid = pubnub.uuid() -print "UUID: " -print uuid diff --git a/python/examples/here-now-example.py b/python/examples/here-now-example.py deleted file mode 100644 index 0bc3015..0000000 --- a/python/examples/here-now-example.py +++ /dev/null @@ -1,32 +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/ - - -import sys -from Pubnub import PubnubAsync as Pubnub - -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' -subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' -ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False - -## ----------------------------------------------------------------------- -## Initiate Pubnub State -## ----------------------------------------------------------------------- -pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, - secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) -crazy = 'hello_world' - - -def print_cb(message): - print(message) - -pubnub.here_now({ - 'channel': crazy, - 'callback': print_cb -}) diff --git a/python/examples/here-now.py b/python/examples/here-now.py new file mode 100644 index 0000000..f573389 --- /dev/null +++ b/python/examples/here-now.py @@ -0,0 +1,36 @@ +## 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/ + + +import sys +from Pubnub import PubnubAsync as Pubnub + +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False + +## ----------------------------------------------------------------------- +## Initiate Pubnub State +## ----------------------------------------------------------------------- +pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, + secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) +channel = 'hello_world' + + + +# Synchronous usage + +print pubnub.here_now(channel) + +# Asynchronous usage + +def callback(message): + print(message) + +pubnub.here_now(channel, callback=callback, error=callback) diff --git a/python/examples/history-example.py b/python/examples/history-example.py deleted file mode 100755 index 793c612..0000000 --- a/python/examples/history-example.py +++ /dev/null @@ -1,12 +0,0 @@ -import sys -from Pubnub import PubnubAsync as Pubnub - -## Initiat Class -pubnub = Pubnub('demo', 'demo', None, False) - -## History Example -history = pubnub.history({ - 'channel': 'hello_world', - 'limit': 1 -}) -print(history) diff --git a/python/examples/history.py b/python/examples/history.py new file mode 100644 index 0000000..3d6addf --- /dev/null +++ b/python/examples/history.py @@ -0,0 +1,34 @@ +## 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/ + + +import sys +from Pubnub import PubnubAsync as Pubnub + +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False + +## ----------------------------------------------------------------------- +## Initiate Pubnub State +## ----------------------------------------------------------------------- +pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, + secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) +channel = 'a' + +# Synchronous usage + +print pubnub.history(channel, count=2) + +# Asynchronous usage + +def callback(message): + print(message) + +pubnub.history(channel, count=2 , callback=callback, error=callback) diff --git a/python/examples/publish-example.py b/python/examples/publish-example.py deleted file mode 100755 index 78b7f36..0000000 --- a/python/examples/publish-example.py +++ /dev/null @@ -1,44 +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/ - -import sys -from Pubnub import PubnubAsync as Pubnub - -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' -subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' -cipher_key = len( - sys.argv) > 4 and sys.argv[4] or '' # (Cipher key is Optional) -auth_key = len( - sys.argv) > 5 and sys.argv[4] or 'abcd' # (Cipher key is Optional) -ssl_on = len(sys.argv) > 6 and bool(sys.argv[5]) or False - -## ----------------------------------------------------------------------- -## Initiate Pubnub State -## ----------------------------------------------------------------------- -pubnub = Pubnub( - publish_key, subscribe_key, secret_key, cipher_key, auth_key, ssl_on, pooling=True) -crazy = 'hello_world' - -## ----------------------------------------------------------------------- -## Publish Example -## ----------------------------------------------------------------------- - - -def publish_complete(info): - print(info) - - -def publish_error(info): - print('ERROR : ' + str(info)) - -import time -start = time.time() -for i in range(1,100): - print pubnub.publish(crazy, 'hello world-' + str(i)) -end = time.time() -print(end - start); diff --git a/python/examples/publish.py b/python/examples/publish.py new file mode 100644 index 0000000..029c17a --- /dev/null +++ b/python/examples/publish.py @@ -0,0 +1,37 @@ +## 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/ + + +import sys +from Pubnub import PubnubAsync as Pubnub + +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False + +## ----------------------------------------------------------------------- +## Initiate Pubnub State +## ----------------------------------------------------------------------- +pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, + secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) +channel = 'hello_world' +message = 'Hello World !!!' + + + +# Synchronous usage + +print pubnub.publish(channel, message) + +# Asynchronous usage + +def callback(message): + print(message) + +pubnub.publish(channel, message, callback=callback, error=callback) diff --git a/python/examples/subscribe-example.py b/python/examples/subscribe-example.py deleted file mode 100755 index 9c16bbe..0000000 --- a/python/examples/subscribe-example.py +++ /dev/null @@ -1,70 +0,0 @@ -import sys -import threading -import time -import random -import string -from Pubnub import PubnubAsync as Pubnub - -## Initiate Class -pubnub = Pubnub('demo', 'demo', None, False) - -print("My UUID is: " + pubnub.uuid) - -channel = ''.join( - random.choice(string.ascii_letters + string.digits) for x in range(20)) - -## Subscribe Example - - -def receive(message): - print(message) - return False - - -def pres_event(message): - print(message) - return False - - -def subscribe(): - print("Listening for messages on '%s' channel..." % channel) - pubnub.subscribe({ - 'channel': channel, - 'callback': receive - }) - - -def presence(): - print("Listening for presence events on '%s' channel..." % channel) - pubnub.presence({ - 'channel': channel, - 'callback': pres_event - }) - - -def publish(): - print("Publishing a test message on '%s' channel..." % channel) - pubnub.publish({ - 'channel': channel, - 'message': {'text': 'foo bar'} - }) - -pres_thread = threading.Thread(target=presence) -pres_thread.daemon = True -pres_thread.start() - -sub_thread = threading.Thread(target=subscribe) -sub_thread.daemon = True -sub_thread.start() - -time.sleep(3) - -publish() - - -print("waiting for subscribes and presence") -pres_thread.join() - -print(pubnub.here_now({'channel': channel})) - -sub_thread.join() diff --git a/python/examples/subscribe.py b/python/examples/subscribe.py new file mode 100644 index 0000000..a410297 --- /dev/null +++ b/python/examples/subscribe.py @@ -0,0 +1,46 @@ +## 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/ + + +import sys +from Pubnub import PubnubAsync as Pubnub + +publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' +subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' +secret_key = len(sys.argv) > 3 and sys.argv[3] or 'demo' +cipher_key = len(sys.argv) > 4 and sys.argv[4] or '' +ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False + +## ----------------------------------------------------------------------- +## Initiate Pubnub State +## ----------------------------------------------------------------------- +pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, + secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) + +channel = 'a' + + + +# Asynchronous usage + +def callback(message, channel): + print(message) + +def error(message): + print("ERROR : " + str(message)) + +def connect(message): + print("CONNECTED") + +def reconnect(message): + print("RECONNECTED") + +def disconnect(message): + print("DISCONNECTED") + + +pubnub.subscribe(channel, callback=callback, error=callback, connect=connect, reconnect=reconnect, disconnect=disconnect) -- cgit v1.2.3 From 338ffccb4d6603a8af5951dda6fd1e1dd11473f9 Mon Sep 17 00:00:00 2001 From: Devendra Date: Tue, 6 May 2014 20:04:19 +0530 Subject: changes for python 3 compatibility --- python/examples/console.py | 45 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/python/examples/console.py b/python/examples/console.py index 1f25eb6..084c49a 100644 --- a/python/examples/console.py +++ b/python/examples/console.py @@ -20,9 +20,6 @@ import os import readline import rlcompleter -if sys.argv[0] == "screen": - print "screen" - historyPath = os.path.expanduser("~/.pubnub_console_history") def save_history(historyPath=historyPath): @@ -38,6 +35,34 @@ of=sys.stdout color = Cmd() +stop = None + +def stop_2(th): + th._Thread__stop() + +def stop_3(th): + th._stop() + +def print_console_2(of,message): + print >>of, message + +def print_console_3(of,message): + of.write(message) + of.write("\n") + +print_console = None + +if type(sys.version_info) is tuple: + print_console = print_console_2 + stop = stop_2 +else: + if sys.version_info.major == 2: + print_console = print_console_2 + stop = stop_2 + else: + print_console = print_console_3 + stop = stop_3 + def print_ok(msg, channel=None): if msg is None: return @@ -46,9 +71,9 @@ def print_ok(msg, channel=None): chstr += color.colorize("[Channel : " + channel + \ "] " if channel is not None else "", "cyan") try: - print >>of, (chstr + color.colorize(str(msg),"green")) + print_console(of, (chstr + color.colorize(str(msg),"green"))) except UnicodeEncodeError as e: - print >>of, (msg) + print_console(of, (msg)) of.flush() def print_error(msg, channel=None): @@ -59,9 +84,9 @@ def print_error(msg, channel=None): chstr += color.colorize("[Channel : " + channel + \ "] " if channel is not None else "", "cyan") try: - print >>of, (chstr + color.colorize(color.colorize(str(msg),"red"),"bold")) + print_console(of, (chstr + color.colorize(color.colorize(str(msg),"red"),"bold"))) except UnicodeEncodeError as e: - print >>of, (msg) + print_console(of, (msg)) of.flush() class DefaultPubnub(object): @@ -79,7 +104,7 @@ pubnub=DefaultPubnub() def kill_all_threads(): for thread in threading.enumerate(): if thread.isAlive(): - thread._Thread__stop() + stop(thread) def get_input(message, t=None): while True: @@ -209,7 +234,7 @@ def _here_now_command_handler(channel,async=False): def kill_all_threads(): for thread in threading.enumerate(): if thread.isAlive(): - thread._Thread__stop() + stop(thread) def get_date(full=False): @@ -240,7 +265,7 @@ class DevConsole(Cmd): channels = pubnub.get_channel_array() channels_str = ",".join(channels) sl = self.channel_truncation - if len(channels) > 0 and sl > 0: + if len(channels) > int(sl) and int(sl) > 0: cho += ",".join(channels[:int(sl)]) + " " + str(len(channels) - int(sl)) + " more..." else: cho += ",".join(channels) -- cgit v1.2.3 From a38e680ae11453c2f3d5082c2ad39004366a9ad7 Mon Sep 17 00:00:00 2001 From: Devendra Date: Tue, 6 May 2014 20:08:46 +0530 Subject: fixing history api --- Pubnub.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Pubnub.py b/Pubnub.py index 75e2243..a759f75 100644 --- a/Pubnub.py +++ b/Pubnub.py @@ -504,7 +504,7 @@ class PubnubBase(object): 'subscribe_key': self.subscribe_key, 'callback': self._return_wrapped_callback(callback)}) - def here_now(self, channel, callback, error=None): + def here_now(self, channel, callback=None, error=None): """ #** #* Here Now @@ -557,6 +557,7 @@ class PubnubBase(object): params['reverse'] = reverse params['start'] = start params['end'] = end + params['auth_key'] = self.auth_key ## Get History return self._request({'urlcomponents': [ @@ -566,7 +567,7 @@ class PubnubBase(object): self.subscribe_key, 'channel', channel, - ], 'urlparams': {'auth': self.auth_key}}, + ], 'urlparams': params}, callback=self._return_wrapped_callback(callback), error=self._return_wrapped_callback(error)) @@ -1137,7 +1138,6 @@ def _requests_request(url, timeout=320): #print('timeout'); msg = str(error) return (json.dumps(msg), 0) - return (resp.text, resp.status_code) -- cgit v1.2.3 From 1b49e712e12ba833f460324b95969b162d464edf Mon Sep 17 00:00:00 2001 From: Devendra Date: Wed, 7 May 2014 12:13:17 +0530 Subject: console changes and pep8 compliance --- Pubnub.py | 17 ++++++++-------- python-tornado/examples/history.py | 5 +++-- python-tornado/examples/publish.py | 5 +++-- python-tornado/examples/subscribe.py | 11 +++++++---- python-twisted/examples/history.py | 5 +++-- python-twisted/examples/publish.py | 5 +++-- python-twisted/examples/subscribe.py | 11 +++++++---- python/examples/console.py | 38 ++++++++++++++++++++---------------- python/examples/here-now.py | 3 +-- python/examples/history.py | 5 +++-- python/examples/publish.py | 7 +++---- python/examples/subscribe.py | 11 +++++++---- 12 files changed, 69 insertions(+), 54 deletions(-) diff --git a/Pubnub.py b/Pubnub.py index a759f75..9cd33af 100644 --- a/Pubnub.py +++ b/Pubnub.py @@ -1,5 +1,5 @@ -## www.pubnub.com - PubNub Real-time push service in the cloud. +## www.pubnub.com - PubNub Real-time push service in the cloud. # coding=utf8 ## PubNub Real-time Push APIs and Notifications Framework @@ -11,7 +11,6 @@ ## ----------------------------------- - try: import json except ImportError: @@ -96,7 +95,6 @@ try: def getContext(self, hostname, port): return ClientContextFactory.getContext(self) - class PubNubPamResponse(Protocol): def __init__(self, finished): self.finished = finished @@ -104,7 +102,6 @@ try: def dataReceived(self, bytes): self.finished.callback(bytes) - class PubNubResponse(Protocol): def __init__(self, finished): self.finished = finished @@ -760,10 +757,10 @@ class PubnubCoreAsync(PubnubBase): def _invoke(func, msg=None, channel=None): if func is not None: if msg is not None and channel is not None: - func(msg,channel) + func(msg, channel) elif msg is not None: func(msg) - else : + else: func() def _invoke_connect(): @@ -779,7 +776,7 @@ class PubnubCoreAsync(PubnubBase): if chobj['disconnected'] is True: chobj['disconnected'] = False _invoke(chobj['reconnect'], chobj['name']) - + def _invoke_disconnect(): if self._channel_list_lock: with self._channel_list_lock: @@ -805,7 +802,8 @@ class PubnubCoreAsync(PubnubBase): chobj = self.subscriptions[ch] if chobj['subscribed'] is True: return chobj - channels = channels if isinstance(channels,list) else channels.split(",") + channels = channels if isinstance( + channels, list) else channels.split(",") for channel in channels: ## New Channel? if not channel in self.subscriptions or \ @@ -1125,6 +1123,8 @@ def _urllib_request_2(url, timeout=320): return (resp.read(), resp.code) s = requests.Session() + + def _requests_request(url, timeout=320): try: resp = s.get(url, timeout=timeout) @@ -1370,7 +1370,6 @@ class PubnubTwisted(PubnubCoreAsync): return abort - # PubnubTornado class PubnubTornado(PubnubCoreAsync): diff --git a/python-tornado/examples/history.py b/python-tornado/examples/history.py index da3d6a5..daf1c6e 100644 --- a/python-tornado/examples/history.py +++ b/python-tornado/examples/history.py @@ -20,13 +20,14 @@ ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) -channel = 'a' +channel = 'a' # Asynchronous usage + def callback(message): print(message) -pubnub.history(channel, count=2 , callback=callback, error=callback) +pubnub.history(channel, count=2, callback=callback, error=callback) pubnub.start() diff --git a/python-tornado/examples/publish.py b/python-tornado/examples/publish.py index 4e662fd..04e88fd 100644 --- a/python-tornado/examples/publish.py +++ b/python-tornado/examples/publish.py @@ -20,11 +20,12 @@ ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) -channel = 'hello_world' -message = 'Hello World !!!' +channel = 'hello_world' +message = 'Hello World !!!' # Asynchronous usage + def callback(message): print(message) diff --git a/python-tornado/examples/subscribe.py b/python-tornado/examples/subscribe.py index 9288836..72f0fc1 100644 --- a/python-tornado/examples/subscribe.py +++ b/python-tornado/examples/subscribe.py @@ -21,28 +21,31 @@ ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) -channel = 'a' - +channel = 'a' # Asynchronous usage - def callback(message, channel): print(message) + def error(message): print("ERROR : " + str(message)) + def connect(message): print("CONNECTED") + def reconnect(message): print("RECONNECTED") + def disconnect(message): print("DISCONNECTED") -pubnub.subscribe(channel, callback=callback, error=callback, connect=connect, reconnect=reconnect, disconnect=disconnect) +pubnub.subscribe(channel, callback=callback, error=callback, + connect=connect, reconnect=reconnect, disconnect=disconnect) pubnub.start() diff --git a/python-twisted/examples/history.py b/python-twisted/examples/history.py index 10e86b3..81974ec 100644 --- a/python-twisted/examples/history.py +++ b/python-twisted/examples/history.py @@ -20,13 +20,14 @@ ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) -channel = 'a' +channel = 'a' # Asynchronous usage + def callback(message): print(message) -pubnub.history(channel, count=2 , callback=callback, error=callback) +pubnub.history(channel, count=2, callback=callback, error=callback) pubnub.start() diff --git a/python-twisted/examples/publish.py b/python-twisted/examples/publish.py index f7b746f..13b5357 100644 --- a/python-twisted/examples/publish.py +++ b/python-twisted/examples/publish.py @@ -20,11 +20,12 @@ ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) -channel = 'hello_world' -message = 'Hello World !!!' +channel = 'hello_world' +message = 'Hello World !!!' # Asynchronous usage + def callback(message): print(message) diff --git a/python-twisted/examples/subscribe.py b/python-twisted/examples/subscribe.py index 1462a69..9c73439 100644 --- a/python-twisted/examples/subscribe.py +++ b/python-twisted/examples/subscribe.py @@ -21,28 +21,31 @@ ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) -channel = 'a' - +channel = 'a' # Asynchronous usage - def callback(message, channel): print(message) + def error(message): print("ERROR : " + str(message)) + def connect(message): print("CONNECTED") + def reconnect(message): print("RECONNECTED") + def disconnect(message): print("DISCONNECTED") -pubnub.subscribe(channel, callback=callback, error=callback, connect=connect, reconnect=reconnect, disconnect=disconnect) +pubnub.subscribe(channel, callback=callback, error=callback, + connect=connect, reconnect=reconnect, disconnect=disconnect) pubnub.start() diff --git a/python/examples/console.py b/python/examples/console.py index 084c49a..342c70f 100644 --- a/python/examples/console.py +++ b/python/examples/console.py @@ -37,12 +37,16 @@ color = Cmd() stop = None +full_date = False + def stop_2(th): th._Thread__stop() def stop_3(th): th._stop() + + def print_console_2(of,message): print >>of, message @@ -63,11 +67,20 @@ else: print_console = print_console_3 stop = stop_3 + +def get_date(): + if full_date is True: + return color.colorize(datetime.now().strftime( + '%Y-%m-%d %H:%M:%S'), "magenta") + else: + return color.colorize(datetime.now().strftime( + '%H:%M:%S'), "magenta") + + def print_ok(msg, channel=None): if msg is None: return - chstr = color.colorize("[" + datetime.now().strftime( - '%Y-%m-%d %H:%M:%S') + "] ","magenta") + chstr = color.colorize("[" + get_date() + "] ","magenta") chstr += color.colorize("[Channel : " + channel + \ "] " if channel is not None else "", "cyan") try: @@ -79,8 +92,7 @@ def print_ok(msg, channel=None): def print_error(msg, channel=None): if msg is None: return - chstr = color.colorize("[" + datetime.now().strftime( - '%Y-%m-%d %H:%M:%S') + "] ", "magenta") + chstr = color.colorize("[" + get_date() + "] ", "magenta") chstr += color.colorize("[Channel : " + channel + \ "] " if channel is not None else "", "cyan") try: @@ -237,15 +249,6 @@ def kill_all_threads(): stop(thread) -def get_date(full=False): - if full is True: - return color.colorize("[" + datetime.now().strftime( - '%Y-%m-%d %H:%M:%S') + "] ", "magenta") - else: - return color.colorize("[" + datetime.now().strftime( - '%H:%M:%S') + "] ", "magenta") - - class DevConsole(Cmd): def __init__(self): @@ -255,7 +258,6 @@ class DevConsole(Cmd): self.default_channel = None self.async = False pubnub = Pubnub("demo", "demo") - self.full_date = False self.channel_truncation = 3 self.prompt = self.get_prompt() @@ -279,7 +281,7 @@ class DevConsole(Cmd): def get_prompt(self): - prompt = get_date(self.full_date) + prompt = "[" + get_date() + "]" if self.default_channel is not None and len(self.default_channel) > 0: prompt += " [default channel: " + color.colorize(self.default_channel,"bold") + "]" @@ -352,15 +354,17 @@ class DevConsole(Cmd): self.prompt = self.get_prompt() def do_set_full_date(self, command): + global full_date """do_set_full_date Set Full Date""" - self.full_date = True + full_date = True self.prompt = self.get_prompt() def do_unset_full_date(self, command): + global full_date """do_unset_full_date Unset Full Date""" - self.full_date = False + full_date = False self.prompt = self.get_prompt() @options([make_option('-c', '--channel', action="store", help="Default Channel") diff --git a/python/examples/here-now.py b/python/examples/here-now.py index f573389..d03a110 100644 --- a/python/examples/here-now.py +++ b/python/examples/here-now.py @@ -23,13 +23,12 @@ pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, channel = 'hello_world' - # Synchronous usage - print pubnub.here_now(channel) # Asynchronous usage + def callback(message): print(message) diff --git a/python/examples/history.py b/python/examples/history.py index 3d6addf..7f7466b 100644 --- a/python/examples/history.py +++ b/python/examples/history.py @@ -20,7 +20,7 @@ ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) -channel = 'a' +channel = 'a' # Synchronous usage @@ -28,7 +28,8 @@ print pubnub.history(channel, count=2) # Asynchronous usage + def callback(message): print(message) -pubnub.history(channel, count=2 , callback=callback, error=callback) +pubnub.history(channel, count=2, callback=callback, error=callback) diff --git a/python/examples/publish.py b/python/examples/publish.py index 029c17a..a1b913b 100644 --- a/python/examples/publish.py +++ b/python/examples/publish.py @@ -20,17 +20,16 @@ ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False ## ----------------------------------------------------------------------- pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) -channel = 'hello_world' -message = 'Hello World !!!' - +channel = 'hello_world' +message = 'Hello World !!!' # Synchronous usage - print pubnub.publish(channel, message) # Asynchronous usage + def callback(message): print(message) diff --git a/python/examples/subscribe.py b/python/examples/subscribe.py index a410297..6cf93b1 100644 --- a/python/examples/subscribe.py +++ b/python/examples/subscribe.py @@ -21,26 +21,29 @@ ssl_on = len(sys.argv) > 5 and bool(sys.argv[5]) or False pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key, secret_key=secret_key, cipher_key=cipher_key, ssl_on=ssl_on) -channel = 'a' - +channel = 'a' # Asynchronous usage - def callback(message, channel): print(message) + def error(message): print("ERROR : " + str(message)) + def connect(message): print("CONNECTED") + def reconnect(message): print("RECONNECTED") + def disconnect(message): print("DISCONNECTED") -pubnub.subscribe(channel, callback=callback, error=callback, connect=connect, reconnect=reconnect, disconnect=disconnect) +pubnub.subscribe(channel, callback=callback, error=callback, + connect=connect, reconnect=reconnect, disconnect=disconnect) -- cgit v1.2.3 From 4ab1fa41e1a10efc88909bceb78222ffb406145a Mon Sep 17 00:00:00 2001 From: Devendra Date: Wed, 7 May 2014 13:01:21 +0530 Subject: pep 8 compliance --- Pubnub.py | 6 +- python/examples/console.py | 314 +++++++++++++++++++++++++++------------------ 2 files changed, 192 insertions(+), 128 deletions(-) diff --git a/Pubnub.py b/Pubnub.py index 9cd33af..ee9371a 100644 --- a/Pubnub.py +++ b/Pubnub.py @@ -873,13 +873,15 @@ class PubnubCoreAsync(PubnubBase): if ch[1] in self.subscriptions: chobj = self.subscriptions[ch[1]] _invoke(chobj['callback'], - self.decrypt(response_list[ch[0]]), chobj['name']) + self.decrypt(response_list[ch[0]]), + chobj['name']) else: response_list = response[0] chobj = _get_channel() for r in response_list: if chobj: - _invoke(chobj['callback'], self.decrypt(r), chobj['name']) + _invoke(chobj['callback'], self.decrypt(r), + chobj['name']) _connect() diff --git a/python/examples/console.py b/python/examples/console.py index 342c70f..674b6d4 100644 --- a/python/examples/console.py +++ b/python/examples/console.py @@ -22,6 +22,7 @@ import rlcompleter historyPath = os.path.expanduser("~/.pubnub_console_history") + def save_history(historyPath=historyPath): import readline readline.write_history_file(historyPath) @@ -31,7 +32,7 @@ if os.path.exists(historyPath): atexit.register(save_history) -of=sys.stdout +of = sys.stdout color = Cmd() @@ -39,18 +40,20 @@ stop = None full_date = False + def stop_2(th): th._Thread__stop() + def stop_3(th): th._stop() +def print_console_2(of, message): + print >>of, message -def print_console_2(of,message): - print >>of, message -def print_console_3(of,message): +def print_console_3(of, message): of.write(message) of.write("\n") @@ -72,45 +75,49 @@ def get_date(): if full_date is True: return color.colorize(datetime.now().strftime( '%Y-%m-%d %H:%M:%S'), "magenta") - else: + else: return color.colorize(datetime.now().strftime( - '%H:%M:%S'), "magenta") + '%H:%M:%S'), "magenta") def print_ok(msg, channel=None): if msg is None: return - chstr = color.colorize("[" + get_date() + "] ","magenta") - chstr += color.colorize("[Channel : " + channel + \ - "] " if channel is not None else "", "cyan") + chstr = color.colorize("[" + get_date() + "] ", "magenta") + chstr += color.colorize("[Channel : " + channel + + "] " if channel is not None else "", "cyan") try: - print_console(of, (chstr + color.colorize(str(msg),"green"))) + print_console(of, (chstr + color.colorize(str(msg), "green"))) except UnicodeEncodeError as e: print_console(of, (msg)) of.flush() + def print_error(msg, channel=None): if msg is None: return chstr = color.colorize("[" + get_date() + "] ", "magenta") - chstr += color.colorize("[Channel : " + channel + \ - "] " if channel is not None else "", "cyan") + chstr += color.colorize("[Channel : " + channel + + "] " if channel is not None else "", "cyan") try: - print_console(of, (chstr + color.colorize(color.colorize(str(msg),"red"),"bold"))) + print_console(of, (chstr + color.colorize(color.colorize( + str(msg), "red"), "bold"))) except UnicodeEncodeError as e: print_console(of, (msg)) of.flush() + class DefaultPubnub(object): - def handlerFunctionClosure(self,name): - def handlerFunction(*args,**kwargs): - print_error("Pubnub not initialized. Use init command to initialize") + def handlerFunctionClosure(self, name): + def handlerFunction(*args, **kwargs): + print_error("Pubnub not initialized." + + "Use init command to initialize") return handlerFunction - def __getattr__(self,name): - return self.handlerFunctionClosure(name) -pubnub=DefaultPubnub() + def __getattr__(self, name): + return self.handlerFunctionClosure(name) +pubnub = DefaultPubnub() def kill_all_threads(): @@ -118,6 +125,7 @@ def kill_all_threads(): if thread.isAlive(): stop(thread) + def get_input(message, t=None): while True: try: @@ -148,21 +156,24 @@ def get_input(message, t=None): except ValueError: print_error("Invalid input : " + command) -def _publish_command_handler(channel, message,async=False): + +def _publish_command_handler(channel, message, async=False): def _callback(r): print_ok(r) def _error(r): print_error(r) - print_ok(pubnub.publish(channel, message, _callback if async is True else None, _error if async is True else None)) + print_ok(pubnub.publish(channel, message, + _callback if async is True else None, + _error if async is True else None)) def _subscribe_command_handler(channel): - def _callback(r,ch): + def _callback(r, ch): print_ok(r, ch) - def _error(r,ch=None): + def _error(r, ch=None): print_error(r, ch if ch is not None else channel) def _disconnect(r): @@ -174,7 +185,8 @@ def _subscribe_command_handler(channel): def _connect(r): print_error("CONNECTED", r) - pubnub.subscribe(channel, _callback, _error,connect=_connect, disconnect=_disconnect, reconnect=_reconnect) + pubnub.subscribe(channel, _callback, _error, connect=_connect, + disconnect=_disconnect, reconnect=_reconnect) def _unsubscribe_command_handler(channels): @@ -184,7 +196,7 @@ def _unsubscribe_command_handler(channels): def _error(r): print_error(r) - if not isinstance(channels,list): + if not isinstance(channels, list): ch = [] ch.append(channels) channels = ch @@ -193,54 +205,64 @@ def _unsubscribe_command_handler(channels): pubnub.unsubscribe(channel) -def _grant_command_handler(channel, auth_key, read, write, ttl,async=False): +def _grant_command_handler(channel, auth_key, read, write, ttl, async=False): def _callback(r): print_ok(r) def _error(r): print_error(r) - print_ok(pubnub.grant(channel, auth_key, read, write, ttl, _callback if async is True else None, _error if async is True else None)) + print_ok(pubnub.grant(channel, auth_key, + read, write, ttl, + _callback if async is True else None, + _error if async is True else None)) -def _revoke_command_handler(channel, auth_key, ttl,async=False): +def _revoke_command_handler(channel, auth_key, ttl, async=False): def _callback(r): print_ok(r) def _error(r): print_error(r) - print_ok(pubnub.revoke(channel, auth_key, ttl, _callback if async is True else None, _error if async is True else None)) + print_ok(pubnub.revoke(channel, auth_key, ttl, + _callback if async is True else None, + _error if async is True else None)) -def _audit_command_handler(channel, auth_key,async=False): +def _audit_command_handler(channel, auth_key, async=False): def _callback(r): print_ok(r) def _error(r): print_error(r) - print_ok(pubnub.audit(channel, auth_key, _callback if async is True else None, _error if async is True else None)) + print_ok(pubnub.audit(channel, auth_key, + _callback if async is True else None, + _error if async is True else None)) -def _history_command_handler(channel, count,async=False): +def _history_command_handler(channel, count, async=False): def _callback(r): print_ok(r) def _error(r): print_error(r) - print_ok(pubnub.history(channel, count, _callback if async is True else None, _error if async is True else None)) + print_ok(pubnub.history(channel, count, + _callback if async is True else None, + _error if async is True else None)) -def _here_now_command_handler(channel,async=False): +def _here_now_command_handler(channel, async=False): def _callback(r): print_ok(r) def _error(r): print_error(r) - print_ok(pubnub.here_now(channel, _callback if async is True else None, _error if async is True else None)) + print_ok(pubnub.here_now(channel, _callback if async is True else None, + _error if async is True else None)) def kill_all_threads(): @@ -250,42 +272,44 @@ def kill_all_threads(): class DevConsole(Cmd): - + def __init__(self): Cmd.__init__(self) global pubnub - self.intro = "For Help type ? or help . To quit/exit type exit" ## defaults to None + self.intro = "For Help type ? or help . " + + "To quit/exit type exit" self.default_channel = None self.async = False pubnub = Pubnub("demo", "demo") self.channel_truncation = 3 self.prompt = self.get_prompt() - def get_channel_origin(self): cho = " [" channels = pubnub.get_channel_array() channels_str = ",".join(channels) sl = self.channel_truncation if len(channels) > int(sl) and int(sl) > 0: - cho += ",".join(channels[:int(sl)]) + " " + str(len(channels) - int(sl)) + " more..." + cho += ",".join(channels[:int(sl)]) + " " + str( + len(channels) - int(sl)) + " more..." else: cho += ",".join(channels) if len(channels) > 0: - cho = color.colorize(cho,"bold") + "@" + cho = color.colorize(cho, "bold") + "@" origin = pubnub.get_origin().split("://")[1] - origin += color.colorize(" (SSL)","green") if pubnub.get_origin().split("://")[0] == "https" else "" - return cho + color.colorize(origin,"blue") + "] > " - + origin += color.colorize(" (SSL)", "green") if pubnub.get_origin( + ).split("://")[0] == "https" else "" + return cho + color.colorize(origin, "blue") + "] > " def get_prompt(self): prompt = "[" + get_date() + "]" if self.default_channel is not None and len(self.default_channel) > 0: - prompt += " [default channel: " + color.colorize(self.default_channel,"bold") + "]" - + prompt += " [default channel: " + color.colorize( + self.default_channel, "bold") + "]" + prompt += self.get_channel_origin() return prompt @@ -295,7 +319,8 @@ class DevConsole(Cmd): def emptyline(self): print('empty line') - self.prompt = get_date() + " [" + color.colorize(pubnub.get_origin(),"blue") + "] > " + self.prompt = get_date() + " [" + color.colorize( + pubnub.get_origin(), "blue") + "] > " def cmdloop_with_keyboard_interrupt(self): try: @@ -305,28 +330,35 @@ class DevConsole(Cmd): sys.stdout.write('\n') kill_all_threads() - @options([make_option('-p', '--publish-key', action="store", default="demo", help="Publish Key"), - make_option('-s', '--subscribe-key', action="store", default="demo", help="Subscribe Key"), - make_option('-k', '--secret-key', action="store", default="demo", help="cipher Key"), - make_option('-c', '--cipher-key', action="store", default="", help="Secret Key"), - make_option('-a', '--auth-key', action="store", default=None, help="Auth Key"), - make_option('--ssl-on', dest='ssl', action='store_true', default=False, help="SSL Enabled ?"), - make_option('-o', '--origin', action="store", default="pubsub.pubnub.com", help="Origin"), - make_option('-u', '--uuid', action="store", default=None, help="UUID") - ]) + @options([make_option('-p', '--publish-key', action="store", + default="demo", help="Publish Key"), + make_option('-s', '--subscribe-key', action="store", + default="demo", help="Subscribe Key"), + make_option('-k', '--secret-key', action="store", + default="demo", help="cipher Key"), + make_option('-c', '--cipher-key', action="store", + default="", help="Secret Key"), + make_option('-a', '--auth-key', action="store", + default=None, help="Auth Key"), + make_option('--ssl-on', dest='ssl', action='store_true', + default=False, help="SSL Enabled ?"), + make_option('-o', '--origin', action="store", + default="pubsub.pubnub.com", help="Origin"), + make_option('-u', '--uuid', action="store", + default=None, help="UUID") + ]) def do_init(self, command, opts): global pubnub pubnub = Pubnub(opts.publish_key, - opts.subscribe_key, - opts.secret_key, - opts.cipher_key, - opts.auth_key, - opts.ssl, - opts.origin, - opts.uuid) + opts.subscribe_key, + opts.secret_key, + opts.cipher_key, + opts.auth_key, + opts.ssl, + opts.origin, + opts.uuid) self.prompt = self.get_prompt() - def do_set_sync(self, command): """unset_async Unset Async mode""" @@ -337,8 +369,9 @@ class DevConsole(Cmd): Set Async mode""" self.async = True - @options([make_option('-n', '--count', action="store", default=3, help="Number of channels on prompt") - ]) + @options([make_option('-n', '--count', action="store", + default=3, help="Number of channels on prompt") + ]) def do_set_channel_truncation(self, command, opts): """set_channel_truncation Set Channel Truncation""" @@ -367,8 +400,9 @@ class DevConsole(Cmd): full_date = False self.prompt = self.get_prompt() - @options([make_option('-c', '--channel', action="store", help="Default Channel") - ]) + @options([make_option('-c', '--channel', + action="store", help="Default Channel") + ]) def do_set_default_channel(self, command, opts): if opts.channel is None: @@ -377,42 +411,48 @@ class DevConsole(Cmd): self.default_channel = opts.channel self.prompt = self.get_prompt() - @options([make_option('-f', '--file', action="store", default="./pubnub-console.log", help="Output file") - ]) + @options([make_option('-f', '--file', action="store", + default="./pubnub-console.log", help="Output file") + ]) def do_set_output_file(self, command, opts): global of try: - of = file(opts.file,'w+') + of = file(opts.file, 'w+') except IOError as e: print_error("Could not set output file. " + e.reason) - - @options([make_option('-c', '--channel', action="store", help="Channel for here now data") - ]) + @options([make_option('-c', '--channel', action="store", + help="Channel for here now data") + ]) def do_here_now(self, command, opts): - opts.channel = self.default_channel if opts.channel is None else opts.channel + opts.channel = self.default_channel \ + if opts.channel is None else opts.channel if opts.channel is None: print_error("Missing channel") return - _here_now_command_handler(opts.channel,async=self.async) + _here_now_command_handler(opts.channel, async=self.async) - @options([make_option('-c', '--channel', action="store", help="Channel for history data"), - make_option('-n', '--count', action="store", default=5, help="Number of messages") - ]) + @options([make_option('-c', '--channel', action="store", + help="Channel for history data"), + make_option('-n', '--count', action="store", + default=5, help="Number of messages") + ]) def do_get_history(self, command, opts): - opts.channel = self.default_channel if opts.channel is None else opts.channel + opts.channel = self.default_channel \ + if opts.channel is None else opts.channel if opts.channel is None: print_error("Missing channel") return - _history_command_handler(opts.channel, opts.count,async=self.async) - + _history_command_handler(opts.channel, opts.count, async=self.async) - @options([make_option('-c', '--channel', action="store", help="Channel on which to publish") - ]) + @options([make_option('-c', '--channel', action="store", + help="Channel on which to publish") + ]) def do_publish(self, command, opts): - opts.channel = self.default_channel if opts.channel is None else opts.channel + opts.channel = self.default_channel \ + if opts.channel is None else opts.channel if opts.channel is None: print_error("Missing channel") return @@ -426,61 +466,81 @@ class DevConsole(Cmd): except ValueError as ve: message = str(command) - _publish_command_handler(opts.channel,message,async=self.async) - - @options([make_option('-c', '--channel', action="store", help="Channel on which to grant"), - make_option('-a', '--auth-key', dest="auth_key", action="store", - help="Auth Key"), - make_option('-r', '--read-enabled', dest='read', action='store_true', default=False, help="Read ?"), - make_option('-w', '--write-enabled', dest='write', action='store_true', default=False, help="Write ?"), - make_option('-t', '--ttl', action="store", default=5, help="TTL") - ]) + _publish_command_handler(opts.channel, message, async=self.async) + + @options([make_option('-c', '--channel', action="store", + help="Channel on which to grant"), + make_option('-a', '--auth-key', dest="auth_key", + action="store", + help="Auth Key"), + make_option('-r', '--read-enabled', dest='read', + action='store_true', + default=False, help="Read ?"), + make_option('-w', '--write-enabled', dest='write', + action='store_true', + default=False, help="Write ?"), + make_option('-t', '--ttl', action="store", + default=5, help="TTL") + ]) def do_grant(self, command, opts): - opts.channel = self.default_channel if opts.channel is None else opts.channel + opts.channel = self.default_channel \ + if opts.channel is None else opts.channel if opts.channel is None: print_error("Missing channel") return - opts.auth_key = pubnub.auth_key if opts.auth_key is None else opts.auth_key + opts.auth_key = pubnub.auth_key \ + if opts.auth_key is None else opts.auth_key - _grant_command_handler(opts.channel,opts.auth_key, opts.read, opts.write, opts.ttl,async=self.async) + _grant_command_handler(opts.channel, opts.auth_key, + opts.read, opts.write, + opts.ttl, async=self.async) - @options([make_option('-c', '--channel', action="store", help="Channel on which to revoke"), - make_option('-a', '--auth-key', dest="auth_key", action="store", - help="Auth Key"), - make_option('-t', '--ttl', action="store", default=5, help="TTL") - ]) + @options([make_option('-c', '--channel', action="store", + help="Channel on which to revoke"), + make_option('-a', '--auth-key', dest="auth_key", action="store", + help="Auth Key"), + make_option('-t', '--ttl', action="store", + default=5, help="TTL") + ]) def do_revoke(self, command, opts): - opts.channel = self.default_channel if opts.channel is None else opts.channel + opts.channel = self.default_channel \ + if opts.channel is None else opts.channel if opts.channel is None: print_error("Missing channel") return - opts.auth_key = pubnub.auth_key if opts.auth_key is None else opts.auth_key + opts.auth_key = pubnub.auth_key \ + if opts.auth_key is None else opts.auth_key - _revoke_command_handler(opts.channel,opts.auth_key, opts.ttl,async=self.async) + _revoke_command_handler( + opts.channel, opts.auth_key, opts.ttl, async=self.async) - @options([make_option('-c', '--channel', action="store", help="Channel on which to revoke"), - make_option('-a', '--auth-key', dest="auth_key", action="store", - help="Auth Key") - ]) + @options([make_option('-c', '--channel', action="store", + help="Channel on which to revoke"), + make_option('-a', '--auth-key', dest="auth_key", action="store", + help="Auth Key") + ]) def do_audit(self, command, opts): - opts.channel = self.default_channel if opts.channel is None else opts.channel + opts.channel = self.default_channel \ + if opts.channel is None else opts.channel if opts.channel is None: print_error("Missing channel") return - opts.auth_key = pubnub.auth_key if opts.auth_key is None else opts.auth_key - - _audit_command_handler(opts.channel, opts.auth_key,async=self.async) + opts.auth_key = pubnub.auth_key \ + if opts.auth_key is None else opts.auth_key + _audit_command_handler(opts.channel, opts.auth_key, async=self.async) - @options([make_option('-c', '--channel', action="store", help="Channel for unsubscribe"), - make_option('-a', '--all', action="store_true", dest="all", - default=False, help="Unsubscribe from all channels") - ]) + @options([make_option('-c', '--channel', action="store", + help="Channel for unsubscribe"), + make_option('-a', '--all', action="store_true", dest="all", + default=False, help="Unsubscribe from all channels") + ]) def do_unsubscribe(self, command, opts): - opts.channel = self.default_channel if opts.channel is None else opts.channel + opts.channel = self.default_channel \ + if opts.channel is None else opts.channel if (opts.all is True): opts.channel = pubnub.get_channel_array() if opts.channel is None: @@ -489,13 +549,15 @@ class DevConsole(Cmd): _unsubscribe_command_handler(opts.channel) self.prompt = self.get_prompt() - - @options([make_option('-c', '--channel', action="store", help="Channel for subscribe"), - make_option('-g', '--get-channel-list', action="store_true", dest="get", - default=False, help="Get susbcribed channel list") - ]) + @options([make_option('-c', '--channel', action="store", + help="Channel for subscribe"), + make_option('-g', '--get-channel-list', action="store_true", + dest="get", + default=False, help="Get susbcribed channel list") + ]) def do_subscribe(self, command, opts): - opts.channel = self.default_channel if opts.channel is None else opts.channel + opts.channel = self.default_channel \ + if opts.channel is None else opts.channel if opts is None: print_error("Missing argument") return @@ -518,10 +580,10 @@ class DevConsole(Cmd): def handler(self, signum, frame): kill_all_threads() + def main(): app = DevConsole() app.cmdloop_with_keyboard_interrupt() - -if __name__ == "__main__": - main() +if __name__ == "__main__": + main() -- cgit v1.2.3 From 8e3ee358718686a2292b555e1184eb817b2a051a Mon Sep 17 00:00:00 2001 From: Devendra Date: Wed, 7 May 2014 17:16:11 +0530 Subject: added presence option to subscribe command --- python/examples/console.py | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/python/examples/console.py b/python/examples/console.py index 674b6d4..3d7ba38 100644 --- a/python/examples/console.py +++ b/python/examples/console.py @@ -203,6 +203,7 @@ def _unsubscribe_command_handler(channels): for channel in channels: pubnub.unsubscribe(channel) + pubnub.unsubscribe(channel + '-pnpres') def _grant_command_handler(channel, auth_key, read, write, ttl, async=False): @@ -271,13 +272,23 @@ def kill_all_threads(): stop(thread) -class DevConsole(Cmd): +def get_channel_array(): + channels = pubnub.get_channel_array() + + for channel in channels: + if "-pnpres" in channel: + i = channels.index(channel.split("-pnpres")[0]) + channels[i] = channels[i] + color.colorize("(P)", "blue") + channels.remove(channel) + return channels + +class DevConsole(Cmd): def __init__(self): Cmd.__init__(self) global pubnub - self.intro = "For Help type ? or help . " + - "To quit/exit type exit" + self.intro = "For Help type ? or help . " + \ + "To quit/exit type exit" self.default_channel = None self.async = False pubnub = Pubnub("demo", "demo") @@ -286,7 +297,7 @@ class DevConsole(Cmd): def get_channel_origin(self): cho = " [" - channels = pubnub.get_channel_array() + channels = get_channel_array() channels_str = ",".join(channels) sl = self.channel_truncation if len(channels) > int(sl) and int(sl) > 0: @@ -318,7 +329,6 @@ class DevConsole(Cmd): return line def emptyline(self): - print('empty line') self.prompt = get_date() + " [" + color.colorize( pubnub.get_origin(), "blue") + "] > " @@ -553,7 +563,10 @@ class DevConsole(Cmd): help="Channel for subscribe"), make_option('-g', '--get-channel-list', action="store_true", dest="get", - default=False, help="Get susbcribed channel list") + default=False, help="Get susbcribed channel list"), + make_option('-p', '--presence', action="store_true", + dest="presence", + default=False, help="Presence events ?") ]) def do_subscribe(self, command, opts): opts.channel = self.default_channel \ @@ -565,8 +578,11 @@ class DevConsole(Cmd): if opts.channel is not None: _subscribe_command_handler(opts.channel) + if opts.presence is True: + _subscribe_command_handler(opts.channel + '-pnpres') + if opts.get is True: - print_ok(pubnub.get_channel_array()) + print_ok(get_channel_array()) self.prompt = self.get_prompt() def do_exit(self, args): -- cgit v1.2.3 From 4a14f1f57546a7ccb24b9ced41f5743c3f49f96e Mon Sep 17 00:00:00 2001 From: Devendra Date: Wed, 7 May 2014 18:11:35 +0530 Subject: check for channel length 0 in subscribe --- Pubnub.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Pubnub.py b/Pubnub.py index ee9371a..4ae27ab 100644 --- a/Pubnub.py +++ b/Pubnub.py @@ -806,8 +806,9 @@ class PubnubCoreAsync(PubnubBase): channels, list) else channels.split(",") for channel in channels: ## New Channel? - if not channel in self.subscriptions or \ - self.subscriptions[channel]['subscribed'] is False: + if len(channel) > 0 and \ + (not channel in self.subscriptions or + self.subscriptions[channel]['subscribed'] is False): with self._channel_list_lock: self.subscriptions[channel] = { 'name': channel, @@ -1131,12 +1132,14 @@ def _requests_request(url, timeout=320): try: resp = s.get(url, timeout=timeout) except requests.exceptions.HTTPError as http_error: + print http_error resp = http_error except requests.exceptions.ConnectionError as error: + print error msg = str(error) return (json.dumps(msg), 0) except requests.exceptions.Timeout as error: - #print(error); + print(error) #print('timeout'); msg = str(error) return (json.dumps(msg), 0) -- cgit v1.2.3 From 20f55f6d739451629c4d918319362962bee5a141 Mon Sep 17 00:00:00 2001 From: Devendra Date: Wed, 7 May 2014 18:21:27 +0530 Subject: adding presence channel option to grant and revoke --- python/examples/console.py | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/python/examples/console.py b/python/examples/console.py index 3d7ba38..7798340 100644 --- a/python/examples/console.py +++ b/python/examples/console.py @@ -328,9 +328,8 @@ class DevConsole(Cmd): self.prompt = self.get_prompt() return line - def emptyline(self): - self.prompt = get_date() + " [" + color.colorize( - pubnub.get_origin(), "blue") + "] > " + #def emptyline(self): + # self.prompt = self.get_prompt() def cmdloop_with_keyboard_interrupt(self): try: @@ -490,7 +489,10 @@ class DevConsole(Cmd): action='store_true', default=False, help="Write ?"), make_option('-t', '--ttl', action="store", - default=5, help="TTL") + default=5, help="TTL"), + make_option('-p', '--presence', action="store_true", + dest="presence", + default=False, help="Grant on presence channel ?") ]) def do_grant(self, command, opts): opts.channel = self.default_channel \ @@ -506,12 +508,20 @@ class DevConsole(Cmd): opts.read, opts.write, opts.ttl, async=self.async) + if opts.presence is True: + _grant_command_handler(opts.channel + '-pnpres', opts.auth_key, + opts.read, opts.write, + opts.ttl, async=self.async) + @options([make_option('-c', '--channel', action="store", help="Channel on which to revoke"), make_option('-a', '--auth-key', dest="auth_key", action="store", help="Auth Key"), make_option('-t', '--ttl', action="store", - default=5, help="TTL") + default=5, help="TTL"), + make_option('-p', '--presence', action="store_true", + dest="presence", + default=False, help="Revoke on presence channel ?") ]) def do_revoke(self, command, opts): opts.channel = self.default_channel \ @@ -526,6 +536,11 @@ class DevConsole(Cmd): _revoke_command_handler( opts.channel, opts.auth_key, opts.ttl, async=self.async) + if opts.presence is True: + _revoke_command_handler( + opts.channel + '-pnpres', opts.auth_key, + opts.ttl, async=self.async) + @options([make_option('-c', '--channel', action="store", help="Channel on which to revoke"), make_option('-a', '--auth-key', dest="auth_key", action="store", @@ -589,12 +604,12 @@ class DevConsole(Cmd): kill_all_threads() return -1 - def do_EOF(self, args): - kill_all_threads() - return self.do_exit(args) + #def do_EOF(self, args): + # kill_all_threads() + # return self.do_exit(args) - def handler(self, signum, frame): - kill_all_threads() + #def handler(self, signum, frame): + # kill_all_threads() def main(): -- cgit v1.2.3 From 09dbc7589b35963be1835ed58dcfd09d4d5c3ccc Mon Sep 17 00:00:00 2001 From: Devendra Date: Thu, 8 May 2014 04:08:48 +0530 Subject: adding packaging for pushing to pip --- dist/pubnub-3.5.0-beta.tar.gz | Bin 0 -> 9447 bytes .../dist/pubnub-console-3.5.0-beta.tar.gz | Bin 0 -> 4627 bytes python/examples/pubnub-console/pubnub-console | 622 +++++++++++++++++++++ python/examples/pubnub-console/setup.py | 26 + setup.py | 26 + 5 files changed, 674 insertions(+) create mode 100644 dist/pubnub-3.5.0-beta.tar.gz create mode 100644 python/examples/pubnub-console/dist/pubnub-console-3.5.0-beta.tar.gz create mode 100644 python/examples/pubnub-console/pubnub-console create mode 100644 python/examples/pubnub-console/setup.py create mode 100644 setup.py diff --git a/dist/pubnub-3.5.0-beta.tar.gz b/dist/pubnub-3.5.0-beta.tar.gz new file mode 100644 index 0000000..6201683 Binary files /dev/null and b/dist/pubnub-3.5.0-beta.tar.gz differ diff --git a/python/examples/pubnub-console/dist/pubnub-console-3.5.0-beta.tar.gz b/python/examples/pubnub-console/dist/pubnub-console-3.5.0-beta.tar.gz new file mode 100644 index 0000000..39540f6 Binary files /dev/null and b/python/examples/pubnub-console/dist/pubnub-console-3.5.0-beta.tar.gz differ diff --git a/python/examples/pubnub-console/pubnub-console b/python/examples/pubnub-console/pubnub-console new file mode 100644 index 0000000..a12c77f --- /dev/null +++ b/python/examples/pubnub-console/pubnub-console @@ -0,0 +1,622 @@ +#!/usr/bin/env python + +## 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/ + + +import sys +from Pubnub import PubnubAsync as Pubnub +import threading +from datetime import datetime + +from cmd2 import Cmd, make_option, options, Cmd2TestCase +import optparse +import json + +import atexit +import os +import readline +import rlcompleter + +historyPath = os.path.expanduser("~/.pubnub_console_history") + + +def save_history(historyPath=historyPath): + import readline + readline.write_history_file(historyPath) + +if os.path.exists(historyPath): + readline.read_history_file(historyPath) + +atexit.register(save_history) + +of = sys.stdout + +color = Cmd() + +stop = None + +full_date = False + + +def stop_2(th): + th._Thread__stop() + + +def stop_3(th): + th._stop() + + +def print_console_2(of, message): + print >>of, message + + +def print_console_3(of, message): + of.write(message) + of.write("\n") + +print_console = None + +if type(sys.version_info) is tuple: + print_console = print_console_2 + stop = stop_2 +else: + if sys.version_info.major == 2: + print_console = print_console_2 + stop = stop_2 + else: + print_console = print_console_3 + stop = stop_3 + + +def get_date(): + if full_date is True: + return color.colorize(datetime.now().strftime( + '%Y-%m-%d %H:%M:%S'), "magenta") + else: + return color.colorize(datetime.now().strftime( + '%H:%M:%S'), "magenta") + + +def print_ok(msg, channel=None): + if msg is None: + return + chstr = color.colorize("[" + get_date() + "] ", "magenta") + chstr += color.colorize("[Channel : " + channel + + "] " if channel is not None else "", "cyan") + try: + print_console(of, (chstr + color.colorize(str(msg), "green"))) + except UnicodeEncodeError as e: + print_console(of, (msg)) + of.flush() + + +def print_error(msg, channel=None): + if msg is None: + return + chstr = color.colorize("[" + get_date() + "] ", "magenta") + chstr += color.colorize("[Channel : " + channel + + "] " if channel is not None else "", "cyan") + try: + print_console(of, (chstr + color.colorize(color.colorize( + str(msg), "red"), "bold"))) + except UnicodeEncodeError as e: + print_console(of, (msg)) + of.flush() + + +class DefaultPubnub(object): + def handlerFunctionClosure(self, name): + def handlerFunction(*args, **kwargs): + print_error("Pubnub not initialized." + + "Use init command to initialize") + return handlerFunction + + def __getattr__(self, name): + return self.handlerFunctionClosure(name) + +pubnub = DefaultPubnub() + + +def kill_all_threads(): + for thread in threading.enumerate(): + if thread.isAlive(): + stop(thread) + + +def get_input(message, t=None): + while True: + try: + try: + command = raw_input(message) + except NameError: + command = input(message) + except KeyboardInterrupt: + return None + + command = command.strip() + + if command is None or len(command) == 0: + raise ValueError + + if t is not None and t == bool: + valid = ["True", "true", "1", 1, "y", "Y", "yes", "Yes", "YES"] + if command in valid: + return True + else: + return False + if t is not None: + command = t(command) + else: + command = eval("'" + command + "'") + + return command + except ValueError: + print_error("Invalid input : " + command) + + +def _publish_command_handler(channel, message, async=False): + def _callback(r): + print_ok(r) + + def _error(r): + print_error(r) + print_ok(pubnub.publish(channel, message, + _callback if async is True else None, + _error if async is True else None)) + + +def _subscribe_command_handler(channel): + + def _callback(r, ch): + print_ok(r, ch) + + def _error(r, ch=None): + print_error(r, ch if ch is not None else channel) + + def _disconnect(r): + print_error("DISCONNECTED", r) + + def _reconnect(r): + print_error("RECONNECTED", r) + + def _connect(r): + print_error("CONNECTED", r) + + pubnub.subscribe(channel, _callback, _error, connect=_connect, + disconnect=_disconnect, reconnect=_reconnect) + + +def _unsubscribe_command_handler(channels): + + def _callback(r): + print_ok(r) + + def _error(r): + print_error(r) + if not isinstance(channels, list): + ch = [] + ch.append(channels) + channels = ch + + for channel in channels: + pubnub.unsubscribe(channel) + pubnub.unsubscribe(channel + '-pnpres') + + +def _grant_command_handler(channel, auth_key, read, write, ttl, async=False): + def _callback(r): + print_ok(r) + + def _error(r): + print_error(r) + + print_ok(pubnub.grant(channel, auth_key, + read, write, ttl, + _callback if async is True else None, + _error if async is True else None)) + + +def _revoke_command_handler(channel, auth_key, ttl, async=False): + def _callback(r): + print_ok(r) + + def _error(r): + print_error(r) + + print_ok(pubnub.revoke(channel, auth_key, ttl, + _callback if async is True else None, + _error if async is True else None)) + + +def _audit_command_handler(channel, auth_key, async=False): + def _callback(r): + print_ok(r) + + def _error(r): + print_error(r) + + print_ok(pubnub.audit(channel, auth_key, + _callback if async is True else None, + _error if async is True else None)) + + +def _history_command_handler(channel, count, async=False): + def _callback(r): + print_ok(r) + + def _error(r): + print_error(r) + + print_ok(pubnub.history(channel, count, + _callback if async is True else None, + _error if async is True else None)) + + +def _here_now_command_handler(channel, async=False): + def _callback(r): + print_ok(r) + + def _error(r): + print_error(r) + + print_ok(pubnub.here_now(channel, _callback if async is True else None, + _error if async is True else None)) + + +def kill_all_threads(): + for thread in threading.enumerate(): + if thread.isAlive(): + stop(thread) + + +def get_channel_array(): + channels = pubnub.get_channel_array() + + for channel in channels: + if "-pnpres" in channel: + i = channels.index(channel.split("-pnpres")[0]) + channels[i] = channels[i] + color.colorize("(P)", "blue") + channels.remove(channel) + return channels + + +class DevConsole(Cmd): + def __init__(self): + Cmd.__init__(self) + global pubnub + self.intro = "For Help type ? or help . " + \ + "To quit/exit type exit" + self.default_channel = None + self.async = False + pubnub = Pubnub("demo", "demo") + self.channel_truncation = 3 + self.prompt = self.get_prompt() + + def get_channel_origin(self): + cho = " [" + channels = get_channel_array() + channels_str = ",".join(channels) + sl = self.channel_truncation + if len(channels) > int(sl) and int(sl) > 0: + cho += ",".join(channels[:int(sl)]) + " " + str( + len(channels) - int(sl)) + " more..." + else: + cho += ",".join(channels) + + if len(channels) > 0: + cho = color.colorize(cho, "bold") + "@" + + origin = pubnub.get_origin().split("://")[1] + origin += color.colorize(" (SSL)", "green") if pubnub.get_origin( + ).split("://")[0] == "https" else "" + return cho + color.colorize(origin, "blue") + "] > " + + def get_prompt(self): + prompt = "[" + get_date() + "]" + + if self.default_channel is not None and len(self.default_channel) > 0: + prompt += " [default channel: " + color.colorize( + self.default_channel, "bold") + "]" + + prompt += self.get_channel_origin() + return prompt + + def precmd(self, line): + self.prompt = self.get_prompt() + return line + + #def emptyline(self): + # self.prompt = self.get_prompt() + + def cmdloop_with_keyboard_interrupt(self): + try: + self.cmdloop() + except KeyboardInterrupt as e: + pass + sys.stdout.write('\n') + kill_all_threads() + + @options([make_option('-p', '--publish-key', action="store", + default="demo", help="Publish Key"), + make_option('-s', '--subscribe-key', action="store", + default="demo", help="Subscribe Key"), + make_option('-k', '--secret-key', action="store", + default="demo", help="cipher Key"), + make_option('-c', '--cipher-key', action="store", + default="", help="Secret Key"), + make_option('-a', '--auth-key', action="store", + default=None, help="Auth Key"), + make_option('--ssl-on', dest='ssl', action='store_true', + default=False, help="SSL Enabled ?"), + make_option('-o', '--origin', action="store", + default="pubsub.pubnub.com", help="Origin"), + make_option('-u', '--uuid', action="store", + default=None, help="UUID") + ]) + def do_init(self, command, opts): + global pubnub + pubnub = Pubnub(opts.publish_key, + opts.subscribe_key, + opts.secret_key, + opts.cipher_key, + opts.auth_key, + opts.ssl, + opts.origin, + opts.uuid) + self.prompt = self.get_prompt() + + def do_set_sync(self, command): + """unset_async + Unset Async mode""" + self.async = False + + def do_set_async(self, command): + """set_async + Set Async mode""" + self.async = True + + @options([make_option('-n', '--count', action="store", + default=3, help="Number of channels on prompt") + ]) + def do_set_channel_truncation(self, command, opts): + """set_channel_truncation + Set Channel Truncation""" + + self.channel_truncation = opts.count + + self.prompt = self.get_prompt() + + def do_unset_channel_truncation(self, command): + """unset_channel_truncation + Unset Channel Truncation""" + self.channel_truncation = 0 + self.prompt = self.get_prompt() + + def do_set_full_date(self, command): + global full_date + """do_set_full_date + Set Full Date""" + full_date = True + self.prompt = self.get_prompt() + + def do_unset_full_date(self, command): + global full_date + """do_unset_full_date + Unset Full Date""" + full_date = False + self.prompt = self.get_prompt() + + @options([make_option('-c', '--channel', + action="store", help="Default Channel") + ]) + def do_set_default_channel(self, command, opts): + + if opts.channel is None: + print_error("Missing channel") + return + self.default_channel = opts.channel + self.prompt = self.get_prompt() + + @options([make_option('-f', '--file', action="store", + default="./pubnub-console.log", help="Output file") + ]) + def do_set_output_file(self, command, opts): + global of + try: + of = file(opts.file, 'w+') + except IOError as e: + print_error("Could not set output file. " + e.reason) + + @options([make_option('-c', '--channel', action="store", + help="Channel for here now data") + ]) + def do_here_now(self, command, opts): + opts.channel = self.default_channel \ + if opts.channel is None else opts.channel + if opts.channel is None: + print_error("Missing channel") + return + + _here_now_command_handler(opts.channel, async=self.async) + + @options([make_option('-c', '--channel', action="store", + help="Channel for history data"), + make_option('-n', '--count', action="store", + default=5, help="Number of messages") + ]) + def do_get_history(self, command, opts): + opts.channel = self.default_channel \ + if opts.channel is None else opts.channel + if opts.channel is None: + print_error("Missing channel") + return + + _history_command_handler(opts.channel, opts.count, async=self.async) + + @options([make_option('-c', '--channel', action="store", + help="Channel on which to publish") + ]) + def do_publish(self, command, opts): + opts.channel = self.default_channel \ + if opts.channel is None else opts.channel + if opts.channel is None: + print_error("Missing channel") + return + + if command is None: + print_error("Missing message") + return + + try: + message = json.loads(str(command)) + except ValueError as ve: + message = str(command) + + _publish_command_handler(opts.channel, message, async=self.async) + + @options([make_option('-c', '--channel', action="store", + help="Channel on which to grant"), + make_option('-a', '--auth-key', dest="auth_key", + action="store", + help="Auth Key"), + make_option('-r', '--read-enabled', dest='read', + action='store_true', + default=False, help="Read ?"), + make_option('-w', '--write-enabled', dest='write', + action='store_true', + default=False, help="Write ?"), + make_option('-t', '--ttl', action="store", + default=5, help="TTL"), + make_option('-p', '--presence', action="store_true", + dest="presence", + default=False, help="Grant on presence channel ?") + ]) + def do_grant(self, command, opts): + opts.channel = self.default_channel \ + if opts.channel is None else opts.channel + if opts.channel is None: + print_error("Missing channel") + return + + opts.auth_key = pubnub.auth_key \ + if opts.auth_key is None else opts.auth_key + + _grant_command_handler(opts.channel, opts.auth_key, + opts.read, opts.write, + opts.ttl, async=self.async) + + if opts.presence is True: + _grant_command_handler(opts.channel + '-pnpres', opts.auth_key, + opts.read, opts.write, + opts.ttl, async=self.async) + + @options([make_option('-c', '--channel', action="store", + help="Channel on which to revoke"), + make_option('-a', '--auth-key', dest="auth_key", action="store", + help="Auth Key"), + make_option('-t', '--ttl', action="store", + default=5, help="TTL"), + make_option('-p', '--presence', action="store_true", + dest="presence", + default=False, help="Revoke on presence channel ?") + ]) + def do_revoke(self, command, opts): + opts.channel = self.default_channel \ + if opts.channel is None else opts.channel + if opts.channel is None: + print_error("Missing channel") + return + + opts.auth_key = pubnub.auth_key \ + if opts.auth_key is None else opts.auth_key + + _revoke_command_handler( + opts.channel, opts.auth_key, opts.ttl, async=self.async) + + if opts.presence is True: + _revoke_command_handler( + opts.channel + '-pnpres', opts.auth_key, + opts.ttl, async=self.async) + + @options([make_option('-c', '--channel', action="store", + help="Channel on which to revoke"), + make_option('-a', '--auth-key', dest="auth_key", action="store", + help="Auth Key") + ]) + def do_audit(self, command, opts): + opts.channel = self.default_channel \ + if opts.channel is None else opts.channel + if opts.channel is None: + print_error("Missing channel") + return + + opts.auth_key = pubnub.auth_key \ + if opts.auth_key is None else opts.auth_key + + _audit_command_handler(opts.channel, opts.auth_key, async=self.async) + + @options([make_option('-c', '--channel', action="store", + help="Channel for unsubscribe"), + make_option('-a', '--all', action="store_true", dest="all", + default=False, help="Unsubscribe from all channels") + ]) + def do_unsubscribe(self, command, opts): + opts.channel = self.default_channel \ + if opts.channel is None else opts.channel + if (opts.all is True): + opts.channel = pubnub.get_channel_array() + if opts.channel is None: + print_error("Missing channel") + return + _unsubscribe_command_handler(opts.channel) + self.prompt = self.get_prompt() + + @options([make_option('-c', '--channel', action="store", + help="Channel for subscribe"), + make_option('-g', '--get-channel-list', action="store_true", + dest="get", + default=False, help="Get susbcribed channel list"), + make_option('-p', '--presence', action="store_true", + dest="presence", + default=False, help="Presence events ?") + ]) + def do_subscribe(self, command, opts): + opts.channel = self.default_channel \ + if opts.channel is None else opts.channel + if opts is None: + print_error("Missing argument") + return + + if opts.channel is not None: + _subscribe_command_handler(opts.channel) + + if opts.presence is True: + _subscribe_command_handler(opts.channel + '-pnpres') + + if opts.get is True: + print_ok(get_channel_array()) + self.prompt = self.get_prompt() + + def do_exit(self, args): + kill_all_threads() + return -1 + + #def do_EOF(self, args): + # kill_all_threads() + # return self.do_exit(args) + + #def handler(self, signum, frame): + # kill_all_threads() + + +def main(): + app = DevConsole() + app.cmdloop_with_keyboard_interrupt() + +if __name__ == "__main__": + main() diff --git a/python/examples/pubnub-console/setup.py b/python/examples/pubnub-console/setup.py new file mode 100644 index 0000000..1ef09be --- /dev/null +++ b/python/examples/pubnub-console/setup.py @@ -0,0 +1,26 @@ +from setuptools import setup, find_packages + +setup( + name='pubnub-console', + version='3.5.0-beta', + description='PubNub Developer Console', + author='Stephen Blum', + author_email='support@pubnub.com', + url='http://pubnub.s3.amazonaws.com/pip/pubnub-3.3.5.tar.gz', + scripts=['pubnub-console'], + license='MIT', + classifiers=( + 'Development Status :: 5 - Production/Stable', + 'Intended Audience :: Developers', + 'Programming Language :: Python', + 'License :: OSI Approved :: MIT License', + 'Operating System :: OS Independent', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Software Development :: Libraries :: Python Modules', + ), + install_requires=[ + 'pubnub==3.5.0-beta', + 'cmd2>=0.6.7', + ], + zip_safe=False, +) diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..c98ee99 --- /dev/null +++ b/setup.py @@ -0,0 +1,26 @@ +from setuptools import setup, find_packages + +setup( + name='pubnub', + version='3.5.0-beta', + description='PubNub Real-time push service in the cloud', + author='Stephen Blum', + author_email='support@pubnub.com', + url='http://pubnub.s3.amazonaws.com/pip/pubnub-3.3.5.tar.gz', + py_modules=['Pubnub'], + license='MIT', + classifiers=( + 'Development Status :: 5 - Production/Stable', + 'Intended Audience :: Developers', + 'Programming Language :: Python', + 'License :: OSI Approved :: MIT License', + 'Operating System :: OS Independent', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Software Development :: Libraries :: Python Modules', + ), + install_requires=[ + 'pycrypto>=2.6.1', + 'requests' + ], + zip_safe=False, +) -- cgit v1.2.3 From 1607828ef5d2ef6c3ce357f83f53ea109be02182 Mon Sep 17 00:00:00 2001 From: Devendra Date: Thu, 8 May 2014 04:12:28 +0530 Subject: updating package urls --- Pubnub.py | 23 ++++++++++++--------- dist/pubnub-3.5.0-beta.tar.gz | Bin 9447 -> 9451 bytes .../dist/pubnub-console-3.5.0-beta.tar.gz | Bin 4627 -> 4647 bytes python/examples/pubnub-console/setup.py | 2 +- setup.py | 2 +- 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/Pubnub.py b/Pubnub.py index 4ae27ab..e00ebb7 100644 --- a/Pubnub.py +++ b/Pubnub.py @@ -115,6 +115,13 @@ except ImportError: ####################################### +def get_data_for_user(data): + if 'message' in data and 'payload' in data: + return {'message': data['message'], 'payload': data['payload']} + else: + return data + + class PubnubCrypto2(): """ #** @@ -757,9 +764,9 @@ class PubnubCoreAsync(PubnubBase): def _invoke(func, msg=None, channel=None): if func is not None: if msg is not None and channel is not None: - func(msg, channel) + func(get_data_for_user(msg), channel) elif msg is not None: - func(msg) + func(get_data_for_user(msg)) else: func() @@ -1065,7 +1072,7 @@ class HTTPClient: def _invoke(func, data): if func is not None: - func(data) + func(get_data_for_user(data)) if self._urllib_func is None: return @@ -1132,15 +1139,11 @@ def _requests_request(url, timeout=320): try: resp = s.get(url, timeout=timeout) except requests.exceptions.HTTPError as http_error: - print http_error resp = http_error except requests.exceptions.ConnectionError as error: - print error msg = str(error) return (json.dumps(msg), 0) except requests.exceptions.Timeout as error: - print(error) - #print('timeout'); msg = str(error) return (json.dumps(msg), 0) return (resp.text, resp.status_code) @@ -1242,7 +1245,7 @@ class PubnubAsync(PubnubCoreAsync): def _request(self, request, callback=None, error=None, single=False): if callback is None: - return self._request_sync(request) + return get_data_for_user(self._request_sync(request)) else: self._request_async(request, callback, error, single=single) @@ -1313,7 +1316,7 @@ class PubnubTwisted(PubnubCoreAsync): def _invoke(func, data): if func is not None: - func(data) + func(get_data_for_user(data)) ## Build URL @@ -1418,7 +1421,7 @@ class PubnubTornado(PubnubCoreAsync): def _invoke(func, data): if func is not None: - func(data) + func(get_data_for_user(data)) url = self.getUrl(request) request = tornado.httpclient.HTTPRequest( diff --git a/dist/pubnub-3.5.0-beta.tar.gz b/dist/pubnub-3.5.0-beta.tar.gz index 6201683..3ed2de3 100644 Binary files a/dist/pubnub-3.5.0-beta.tar.gz and b/dist/pubnub-3.5.0-beta.tar.gz differ diff --git a/python/examples/pubnub-console/dist/pubnub-console-3.5.0-beta.tar.gz b/python/examples/pubnub-console/dist/pubnub-console-3.5.0-beta.tar.gz index 39540f6..278e9fa 100644 Binary files a/python/examples/pubnub-console/dist/pubnub-console-3.5.0-beta.tar.gz and b/python/examples/pubnub-console/dist/pubnub-console-3.5.0-beta.tar.gz differ diff --git a/python/examples/pubnub-console/setup.py b/python/examples/pubnub-console/setup.py index 1ef09be..d46314e 100644 --- a/python/examples/pubnub-console/setup.py +++ b/python/examples/pubnub-console/setup.py @@ -6,7 +6,7 @@ setup( description='PubNub Developer Console', author='Stephen Blum', author_email='support@pubnub.com', - url='http://pubnub.s3.amazonaws.com/pip/pubnub-3.3.5.tar.gz', + url='https://github.com/pubnub/python/raw/async/python/examples/pubnub-console/dist/pubnub-console-3.5.0-beta.tar.gz', scripts=['pubnub-console'], license='MIT', classifiers=( diff --git a/setup.py b/setup.py index c98ee99..373efde 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ setup( description='PubNub Real-time push service in the cloud', author='Stephen Blum', author_email='support@pubnub.com', - url='http://pubnub.s3.amazonaws.com/pip/pubnub-3.3.5.tar.gz', + url='https://github.com/pubnub/python/raw/async/dist/pubnub-3.5.0-beta.tar.gz', py_modules=['Pubnub'], license='MIT', classifiers=( -- cgit v1.2.3 From ca4b031be0c0964fd1dbfa952f23c5537ca02336 Mon Sep 17 00:00:00 2001 From: Devendra Date: Tue, 13 May 2014 04:03:30 +0530 Subject: adding comments for docs --- Pubnub.py | 719 ++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 446 insertions(+), 273 deletions(-) diff --git a/Pubnub.py b/Pubnub.py index e00ebb7..52091ad 100644 --- a/Pubnub.py +++ b/Pubnub.py @@ -3,11 +3,11 @@ # coding=utf8 ## PubNub Real-time Push APIs and Notifications Framework -## Copyright (c) 2010 Stephen Blum +## Copyright (c) 2014-15 Stephen Blum ## http://www.pubnub.com/ ## ----------------------------------- -## PubNub 3.3.4 Real-time Push Cloud API +## PubNub 3.5.0-beta Real-time Push Cloud API ## ----------------------------------- @@ -123,62 +123,22 @@ def get_data_for_user(data): class PubnubCrypto2(): - """ - #** - #* 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) @@ -186,14 +146,7 @@ class PubnubCrypto2(): 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) @@ -201,62 +154,22 @@ class PubnubCrypto2(): class PubnubCrypto3(): - """ - #** - #* 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).encode('utf-8') 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.encode("utf-8")).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) @@ -264,14 +177,7 @@ class PubnubCrypto3(): cipher.encrypt(self.pad(msg.encode('utf-8')))).decode('utf-8') 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) @@ -291,25 +197,20 @@ class PubnubBase(object): origin='pubsub.pubnub.com', UUID=None ): + """Pubnub Class + + Provides methods to communicate with Pubnub cloud + + Attributes: + publish_key: Publish Key + subscribe_key: Subscribe Key + secret_key: Secret Key + cipher_key: Cipher Key + auth_key: Auth Key (used with Pubnub Access Manager i.e. PAM) + ssl: SSL enabled ? + origin: Origin """ - #** - #* 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 @@ -341,7 +242,6 @@ class PubnubBase(object): raise AttributeError("pres_uuid must be a string") def _pam_sign(self, msg): - """Calculate a signature by secret key and message.""" return urlsafe_b64encode(hmac.new( self.secret_key.encode("utf-8"), @@ -350,7 +250,6 @@ class PubnubBase(object): ).digest()) def _pam_auth(self, query, apicode=0, callback=None, error=None): - """Issue an authenticated request.""" if 'timestamp' not in query: query['timestamp'] = int(time.time()) @@ -384,38 +283,226 @@ class PubnubBase(object): self._return_wrapped_callback(error)) def get_origin(self): + return self.origin - def grant(self, channel, authkey=False, read=True, + def grant(self, channel, auth_key=False, read=True, write=True, ttl=5, callback=None, error=None): - """Grant Access on a Channel.""" + """Method for granting permissions. + + This function establishes subscribe and/or write permissions for + PubNub Access Manager (PAM) by setting the read or write attribute + to true. A grant with read or write set to false (or not included) + will revoke any previous grants with read or write set to true. + + Permissions can be applied to any one of three levels: + 1. Application level privileges are based on subscribe_key applying to all associated channels. + 2. Channel level privileges are based on a combination of subscribe_key and channel name. + 3. User level privileges are based on the combination of subscribe_key, channel and auth_key. + + Args: + channel: (string) (optional) + Specifies channel name to grant permissions to. + If channel is not specified, the grant applies to all + channels associated with the subscribe_key. If auth_key + is not specified, it is possible to grant permissions to + multiple channels simultaneously by specifying the channels + as a comma separated list. + + auth_key: (string) (optional) + Specifies auth_key to grant permissions to. + It is possible to specify multiple auth_keys as comma + separated list in combination with a single channel name. + If auth_key is provided as the special-case value "null" + (or included in a comma-separated list, eg. "null,null,abc"), + a new auth_key will be generated and returned for each "null" value. + + read: (boolean) (default: True) + Read permissions are granted by setting to True. + Read permissions are removed by setting to False. + + write: (boolean) (default: True) + Write permissions are granted by setting to true. + Write permissions are removed by setting to false. + + ttl: (int) (default: 1440 i.e 24 hrs) + Time in minutes for which granted permissions are valid. + Max is 525600 , Min is 1. + Setting ttl to 0 will apply the grant indefinitely. + + callback: (function) (optional) + A callback method can be passed to the method. + If set, the api works in async mode. + Required argument when working with twisted or tornado + + error: (function) (optional) + An error method can be passed to the method. + If set, the api works in async mode. + Required argument when working with twisted or tornado . + + Returns: + Returns a dict in sync mode i.e. when callback argument is not given + The dict returned contains values with keys 'message' and 'payload' + + Sample Response: + { + "message":"Success", + "payload":{ + "ttl":5, + "auths":{ + "my_ro_authkey":{"r":1,"w":0} + }, + "subscribe_key":"my_subkey", + "level":"user", + "channel":"my_channel" + } + } + """ return self._pam_auth({ "channel": channel, - "auth": authkey, + "auth": auth_key, "r": read and 1 or 0, "w": write and 1 or 0, "ttl": ttl }, callback=callback, error=error) - def revoke(self, channel, authkey=False, ttl=1, callback=None, error=None): - """Revoke Access on a Channel.""" + def revoke(self, channel, auth_key=False, ttl=1, callback=None, error=None): + """Method for revoking permissions. + + Args: + channel: (string) (optional) + Specifies channel name to revoke permissions to. + If channel is not specified, the revoke applies to all + channels associated with the subscribe_key. If auth_key + is not specified, it is possible to grant permissions to + multiple channels simultaneously by specifying the channels + as a comma separated list. + + auth_key: (string) (optional) + Specifies auth_key to revoke permissions to. + It is possible to specify multiple auth_keys as comma + separated list in combination with a single channel name. + If auth_key is provided as the special-case value "null" + (or included in a comma-separated list, eg. "null,null,abc"), + a new auth_key will be generated and returned for each "null" value. + + ttl: (int) (default: 1440 i.e 24 hrs) + Time in minutes for which granted permissions are valid. + Max is 525600 , Min is 1. + Setting ttl to 0 will apply the grant indefinitely. + + callback: (function) (optional) + A callback method can be passed to the method. + If set, the api works in async mode. + Required argument when working with twisted or tornado + + error: (function) (optional) + An error method can be passed to the method. + If set, the api works in async mode. + Required argument when working with twisted or tornado . + + Returns: + Returns a dict in sync mode i.e. when callback argument is not given + The dict returned contains values with keys 'message' and 'payload' + + Sample Response: + { + "message":"Success", + "payload":{ + "ttl":5, + "auths":{ + "my_authkey":{"r":0,"w":0} + }, + "subscribe_key":"my_subkey", + "level":"user", + "channel":"my_channel" + } + } + + """ return self._pam_auth({ "channel": channel, - "auth": authkey, + "auth": auth_key, "r": 0, "w": 0, "ttl": ttl }, callback=callback, error=error) - def audit(self, channel=False, authkey=False, callback=None, error=None): + def audit(self, channel=False, auth_key=False, callback=None, error=None): + """Method for fetching permissions from pubnub servers. + + This method provides a mechanism to reveal existing PubNub Access Manager attributes + for any combination of subscribe_key, channel and auth_key. + + Args: + channel: (string) (optional) + Specifies channel name to return PAM + attributes optionally in combination with auth_key. + If channel is not specified, results for all channels + associated with subscribe_key are returned. + If auth_key is not specified, it is possible to return + results for a comma separated list of channels. + + auth_key: (string) (optional) + Specifies the auth_key to return PAM attributes for. + If only a single channel is specified, it is possible to return + results for a comma separated list of auth_keys. + + callback: (function) (optional) + A callback method can be passed to the method. + If set, the api works in async mode. + Required argument when working with twisted or tornado + + error: (function) (optional) + An error method can be passed to the method. + If set, the api works in async mode. + Required argument when working with twisted or tornado . + + Returns: + Returns a dict in sync mode i.e. when callback argument is not given + The dict returned contains values with keys 'message' and 'payload' + + Sample Response + { + "message":"Success", + "payload":{ + "channels":{ + "my_channel":{ + "auths":{"my_ro_authkey":{"r":1,"w":0}, + "my_rw_authkey":{"r":0,"w":1}, + "my_admin_authkey":{"r":1,"w":1} + } + } + }, + } + + Usage: + + pubnub.audit ('my_channel'); # Sync Mode + + """ + return self._pam_auth({ "channel": channel, - "auth": authkey + "auth": auth_key }, 1, callback=callback, error=error) def encrypt(self, message): + """Method for encrypting data. + + This method takes plaintext as input and returns encrypted data. + This need not be called directly as enncryption/decryption is + taken care of transparently by Pubnub class if cipher key is + provided at time of initializing pubnub object + + Args: + message: Message to be encrypted. + + Returns: + Returns encrypted message if cipher key is set + """ if self.cipher_key: message = json.dumps(self.pc.encrypt( self.cipher_key, json.dumps(message)).replace('\n', '')) @@ -425,6 +512,19 @@ class PubnubBase(object): return message def decrypt(self, message): + """Method for decrypting data. + + This method takes ciphertext as input and returns decrypted data. + This need not be called directly as enncryption/decryption is + taken care of transparently by Pubnub class if cipher key is + provided at time of initializing pubnub object + + Args: + message: Message to be decrypted. + + Returns: + Returns decrypted message if cipher key is set + """ if self.cipher_key: message = self.pc.decrypt(self.cipher_key, message) @@ -445,24 +545,43 @@ class PubnubBase(object): return None def publish(self, channel, message, callback=None, error=None): - """ - #** - #* 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) + """Publishes data on a channel. + + The publish() method is used to send a message to all subscribers of a channel. + To publish a message you must first specify a valid publish_key at initialization. + A successfully published message is replicated across the PubNub Real-Time Network + and sent simultaneously to all subscribed clients on a channel. + Messages in transit can be secured from potential eavesdroppers with SSL/TLS by + setting ssl to True during initialization. + + Published messages can also be encrypted with AES-256 simply by specifying a cipher_key + during initialization. + + Args: + channel: (string) + Specifies channel name to publish messages to. + message: (string/int/double/dict/list) + Message to be published + callback: (optional) + A callback method can be passed to the method. + If set, the api works in async mode. + Required argument when working with twisted or tornado + error: (optional) + An error method can be passed to the method. + If set, the api works in async mode. + Required argument when working with twisted or tornado + + Returns: + Sync Mode : list + Async Mode : None + + The function returns the following formatted response: + + [ Number, "Status", "Time Token"] + + The output below demonstrates the response to a successful call: + + [1,"Sent","13769558699541401"] """ @@ -482,26 +601,21 @@ class PubnubBase(object): error=self._return_wrapped_callback(error)) def presence(self, channel, callback, error=None): - """ - #** - #* 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 - }) + """Subscribe to presence data on a channel. + + Only works in async mode + + Args: + channel: Channel name ( string ) on which to publish message + callback: A callback method should be passed to the method. + If set, the api works in async mode. + Required argument when working with twisted or tornado . + error: Optional variable. An error method can be passed to the method. + If set, the api works in async mode. + Required argument when working with twisted or tornado . + + Returns: + None """ return self.subscribe({ 'channel': channel + '-pnpres', @@ -509,23 +623,51 @@ class PubnubBase(object): 'callback': self._return_wrapped_callback(callback)}) def here_now(self, channel, callback=None, error=None): - """ - #** - #* Here Now - #* - #* Load current occupancy from a channel. - #* - #* @param array args with 'channel'. - #* @return mixed false on fail, array on success. - #* + """Get here now data. - ## Presence Example - here_now = pubnub.here_now({ - 'channel' : 'hello_world', - }) - print(here_now['occupancy']) - print(here_now['uuids']) + You can obtain information about the current state of a channel including + a list of unique user-ids currently subscribed to the channel and the total + occupancy count of the channel by calling the here_now() function in your + application. + + + Args: + channel: (string) (optional) + Specifies the channel name to return occupancy results. + If channel is not provided, here_now will return data for all channels. + + callback: (optional) + A callback method should be passed to the method. + If set, the api works in async mode. + Required argument when working with twisted or tornado . + error: (optional) + Optional variable. An error method can be passed to the method. + If set, the api works in async mode. + Required argument when working with twisted or tornado . + + Returns: + Sync Mode: list + Async Mode: None + + Response Format: + + The here_now() method returns a list of uuid s currently subscribed to the channel. + + uuids:["String","String", ... ,"String"] - List of UUIDs currently subscribed to the channel. + + occupancy: Number - Total current occupancy of the channel. + + Example Response: + { + occupancy: 4, + uuids: [ + '123123234t234f34fq3dq', + '143r34f34t34fq34q34q3', + '23f34d3f4rq34r34rq23q', + 'w34tcw45t45tcw435tww3', + ] + } """ ## Get Presence Here Now @@ -537,22 +679,54 @@ class PubnubBase(object): callback=self._return_wrapped_callback(callback), error=self._return_wrapped_callback(error)) + def history(self, channel, count=100, reverse=False, start=None, end=None, callback=None, error=None): - """ - #** - #* History - #* - #* Load history from a channel. - #* + """This method fetches historical messages of a channel. - ## History Example - history = pubnub.detailedHistory({ - 'channel' : 'hello_world', - 'count' : 5 - }) - print(history) + PubNub Storage/Playback Service provides real-time access to an unlimited + history for all messages published to PubNub. Stored messages are replicated + across multiple availability zones in several geographical data center + locations. Stored messages can be encrypted with AES-256 message encryption + ensuring that they are not readable while stored on PubNub's network. + + It is possible to control how messages are returned and in what order, + for example you can: + + Return messages in the order newest to oldest (default behavior). + + Return messages in the order oldest to newest by setting reverse to true. + + Page through results by providing a start or end time token. + + Retrieve a "slice" of the time line by providing both a start and end time token. + + Limit the number of messages to a specific quantity using the count parameter. + + + + Args: + channel: (string) + Specifies channel to return history messages from + + count: (int) (default: 100) + Specifies the number of historical messages to return + + callback: (optional) + A callback method should be passed to the method. + If set, the api works in async mode. + Required argument when working with twisted or tornado . + error: (optional) + An error method can be passed to the method. + If set, the api works in async mode. + Required argument when working with twisted or tornado . + + Returns: + Returns a list in sync mode i.e. when callback argument is not given + + Sample Response: + [["Pub1","Pub2","Pub3","Pub4","Pub5"],13406746729185766,13406746845892666] """ params = dict() @@ -576,19 +750,20 @@ class PubnubBase(object): error=self._return_wrapped_callback(error)) def time(self, callback=None): - """ - #** - #* Time - #* - #* Timestamp from PubNub Cloud. - #* - #* @return int timestamp. - #* + """This function will return a 17 digit precision Unix epoch. + + Args: + + callback: (optional) + A callback method should be passed to the method. + If set, the api works in async mode. + Required argument when working with twisted or tornado . - ## PubNub Server Time Example - timestamp = pubnub.time() - print(timestamp) + Returns: + Returns a 17 digit number in sync mode i.e. when callback argument is not given + Sample: + 13769501243685161 """ time = self._request({'urlcomponents': [ @@ -649,23 +824,16 @@ class PubnubCoreAsync(PubnubBase): _tt_lock=empty_lock, _channel_list_lock=empty_lock ): - """ - #** - #* 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. - #** + """Summary of class here. - ## Initiat Class - pubnub = Pubnub( 'PUBLISH-KEY', 'SUBSCRIBE-KEY', 'SECRET-KEY', False ) + Longer class information.... + Longer class information.... + Attributes: + likes_spam: A boolean indicating if we like SPAM or not. + eggs: An integer count of the eggs we have laid. """ + super(PubnubCoreAsync, self).__init__( publish_key=publish_key, subscribe_key=subscribe_key, @@ -703,6 +871,14 @@ class PubnubCoreAsync(PubnubBase): return channel def get_channel_array(self): + """Get List of currently subscribed channels + + Returns: + Returns a list containing names of channels subscribed + + Sample return value: + ["a","b","c] + """ channels = self.subscriptions channel = [] with self._channel_list_lock: @@ -720,36 +896,37 @@ class PubnubCoreAsync(PubnubBase): def subscribe(self, channels, callback, error=None, connect=None, disconnect=None, reconnect=None, sync=False): - """ - #** - #* 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 - }) - + """Subscribe to data on a channel. + + This function causes the client to create an open TCP socket to the + PubNub Real-Time Network and begin listening for messages on a specified channel. + To subscribe to a channel the client must send the appropriate subscribe_key at + initialization. + + Only works in async mode + + Args: + channel: (string/list) + Specifies the channel to subscribe to. It is possible to specify + multiple channels as a comma separated list or andarray. + + callback: (function) + This callback is called on receiving a message from the channel. + + error: (function) (optional) + This callback is called on an error event + + connect: (function) (optional) + This callback is called on a successful connection to the PubNub cloud + + disconnect: (function) (optional) + This callback is called on client disconnect from the PubNub cloud + + reconnect: (function) (optional) + This callback is called on successfully re-connecting to the PubNub cloud + + Returns: + None """ with self._tt_lock: @@ -931,7 +1108,22 @@ class PubnubCoreAsync(PubnubBase): self._connect() def unsubscribe(self, channel): - + """Subscribe to presence data on a channel. + Only works in async mode + + Args: + channel: Channel name ( string ) on which to publish message + message: Message to be published ( String / int / double / dict / list ). + callback: A callback method should be passed to the method. + If set, the api works in async mode. + Required argument when working with twisted or tornado . + error: Optional variable. An error method can be passed to the method. + If set, the api works in async mode. + Required argument when working with twisted or tornado . + + Returns: + Returns a list in sync mode i.e. when callback argument is not given + """ if channel in self.subscriptions is False: return False @@ -957,25 +1149,6 @@ class PubnubCore(PubnubCoreAsync): 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 ) - - """ super(PubnubCore, self).__init__( publish_key=publish_key, subscribe_key=subscribe_key, -- cgit v1.2.3 From 9dda9200997330b686bdb26495bed1023a1d8f7e Mon Sep 17 00:00:00 2001 From: Devendra Date: Thu, 15 May 2014 12:06:49 +0530 Subject: adding sync and async tests for grant and revoke --- Pubnub.py | 59 +--- python/examples/console.py | 2 +- python/examples/here-now.py | 2 +- python/examples/history.py | 2 +- python/examples/publish.py | 2 +- python/examples/pubnub-console/pubnub-console | 2 +- python/examples/subscribe.py | 2 +- python/tests/test_grant.py | 199 ++++++++++++++ python/tests/test_grant_async.py | 369 ++++++++++++++++++++++++++ 9 files changed, 586 insertions(+), 53 deletions(-) create mode 100644 python/tests/test_grant.py create mode 100644 python/tests/test_grant_async.py diff --git a/Pubnub.py b/Pubnub.py index 52091ad..d75b452 100644 --- a/Pubnub.py +++ b/Pubnub.py @@ -283,10 +283,15 @@ class PubnubBase(object): self._return_wrapped_callback(error)) def get_origin(self): - return self.origin - def grant(self, channel, auth_key=False, read=True, + def set_auth_key(self, auth_key): + self.auth_key = auth_key + + def get_auth_key(self): + return auth_key + + def grant(self, channel=None, auth_key=False, read=True, write=True, ttl=5, callback=None, error=None): """Method for granting permissions. @@ -367,7 +372,7 @@ class PubnubBase(object): "ttl": ttl }, callback=callback, error=error) - def revoke(self, channel, auth_key=False, ttl=1, callback=None, error=None): + def revoke(self, channel=None, auth_key=None, ttl=1, callback=None, error=None): """Method for revoking permissions. Args: @@ -430,7 +435,7 @@ class PubnubBase(object): "ttl": ttl }, callback=callback, error=error) - def audit(self, channel=False, auth_key=False, callback=None, error=None): + def audit(self, channel=None, auth_key=None, callback=None, error=None): """Method for fetching permissions from pubnub servers. This method provides a mechanism to reveal existing PubNub Access Manager attributes @@ -790,6 +795,7 @@ class PubnubBase(object): if ("urlparams" in request): url = url + '?' + "&".join([x + "=" + str(y) for x, y in request[ "urlparams"].items() if y is not None]) + print url return url @@ -824,15 +830,6 @@ class PubnubCoreAsync(PubnubBase): _tt_lock=empty_lock, _channel_list_lock=empty_lock ): - """Summary of class here. - - Longer class information.... - Longer class information.... - - Attributes: - likes_spam: A boolean indicating if we like SPAM or not. - eggs: An integer count of the eggs we have laid. - """ super(PubnubCoreAsync, self).__init__( publish_key=publish_key, @@ -1250,12 +1247,6 @@ class HTTPClient: if self._urllib_func is None: return - ''' - try: - resp = urllib2.urlopen(self.url, timeout=320) - except urllib2.HTTPError as http_error: - resp = http_error - ''' resp = self._urllib_func(self.url, timeout=320) data = resp[0] code = resp[1] @@ -1335,7 +1326,7 @@ _urllib_request = None # PubnubAsync -class PubnubAsync(PubnubCoreAsync): +class Pubnub(PubnubCoreAsync): def __init__( self, publish_key, @@ -1348,7 +1339,7 @@ class PubnubAsync(PubnubCoreAsync): pres_uuid=None, pooling=True ): - super(PubnubAsync, self).__init__( + super(Pubnub, self).__init__( publish_key=publish_key, subscribe_key=subscribe_key, secret_key=secret_key, @@ -1422,31 +1413,6 @@ class PubnubAsync(PubnubCoreAsync): else: self._request_async(request, callback, error, single=single) -''' - - def _request3_sync( self, request) : - ## Build URL - url = self.getUrl(request) - ## Send Request Expecting JSONP Response - try: - response = urllib.request.urlopen(url,timeout=310) - resp_json = json.loads(response.read().decode("utf-8")) - except Exception as e: - return None - - return resp_json - - def _request3_async( self, request, callback, single=False ) : - pass - - def _request3(self, request, callback=None, single=False): - if callback is None: - return self._request3_sync(request,single=single) - else: - self._request3_async(request, callback, single=single) - ''' - - # Pubnub Twisted class PubnubTwisted(PubnubCoreAsync): @@ -1481,7 +1447,6 @@ class PubnubTwisted(PubnubCoreAsync): ) self.headers = {} self.headers['User-Agent'] = ['Python-Twisted'] - #self.headers['Accept-Encoding'] = [self.accept_encoding] self.headers['V'] = [self.version] def _request(self, request, callback=None, error=None, single=False): diff --git a/python/examples/console.py b/python/examples/console.py index 7798340..5d74517 100644 --- a/python/examples/console.py +++ b/python/examples/console.py @@ -7,7 +7,7 @@ import sys -from Pubnub import PubnubAsync as Pubnub +from Pubnub import Pubnub import threading from datetime import datetime diff --git a/python/examples/here-now.py b/python/examples/here-now.py index d03a110..9640cc5 100644 --- a/python/examples/here-now.py +++ b/python/examples/here-now.py @@ -7,7 +7,7 @@ import sys -from Pubnub import PubnubAsync as Pubnub +from Pubnub import Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' diff --git a/python/examples/history.py b/python/examples/history.py index 7f7466b..603a0f8 100644 --- a/python/examples/history.py +++ b/python/examples/history.py @@ -7,7 +7,7 @@ import sys -from Pubnub import PubnubAsync as Pubnub +from Pubnub import Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' diff --git a/python/examples/publish.py b/python/examples/publish.py index a1b913b..594e7c4 100644 --- a/python/examples/publish.py +++ b/python/examples/publish.py @@ -7,7 +7,7 @@ import sys -from Pubnub import PubnubAsync as Pubnub +from Pubnub import Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' diff --git a/python/examples/pubnub-console/pubnub-console b/python/examples/pubnub-console/pubnub-console index a12c77f..7276fb9 100644 --- a/python/examples/pubnub-console/pubnub-console +++ b/python/examples/pubnub-console/pubnub-console @@ -9,7 +9,7 @@ import sys -from Pubnub import PubnubAsync as Pubnub +from Pubnub import Pubnub import threading from datetime import datetime diff --git a/python/examples/subscribe.py b/python/examples/subscribe.py index 6cf93b1..9b8b223 100644 --- a/python/examples/subscribe.py +++ b/python/examples/subscribe.py @@ -7,7 +7,7 @@ import sys -from Pubnub import PubnubAsync as Pubnub +from Pubnub import Pubnub publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' diff --git a/python/tests/test_grant.py b/python/tests/test_grant.py new file mode 100644 index 0000000..6826335 --- /dev/null +++ b/python/tests/test_grant.py @@ -0,0 +1,199 @@ + + +from Pubnub import Pubnub +import time + +pubnub = Pubnub("demo","demo") +pubnub_pam = Pubnub("pub-c-c077418d-f83c-4860-b213-2f6c77bde29a", + "sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe", "sec-c-OGU3Y2Q4ZWUtNDQwMC00NTI1LThjNWYtNWJmY2M4OGIwNjEy") + + +# Grant permission read true, write true, on channel ( Sync Mode ) +def test_1(): + resp = pubnub_pam.grant(channel="abcd", auth_key="abcd", read=True, write=True, ttl=1) + assert resp['message'] == 'Success' + assert resp['payload'] == { + 'auths': {'abcd': {'r': 1, 'w': 1}}, + 'subscribe_key': 'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + 'level': 'user', 'channel': 'abcd', 'ttl': 1 + } + + +# Grant permission read false, write false, on channel ( Sync Mode ) +def test_2(): + resp = pubnub_pam.grant(channel="abcd", auth_key="abcd", read=False, write=False, ttl=1) + assert resp['message'] == 'Success' + assert resp['payload'] == { + 'auths': {'abcd': {'r': 0, 'w': 0}}, + 'subscribe_key': 'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + 'level': 'user', 'channel': 'abcd', 'ttl': 1 + } + +# Grant permission read True, write false, on channel ( Sync Mode ) +def test_3(): + resp = pubnub_pam.grant(channel="abcd", auth_key="abcd", read=True, write=False, ttl=1) + assert resp['message'] == 'Success' + assert resp['payload'] == { + 'auths': {'abcd': {'r': 1, 'w': 0}}, + 'subscribe_key': 'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + 'level': 'user', 'channel': 'abcd', 'ttl': 1 + } + +# Grant permission read False, write True, on channel ( Sync Mode ) +def test_4(): + resp = pubnub_pam.grant(channel="abcd", auth_key="abcd", read=True, write=False, ttl=1) + assert resp['message'] == 'Success' + assert resp['payload'] == { + 'auths': {'abcd': {'r': 1, 'w': 0}}, + 'subscribe_key': 'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + 'level': 'user', 'channel': 'abcd', 'ttl': 1 + } + +# Grant permission read False, write True, on channel ( Sync Mode ), TTL 10 +def test_5(): + resp = pubnub_pam.grant(channel="abcd", auth_key="abcd", read=True, write=False, ttl=10) + assert resp['message'] == 'Success' + assert resp['payload'] == { + 'auths': {'abcd': {'r': 1, 'w': 0}}, + 'subscribe_key': 'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + 'level': 'user', 'channel': 'abcd', 'ttl': 10 + } + +# Grant permission read False, write True, without channel ( Sync Mode ), TTL 10 +def test_6(): + resp = pubnub_pam.grant(auth_key="abcd", read=True, write=False, ttl=10) + assert resp['message'] == 'Success' + assert resp['payload'] == { + 'subscribe_key': 'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + 'level': 'subkey' , u'r': 1, u'w': 0, 'ttl': 10 + } + + +# Grant permission read False, write False, without channel ( Sync Mode ) +def test_7(): + resp = pubnub_pam.grant(auth_key="abcd", read=False, write=False) + assert resp['message'] == 'Success' + assert resp['payload'] == { + 'subscribe_key': 'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + 'level': 'subkey' , u'r': 0, u'w': 0, 'ttl': 1 + } + + +# Complete flow , try publish on forbidden channel, grant permission to auth key and try again. ( Sync Mode) + +def test_8(): + channel = "test_8-" + str(time.time()) + message = "Hello World" + auth_key = "auth-" + channel + pubnub_pam.set_auth_key(auth_key) + resp = pubnub_pam.publish(channel=channel,message=message) + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + resp = pubnub_pam.grant(channel=channel, read=True, write=True, auth_key=auth_key, ttl=10) + assert resp == { + 'message': u'Success', + 'payload': {u'auths': {auth_key : {u'r': 1, u'w': 1}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': channel, u'ttl': 10} + } + resp = pubnub_pam.publish(channel=channel,message=message) + assert resp[0] == 1 + + +# Complete flow , try publish on forbidden channel, grant permission to authkey and try again. ( Sync Mode) +# then revoke and try again +def test_9(): + channel = "test_9-" + str(time.time()) + message = "Hello World" + auth_key = "auth-" + channel + pubnub_pam.set_auth_key(auth_key) + resp = pubnub_pam.publish(channel=channel,message=message) + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + resp = pubnub_pam.grant(channel=channel, read=True, write=True, auth_key=auth_key, ttl=10) + print resp + assert resp == { + 'message': u'Success', + 'payload': {u'auths': {auth_key : {u'r': 1, u'w': 1}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': channel, u'ttl': 10} + } + resp = pubnub_pam.publish(channel=channel,message=message) + assert resp[0] == 1 + resp = pubnub_pam.revoke(channel=channel, auth_key=auth_key) + print resp + assert resp == { + 'message': u'Success', + 'payload': {u'auths': {auth_key : {u'r': 0, u'w': 0}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': channel, u'ttl': 1} + } + resp = pubnub_pam.publish(channel=channel,message=message) + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + +# Complete flow , try publish on forbidden channel, grant permission channel level for subkey and try again. ( Sync Mode) +# then revoke and try again +def test_10(): + channel = "test_10-" + str(time.time()) + message = "Hello World" + auth_key = "auth-" + channel + pubnub_pam.set_auth_key(auth_key) + resp = pubnub_pam.publish(channel=channel,message=message) + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + resp = pubnub_pam.grant(channel=channel, read=True, write=True, ttl=10) + print resp + assert resp == { + 'message': u'Success', + 'payload': { u'channels': {channel: {u'r': 1, u'w': 1}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'channel', u'ttl': 10} + } + resp = pubnub_pam.publish(channel=channel,message=message) + assert resp[0] == 1 + resp = pubnub_pam.revoke(channel=channel) + print resp + assert resp == { + 'message': u'Success', + 'payload': { u'channels': {channel : {u'r': 0, u'w': 0}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'channel', u'ttl': 1} + } + resp = pubnub_pam.publish(channel=channel,message=message) + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + +# Complete flow , try publish on forbidden channel, grant permission subkey level for subkey and try again. ( Sync Mode) +# then revoke and try again +def test_11(): + channel = "test_11-" + str(time.time()) + message = "Hello World" + auth_key = "auth-" + channel + pubnub_pam.set_auth_key(auth_key) + resp = pubnub_pam.publish(channel=channel,message=message) + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + resp = pubnub_pam.grant(read=True, write=True, ttl=10) + print resp + assert resp == { + 'message': u'Success', + 'payload': { u'r': 1, u'w': 1, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'subkey', u'ttl': 10} + } + resp = pubnub_pam.publish(channel=channel,message=message) + assert resp[0] == 1 + resp = pubnub_pam.revoke() + print resp + assert resp == { + 'message': u'Success', + 'payload': {u'r': 0, u'w': 0, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'subkey', u'ttl': 1} + } + resp = pubnub_pam.publish(channel=channel,message=message) + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + + diff --git a/python/tests/test_grant_async.py b/python/tests/test_grant_async.py new file mode 100644 index 0000000..4d38a0a --- /dev/null +++ b/python/tests/test_grant_async.py @@ -0,0 +1,369 @@ + + +from Pubnub import Pubnub +import time + +pubnub = Pubnub("demo","demo") +pubnub_pam = Pubnub("pub-c-c077418d-f83c-4860-b213-2f6c77bde29a", + "sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe", "sec-c-OGU3Y2Q4ZWUtNDQwMC00NTI1LThjNWYtNWJmY2M4OGIwNjEy") + + + +# Grant permission read true, write true, on channel ( Async Mode ) +def test_1(): + resp = {'response' : None} + def _callback(response): + resp['response'] = response + + def _error(response): + resp['response'] = response + + pubnub_pam.grant(channel="abcd", auth_key="abcd", read=True, write=True, ttl=1, callback=_callback, error=_error) + time.sleep(2) + assert resp['response'] == { + 'message': u'Success', + 'payload': {u'auths': {u'abcd': {u'r': 1, u'w': 1}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': u'abcd', u'ttl': 1} + } + + +# Grant permission read false, write false, on channel ( Async Mode ) +def test_2(): + resp = {'response' : None} + def _callback(response): + resp['response'] = response + + def _error(response): + resp['response'] = response + + pubnub_pam.grant(channel="abcd", auth_key="abcd", read=False, write=False, ttl=1, callback=_callback, error=_error) + time.sleep(2) + assert resp['response'] == { + 'message': u'Success', + 'payload': {u'auths': {u'abcd': {u'r': 0, u'w': 0}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': u'abcd', u'ttl': 1} + } + + +# Grant permission read True, write false, on channel ( Async Mode ) +def test_3(): + resp = {'response' : None} + def _callback(response): + resp['response'] = response + + def _error(response): + resp['response'] = response + + pubnub_pam.grant(channel="abcd", auth_key="abcd", read=True, write=False, ttl=1, callback=_callback, error=_error) + time.sleep(2) + assert resp['response'] == { + 'message': u'Success', + 'payload': {u'auths': {u'abcd': {u'r': 1, u'w': 0}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': u'abcd', u'ttl': 1} + } + +# Grant permission read False, write True, on channel ( Async Mode ) +def test_4(): + resp = {'response' : None} + def _callback(response): + resp['response'] = response + + def _error(response): + resp['response'] = response + + pubnub_pam.grant(channel="abcd", auth_key="abcd", read=False, write=True, ttl=1, callback=_callback, error=_error) + time.sleep(2) + assert resp['response'] == { + 'message': u'Success', + 'payload': {u'auths': {u'abcd': {u'r': 0, u'w': 1}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': u'abcd', u'ttl': 1} + } + + +# Grant permission read False, write True, on channel ( Async Mode ), TTL 10 +def test_5(): + resp = {'response' : None} + def _callback(response): + resp['response'] = response + + def _error(response): + resp['response'] = response + + pubnub_pam.grant(channel="abcd", auth_key="abcd", read=False, write=True, ttl=10, callback=_callback, error=_error) + time.sleep(2) + assert resp['response'] == { + 'message': u'Success', + 'payload': {u'auths': {u'abcd': {u'r': 0, u'w': 1}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': u'abcd', u'ttl': 10} + } + + +# Grant permission read False, write True, without channel ( Async Mode ), TTL 10 +def test_6(): + resp = {'response' : None} + def _callback(response): + resp['response'] = response + + def _error(response): + resp['response'] = response + + pubnub_pam.grant(auth_key="abcd", read=False, write=True, ttl=10, callback=_callback, error=_error) + time.sleep(2) + assert resp['response'] == { + 'message': u'Success', + 'payload': { u'r': 0, u'w': 1, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'subkey', u'ttl': 10} + } + + +# Grant permission read False, write False, without channel ( Async Mode ) +def test_7(): + resp = {'response' : None} + def _callback(response): + resp['response'] = response + + def _error(response): + resp['response'] = response + + pubnub_pam.grant(auth_key="abcd", read=False, write=False, callback=_callback, error=_error) + time.sleep(2) + assert resp['response'] == { + 'message': u'Success', + 'payload': { u'r': 0, u'w': 0, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'subkey', u'ttl': 1} + } + + +# Complete flow , try publish on forbidden channel, grant permission to subkey and try again. ( Sync Mode) + +def test_8(): + channel = "test_8-" + str(time.time()) + message = "Hello World" + auth_key = "auth-" + channel + pubnub_pam.set_auth_key(auth_key) + + + + def _cb1(resp, ch=None): + assert False + def _err1(resp): + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + pubnub_pam.publish(channel=channel,message=message, callback=_cb1, error=_err1) + time.sleep(2) + + + def _cb2(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': {u'auths': {auth_key : {u'r': 1, u'w': 1}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': channel, u'ttl': 10} + } + def _err2(resp): + assert False + + + resp = pubnub_pam.grant(channel=channel, read=True, write=True, auth_key=auth_key, ttl=10, callback=_cb2, error=_err2) + time.sleep(2) + + def _cb3(resp, ch=None): + assert resp[0] == 1 + def _err3(resp): + assert False + + pubnub_pam.publish(channel=channel,message=message, callback=_cb3, error=_err3) + time.sleep(2) + + + + + +# Complete flow , try publish on forbidden channel, grant permission to authkey and try again. +# then revoke and try again +def test_9(): + channel = "test_9-" + str(time.time()) + message = "Hello World" + auth_key = "auth-" + channel + pubnub_pam.set_auth_key(auth_key) + + def _cb1(resp, ch=None): + assert False + def _err1(resp): + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + pubnub_pam.publish(channel=channel,message=message, callback=_cb1, error=_err1) + time.sleep(2) + + + def _cb2(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': {u'auths': {auth_key : {u'r': 1, u'w': 1}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': channel, u'ttl': 10} + } + def _err2(resp): + assert False + + + pubnub_pam.grant(channel=channel, read=True, write=True, auth_key=auth_key, ttl=10, callback=_cb2, error=_err2) + time.sleep(2) + + def _cb3(resp, ch=None): + assert resp[0] == 1 + def _err3(resp): + assert False + + pubnub_pam.publish(channel=channel,message=message, callback=_cb3, error=_err3) + time.sleep(2) + + def _cb4(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': {u'auths': {auth_key : {u'r': 0, u'w': 0}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': channel, u'ttl': 1} + } + def _err4(resp): + assert False + pubnub_pam.revoke(channel=channel, auth_key=auth_key, callback=_cb4, error=_err4) + time.sleep(2) + + def _cb5(resp, ch=None): + assert False + def _err5(resp): + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + pubnub_pam.publish(channel=channel,message=message, callback=_cb5, error=_err5) + time.sleep(2) + + + + +# Complete flow , try publish on forbidden channel, grant permission channel level for subkey and try again. +# then revoke and try again +def test_10(): + channel = "test_10-" + str(time.time()) + message = "Hello World" + auth_key = "auth-" + channel + pubnub_pam.set_auth_key(auth_key) + + def _cb1(resp, ch=None): + assert False + def _err1(resp): + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + pubnub_pam.publish(channel=channel,message=message, callback=_cb1, error=_err1) + time.sleep(2) + + + def _cb2(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': { u'channels': {channel: {u'r': 1, u'w': 1}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'channel', u'ttl': 10} + } + def _err2(resp): + assert False + + + pubnub_pam.grant(channel=channel, read=True, write=True, ttl=10, callback=_cb2, error=_err2) + time.sleep(2) + + def _cb3(resp, ch=None): + assert resp[0] == 1 + def _err3(resp): + assert False + + pubnub_pam.publish(channel=channel,message=message, callback=_cb3, error=_err3) + time.sleep(2) + + def _cb4(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': { u'channels': {channel : {u'r': 0, u'w': 0}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'channel', u'ttl': 1} + } + def _err4(resp): + assert False + pubnub_pam.revoke(channel=channel, callback=_cb4, error=_err4) + time.sleep(2) + + def _cb5(resp, ch=None): + assert False + def _err5(resp): + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + pubnub_pam.publish(channel=channel,message=message, callback=_cb5, error=_err5) + time.sleep(2) + + + +# Complete flow , try publish on forbidden channel, grant permission subkey level for subkey and try again. +# then revoke and try again +def test_11(): + channel = "test_11-" + str(time.time()) + message = "Hello World" + auth_key = "auth-" + channel + pubnub_pam.set_auth_key(auth_key) + + def _cb1(resp, ch=None): + assert False + def _err1(resp): + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + pubnub_pam.publish(channel=channel,message=message, callback=_cb1, error=_err1) + time.sleep(2) + + + def _cb2(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': { u'r': 1, u'w': 1, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'subkey', u'ttl': 10} + } + def _err2(resp): + assert False + + + pubnub_pam.grant(read=True, write=True, ttl=10, callback=_cb2, error=_err2) + time.sleep(2) + + def _cb3(resp, ch=None): + assert resp[0] == 1 + def _err3(resp): + assert False + + pubnub_pam.publish(channel=channel,message=message, callback=_cb3, error=_err3) + time.sleep(2) + + def _cb4(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': {u'r': 0, u'w': 0, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'subkey', u'ttl': 1} + } + def _err4(resp): + assert False + pubnub_pam.revoke(callback=_cb4, error=_err4) + time.sleep(2) + + def _cb5(resp, ch=None): + assert False + def _err5(resp): + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + pubnub_pam.publish(channel=channel,message=message, callback=_cb5, error=_err5) + time.sleep(2) -- cgit v1.2.3 From 66ffd7e19feb9e65e2a043d78b727c90c4284efb Mon Sep 17 00:00:00 2001 From: Devendra Date: Thu, 15 May 2014 15:34:22 +0530 Subject: async tests --- python-tornado/tests/test_grant_async.py | 359 +++++++++++++++++++++++++++++++ 1 file changed, 359 insertions(+) create mode 100644 python-tornado/tests/test_grant_async.py diff --git a/python-tornado/tests/test_grant_async.py b/python-tornado/tests/test_grant_async.py new file mode 100644 index 0000000..b51b275 --- /dev/null +++ b/python-tornado/tests/test_grant_async.py @@ -0,0 +1,359 @@ + + +from Pubnub import PubnubTornado as Pubnub +import time + +pubnub = Pubnub("demo","demo") +pubnub_pam = Pubnub("pub-c-c077418d-f83c-4860-b213-2f6c77bde29a", + "sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe", "sec-c-OGU3Y2Q4ZWUtNDQwMC00NTI1LThjNWYtNWJmY2M4OGIwNjEy") + + + +# Grant permission read true, write true, on channel ( Async Mode ) +def test_1(): + + def _callback(resp, ch= None): + assert resp == { + 'message': u'Success', + 'payload': {u'auths': {u'abcd': {u'r': 1, u'w': 1}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': u'abcd', u'ttl': 1} + } + + def _error(response): + assert False + + pubnub_pam.grant(channel="abcd", auth_key="abcd", read=True, write=True, ttl=1, callback=_callback, error=_error) + + +# Grant permission read false, write false, on channel ( Async Mode ) +def test_2(): + + def _callback(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': {u'auths': {u'abcd': {u'r': 0, u'w': 0}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': u'abcd', u'ttl': 1} + } + + def _error(response): + assert False + + pubnub_pam.grant(channel="abcd", auth_key="abcd", read=False, write=False, ttl=1, callback=_callback, error=_error) + + +# Grant permission read True, write false, on channel ( Async Mode ) +def test_3(): + + def _callback(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': {u'auths': {u'abcd': {u'r': 1, u'w': 0}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': u'abcd', u'ttl': 1} + } + + def _error(response): + assert False + + pubnub_pam.grant(channel="abcd", auth_key="abcd", read=True, write=False, ttl=1, callback=_callback, error=_error) + + +# Grant permission read False, write True, on channel ( Async Mode ) +def test_4(): + + def _callback(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': {u'auths': {u'abcd': {u'r': 0, u'w': 1}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': u'abcd', u'ttl': 1} + } + + def _error(response): + assert False + + pubnub_pam.grant(channel="abcd", auth_key="abcd", read=False, write=True, ttl=1, callback=_callback, error=_error) + + +# Grant permission read False, write True, on channel ( Async Mode ), TTL 10 +def test_5(): + + def _callback(resp,ch=None): + assert resp == { + 'message': u'Success', + 'payload': {u'auths': {u'abcd': {u'r': 0, u'w': 1}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': u'abcd', u'ttl': 10} + } + + + def _error(response): + assert False + + pubnub_pam.grant(channel="abcd", auth_key="abcd", read=False, write=True, ttl=10, callback=_callback, error=_error) + + +# Grant permission read False, write True, without channel ( Async Mode ), TTL 10 +def test_6(): + def _callback(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': { u'r': 0, u'w': 1, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'subkey', u'ttl': 10} + } + + def _error(response): + assert False + + pubnub_pam.grant(auth_key="abcd", read=False, write=True, ttl=10, callback=_callback, error=_error) + + + +# Grant permission read False, write False, without channel ( Async Mode ) +def test_7(): + + def _callback(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': { u'r': 0, u'w': 0, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'subkey', u'ttl': 1} + } + + def _error(response): + resp['response'] = response + + pubnub_pam.grant(auth_key="abcd", read=False, write=False, callback=_callback, error=_error) + + +# Complete flow , try publish on forbidden channel, grant permission to subkey and try again. ( Sync Mode) + +def test_8(): + channel = "test_8-" + str(time.time()) + message = "Hello World" + auth_key = "auth-" + channel + pubnub_pam.set_auth_key(auth_key) + + def _cb1(resp, ch=None): + assert False + def _err1(resp): + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + def _cb2(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': {u'auths': {auth_key : {u'r': 1, u'w': 1}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': channel, u'ttl': 10} + } + def _cb3(resp, ch=None): + assert resp[0] == 1 + def _err3(resp): + assert False + + pubnub_pam.publish(channel=channel,message=message, callback=_cb3, error=_err3) + def _err2(resp): + assert False + + + pubnub_pam.grant(channel=channel, read=True, write=True, auth_key=auth_key, ttl=10, callback=_cb2, error=_err2) + + pubnub_pam.publish(channel=channel,message=message, callback=_cb1, error=_err1) + + +# Complete flow , try publish on forbidden channel, grant permission to authkey and try again. +# then revoke and try again +def test_9(): + channel = "test_9-" + str(time.time()) + message = "Hello World" + auth_key = "auth-" + channel + pubnub_pam.set_auth_key(auth_key) + + def _cb1(resp, ch=None): + assert False + def _err1(resp): + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + def _cb2(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': {u'auths': {auth_key : {u'r': 1, u'w': 1}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': channel, u'ttl': 10} + } + def _cb3(resp, ch=None): + assert resp[0] == 1 + def _cb4(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': {u'auths': {auth_key : {u'r': 0, u'w': 0}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': channel, u'ttl': 1} + } + + def _cb5(resp, ch=None): + assert False + def _err5(resp): + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + + pubnub_pam.publish(channel=channel,message=message, callback=_cb5, error=_err5) + def _err4(resp): + assert False + pubnub_pam.revoke(channel=channel, auth_key=auth_key, callback=_cb4, error=_err4) + def _err3(resp): + assert False + + pubnub_pam.publish(channel=channel,message=message, callback=_cb3, error=_err3) + def _err2(resp): + assert False + + + pubnub_pam.grant(channel=channel, read=True, write=True, auth_key=auth_key, ttl=10, callback=_cb2, error=_err2) + + pubnub_pam.publish(channel=channel,message=message, callback=_cb1, error=_err1) + + +# Complete flow , try publish on forbidden channel, grant permission channel level for subkey and try again. +# then revoke and try again +def test_10(): + channel = "test_10-" + str(time.time()) + message = "Hello World" + auth_key = "auth-" + channel + pubnub_pam.set_auth_key(auth_key) + + def _cb1(resp, ch=None): + assert False + def _err1(resp): + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + def _cb2(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': { u'channels': {channel: {u'r': 1, u'w': 1}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'channel', u'ttl': 10} + } + def _cb3(resp, ch=None): + assert resp[0] == 1 + def _cb4(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': { u'channels': {channel : {u'r': 0, u'w': 0}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'channel', u'ttl': 1} + } + + def _cb5(resp, ch=None): + assert False + def _err5(resp): + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + + pubnub_pam.publish(channel=channel,message=message, callback=_cb5, error=_err5) + def _err4(resp): + assert False + pubnub_pam.revoke(channel=channel, callback=_cb4, error=_err4) + def _err3(resp): + assert False + + pubnub_pam.publish(channel=channel,message=message, callback=_cb3, error=_err3) + def _err2(resp): + assert False + + + pubnub_pam.grant(channel=channel, read=True, write=True, ttl=10, callback=_cb2, error=_err2) + + pubnub_pam.publish(channel=channel,message=message, callback=_cb1, error=_err1) + + + + + + +# Complete flow , try publish on forbidden channel, grant permission subkey level for subkey and try again. +# then revoke and try again +def test_11(): + channel = "test_11-" + str(time.time()) + message = "Hello World" + auth_key = "auth-" + channel + pubnub_pam.set_auth_key(auth_key) + + def _cb1(resp, ch=None): + assert False + def _err1(resp): + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + def _cb2(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': { u'r': 1, u'w': 1, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'subkey', u'ttl': 10} + } + def _cb3(resp, ch=None): + assert resp[0] == 1 + def _cb4(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': {u'r': 0, u'w': 0, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'subkey', u'ttl': 1} + } + + def _cb5(resp, ch=None): + assert False + def _err5(resp): + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + + pubnub_pam.publish(channel=channel,message=message, callback=_cb5, error=_err5) + def _err4(resp): + assert False + pubnub_pam.revoke(callback=_cb4, error=_err4) + def _err3(resp): + assert False + + pubnub_pam.publish(channel=channel,message=message, callback=_cb3, error=_err3) + def _err2(resp): + assert False + + + pubnub_pam.grant(read=True, write=True, ttl=10, callback=_cb2, error=_err2) + + pubnub_pam.publish(channel=channel,message=message, callback=_cb1, error=_err1) + + +x = 5 +def run_test(t): + global x + x += 5 + i = (x / 5) - 1 + def _print(): + print('Running test ' + str(i)) + pubnub.timeout(x, _print) + pubnub.timeout(x + 1,t) + +def stop(): + pubnub.stop() + +run_test(test_1) +run_test(test_2) +run_test(test_3) +run_test(test_4) +run_test(test_5) +run_test(test_6) +run_test(test_7) +run_test(test_8) +run_test(test_9) +run_test(test_10) +run_test(test_11) +run_test(stop) + + +pubnub_pam.start() + + -- cgit v1.2.3 From 3faa087aca856d14e4dca7b3ec41a691f8d468f2 Mon Sep 17 00:00:00 2001 From: Devendra Date: Thu, 15 May 2014 18:33:10 +0530 Subject: adding unit tests --- Pubnub.py | 19 ++-- python/tests/test_publish_async.py | 228 +++++++++++++++++++++++++++++++++++++ 2 files changed, 240 insertions(+), 7 deletions(-) create mode 100644 python/tests/test_publish_async.py diff --git a/Pubnub.py b/Pubnub.py index d75b452..acc680b 100644 --- a/Pubnub.py +++ b/Pubnub.py @@ -116,9 +116,12 @@ except ImportError: def get_data_for_user(data): - if 'message' in data and 'payload' in data: - return {'message': data['message'], 'payload': data['payload']} - else: + try: + if 'message' in data and 'payload' in data: + return {'message': data['message'], 'payload': data['payload']} + else: + return data + except TypeError: return data @@ -138,7 +141,6 @@ class PubnubCrypto2(): return hashlib.sha256(key).hexdigest() def encrypt(self, key, msg): - secret = self.getSecret(key) Initial16bytes = '0123456789012345' cipher = AES.new(secret[0:32], AES.MODE_CBC, Initial16bytes) @@ -150,8 +152,11 @@ class PubnubCrypto2(): secret = self.getSecret(key) Initial16bytes = '0123456789012345' cipher = AES.new(secret[0:32], AES.MODE_CBC, Initial16bytes) - return self.depad((cipher.decrypt(decodestring(msg)))) - + plain = self.depad(cipher.decrypt(decodestring(msg))) + try: + return eval(plain) + except SyntaxError: + return plain class PubnubCrypto3(): @@ -795,7 +800,7 @@ class PubnubBase(object): if ("urlparams" in request): url = url + '?' + "&".join([x + "=" + str(y) for x, y in request[ "urlparams"].items() if y is not None]) - print url + #print url return url diff --git a/python/tests/test_publish_async.py b/python/tests/test_publish_async.py new file mode 100644 index 0000000..7270727 --- /dev/null +++ b/python/tests/test_publish_async.py @@ -0,0 +1,228 @@ + + +from Pubnub import Pubnub +import time + +pubnub = Pubnub("demo","demo") +pubnub_enc = Pubnub("demo", "demo", cipher_key="enigma") +pubnub_pam = Pubnub("pub-c-c077418d-f83c-4860-b213-2f6c77bde29a", + "sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe", "sec-c-OGU3Y2Q4ZWUtNDQwMC00NTI1LThjNWYtNWJmY2M4OGIwNjEy") + + + +# Publish and receive string +def test_1(): + + channel = "test_1-" + str(time.time()) + message = "I am a string" + + def _cb(resp, ch=None): + assert resp == message + pubnub.unsubscribe(channel) + + def _connect(resp): + pubnub.publish(channel,message) + + def _error(resp): + assert False + + pubnub.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive array +def test_2(): + + channel = "test_2-" + str(time.time()) + message = [1,2] + + def _cb(resp, ch=None): + assert resp == message + pubnub.unsubscribe(channel) + + def _connect(resp): + pubnub.publish(channel,message) + + def _error(resp): + assert False + + pubnub.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive json object +def test_3(): + + channel = "test_2-" + str(time.time()) + message = { "a" : "b" } + + def _cb(resp, ch=None): + assert resp == message + pubnub.unsubscribe(channel) + + def _connect(resp): + pubnub.publish(channel,message) + + def _error(resp): + assert False + + pubnub.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive number +def test_4(): + + channel = "test_2-" + str(time.time()) + message = 100 + + def _cb(resp, ch=None): + assert resp == message + pubnub.unsubscribe(channel) + + def _connect(resp): + pubnub.publish(channel,message) + + def _error(resp): + assert False + + pubnub.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive number string +def test_5(): + + channel = "test_5-" + str(time.time()) + message = "100" + + def _cb(resp, ch=None): + assert resp == message + pubnub.unsubscribe(channel) + + def _connect(resp): + pubnub.publish(channel,message) + + def _error(resp): + assert False + + pubnub.subscribe(channel, callback=_cb, connect=_connect, error=_error) + + +# Publish and receive string (Encryption enabled) +def test_6(): + + channel = "test_6-" + str(time.time()) + message = "I am a string" + + def _cb(resp, ch=None): + assert resp == message + pubnub_enc.unsubscribe(channel) + + def _connect(resp): + pubnub_enc.publish(channel,message) + + def _error(resp): + assert False + + pubnub_enc.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive array (Encryption enabled) +def test_7(): + + channel = "test_7-" + str(time.time()) + message = [1,2] + + def _cb(resp, ch=None): + assert resp == message + pubnub_enc.unsubscribe(channel) + + def _connect(resp): + pubnub.publish(channel,message) + + def _error(resp): + assert False + + pubnub.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive json object (Encryption enabled) +def test_8(): + + channel = "test_8-" + str(time.time()) + message = { "a" : "b" } + + def _cb(resp, ch=None): + assert resp == message + pubnub_enc.unsubscribe(channel) + + def _connect(resp): + pubnub_enc.publish(channel,message) + + def _error(resp): + assert False + + pubnub_enc.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive number (Encryption enabled) +def test_9(): + + channel = "test_9-" + str(time.time()) + message = 100 + + def _cb(resp, ch=None): + assert resp == message + pubnub_enc.unsubscribe(channel) + + def _connect(resp): + pubnub_enc.publish(channel,message) + + def _error(resp): + assert False + + pubnub_enc.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive number string (Encryption enabled) +def test_10(): + + channel = "test_10-" + str(time.time()) + message = "100" + + def _cb(resp, ch=None): + assert resp == message + pubnub_enc.unsubscribe(channel) + + def _connect(resp): + pubnub_enc.publish(channel,message) + + def _error(resp): + assert False + + pubnub_enc.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive object string (Encryption enabled) +def test_11(): + + channel = "test_11-" + str(time.time()) + message = '{"a" : "b"}' + + def _cb(resp, ch=None): + assert resp == message + pubnub_enc.unsubscribe(channel) + + def _connect(resp): + pubnub_enc.publish(channel,message) + + def _error(resp): + assert False + + pubnub_enc.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive array string (Encryption enabled) +def test_12(): + + channel = "test_12-" + str(time.time()) + message = '[1,2]' + + def _cb(resp, ch=None): + assert resp == message + pubnub_enc.unsubscribe(channel) + + def _connect(resp): + pubnub_enc.publish(channel,message) + + def _error(resp): + assert False + + pubnub_enc.subscribe(channel, callback=_cb, connect=_connect, error=_error) -- cgit v1.2.3 From 32492b68b66a46bdbf6736e1ddd16a34dca12b9b Mon Sep 17 00:00:00 2001 From: Devendra Date: Thu, 15 May 2014 19:48:06 +0530 Subject: adding more unit tests --- python-tornado/tests/test_publish_async.py | 304 ++++++++++++++++++++++++ python-tornado/tests/unit-tests.py | 67 ------ python-twisted/tests/test_grant_async.py | 359 +++++++++++++++++++++++++++++ python-twisted/tests/test_publish_async.py | 304 ++++++++++++++++++++++++ python-twisted/tests/unit-tests.py | 107 --------- python/tests/detailed-history-unit-test.py | 134 ----------- python/tests/unit-test.py | 66 ------ 7 files changed, 967 insertions(+), 374 deletions(-) create mode 100644 python-tornado/tests/test_publish_async.py delete mode 100644 python-tornado/tests/unit-tests.py create mode 100644 python-twisted/tests/test_grant_async.py create mode 100644 python-twisted/tests/test_publish_async.py delete mode 100644 python-twisted/tests/unit-tests.py delete mode 100755 python/tests/detailed-history-unit-test.py delete mode 100755 python/tests/unit-test.py diff --git a/python-tornado/tests/test_publish_async.py b/python-tornado/tests/test_publish_async.py new file mode 100644 index 0000000..391297d --- /dev/null +++ b/python-tornado/tests/test_publish_async.py @@ -0,0 +1,304 @@ + + +from Pubnub import PubnubTwisted as Pubnub +import time + +pubnub = Pubnub("demo","demo") +pubnub_enc = Pubnub("demo", "demo", cipher_key="enigma") +pubnub_pam = Pubnub("pub-c-c077418d-f83c-4860-b213-2f6c77bde29a", + "sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe", "sec-c-OGU3Y2Q4ZWUtNDQwMC00NTI1LThjNWYtNWJmY2M4OGIwNjEy") + + + +# Publish and receive string +def test_1(): + + channel = "test_1-" + str(time.time()) + message = "I am a string" + + def _cb(resp, ch=None): + assert resp == message + pubnub.unsubscribe(channel) + + def _connect(resp): + def _cb1(resp,ch=None): + assert resp[0] == 1 + def _err1(resp): + assert False + pubnub.publish(channel,message, callback=_cb1, error=_err1) + + def _error(resp): + assert False + + pubnub.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive array +def test_2(): + + channel = "test_2-" + str(time.time()) + message = [1,2] + + def _cb(resp, ch=None): + assert resp == message + pubnub.unsubscribe(channel) + + def _connect(resp): + def _cb1(resp,ch=None): + assert resp[0] == 1 + def _err1(resp): + assert False + pubnub.publish(channel,message, callback=_cb1, error=_err1) + + def _error(resp): + assert False + + pubnub.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive json object +def test_3(): + + channel = "test_2-" + str(time.time()) + message = { "a" : "b" } + + def _cb(resp, ch=None): + assert resp == message + pubnub.unsubscribe(channel) + + def _connect(resp): + def _cb1(resp,ch=None): + assert resp[0] == 1 + def _err1(resp): + assert False + pubnub.publish(channel,message, callback=_cb1, error=_err1) + + def _error(resp): + assert False + + pubnub.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive number +def test_4(): + + channel = "test_2-" + str(time.time()) + message = 100 + + def _cb(resp, ch=None): + assert resp == message + pubnub.unsubscribe(channel) + + def _connect(resp): + def _cb1(resp,ch=None): + assert resp[0] == 1 + def _err1(resp): + assert False + pubnub.publish(channel,message, callback=_cb1, error=_err1) + + def _error(resp): + assert False + + pubnub.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive number string +def test_5(): + + channel = "test_5-" + str(time.time()) + message = "100" + + def _cb(resp, ch=None): + assert resp == message + pubnub.unsubscribe(channel) + + def _connect(resp): + def _cb1(resp,ch=None): + assert resp[0] == 1 + def _err1(resp): + assert False + pubnub.publish(channel,message, callback=_cb1, error=_err1) + + def _error(resp): + assert False + + pubnub.subscribe(channel, callback=_cb, connect=_connect, error=_error) + + +# Publish and receive string (Encryption enabled) +def test_6(): + + channel = "test_6-" + str(time.time()) + message = "I am a string" + + def _cb(resp, ch=None): + assert resp == message + pubnub_enc.unsubscribe(channel) + + def _connect(resp): + def _cb1(resp,ch=None): + assert resp[0] == 1 + def _err1(resp): + assert False + pubnub_enc.publish(channel,message, callback=_cb1, error=_err1) + + def _error(resp): + assert False + + pubnub_enc.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive array (Encryption enabled) +def test_7(): + + channel = "test_7-" + str(time.time()) + message = [1,2] + + def _cb(resp, ch=None): + assert resp == message + pubnub_enc.unsubscribe(channel) + + def _connect(resp): + def _cb1(resp,ch=None): + assert resp[0] == 1 + def _err1(resp): + assert False + pubnub_enc.publish(channel,message, callback=_cb1, error=_err1) + + def _error(resp): + assert False + + pubnub_enc.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive json object (Encryption enabled) +def test_8(): + + channel = "test_8-" + str(time.time()) + message = { "a" : "b" } + + def _cb(resp, ch=None): + assert resp == message + pubnub_enc.unsubscribe(channel) + + def _connect(resp): + def _cb1(resp,ch=None): + assert resp[0] == 1 + def _err1(resp): + assert False + pubnub_enc.publish(channel,message, callback=_cb1, error=_err1) + + def _error(resp): + assert False + + pubnub_enc.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive number (Encryption enabled) +def test_9(): + + channel = "test_9-" + str(time.time()) + message = 100 + + def _cb(resp, ch=None): + assert resp == message + pubnub_enc.unsubscribe(channel) + + def _connect(resp): + def _cb1(resp,ch=None): + assert resp[0] == 1 + def _err1(resp): + assert False + pubnub_enc.publish(channel,message, callback=_cb1, error=_err1) + + def _error(resp): + assert False + + pubnub_enc.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive number string (Encryption enabled) +def test_10(): + + channel = "test_10-" + str(time.time()) + message = "100" + + def _cb(resp, ch=None): + assert resp == message + pubnub_enc.unsubscribe(channel) + + def _connect(resp): + def _cb1(resp,ch=None): + assert resp[0] == 1 + def _err1(resp): + assert False + pubnub_enc.publish(channel,message, callback=_cb1, error=_err1) + + def _error(resp): + assert False + + pubnub_enc.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive object string (Encryption enabled) +def test_11(): + + channel = "test_11-" + str(time.time()) + message = '{"a" : "b"}' + + def _cb(resp, ch=None): + assert resp == message + pubnub_enc.unsubscribe(channel) + + def _connect(resp): + def _cb1(resp,ch=None): + assert resp[0] == 1 + def _err1(resp): + assert False + pubnub_enc.publish(channel,message, callback=_cb1, error=_err1) + + def _error(resp): + assert False + + pubnub_enc.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive array string (Encryption enabled) +def test_12(): + + channel = "test_12-" + str(time.time()) + message = '[1,2]' + + def _cb(resp, ch=None): + assert resp == message + pubnub_enc.unsubscribe(channel) + + def _connect(resp): + def _cb1(resp,ch=None): + assert resp[0] == 1 + def _err1(resp): + assert False + pubnub_enc.publish(channel,message, callback=_cb1, error=_err1) + + def _error(resp): + assert False + + pubnub_enc.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +x = 5 +def run_test(t): + global x + x += 5 + i = (x / 5) - 1 + def _print(): + print('Running test ' + str(i)) + pubnub.timeout(x, _print) + pubnub.timeout(x + 1,t) + +def stop(): + pubnub.stop() + +run_test(test_1) +run_test(test_2) +run_test(test_3) +run_test(test_4) +run_test(test_5) +run_test(test_6) +run_test(test_7) +run_test(test_8) +run_test(test_9) +run_test(test_10) +run_test(test_11) +run_test(stop) + +pubnub_enc.start() diff --git a/python-tornado/tests/unit-tests.py b/python-tornado/tests/unit-tests.py deleted file mode 100644 index b00f2b7..0000000 --- a/python-tornado/tests/unit-tests.py +++ /dev/null @@ -1,67 +0,0 @@ - -import sys - - -from PubnubUnitTest import Suite -from Pubnub import PubnubTwisted as Pubnub - -pubnub = Pubnub("demo", "demo") - -tests_count = 1 + 2 -test_suite = Suite(pubnub, tests_count) - -tests = [] - - -def test_publish(): - name = "Publish Test" - - def success(r): - test_suite.test(r[0] == 1, name) - - def fail(e): - test_suite.test(False, msg, e) - - pubnub.publish({ - 'channel': 'hello', - 'message': 'hi', - 'callback': success, - 'error': fail - }) -tests.append(test_publish) - - -def test_subscribe_publish(): - channel = "hello" - name = "Subscribe Publish Test" - publish_msg = "This is Pubnub Python-Twisted" - - def connect(): - def success(r): - test_suite.test(r[0] == 1, name, "publish success") - - def fail(e): - test_suite.test(False, name, "Publish Failed", e) - - pubnub.publish({ - 'channel': channel, - 'message': publish_msg, - 'callback': success, - 'error': fail - }) - - def callback(r): - test_suite.test(r == publish_msg, name, "message received") - - pubnub.subscribe({ - 'channel': channel, - 'callback': callback, - 'connect': connect - }) -tests.append(test_subscribe_publish) - - -for t in tests: - t() - -pubnub.start() diff --git a/python-twisted/tests/test_grant_async.py b/python-twisted/tests/test_grant_async.py new file mode 100644 index 0000000..5b33b11 --- /dev/null +++ b/python-twisted/tests/test_grant_async.py @@ -0,0 +1,359 @@ + + +from Pubnub import PubnubTwisted as Pubnub +import time + +pubnub = Pubnub("demo","demo") +pubnub_pam = Pubnub("pub-c-c077418d-f83c-4860-b213-2f6c77bde29a", + "sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe", "sec-c-OGU3Y2Q4ZWUtNDQwMC00NTI1LThjNWYtNWJmY2M4OGIwNjEy") + + + +# Grant permission read true, write true, on channel ( Async Mode ) +def test_1(): + + def _callback(resp, ch= None): + assert resp == { + 'message': u'Success', + 'payload': {u'auths': {u'abcd': {u'r': 1, u'w': 1}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': u'abcd', u'ttl': 1} + } + + def _error(response): + assert False + + pubnub_pam.grant(channel="abcd", auth_key="abcd", read=True, write=True, ttl=1, callback=_callback, error=_error) + + +# Grant permission read false, write false, on channel ( Async Mode ) +def test_2(): + + def _callback(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': {u'auths': {u'abcd': {u'r': 0, u'w': 0}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': u'abcd', u'ttl': 1} + } + + def _error(response): + assert False + + pubnub_pam.grant(channel="abcd", auth_key="abcd", read=False, write=False, ttl=1, callback=_callback, error=_error) + + +# Grant permission read True, write false, on channel ( Async Mode ) +def test_3(): + + def _callback(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': {u'auths': {u'abcd': {u'r': 1, u'w': 0}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': u'abcd', u'ttl': 1} + } + + def _error(response): + assert False + + pubnub_pam.grant(channel="abcd", auth_key="abcd", read=True, write=False, ttl=1, callback=_callback, error=_error) + + +# Grant permission read False, write True, on channel ( Async Mode ) +def test_4(): + + def _callback(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': {u'auths': {u'abcd': {u'r': 0, u'w': 1}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': u'abcd', u'ttl': 1} + } + + def _error(response): + assert False + + pubnub_pam.grant(channel="abcd", auth_key="abcd", read=False, write=True, ttl=1, callback=_callback, error=_error) + + +# Grant permission read False, write True, on channel ( Async Mode ), TTL 10 +def test_5(): + + def _callback(resp,ch=None): + assert resp == { + 'message': u'Success', + 'payload': {u'auths': {u'abcd': {u'r': 0, u'w': 1}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': u'abcd', u'ttl': 10} + } + + + def _error(response): + assert False + + pubnub_pam.grant(channel="abcd", auth_key="abcd", read=False, write=True, ttl=10, callback=_callback, error=_error) + + +# Grant permission read False, write True, without channel ( Async Mode ), TTL 10 +def test_6(): + def _callback(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': { u'r': 0, u'w': 1, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'subkey', u'ttl': 10} + } + + def _error(response): + assert False + + pubnub_pam.grant(auth_key="abcd", read=False, write=True, ttl=10, callback=_callback, error=_error) + + + +# Grant permission read False, write False, without channel ( Async Mode ) +def test_7(): + + def _callback(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': { u'r': 0, u'w': 0, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'subkey', u'ttl': 1} + } + + def _error(response): + resp['response'] = response + + pubnub_pam.grant(auth_key="abcd", read=False, write=False, callback=_callback, error=_error) + + +# Complete flow , try publish on forbidden channel, grant permission to subkey and try again. ( Sync Mode) + +def test_8(): + channel = "test_8-" + str(time.time()) + message = "Hello World" + auth_key = "auth-" + channel + pubnub_pam.set_auth_key(auth_key) + + def _cb1(resp, ch=None): + assert False + def _err1(resp): + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + def _cb2(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': {u'auths': {auth_key : {u'r': 1, u'w': 1}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': channel, u'ttl': 10} + } + def _cb3(resp, ch=None): + assert resp[0] == 1 + def _err3(resp): + assert False + + pubnub_pam.publish(channel=channel,message=message, callback=_cb3, error=_err3) + def _err2(resp): + assert False + + + pubnub_pam.grant(channel=channel, read=True, write=True, auth_key=auth_key, ttl=10, callback=_cb2, error=_err2) + + pubnub_pam.publish(channel=channel,message=message, callback=_cb1, error=_err1) + + +# Complete flow , try publish on forbidden channel, grant permission to authkey and try again. +# then revoke and try again +def test_9(): + channel = "test_9-" + str(time.time()) + message = "Hello World" + auth_key = "auth-" + channel + pubnub_pam.set_auth_key(auth_key) + + def _cb1(resp, ch=None): + assert False + def _err1(resp): + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + def _cb2(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': {u'auths': {auth_key : {u'r': 1, u'w': 1}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': channel, u'ttl': 10} + } + def _cb3(resp, ch=None): + assert resp[0] == 1 + def _cb4(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': {u'auths': {auth_key : {u'r': 0, u'w': 0}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'user', u'channel': channel, u'ttl': 1} + } + + def _cb5(resp, ch=None): + assert False + def _err5(resp): + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + + pubnub_pam.publish(channel=channel,message=message, callback=_cb5, error=_err5) + def _err4(resp): + assert False + pubnub_pam.revoke(channel=channel, auth_key=auth_key, callback=_cb4, error=_err4) + def _err3(resp): + assert False + + pubnub_pam.publish(channel=channel,message=message, callback=_cb3, error=_err3) + def _err2(resp): + assert False + + + pubnub_pam.grant(channel=channel, read=True, write=True, auth_key=auth_key, ttl=10, callback=_cb2, error=_err2) + + pubnub_pam.publish(channel=channel,message=message, callback=_cb1, error=_err1) + + +# Complete flow , try publish on forbidden channel, grant permission channel level for subkey and try again. +# then revoke and try again +def test_10(): + channel = "test_10-" + str(time.time()) + message = "Hello World" + auth_key = "auth-" + channel + pubnub_pam.set_auth_key(auth_key) + + def _cb1(resp, ch=None): + assert False + def _err1(resp): + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + def _cb2(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': { u'channels': {channel: {u'r': 1, u'w': 1}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'channel', u'ttl': 10} + } + def _cb3(resp, ch=None): + assert resp[0] == 1 + def _cb4(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': { u'channels': {channel : {u'r': 0, u'w': 0}}, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'channel', u'ttl': 1} + } + + def _cb5(resp, ch=None): + assert False + def _err5(resp): + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + + pubnub_pam.publish(channel=channel,message=message, callback=_cb5, error=_err5) + def _err4(resp): + assert False + pubnub_pam.revoke(channel=channel, callback=_cb4, error=_err4) + def _err3(resp): + assert False + + pubnub_pam.publish(channel=channel,message=message, callback=_cb3, error=_err3) + def _err2(resp): + assert False + + + pubnub_pam.grant(channel=channel, read=True, write=True, ttl=10, callback=_cb2, error=_err2) + + pubnub_pam.publish(channel=channel,message=message, callback=_cb1, error=_err1) + + + + + + +# Complete flow , try publish on forbidden channel, grant permission subkey level for subkey and try again. +# then revoke and try again +def test_11(): + channel = "test_11-" + str(time.time()) + message = "Hello World" + auth_key = "auth-" + channel + pubnub_pam.set_auth_key(auth_key) + + def _cb1(resp, ch=None): + assert False + def _err1(resp): + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + def _cb2(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': { u'r': 1, u'w': 1, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'subkey', u'ttl': 10} + } + def _cb3(resp, ch=None): + assert resp[0] == 1 + def _cb4(resp, ch=None): + assert resp == { + 'message': u'Success', + 'payload': {u'r': 0, u'w': 0, + u'subscribe_key': u'sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe', + u'level': u'subkey', u'ttl': 1} + } + + def _cb5(resp, ch=None): + assert False + def _err5(resp): + assert resp['message'] == 'Forbidden' + assert resp['payload'] == {u'channels': [channel]} + + pubnub_pam.publish(channel=channel,message=message, callback=_cb5, error=_err5) + def _err4(resp): + assert False + pubnub_pam.revoke(callback=_cb4, error=_err4) + def _err3(resp): + assert False + + pubnub_pam.publish(channel=channel,message=message, callback=_cb3, error=_err3) + def _err2(resp): + assert False + + + pubnub_pam.grant(read=True, write=True, ttl=10, callback=_cb2, error=_err2) + + pubnub_pam.publish(channel=channel,message=message, callback=_cb1, error=_err1) + + +x = 5 +def run_test(t): + global x + x += 5 + i = (x / 5) - 1 + def _print(): + print('Running test ' + str(i)) + pubnub.timeout(x, _print) + pubnub.timeout(x + 1,t) + +def stop(): + pubnub.stop() + +run_test(test_1) +run_test(test_2) +run_test(test_3) +run_test(test_4) +run_test(test_5) +run_test(test_6) +run_test(test_7) +run_test(test_8) +run_test(test_9) +run_test(test_10) +run_test(test_11) +run_test(stop) + + +pubnub_pam.start() + + diff --git a/python-twisted/tests/test_publish_async.py b/python-twisted/tests/test_publish_async.py new file mode 100644 index 0000000..391297d --- /dev/null +++ b/python-twisted/tests/test_publish_async.py @@ -0,0 +1,304 @@ + + +from Pubnub import PubnubTwisted as Pubnub +import time + +pubnub = Pubnub("demo","demo") +pubnub_enc = Pubnub("demo", "demo", cipher_key="enigma") +pubnub_pam = Pubnub("pub-c-c077418d-f83c-4860-b213-2f6c77bde29a", + "sub-c-e8839098-f568-11e2-a11a-02ee2ddab7fe", "sec-c-OGU3Y2Q4ZWUtNDQwMC00NTI1LThjNWYtNWJmY2M4OGIwNjEy") + + + +# Publish and receive string +def test_1(): + + channel = "test_1-" + str(time.time()) + message = "I am a string" + + def _cb(resp, ch=None): + assert resp == message + pubnub.unsubscribe(channel) + + def _connect(resp): + def _cb1(resp,ch=None): + assert resp[0] == 1 + def _err1(resp): + assert False + pubnub.publish(channel,message, callback=_cb1, error=_err1) + + def _error(resp): + assert False + + pubnub.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive array +def test_2(): + + channel = "test_2-" + str(time.time()) + message = [1,2] + + def _cb(resp, ch=None): + assert resp == message + pubnub.unsubscribe(channel) + + def _connect(resp): + def _cb1(resp,ch=None): + assert resp[0] == 1 + def _err1(resp): + assert False + pubnub.publish(channel,message, callback=_cb1, error=_err1) + + def _error(resp): + assert False + + pubnub.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive json object +def test_3(): + + channel = "test_2-" + str(time.time()) + message = { "a" : "b" } + + def _cb(resp, ch=None): + assert resp == message + pubnub.unsubscribe(channel) + + def _connect(resp): + def _cb1(resp,ch=None): + assert resp[0] == 1 + def _err1(resp): + assert False + pubnub.publish(channel,message, callback=_cb1, error=_err1) + + def _error(resp): + assert False + + pubnub.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive number +def test_4(): + + channel = "test_2-" + str(time.time()) + message = 100 + + def _cb(resp, ch=None): + assert resp == message + pubnub.unsubscribe(channel) + + def _connect(resp): + def _cb1(resp,ch=None): + assert resp[0] == 1 + def _err1(resp): + assert False + pubnub.publish(channel,message, callback=_cb1, error=_err1) + + def _error(resp): + assert False + + pubnub.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive number string +def test_5(): + + channel = "test_5-" + str(time.time()) + message = "100" + + def _cb(resp, ch=None): + assert resp == message + pubnub.unsubscribe(channel) + + def _connect(resp): + def _cb1(resp,ch=None): + assert resp[0] == 1 + def _err1(resp): + assert False + pubnub.publish(channel,message, callback=_cb1, error=_err1) + + def _error(resp): + assert False + + pubnub.subscribe(channel, callback=_cb, connect=_connect, error=_error) + + +# Publish and receive string (Encryption enabled) +def test_6(): + + channel = "test_6-" + str(time.time()) + message = "I am a string" + + def _cb(resp, ch=None): + assert resp == message + pubnub_enc.unsubscribe(channel) + + def _connect(resp): + def _cb1(resp,ch=None): + assert resp[0] == 1 + def _err1(resp): + assert False + pubnub_enc.publish(channel,message, callback=_cb1, error=_err1) + + def _error(resp): + assert False + + pubnub_enc.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive array (Encryption enabled) +def test_7(): + + channel = "test_7-" + str(time.time()) + message = [1,2] + + def _cb(resp, ch=None): + assert resp == message + pubnub_enc.unsubscribe(channel) + + def _connect(resp): + def _cb1(resp,ch=None): + assert resp[0] == 1 + def _err1(resp): + assert False + pubnub_enc.publish(channel,message, callback=_cb1, error=_err1) + + def _error(resp): + assert False + + pubnub_enc.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive json object (Encryption enabled) +def test_8(): + + channel = "test_8-" + str(time.time()) + message = { "a" : "b" } + + def _cb(resp, ch=None): + assert resp == message + pubnub_enc.unsubscribe(channel) + + def _connect(resp): + def _cb1(resp,ch=None): + assert resp[0] == 1 + def _err1(resp): + assert False + pubnub_enc.publish(channel,message, callback=_cb1, error=_err1) + + def _error(resp): + assert False + + pubnub_enc.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive number (Encryption enabled) +def test_9(): + + channel = "test_9-" + str(time.time()) + message = 100 + + def _cb(resp, ch=None): + assert resp == message + pubnub_enc.unsubscribe(channel) + + def _connect(resp): + def _cb1(resp,ch=None): + assert resp[0] == 1 + def _err1(resp): + assert False + pubnub_enc.publish(channel,message, callback=_cb1, error=_err1) + + def _error(resp): + assert False + + pubnub_enc.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive number string (Encryption enabled) +def test_10(): + + channel = "test_10-" + str(time.time()) + message = "100" + + def _cb(resp, ch=None): + assert resp == message + pubnub_enc.unsubscribe(channel) + + def _connect(resp): + def _cb1(resp,ch=None): + assert resp[0] == 1 + def _err1(resp): + assert False + pubnub_enc.publish(channel,message, callback=_cb1, error=_err1) + + def _error(resp): + assert False + + pubnub_enc.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive object string (Encryption enabled) +def test_11(): + + channel = "test_11-" + str(time.time()) + message = '{"a" : "b"}' + + def _cb(resp, ch=None): + assert resp == message + pubnub_enc.unsubscribe(channel) + + def _connect(resp): + def _cb1(resp,ch=None): + assert resp[0] == 1 + def _err1(resp): + assert False + pubnub_enc.publish(channel,message, callback=_cb1, error=_err1) + + def _error(resp): + assert False + + pubnub_enc.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +# Publish and receive array string (Encryption enabled) +def test_12(): + + channel = "test_12-" + str(time.time()) + message = '[1,2]' + + def _cb(resp, ch=None): + assert resp == message + pubnub_enc.unsubscribe(channel) + + def _connect(resp): + def _cb1(resp,ch=None): + assert resp[0] == 1 + def _err1(resp): + assert False + pubnub_enc.publish(channel,message, callback=_cb1, error=_err1) + + def _error(resp): + assert False + + pubnub_enc.subscribe(channel, callback=_cb, connect=_connect, error=_error) + +x = 5 +def run_test(t): + global x + x += 5 + i = (x / 5) - 1 + def _print(): + print('Running test ' + str(i)) + pubnub.timeout(x, _print) + pubnub.timeout(x + 1,t) + +def stop(): + pubnub.stop() + +run_test(test_1) +run_test(test_2) +run_test(test_3) +run_test(test_4) +run_test(test_5) +run_test(test_6) +run_test(test_7) +run_test(test_8) +run_test(test_9) +run_test(test_10) +run_test(test_11) +run_test(stop) + +pubnub_enc.start() diff --git a/python-twisted/tests/unit-tests.py b/python-twisted/tests/unit-tests.py deleted file mode 100644 index 70c373b..0000000 --- a/python-twisted/tests/unit-tests.py +++ /dev/null @@ -1,107 +0,0 @@ - -import sys -import time - - -from PubnubUnitTest import Suite -from Pubnub import PubnubTwisted as Pubnub - -pubnub = Pubnub("demo", "demo") - -tests_count = 1 + 2 + 1 -test_suite = Suite(pubnub, tests_count) - -tests = [] - - -def test_publish(): - channel = "hello" + str(time.time()) - name = "Publish Test" - - def success(r): - test_suite.test(r[0] == 1, name) - - def fail(e): - test_suite.test(False, msg, e) - - pubnub.publish({ - 'channel': 'hello', - 'message': 'hi', - 'callback': success, - 'error': fail - }) -tests.append(test_publish) - -#""" - - -def test_subscribe_publish(): - channel = "hello" + str(time.time()) - name = "Subscribe Publish Test" - publish_msg = "This is Pubnub Python-Twisted" - - def connect(): - #print 'connect' - def success(r): - test_suite.test(r[0] == 1, name, "publish success") - - def fail(e): - test_suite.test(False, name, "Publish Failed", e) - - pubnub.publish({ - 'channel': channel, - 'message': publish_msg, - 'callback': success, - 'error': fail - }) - - def callback(r): - test_suite.test(r == publish_msg, name, "message received") - - pubnub.subscribe({ - 'channel': channel, - 'callback': callback, - 'connect': connect - }) -tests.append(test_subscribe_publish) -#""" - - -def test_here_now(): - channel = "hello12" # + str(time.time()) - name = "Here Now Test" - - def connect(): - print 'connect' - - def call_here_now(): - print 'call_here_now' - - def success(r): - test_suite.test(r['occupancy'] == 1, name, "Here Now success") - - def fail(e): - test_suite.test(False, name, "Here Now Failed", e) - - pubnub.here_now({ - 'channel': channel, - 'callback': success, - 'error': fail - }) - pubnub.timeout(5, call_here_now) - - def callback(r): - pass - print 'Subscribe' - pubnub.subscribe({ - 'channel': channel, - 'callback': callback, - 'connect': connect - }) -tests.append(test_here_now) - - -for t in tests: - t() - -pubnub.start() diff --git a/python/tests/detailed-history-unit-test.py b/python/tests/detailed-history-unit-test.py deleted file mode 100755 index fd2c81a..0000000 --- a/python/tests/detailed-history-unit-test.py +++ /dev/null @@ -1,134 +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.0 Real-time Push Cloud API -## ----------------------------------- - -import sys -from Pubnub import PubnubAsync as Pubnub -import unittest as unittest - - -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' -subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or None -ssl_on = len(sys.argv) > 4 and bool(sys.argv[4]) or False -pubnub = Pubnub(publish_key, subscribe_key, secret_key, ssl_on) -crazy = ' ~`!@#$%^&*(顶顅Ȓ)+=[]\\{}|;\':",./<>?abcd' - - -class TestDetailedHistory(unittest.TestCase): - total_msg = 10 - channel = pubnub.time() - starttime = None - inputs = [] - endtime = None - slice_a = 8 - slice_b = 2 - slice_size = slice_a - slice_b - - @classmethod - def publish_msg(cls, start, end, offset): - print('Publishing messages') - inputs = [] - for i in range(start + offset, end + offset): - message = str(i) + " " + crazy - success = pubnub.publish({ - 'channel': cls.channel, - 'message': message, - }) - t = pubnub.time() - inputs.append({'timestamp': t, 'message': message}) - print(('Message # ' + i + ' published')) - return inputs - - @classmethod - def setUpClass(c): - print('Setting up context for Detailed History tests. Please wait ...') - c.starttime = pubnub.time() - c.inputs = c.inputs + c.publish_msg(0, c.total_msg / 2, 0) - c.midtime = pubnub.time() - c.inputs = c.inputs + c.publish_msg( - 0, c.total_msg / 2, c.total_msg / 2) - c.endtime = pubnub.time() - print('Context setup for Detailed History tests. Now running tests') - - def test_begin_to_end_count(self): - count = 5 - history = pubnub.detailedHistory({ - 'channel': self.__class__.channel, - 'start': self.__class__.starttime, - 'end': self.__class__.endtime, - 'count': count - })[0] - self.assertTrue(len(history) == count and history[-1].encode( - 'utf-8') == self.__class__.inputs[count - 1]['message']) - - def test_end_to_begin_count(self): - count = 5 - history = pubnub.detailedHistory({ - 'channel': self.__class__.channel, - 'start': self.__class__.endtime, - 'end': self.__class__.starttime, - 'count': count - })[0] - self.assertTrue(len(history) == count and history[-1] - .encode('utf-8') == self.__class__.inputs[-1]['message']) - - def test_start_reverse_true(self): - history = pubnub.detailedHistory({ - 'channel': self.__class__.channel, - 'start': self.__class__.midtime, - 'reverse': True - })[0] - self.assertTrue(len(history) == self.__class__.total_msg / 2) - expected_msg = self.__class__.inputs[-1]['message'] - self.assertTrue(history[-1].encode('utf-8') == expected_msg) - - def test_start_reverse_false(self): - history = pubnub.detailedHistory({ - 'channel': self.__class__.channel, - 'start': self.__class__.midtime, - })[0] - self.assertTrue(history[0].encode('utf-8') - == self.__class__.inputs[0]['message']) - - def test_end_reverse_true(self): - history = pubnub.detailedHistory({ - 'channel': self.__class__.channel, - 'end': self.__class__.midtime, - 'reverse': True - })[0] - self.assertTrue(history[0].encode('utf-8') - == self.__class__.inputs[0]['message']) - - def test_end_reverse_false(self): - history = pubnub.detailedHistory({ - 'channel': self.__class__.channel, - 'end': self.__class__.midtime, - })[0] - self.assertTrue(len(history) == self.__class__.total_msg / 2) - self.assertTrue(history[-1].encode('utf-8') - == self.__class__.inputs[-1]['message']) - - def test_count(self): - history = pubnub.detailedHistory({ - 'channel': self.__class__.channel, - 'count': 5 - })[0] - self.assertTrue(len(history) == 5) - - def test_count_zero(self): - history = pubnub.detailedHistory({ - 'channel': self.__class__.channel, - 'count': 0 - })[0] - self.assertTrue(len(history) == 0) - -if __name__ == '__main__': - unittest.main() diff --git a/python/tests/unit-test.py b/python/tests/unit-test.py deleted file mode 100755 index a48cbd3..0000000 --- a/python/tests/unit-test.py +++ /dev/null @@ -1,66 +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.0 Real-time Push Cloud API -## ----------------------------------- - -import sys -from Pubnub import PubnubAsync as Pubnub - -publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo' -subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo' -secret_key = len(sys.argv) > 3 and sys.argv[3] or None -ssl_on = len(sys.argv) > 4 and bool(sys.argv[4]) or False - - -## ----------------------------------------------------------------------- -## Initiat Class -## ----------------------------------------------------------------------- - -pubnub = Pubnub(publish_key, subscribe_key, secret_key, ssl_on) -crazy = 'demo' - -## --------------------------------------------------------------------------- -## Unit Test Function -## --------------------------------------------------------------------------- - - -def test(trial, name): - if trial: - print('PASS: ' + name) - else: - print('FAIL: ' + name) - -## ----------------------------------------------------------------------- -## Publish Example -## ----------------------------------------------------------------------- -publish_success = pubnub.publish({ - 'channel': crazy, - 'message': crazy -}) -test(publish_success[0] == 1, 'Publish First Message Success') - -## ----------------------------------------------------------------------- -## History Example -## ----------------------------------------------------------------------- -history = pubnub.history({ - 'channel': crazy, - 'limit': 1 -}) - -test( - history[0] == crazy, - 'History Message: ' + history[0] -) -test(len(history) == 1, 'History Message Count') - -## ----------------------------------------------------------------------- -## PubNub Server Time Example -## ----------------------------------------------------------------------- -timestamp = pubnub.time() -test(timestamp > 0, 'PubNub Server Time: ' + str(timestamp)) -- cgit v1.2.3 From 26aca4f6f2c6167d5a83be83d1185c54522834e8 Mon Sep 17 00:00:00 2001 From: Devendra Date: Thu, 22 May 2014 20:42:40 +0530 Subject: removing requirement of adding channel for grant and audit --- python/examples/console.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/python/examples/console.py b/python/examples/console.py index 5d74517..6147d21 100644 --- a/python/examples/console.py +++ b/python/examples/console.py @@ -497,9 +497,6 @@ class DevConsole(Cmd): def do_grant(self, command, opts): opts.channel = self.default_channel \ if opts.channel is None else opts.channel - if opts.channel is None: - print_error("Missing channel") - return opts.auth_key = pubnub.auth_key \ if opts.auth_key is None else opts.auth_key @@ -526,9 +523,6 @@ class DevConsole(Cmd): def do_revoke(self, command, opts): opts.channel = self.default_channel \ if opts.channel is None else opts.channel - if opts.channel is None: - print_error("Missing channel") - return opts.auth_key = pubnub.auth_key \ if opts.auth_key is None else opts.auth_key @@ -549,9 +543,6 @@ class DevConsole(Cmd): def do_audit(self, command, opts): opts.channel = self.default_channel \ if opts.channel is None else opts.channel - if opts.channel is None: - print_error("Missing channel") - return opts.auth_key = pubnub.auth_key \ if opts.auth_key is None else opts.auth_key -- cgit v1.2.3 From b60f421b301abf348ab887991809966bbb66087c Mon Sep 17 00:00:00 2001 From: Devendra Date: Fri, 23 May 2014 20:52:10 +0530 Subject: adding success message after unsubscribe --- python/examples/console.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/examples/console.py b/python/examples/console.py index 6147d21..f67e168 100644 --- a/python/examples/console.py +++ b/python/examples/console.py @@ -204,6 +204,7 @@ def _unsubscribe_command_handler(channels): for channel in channels: pubnub.unsubscribe(channel) pubnub.unsubscribe(channel + '-pnpres') + print_ok('Unsubscribed from : ' + str(channels)) def _grant_command_handler(channel, auth_key, read, write, ttl, async=False): -- cgit v1.2.3 From 646fdda7abbd997925e83a497ed70ca27fb64654 Mon Sep 17 00:00:00 2001 From: Devendra Date: Sat, 14 Jun 2014 02:12:38 +0530 Subject: fixing issue where subscribe in two separate pubnub objects was not working correctly --- Pubnub.py | 76 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/Pubnub.py b/Pubnub.py index acc680b..3a4f59b 100644 --- a/Pubnub.py +++ b/Pubnub.py @@ -47,6 +47,7 @@ except ImportError: try: import requests + from requests.adapters import HTTPAdapter except ImportError: pass @@ -800,7 +801,6 @@ class PubnubBase(object): if ("urlparams" in request): url = url + '?' + "&".join([x + "=" + str(y) for x, y in request[ "urlparams"].items() if y is not None]) - #print url return url @@ -1087,7 +1087,7 @@ class PubnubCoreAsync(PubnubBase): ], "urlparams": {"uuid": self.uuid, "auth": self.auth_key}}, sub_callback, error_callback, - single=True) + single=True, timeout=320) ''' except Exception as e: print(e) @@ -1224,19 +1224,17 @@ class PubnubCore(PubnubCoreAsync): return True -latest_sub_callback_lock = threading.RLock() -latest_sub_callback = {'id': None, 'callback': None} - - class HTTPClient: - def __init__(self, url, urllib_func=None, - callback=None, error=None, id=None): + def __init__(self, pubnub, url, urllib_func=None, + callback=None, error=None, id=None, timeout=5): self.url = url self.id = id self.callback = callback self.error = error self.stop = False self._urllib_func = urllib_func + self.timeout = timeout + self.pubnub = pubnub def cancel(self): self.stop = True @@ -1252,31 +1250,29 @@ class HTTPClient: if self._urllib_func is None: return - resp = self._urllib_func(self.url, timeout=320) + resp = self._urllib_func(self.url, timeout=self.timeout) data = resp[0] code = resp[1] if self.stop is True: return if self.callback is None: - global latest_sub_callback - global latest_sub_callback_lock - with latest_sub_callback_lock: - if latest_sub_callback['id'] != self.id: + with self.pubnub.latest_sub_callback_lock: + if self.pubnub.latest_sub_callback['id'] != self.id: return else: - if latest_sub_callback['callback'] is not None: - latest_sub_callback['id'] = 0 + if self.pubnub.latest_sub_callback['callback'] is not None: + self.pubnub.latest_sub_callback['id'] = 0 try: data = json.loads(data) except ValueError as e: - _invoke(latest_sub_callback['error'], + _invoke(self.pubnub.latest_sub_callback['error'], {'error': 'json decoding error'}) return if code != 200: - _invoke(latest_sub_callback['error'], data) + _invoke(self.pubnub.latest_sub_callback['error'], data) else: - _invoke(latest_sub_callback['callback'], data) + _invoke(self.pubnub.latest_sub_callback['callback'], data) else: try: data = json.loads(data) @@ -1290,7 +1286,7 @@ class HTTPClient: _invoke(self.callback, data) -def _urllib_request_2(url, timeout=320): +def _urllib_request_2(url, timeout=5): try: resp = urllib2.urlopen(url, timeout=timeout) except urllib2.HTTPError as http_error: @@ -1302,9 +1298,10 @@ def _urllib_request_2(url, timeout=320): return (resp.read(), resp.code) s = requests.Session() +s.mount('http://pubsub.pubnub.com', HTTPAdapter(max_retries=1)) +s.mount('https://pubsub.pubnub.com', HTTPAdapter(max_retries=1)) - -def _requests_request(url, timeout=320): +def _requests_request(url, timeout=5): try: resp = s.get(url, timeout=timeout) except requests.exceptions.HTTPError as http_error: @@ -1318,7 +1315,7 @@ def _requests_request(url, timeout=320): return (resp.text, resp.status_code) -def _urllib_request_3(url, timeout=320): +def _urllib_request_3(url, timeout=5): try: resp = urllib.request.urlopen(url, timeout=timeout) except (urllib.request.HTTPError, urllib.request.URLError) as http_error: @@ -1365,6 +1362,9 @@ class Pubnub(PubnubCoreAsync): if pooling is True: _urllib_request = _requests_request + self.latest_sub_callback_lock = threading.RLock() + self.latest_sub_callback = {'id': None, 'callback': None} + def timeout(self, interval, func): def cb(): time.sleep(interval) @@ -1372,21 +1372,21 @@ class Pubnub(PubnubCoreAsync): thread = threading.Thread(target=cb) thread.start() - def _request_async(self, request, callback=None, error=None, single=False): + def _request_async(self, request, callback=None, error=None, single=False, timeout=5): global _urllib_request ## Build URL url = self.getUrl(request) if single is True: id = time.time() - client = HTTPClient(url=url, urllib_func=_urllib_request, - callback=None, error=None, id=id) - with latest_sub_callback_lock: - latest_sub_callback['id'] = id - latest_sub_callback['callback'] = callback - latest_sub_callback['error'] = error + client = HTTPClient(self, url=url, urllib_func=_urllib_request, + callback=None, error=None, id=id, timeout=timeout) + with self.latest_sub_callback_lock: + self.latest_sub_callback['id'] = id + self.latest_sub_callback['callback'] = callback + self.latest_sub_callback['error'] = error else: - client = HTTPClient(url=url, urllib_func=_urllib_request, - callback=callback, error=error) + client = HTTPClient(self, url=url, urllib_func=_urllib_request, + callback=callback, error=error, timeout=timeout) thread = threading.Thread(target=client.run) thread.start() @@ -1395,12 +1395,12 @@ class Pubnub(PubnubCoreAsync): client.cancel() return abort - def _request_sync(self, request): + def _request_sync(self, request, timeout=5): global _urllib_request ## Build URL url = self.getUrl(request) ## Send Request Expecting JSONP Response - response = _urllib_request(url, timeout=320) + response = _urllib_request(url, timeout=timeout) try: resp_json = json.loads(response[0]) except ValueError: @@ -1412,11 +1412,11 @@ class Pubnub(PubnubCoreAsync): return resp_json - def _request(self, request, callback=None, error=None, single=False): + def _request(self, request, callback=None, error=None, single=False, timeout=5): if callback is None: - return get_data_for_user(self._request_sync(request)) + return get_data_for_user(self._request_sync(request, timeout=timeout)) else: - self._request_async(request, callback, error, single=single) + self._request_async(request, callback, error, single=single, timeout=timeout) # Pubnub Twisted @@ -1560,7 +1560,7 @@ class PubnubTornado(PubnubCoreAsync): self.id = None def _request(self, request, callback=None, error=None, - single=False, read_timeout=5, connect_timeout=5): + single=False, timeout=5, connect_timeout=5): def _invoke(func, data): if func is not None: @@ -1571,7 +1571,7 @@ class PubnubTornado(PubnubCoreAsync): url, 'GET', self.headers, connect_timeout=connect_timeout, - request_timeout=read_timeout) + request_timeout=timeout) if single is True: id = time.time() self.id = id -- cgit v1.2.3 From 75033e11a429b52b0366d63bdd8f81b795a7145d Mon Sep 17 00:00:00 2001 From: Devendra Date: Sun, 15 Jun 2014 10:23:16 +0530 Subject: fixing customer issue, making changes to dev console to print pretty --- Pubnub.py | 2 +- dist/pubnub-3.5.0-beta.tar.gz | Bin 9451 -> 0 bytes python/examples/console.py | 111 +++++++++++++++++---- .../dist/pubnub-console-3.5.0-beta.tar.gz | Bin 4647 -> 0 bytes python/examples/pubnub-console/setup.py | 5 +- setup.py | 4 +- 6 files changed, 100 insertions(+), 22 deletions(-) delete mode 100644 dist/pubnub-3.5.0-beta.tar.gz delete mode 100644 python/examples/pubnub-console/dist/pubnub-console-3.5.0-beta.tar.gz diff --git a/Pubnub.py b/Pubnub.py index 3a4f59b..18f1b38 100644 --- a/Pubnub.py +++ b/Pubnub.py @@ -1406,7 +1406,7 @@ class Pubnub(PubnubCoreAsync): except ValueError: return [0, "JSON Error"] - if response[1] != 200 and 'status' in resp_json: + if response[1] != 200 and 'message' in resp_json and 'payload' in resp_json: return {'message': resp_json['message'], 'payload': resp_json['payload']} diff --git a/dist/pubnub-3.5.0-beta.tar.gz b/dist/pubnub-3.5.0-beta.tar.gz deleted file mode 100644 index 3ed2de3..0000000 Binary files a/dist/pubnub-3.5.0-beta.tar.gz and /dev/null differ diff --git a/python/examples/console.py b/python/examples/console.py index f67e168..bf82b5f 100644 --- a/python/examples/console.py +++ b/python/examples/console.py @@ -20,6 +20,17 @@ import os import readline import rlcompleter +import pygments +from pygments.lexers import JsonLexer +from pygments.formatters import TerminalFormatter + +lexer = JsonLexer() +formatter = TerminalFormatter() +def highlight(msg): + return pygments.highlight(msg, lexer, formatter) + + + historyPath = os.path.expanduser("~/.pubnub_console_history") @@ -79,8 +90,7 @@ def get_date(): return color.colorize(datetime.now().strftime( '%H:%M:%S'), "magenta") - -def print_ok(msg, channel=None): +def print_ok_normal(msg, channel=None): if msg is None: return chstr = color.colorize("[" + get_date() + "] ", "magenta") @@ -90,10 +100,11 @@ def print_ok(msg, channel=None): print_console(of, (chstr + color.colorize(str(msg), "green"))) except UnicodeEncodeError as e: print_console(of, (msg)) + of.flush() -def print_error(msg, channel=None): +def print_error_normal(msg, channel=None): if msg is None: return chstr = color.colorize("[" + get_date() + "] ", "magenta") @@ -106,6 +117,37 @@ def print_error(msg, channel=None): print_console(of, (msg)) of.flush() +def print_ok_pretty(msg, channel=None): + if msg is None: + return + chstr = color.colorize("[" + get_date() + "] ", "magenta") + chstr += color.colorize("[Channel : " + channel + + "] " if channel is not None else "", "cyan") + try: + print_console(of, (chstr + highlight(json.dumps(msg, indent=2)))) + except UnicodeEncodeError as e: + print_console(of, (msg)) + + of.flush() + + +def print_error_pretty(msg, channel=None): + if msg is None: + return + chstr = color.colorize("[" + get_date() + "] ", "magenta") + chstr += color.colorize("[Channel : " + channel + + "] " if channel is not None else "", "cyan") + try: + print_console(of, (chstr + color.colorize(color.colorize( + "ERROR: ", "red"), "bold") + + highlight(json.dumps(msg, indent=2)))) + except UnicodeEncodeError as e: + print_console(of, (msg)) + of.flush() + +print_ok = print_ok_pretty +print_error = print_error_pretty + class DefaultPubnub(object): def handlerFunctionClosure(self, name): @@ -295,6 +337,15 @@ class DevConsole(Cmd): pubnub = Pubnub("demo", "demo") self.channel_truncation = 3 self.prompt = self.get_prompt() + self.publish_key = "demo" + self.subscribe_key = "demo" + self.origin = "pubsub.pubnub.com" + self.auth_key = None + self.cipher_key = None + self.secret_key = "demo" + self.ssl = False + self.uuid = None + self.disable_pretty = False def get_channel_origin(self): cho = " [" @@ -341,34 +392,60 @@ class DevConsole(Cmd): kill_all_threads() @options([make_option('-p', '--publish-key', action="store", - default="demo", help="Publish Key"), + default=None, help="Publish Key"), make_option('-s', '--subscribe-key', action="store", - default="demo", help="Subscribe Key"), + default=None, help="Subscribe Key"), make_option('-k', '--secret-key', action="store", - default="demo", help="cipher Key"), + default=None, help="cipher Key"), make_option('-c', '--cipher-key', action="store", - default="", help="Secret Key"), + default=None, help="Secret Key"), make_option('-a', '--auth-key', action="store", default=None, help="Auth Key"), make_option('--ssl-on', dest='ssl', action='store_true', default=False, help="SSL Enabled ?"), make_option('-o', '--origin', action="store", - default="pubsub.pubnub.com", help="Origin"), + default=None, help="Origin"), make_option('-u', '--uuid', action="store", - default=None, help="UUID") + default=None, help="UUID"), + make_option('--disable-pretty-print', dest='disable_pretty', action='store_true', + default=False, help="Disable Pretty Print ?") ]) def do_init(self, command, opts): global pubnub - pubnub = Pubnub(opts.publish_key, - opts.subscribe_key, - opts.secret_key, - opts.cipher_key, - opts.auth_key, - opts.ssl, - opts.origin, - opts.uuid) + global print_ok + global print_error + global print_ok_normal + global print_error_normal + global print_error_pretty + global print_ok_pretty + + self.publish_key = opts.publish_key if opts.publish_key is not None else self.publish_key + self.subscribe_key = opts.subscribe_key if opts.subscribe_key is not None else self.subscribe_key + self.secret_key = opts.secret_key if opts.secret_key is not None else self.secret_key + self.cipher_key = opts.cipher_key if opts.cipher_key is not None else self.cipher_key + self.auth_key = opts.auth_key if opts.auth_key is not None else self.auth_key + self.origin = opts.origin if opts.origin is not None else self.origin + self.uuid = opts.uuid if opts.uuid is not None else self.uuid + self.ssl = opts.ssl if opts.ssl is not None else self.ssl + self.disable_pretty = opts.disable_pretty if opts.disable_pretty is not None else self.disable_pretty + + pubnub = Pubnub(self.publish_key, + self.subscribe_key, + self.secret_key, + self.cipher_key, + self.auth_key, + self.ssl, + self.origin, + self.uuid) self.prompt = self.get_prompt() + if opts.disable_pretty is True: + print_ok = print_ok_normal + print_error = print_error_normal + else: + print_ok = print_ok_pretty + print_error = print_error_pretty + def do_set_sync(self, command): """unset_async Unset Async mode""" diff --git a/python/examples/pubnub-console/dist/pubnub-console-3.5.0-beta.tar.gz b/python/examples/pubnub-console/dist/pubnub-console-3.5.0-beta.tar.gz deleted file mode 100644 index 278e9fa..0000000 Binary files a/python/examples/pubnub-console/dist/pubnub-console-3.5.0-beta.tar.gz and /dev/null differ diff --git a/python/examples/pubnub-console/setup.py b/python/examples/pubnub-console/setup.py index d46314e..e5a06ad 100644 --- a/python/examples/pubnub-console/setup.py +++ b/python/examples/pubnub-console/setup.py @@ -2,11 +2,11 @@ from setuptools import setup, find_packages setup( name='pubnub-console', - version='3.5.0-beta', + version='3.5.0-beta-1', description='PubNub Developer Console', author='Stephen Blum', author_email='support@pubnub.com', - url='https://github.com/pubnub/python/raw/async/python/examples/pubnub-console/dist/pubnub-console-3.5.0-beta.tar.gz', + url='http://pubnub.com', scripts=['pubnub-console'], license='MIT', classifiers=( @@ -21,6 +21,7 @@ setup( install_requires=[ 'pubnub==3.5.0-beta', 'cmd2>=0.6.7', + 'pygments >= 1.6' ], zip_safe=False, ) diff --git a/setup.py b/setup.py index 373efde..aec2887 100644 --- a/setup.py +++ b/setup.py @@ -2,11 +2,11 @@ from setuptools import setup, find_packages setup( name='pubnub', - version='3.5.0-beta', + version='3.5.0-beta-1', description='PubNub Real-time push service in the cloud', author='Stephen Blum', author_email='support@pubnub.com', - url='https://github.com/pubnub/python/raw/async/dist/pubnub-3.5.0-beta.tar.gz', + url='http://pubnub.com', py_modules=['Pubnub'], license='MIT', classifiers=( -- cgit v1.2.3 From 019d8f390dc6472a223e6ab9b2f159cd1cd20e4e Mon Sep 17 00:00:00 2001 From: Devendra Date: Sun, 15 Jun 2014 10:29:47 +0530 Subject: dev console modifications --- python/examples/pubnub-console/pubnub-console | 123 ++++++++++++++++++++------ 1 file changed, 95 insertions(+), 28 deletions(-) diff --git a/python/examples/pubnub-console/pubnub-console b/python/examples/pubnub-console/pubnub-console index 7276fb9..bf82b5f 100644 --- a/python/examples/pubnub-console/pubnub-console +++ b/python/examples/pubnub-console/pubnub-console @@ -1,5 +1,3 @@ -#!/usr/bin/env python - ## www.pubnub.com - PubNub Real-time push service in the cloud. # coding=utf8 @@ -22,6 +20,17 @@ import os import readline import rlcompleter +import pygments +from pygments.lexers import JsonLexer +from pygments.formatters import TerminalFormatter + +lexer = JsonLexer() +formatter = TerminalFormatter() +def highlight(msg): + return pygments.highlight(msg, lexer, formatter) + + + historyPath = os.path.expanduser("~/.pubnub_console_history") @@ -81,8 +90,7 @@ def get_date(): return color.colorize(datetime.now().strftime( '%H:%M:%S'), "magenta") - -def print_ok(msg, channel=None): +def print_ok_normal(msg, channel=None): if msg is None: return chstr = color.colorize("[" + get_date() + "] ", "magenta") @@ -92,10 +100,11 @@ def print_ok(msg, channel=None): print_console(of, (chstr + color.colorize(str(msg), "green"))) except UnicodeEncodeError as e: print_console(of, (msg)) + of.flush() -def print_error(msg, channel=None): +def print_error_normal(msg, channel=None): if msg is None: return chstr = color.colorize("[" + get_date() + "] ", "magenta") @@ -108,6 +117,37 @@ def print_error(msg, channel=None): print_console(of, (msg)) of.flush() +def print_ok_pretty(msg, channel=None): + if msg is None: + return + chstr = color.colorize("[" + get_date() + "] ", "magenta") + chstr += color.colorize("[Channel : " + channel + + "] " if channel is not None else "", "cyan") + try: + print_console(of, (chstr + highlight(json.dumps(msg, indent=2)))) + except UnicodeEncodeError as e: + print_console(of, (msg)) + + of.flush() + + +def print_error_pretty(msg, channel=None): + if msg is None: + return + chstr = color.colorize("[" + get_date() + "] ", "magenta") + chstr += color.colorize("[Channel : " + channel + + "] " if channel is not None else "", "cyan") + try: + print_console(of, (chstr + color.colorize(color.colorize( + "ERROR: ", "red"), "bold") + + highlight(json.dumps(msg, indent=2)))) + except UnicodeEncodeError as e: + print_console(of, (msg)) + of.flush() + +print_ok = print_ok_pretty +print_error = print_error_pretty + class DefaultPubnub(object): def handlerFunctionClosure(self, name): @@ -206,6 +246,7 @@ def _unsubscribe_command_handler(channels): for channel in channels: pubnub.unsubscribe(channel) pubnub.unsubscribe(channel + '-pnpres') + print_ok('Unsubscribed from : ' + str(channels)) def _grant_command_handler(channel, auth_key, read, write, ttl, async=False): @@ -296,6 +337,15 @@ class DevConsole(Cmd): pubnub = Pubnub("demo", "demo") self.channel_truncation = 3 self.prompt = self.get_prompt() + self.publish_key = "demo" + self.subscribe_key = "demo" + self.origin = "pubsub.pubnub.com" + self.auth_key = None + self.cipher_key = None + self.secret_key = "demo" + self.ssl = False + self.uuid = None + self.disable_pretty = False def get_channel_origin(self): cho = " [" @@ -342,34 +392,60 @@ class DevConsole(Cmd): kill_all_threads() @options([make_option('-p', '--publish-key', action="store", - default="demo", help="Publish Key"), + default=None, help="Publish Key"), make_option('-s', '--subscribe-key', action="store", - default="demo", help="Subscribe Key"), + default=None, help="Subscribe Key"), make_option('-k', '--secret-key', action="store", - default="demo", help="cipher Key"), + default=None, help="cipher Key"), make_option('-c', '--cipher-key', action="store", - default="", help="Secret Key"), + default=None, help="Secret Key"), make_option('-a', '--auth-key', action="store", default=None, help="Auth Key"), make_option('--ssl-on', dest='ssl', action='store_true', default=False, help="SSL Enabled ?"), make_option('-o', '--origin', action="store", - default="pubsub.pubnub.com", help="Origin"), + default=None, help="Origin"), make_option('-u', '--uuid', action="store", - default=None, help="UUID") + default=None, help="UUID"), + make_option('--disable-pretty-print', dest='disable_pretty', action='store_true', + default=False, help="Disable Pretty Print ?") ]) def do_init(self, command, opts): global pubnub - pubnub = Pubnub(opts.publish_key, - opts.subscribe_key, - opts.secret_key, - opts.cipher_key, - opts.auth_key, - opts.ssl, - opts.origin, - opts.uuid) + global print_ok + global print_error + global print_ok_normal + global print_error_normal + global print_error_pretty + global print_ok_pretty + + self.publish_key = opts.publish_key if opts.publish_key is not None else self.publish_key + self.subscribe_key = opts.subscribe_key if opts.subscribe_key is not None else self.subscribe_key + self.secret_key = opts.secret_key if opts.secret_key is not None else self.secret_key + self.cipher_key = opts.cipher_key if opts.cipher_key is not None else self.cipher_key + self.auth_key = opts.auth_key if opts.auth_key is not None else self.auth_key + self.origin = opts.origin if opts.origin is not None else self.origin + self.uuid = opts.uuid if opts.uuid is not None else self.uuid + self.ssl = opts.ssl if opts.ssl is not None else self.ssl + self.disable_pretty = opts.disable_pretty if opts.disable_pretty is not None else self.disable_pretty + + pubnub = Pubnub(self.publish_key, + self.subscribe_key, + self.secret_key, + self.cipher_key, + self.auth_key, + self.ssl, + self.origin, + self.uuid) self.prompt = self.get_prompt() + if opts.disable_pretty is True: + print_ok = print_ok_normal + print_error = print_error_normal + else: + print_ok = print_ok_pretty + print_error = print_error_pretty + def do_set_sync(self, command): """unset_async Unset Async mode""" @@ -499,9 +575,6 @@ class DevConsole(Cmd): def do_grant(self, command, opts): opts.channel = self.default_channel \ if opts.channel is None else opts.channel - if opts.channel is None: - print_error("Missing channel") - return opts.auth_key = pubnub.auth_key \ if opts.auth_key is None else opts.auth_key @@ -528,9 +601,6 @@ class DevConsole(Cmd): def do_revoke(self, command, opts): opts.channel = self.default_channel \ if opts.channel is None else opts.channel - if opts.channel is None: - print_error("Missing channel") - return opts.auth_key = pubnub.auth_key \ if opts.auth_key is None else opts.auth_key @@ -551,9 +621,6 @@ class DevConsole(Cmd): def do_audit(self, command, opts): opts.channel = self.default_channel \ if opts.channel is None else opts.channel - if opts.channel is None: - print_error("Missing channel") - return opts.auth_key = pubnub.auth_key \ if opts.auth_key is None else opts.auth_key -- cgit v1.2.3 From ac1ea5ddff5aa8615788ab784656b44d6a664100 Mon Sep 17 00:00:00 2001 From: Devendra Date: Sun, 15 Jun 2014 10:38:53 +0530 Subject: adding interpreter header --- python/examples/pubnub-console/pubnub-console | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/examples/pubnub-console/pubnub-console b/python/examples/pubnub-console/pubnub-console index bf82b5f..058253f 100644 --- a/python/examples/pubnub-console/pubnub-console +++ b/python/examples/pubnub-console/pubnub-console @@ -1,3 +1,5 @@ +#!/usr/bin/python + ## www.pubnub.com - PubNub Real-time push service in the cloud. # coding=utf8 -- cgit v1.2.3 From 43162745c37f1e3f8f6b9c102f685a765f7fbc49 Mon Sep 17 00:00:00 2001 From: Devendra Date: Sun, 15 Jun 2014 10:44:12 +0530 Subject: changing dependencies --- python/examples/pubnub-console/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/examples/pubnub-console/setup.py b/python/examples/pubnub-console/setup.py index e5a06ad..c08be33 100644 --- a/python/examples/pubnub-console/setup.py +++ b/python/examples/pubnub-console/setup.py @@ -19,7 +19,7 @@ setup( 'Topic :: Software Development :: Libraries :: Python Modules', ), install_requires=[ - 'pubnub==3.5.0-beta', + 'pubnub==3.5.0-beta-1', 'cmd2>=0.6.7', 'pygments >= 1.6' ], -- cgit v1.2.3 From 6e67486e8e2333e6f7b0128df9bc4f1da8db2bfc Mon Sep 17 00:00:00 2001 From: Devendra Date: Mon, 16 Jun 2014 23:33:20 +0530 Subject: return json array with code and reason in sync mode error --- Pubnub.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Pubnub.py b/Pubnub.py index 18f1b38..5c19109 100644 --- a/Pubnub.py +++ b/Pubnub.py @@ -1410,6 +1410,9 @@ class Pubnub(PubnubCoreAsync): return {'message': resp_json['message'], 'payload': resp_json['payload']} + if response[1] == 0: + return [0, resp_json] + return resp_json def _request(self, request, callback=None, error=None, single=False, timeout=5): -- cgit v1.2.3 From 819dbedf0904b81e866ea6d27219608167d8b8ca Mon Sep 17 00:00:00 2001 From: Devendra Date: Mon, 16 Jun 2014 23:40:07 +0530 Subject: version changes --- Pubnub.py | 5 ++--- VERSION | 2 +- change_version.sh | 1 - python/README.md | 2 +- python/examples/pubnub-console/setup.py | 4 ++-- setup.py | 4 ++-- 6 files changed, 8 insertions(+), 10 deletions(-) delete mode 100644 change_version.sh diff --git a/Pubnub.py b/Pubnub.py index 5c19109..e39dd06 100644 --- a/Pubnub.py +++ b/Pubnub.py @@ -7,7 +7,7 @@ ## http://www.pubnub.com/ ## ----------------------------------- -## PubNub 3.5.0-beta Real-time Push Cloud API +## PubNub 3.5.0 Real-time Push Cloud API ## ----------------------------------- @@ -218,6 +218,7 @@ class PubnubBase(object): """ self.origin = origin + self.version = '3.5.0' self.limit = 1800 self.publish_key = publish_key self.subscribe_key = subscribe_key @@ -850,7 +851,6 @@ class PubnubCoreAsync(PubnubBase): self.subscriptions = {} self.timetoken = 0 self.last_timetoken = 0 - self.version = '3.3.4' self.accept_encoding = 'gzip' self.SUB_RECEIVER = None self._connect = None @@ -1164,7 +1164,6 @@ class PubnubCore(PubnubCoreAsync): self.subscriptions = {} self.timetoken = 0 - self.version = '3.4' self.accept_encoding = 'gzip' def subscribe_sync(self, channel, callback, timetoken=0): diff --git a/VERSION b/VERSION index fa7adc7..1545d96 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.3.5 +3.5.0 diff --git a/change_version.sh b/change_version.sh deleted file mode 100644 index 5ea7a63..0000000 --- a/change_version.sh +++ /dev/null @@ -1 +0,0 @@ -find -name "Pubnub*py" | xargs sed -i "s/PubNub\ [0-9]\.[0-9]\.[0-9]/PubNub\ `cat VERSION`/g" diff --git a/python/README.md b/python/README.md index 68065f0..7232756 100644 --- a/python/README.md +++ b/python/README.md @@ -1,4 +1,4 @@ -## PubNub 3.3 Web Data Push Cloud-hosted API - PYTHON +## PubNub 3.5.0 Web Data Push Cloud-hosted API - PYTHON #### www.pubnub.com - PubNub Web Data Push Service in the Cloud. #### http://github.com/pubnub/python diff --git a/python/examples/pubnub-console/setup.py b/python/examples/pubnub-console/setup.py index c08be33..a9fa506 100644 --- a/python/examples/pubnub-console/setup.py +++ b/python/examples/pubnub-console/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name='pubnub-console', - version='3.5.0-beta-1', + version='3.5.0', description='PubNub Developer Console', author='Stephen Blum', author_email='support@pubnub.com', @@ -19,7 +19,7 @@ setup( 'Topic :: Software Development :: Libraries :: Python Modules', ), install_requires=[ - 'pubnub==3.5.0-beta-1', + 'pubnub>=3.5.0', 'cmd2>=0.6.7', 'pygments >= 1.6' ], diff --git a/setup.py b/setup.py index aec2887..ee01836 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name='pubnub', - version='3.5.0-beta-1', + version='3.5.0', description='PubNub Real-time push service in the cloud', author='Stephen Blum', author_email='support@pubnub.com', @@ -20,7 +20,7 @@ setup( ), install_requires=[ 'pycrypto>=2.6.1', - 'requests' + 'requests>=2.3.0' ], zip_safe=False, ) -- cgit v1.2.3 From 30202de8be4ba24f4fba8dda4b3f28f6ee6600aa Mon Sep 17 00:00:00 2001 From: Devendra Date: Tue, 17 Jun 2014 00:58:40 +0530 Subject: readme changes --- python-tornado/README | 92 +++++++++++-------------------- python-twisted/README | 98 ++++++++++----------------------- python/README.md | 119 ++++++++++++++++++++++++----------------- python/examples/dev-console.py | 2 +- 4 files changed, 130 insertions(+), 181 deletions(-) diff --git a/python-tornado/README b/python-tornado/README index d6eeebe..e046c6b 100644 --- a/python-tornado/README +++ b/python-tornado/README @@ -6,7 +6,7 @@ ## ---------------------------------------------------- ## ---------------------------------------------------- -## PubNub 3.1 Real-time Cloud Push API - PYTHON TORNADO +## PubNub 3.5.0 Real-time Cloud Push API - PYTHON TORNADO ## ---------------------------------------------------- ## ## www.pubnub.com - PubNub Real-time Push Service in the Cloud. @@ -16,93 +16,63 @@ ## This is a cloud-based service for broadcasting Real-time messages ## to thousands of web and mobile clients simultaneously. -## ---------------------------------------------------- -## Third Party Libraries Dependency -## ---------------------------------------------------- -## You must download and install, -## -## 1. pyopenssl -## Download from https://launchpad.net/pyopenssl -## -## 2. pycrypto -## Download from https://github.com/dlitz/pycrypto OR -## from http://code.google.com/p/uploadprj/downloads/detail?name=pycrypto-2.3.win32-py2.7.zip&can=2&q + +from Pubnub import PubnubTornado as Pubnub ## --------------- ## Python Push API ## --------------- -pubnub = Pubnub( - "demo", ## PUBLISH_KEY - "demo", ## SUBSCRIBE_KEY - "demo", ## SECRET_KEY - "", ## CIPHER_KEY (Cipher key is Optional) - False ## SSL_ON? -) +pubnub = Pubnub(publish_key="demo", subscribe_key="demo", ssl_on=False) ## ----------------------------------------------------------------------- ## IO Event Loop ## ----------------------------------------------------------------------- ## VERY IMPORTANT TO ADD THIS LINE AT THE VERY BOTTOM! ## -## tornado.ioloop.IOLoop.instance().start() ## IMPORTANT! +## pubnub.start() ## IMPORTANT! ## ## ----------------------------------------------------------------------- ## Subscribe Example ## ----------------------------------------------------------------------- -def connected() : - ## ----------------------------------------------------------------------- - ## Publish Example - ## ----------------------------------------------------------------------- - def publish_complete(info): - print(info) - - pubnub.publish({ - 'channel' : "my-tornado-channel", - 'message' : { - 'some_text' : 'Hello World!' - }, - 'callback' : publish_complete - }) - -def message_received(message): +channel = 'hello_world' + +def callback(message, channel): print(message) -pubnub.subscribe({ - 'channel' : "my-tornado-channel", - 'connect' : connected, - 'callback' : message_received -}) -## ----------------------------------------------------------------------- -## Time Example -## ----------------------------------------------------------------------- -def time_complete(timestamp): - print(timestamp) +def error(message): + print("ERROR : " + str(message)) + + +def connect(message): + print("CONNECTED") + + +def reconnect(message): + print("RECONNECTED") + + +def disconnect(message): + print("DISCONNECTED") + + +pubnub.subscribe(channel, callback=callback, error=callback, + connect=connect, reconnect=reconnect, disconnect=disconnect) -pubnub.time({ 'callback' : time_complete }) ## ----------------------------------------------------------------------- ## History Example ## ----------------------------------------------------------------------- -def history_complete(messages): - print(messages) +def callback(message): + print(message) + +pubnub.history(channel, count=2, callback=callback, error=callback) -pubnub.history( { - 'channel' : "my-tornado-channel", - 'limit' : 10, - 'callback' : history_complete -}) -## ----------------------------------------------------------------------- -## UUID Example -## ----------------------------------------------------------------------- -uuid = pubnub.uuid() -print "UUID" -print uuid ## ----------------------------------------------------------------------- ## IO Event Loop ## ----------------------------------------------------------------------- -tornado.ioloop.IOLoop.instance().start() +pubnub.start() diff --git a/python-twisted/README b/python-twisted/README index 5f9b350..402fb34 100644 --- a/python-twisted/README +++ b/python-twisted/README @@ -16,103 +16,63 @@ ## This is a cloud-based service for broadcasting Real-time messages ## to thousands of web and mobile clients simultaneously. -## ---------------------------------------------------- -## Python Twisted Setup -## ---------------------------------------------------- -## Download BZ2 archive from http://twistedmatrix.com/ -## -## > tar xvfj Twisted-12.1.0.tar.bz2 -## > cd Twisted-12.1.0 -## > sudo python setup.py install -## -## ---------------------------------------------------- -## Third Party Libraries Dependency -## ---------------------------------------------------- -## You must download and install, -## -## 1. pyopenssl -## Download from https://launchpad.net/pyopenssl -## -## 2. pycrypto -## Download from https://github.com/dlitz/pycrypto OR -## from http://code.google.com/p/uploadprj/downloads/detail?name=pycrypto-2.3.win32-py2.7.zip&can=2&q +from Pubnub import PubnubTwisted as Pubnub ## --------------- ## Python Push API ## --------------- -pubnub = Pubnub( - "demo", ## PUBLISH_KEY - "demo", ## SUBSCRIBE_KEY - "demo", ## SECRET_KEY - "", ## CIPHER_KEY (Cipher key is Optional) - False ## SSL_ON? -) +pubnub = Pubnub(publish_key="demo", subscribe_key="demo", ssl_on=False) ## ----------------------------------------------------------------------- ## IO Event Loop ## ----------------------------------------------------------------------- ## VERY IMPORTANT TO ADD THIS LINE AT THE VERY BOTTOM! ## -## reactor.run() ## IMPORTANT! +## pubnub.start() ## IMPORTANT! ## ## ----------------------------------------------------------------------- ## Subscribe Example ## ----------------------------------------------------------------------- -def connected() : - ## ----------------------------------------------------------------------- - ## Publish Example - ## ----------------------------------------------------------------------- - def publish_complete(info): - print(info) - - pubnub.publish({ - 'channel' : "my-twisted-channel", - 'message' : { - 'some_text' : 'Hello World!' - }, - 'callback' : publish_complete - }) - -def message_received(message): +channel = 'hello_world' + +def callback(message, channel): print(message) -pubnub.subscribe({ - 'channel' : "my-twisted-channel", - 'connect' : connected, - 'callback' : message_received -}) -## ----------------------------------------------------------------------- -## Time Example -## ----------------------------------------------------------------------- -def time_complete(timestamp): - print(timestamp) +def error(message): + print("ERROR : " + str(message)) + + +def connect(message): + print("CONNECTED") + + +def reconnect(message): + print("RECONNECTED") + + +def disconnect(message): + print("DISCONNECTED") + + +pubnub.subscribe(channel, callback=callback, error=callback, + connect=connect, reconnect=reconnect, disconnect=disconnect) -pubnub.time({ 'callback' : time_complete }) ## ----------------------------------------------------------------------- ## History Example ## ----------------------------------------------------------------------- -def history_complete(messages): - print(messages) +def callback(message): + print(message) + +pubnub.history(channel, count=2, callback=callback, error=callback) -pubnub.history( { - 'channel' : "my-twisted-channel", - 'limit' : 10, - 'callback' : history_complete -}) -## ----------------------------------------------------------------------- -## UUID Example -## ----------------------------------------------------------------------- -uuid = pubnub.uuid() -print "UUID" -print uuid ## ----------------------------------------------------------------------- ## IO Event Loop ## ----------------------------------------------------------------------- -reactor.run() +pubnub.start() diff --git a/python/README.md b/python/README.md index 7232756..14d767f 100644 --- a/python/README.md +++ b/python/README.md @@ -6,55 +6,78 @@ #### Init ``` -pubnub = Pubnub( - "demo", ## PUBLISH_KEY - "demo", ## SUBSCRIBE_KEY - None, ## SECRET_KEY - False ## SSL_ON? -) +pubnub = Pubnub(publish_key="demo", subscribe_key="demo", ssl_on=False) + ``` #### PUBLISH ``` -info = pubnub.publish({ - 'channel' : 'hello_world', - 'message' : { - 'some_text' : 'Hello my World' - } -}) -print(info) +channel = 'hello_world' +message = 'Hello World !!!' + +# Synchronous usage +print pubnub.publish(channel='hello_world', message='Hello World !!!') + +# Asynchronous usage + +def callback(message): + print(message) + +pubnub.publish(channel, message, callback=callback, error=callback) + ``` #### SUBSCRIBE ``` -# Listen for Messages *BLOCKING* -def receive(message) : +# Listen for Messages + +channel = 'hello_world' + +def callback(message, channel): print(message) - return True -pubnub.subscribe({ - 'channel' : 'hello_world', - 'callback' : receive -}) + +def error(message): + print("ERROR : " + str(message)) + + +def connect(message): + print("CONNECTED") + + +def reconnect(message): + print("RECONNECTED") + + +def disconnect(message): + print("DISCONNECTED") + + +pubnub.subscribe(channel, callback=callback, error=callback, + connect=connect, reconnect=reconnect, disconnect=disconnect) ``` #### PRESENCE ``` -# Listen for Presence Event Messages *BLOCKING* +# Listen for Presence Event Messages + +channel = 'hello_world' -def pres_event(message) : +def callback(message, channel): print(message) - return True -pubnub.presence({ - 'channel' : 'hello_world', - 'callback' : receive -}) + +def error(message): + print("ERROR : " + str(message)) + + + +pubnub.presence(channel, callback=callback, error=callback) ``` #### HERE_NOW @@ -62,36 +85,32 @@ pubnub.presence({ ``` # Get info on who is here right now! -here_now = pubnub.here_now({ - 'channel' : 'hello_world', -}) +channel = 'hello_world' -print(here_now['occupancy']) -print(here_now['uuids']) -``` +# Synchronous usage +print pubnub.here_now(channel) -#### Channel Analytics -``` -analytics = pubnub.analytics({ - 'channel' : 'channel-name-here', ## Leave blank for all channels - 'limit' : 100, ## aggregation range - 'ago' : 0, ## minutes ago to look backward - 'duration' : 100 ## minutes offset -}) -print(analytics) +# Asynchronous usage +def callback(message): + print(message) + +pubnub.here_now(channel, callback=callback, error=callback) ``` #### HISTORY ``` -# Load Previously Published Messages -history = pubnub.detailedHistory({ - 'channel' : 'my_channel', - 'end' : my_end_time_token, # Optional - 'start' : my_start_time_token, # Optional - 'count' : num_of_msgs_to_return # Optional, default is 100 -}) -print(history) +# Synchronous usage + +print pubnub.history(channel, count=2) + +# Asynchronous usage + + +def callback(message): + print(message) + +pubnub.history(channel, count=2, callback=callback, error=callback) ``` diff --git a/python/examples/dev-console.py b/python/examples/dev-console.py index 5bdbe8c..134d2e7 100755 --- a/python/examples/dev-console.py +++ b/python/examples/dev-console.py @@ -6,7 +6,7 @@ ## http://www.pubnub.com/ import sys -from Pubnub import PubnubAsync as Pubnub +from Pubnub import Pubnub from optparse import OptionParser -- cgit v1.2.3 From 05dbe7714645c65bce4a73ec11d8d424f5fae296 Mon Sep 17 00:00:00 2001 From: Geremy Cohen Date: Mon, 16 Jun 2014 13:36:30 -0700 Subject: Update README.md --- python/README.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/python/README.md b/python/README.md index 14d767f..10d03ae 100644 --- a/python/README.md +++ b/python/README.md @@ -5,7 +5,14 @@ #### Init + + ``` + +# Pre 3.5: +# + +# New in 3.5+ pubnub = Pubnub(publish_key="demo", subscribe_key="demo", ssl_on=False) ``` @@ -16,6 +23,11 @@ pubnub = Pubnub(publish_key="demo", subscribe_key="demo", ssl_on=False) channel = 'hello_world' message = 'Hello World !!!' +# Pre 3.5: +# + +# New in 3.5+ + # Synchronous usage print pubnub.publish(channel='hello_world', message='Hello World !!!') @@ -30,12 +42,19 @@ pubnub.publish(channel, message, callback=callback, error=callback) #### SUBSCRIBE +Pre 3.5.x, subscribe was blocking and would only be terminated via a false return from the callback. In our latest version of the SDK, subscribe is asyncronous, and because of this, usage is a bit different, but the experience is more like our other async SDKs. ``` + # Listen for Messages channel = 'hello_world' +# Pre 3.5: +# + +# New in 3.5+ + def callback(message, channel): print(message) @@ -60,10 +79,27 @@ pubnub.subscribe(channel, callback=callback, error=callback, connect=connect, reconnect=reconnect, disconnect=disconnect) ``` +#### Unsubscribe +Once subscribed, you can easily, gracefully, unsubscribe: + +``` +# Pre 3.5: +# + +# New in 3.5+ + +Unsub example +``` #### PRESENCE ``` + +# Pre 3.5: +# + +# New in 3.5+ + # Listen for Presence Event Messages channel = 'hello_world' @@ -83,6 +119,12 @@ pubnub.presence(channel, callback=callback, error=callback) #### HERE_NOW ``` + +# Pre 3.5: +# + +# New in 3.5+ + # Get info on who is here right now! channel = 'hello_world' @@ -102,6 +144,12 @@ pubnub.here_now(channel, callback=callback, error=callback) #### HISTORY ``` + +# Pre 3.5: +# + +# New in 3.5+ + # Synchronous usage print pubnub.history(channel, count=2) -- cgit v1.2.3 From c731ae584de53da55ed799f8fd59bff10b9b9b72 Mon Sep 17 00:00:00 2001 From: Devendra Date: Tue, 17 Jun 2014 02:43:16 +0530 Subject: readme changes --- python-tornado/README | 78 --------------------- python-tornado/README.md | 61 ++++++++++++++++ python-tornado/migration.md | 164 ++++++++++++++++++++++++++++++++++++++++++++ python-twisted/README | 78 --------------------- python-twisted/README.md | 61 ++++++++++++++++ python-twisted/migration.md | 164 ++++++++++++++++++++++++++++++++++++++++++++ python/README.md | 48 ------------- python/migration.md | 164 ++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 614 insertions(+), 204 deletions(-) delete mode 100644 python-tornado/README create mode 100644 python-tornado/README.md create mode 100644 python-tornado/migration.md delete mode 100644 python-twisted/README create mode 100644 python-twisted/README.md create mode 100644 python-twisted/migration.md create mode 100644 python/migration.md diff --git a/python-tornado/README b/python-tornado/README deleted file mode 100644 index e046c6b..0000000 --- a/python-tornado/README +++ /dev/null @@ -1,78 +0,0 @@ -## --------------------------------------------------- -## -## YOU MUST HAVE A PUBNUB ACCOUNT TO USE THE API. -## http://www.pubnub.com/account -## -## ---------------------------------------------------- - -## ---------------------------------------------------- -## PubNub 3.5.0 Real-time Cloud Push API - PYTHON TORNADO -## ---------------------------------------------------- -## -## www.pubnub.com - PubNub Real-time Push Service in the Cloud. -## http://github.com/pubnub/pubnub-api/tree/master/python-tornado/ -## -## PubNub is a Massively Scalable Real-time Service for Web and Mobile Games. -## This is a cloud-based service for broadcasting Real-time messages -## to thousands of web and mobile clients simultaneously. - - -from Pubnub import PubnubTornado as Pubnub - -## --------------- -## Python Push API -## --------------- -pubnub = Pubnub(publish_key="demo", subscribe_key="demo", ssl_on=False) - -## ----------------------------------------------------------------------- -## IO Event Loop -## ----------------------------------------------------------------------- -## VERY IMPORTANT TO ADD THIS LINE AT THE VERY BOTTOM! -## -## pubnub.start() ## IMPORTANT! -## - -## ----------------------------------------------------------------------- -## Subscribe Example -## ----------------------------------------------------------------------- - -channel = 'hello_world' - -def callback(message, channel): - print(message) - - -def error(message): - print("ERROR : " + str(message)) - - -def connect(message): - print("CONNECTED") - - -def reconnect(message): - print("RECONNECTED") - - -def disconnect(message): - print("DISCONNECTED") - - -pubnub.subscribe(channel, callback=callback, error=callback, - connect=connect, reconnect=reconnect, disconnect=disconnect) - - -## ----------------------------------------------------------------------- -## History Example -## ----------------------------------------------------------------------- -def callback(message): - print(message) - -pubnub.history(channel, count=2, callback=callback, error=callback) - - - -## ----------------------------------------------------------------------- -## IO Event Loop -## ----------------------------------------------------------------------- -pubnub.start() diff --git a/python-tornado/README.md b/python-tornado/README.md new file mode 100644 index 0000000..1d210f9 --- /dev/null +++ b/python-tornado/README.md @@ -0,0 +1,61 @@ +## PubNub 3.5.0 Web Data Push Cloud-hosted API - PYTHON TORNADO +#### www.pubnub.com - PubNub Web Data Push Service in the Cloud. +#### http://github.com/pubnub/python + +#### Import +``` +from Pubnub import PubnubTornado as Pubnub +``` + +#### Init +pubnub = Pubnub(publish_key="demo", subscribe_key="demo", ssl_on=False) + + +#### IO Event Loop +##### VERY IMPORTANT TO ADD THIS LINE AT THE VERY BOTTOM! + +``` +pubnub.start() +``` + +#### Subscribe Example +``` +channel = 'hello_world' + +def callback(message, channel): + print(message) + + +def error(message): + print("ERROR : " + str(message)) + + +def connect(message): + print("CONNECTED") + + +def reconnect(message): + print("RECONNECTED") + + +def disconnect(message): + print("DISCONNECTED") + + +pubnub.subscribe(channel, callback=callback, error=callback, + connect=connect, reconnect=reconnect, disconnect=disconnect) +``` + +#### History Example +``` +def callback(message): + print(message) + +pubnub.history(channel, count=2, callback=callback, error=callback) +``` + + +#### IO Event Loop start +``` +pubnub.start() +``` \ No newline at end of file diff --git a/python-tornado/migration.md b/python-tornado/migration.md new file mode 100644 index 0000000..10d03ae --- /dev/null +++ b/python-tornado/migration.md @@ -0,0 +1,164 @@ +## PubNub 3.5.0 Web Data Push Cloud-hosted API - PYTHON +#### www.pubnub.com - PubNub Web Data Push Service in the Cloud. +#### http://github.com/pubnub/python + + +#### Init + + + +``` + +# Pre 3.5: +# + +# New in 3.5+ +pubnub = Pubnub(publish_key="demo", subscribe_key="demo", ssl_on=False) + +``` + +#### PUBLISH + +``` +channel = 'hello_world' +message = 'Hello World !!!' + +# Pre 3.5: +# + +# New in 3.5+ + +# Synchronous usage +print pubnub.publish(channel='hello_world', message='Hello World !!!') + +# Asynchronous usage + +def callback(message): + print(message) + +pubnub.publish(channel, message, callback=callback, error=callback) + +``` + + +#### SUBSCRIBE +Pre 3.5.x, subscribe was blocking and would only be terminated via a false return from the callback. In our latest version of the SDK, subscribe is asyncronous, and because of this, usage is a bit different, but the experience is more like our other async SDKs. + +``` + +# Listen for Messages + +channel = 'hello_world' + +# Pre 3.5: +# + +# New in 3.5+ + +def callback(message, channel): + print(message) + + +def error(message): + print("ERROR : " + str(message)) + + +def connect(message): + print("CONNECTED") + + +def reconnect(message): + print("RECONNECTED") + + +def disconnect(message): + print("DISCONNECTED") + + +pubnub.subscribe(channel, callback=callback, error=callback, + connect=connect, reconnect=reconnect, disconnect=disconnect) +``` + +#### Unsubscribe +Once subscribed, you can easily, gracefully, unsubscribe: + +``` +# Pre 3.5: +# + +# New in 3.5+ + +Unsub example +``` + +#### PRESENCE + +``` + +# Pre 3.5: +# + +# New in 3.5+ + +# Listen for Presence Event Messages + +channel = 'hello_world' + +def callback(message, channel): + print(message) + + +def error(message): + print("ERROR : " + str(message)) + + + +pubnub.presence(channel, callback=callback, error=callback) +``` + +#### HERE_NOW + +``` + +# Pre 3.5: +# + +# New in 3.5+ + +# Get info on who is here right now! + +channel = 'hello_world' + +# Synchronous usage +print pubnub.here_now(channel) + + +# Asynchronous usage + +def callback(message): + print(message) + +pubnub.here_now(channel, callback=callback, error=callback) +``` + +#### HISTORY + +``` + +# Pre 3.5: +# + +# New in 3.5+ + +# Synchronous usage + +print pubnub.history(channel, count=2) + +# Asynchronous usage + + +def callback(message): + print(message) + +pubnub.history(channel, count=2, callback=callback, error=callback) +``` diff --git a/python-twisted/README b/python-twisted/README deleted file mode 100644 index 402fb34..0000000 --- a/python-twisted/README +++ /dev/null @@ -1,78 +0,0 @@ -## --------------------------------------------------- -## -## YOU MUST HAVE A PUBNUB ACCOUNT TO USE THE API. -## http://www.pubnub.com/account -## -## ---------------------------------------------------- - -## ---------------------------------------------------- -## PubNub 3.1 Real-time Cloud Push API - PYTHON TWISTED -## ---------------------------------------------------- -## -## www.pubnub.com - PubNub Real-time Push Service in the Cloud. -## http://github.com/pubnub/pubnub-api/tree/master/python-twisted/ -## -## PubNub is a Massively Scalable Real-time Service for Web and Mobile Games. -## This is a cloud-based service for broadcasting Real-time messages -## to thousands of web and mobile clients simultaneously. - - -from Pubnub import PubnubTwisted as Pubnub - -## --------------- -## Python Push API -## --------------- -pubnub = Pubnub(publish_key="demo", subscribe_key="demo", ssl_on=False) - -## ----------------------------------------------------------------------- -## IO Event Loop -## ----------------------------------------------------------------------- -## VERY IMPORTANT TO ADD THIS LINE AT THE VERY BOTTOM! -## -## pubnub.start() ## IMPORTANT! -## - -## ----------------------------------------------------------------------- -## Subscribe Example -## ----------------------------------------------------------------------- - -channel = 'hello_world' - -def callback(message, channel): - print(message) - - -def error(message): - print("ERROR : " + str(message)) - - -def connect(message): - print("CONNECTED") - - -def reconnect(message): - print("RECONNECTED") - - -def disconnect(message): - print("DISCONNECTED") - - -pubnub.subscribe(channel, callback=callback, error=callback, - connect=connect, reconnect=reconnect, disconnect=disconnect) - - -## ----------------------------------------------------------------------- -## History Example -## ----------------------------------------------------------------------- -def callback(message): - print(message) - -pubnub.history(channel, count=2, callback=callback, error=callback) - - - -## ----------------------------------------------------------------------- -## IO Event Loop -## ----------------------------------------------------------------------- -pubnub.start() diff --git a/python-twisted/README.md b/python-twisted/README.md new file mode 100644 index 0000000..47045f5 --- /dev/null +++ b/python-twisted/README.md @@ -0,0 +1,61 @@ +## PubNub 3.5.0 Web Data Push Cloud-hosted API - PYTHON TWISTED +#### www.pubnub.com - PubNub Web Data Push Service in the Cloud. +#### http://github.com/pubnub/python + +#### Import +``` +from Pubnub import PubnubTwisted as Pubnub +``` + +#### Init +pubnub = Pubnub(publish_key="demo", subscribe_key="demo", ssl_on=False) + + +#### IO Event Loop +##### VERY IMPORTANT TO ADD THIS LINE AT THE VERY BOTTOM! + +``` +pubnub.start() +``` + +#### Subscribe Example +``` +channel = 'hello_world' + +def callback(message, channel): + print(message) + + +def error(message): + print("ERROR : " + str(message)) + + +def connect(message): + print("CONNECTED") + + +def reconnect(message): + print("RECONNECTED") + + +def disconnect(message): + print("DISCONNECTED") + + +pubnub.subscribe(channel, callback=callback, error=callback, + connect=connect, reconnect=reconnect, disconnect=disconnect) +``` + +#### History Example +``` +def callback(message): + print(message) + +pubnub.history(channel, count=2, callback=callback, error=callback) +``` + + +#### IO Event Loop start +``` +pubnub.start() +``` \ No newline at end of file diff --git a/python-twisted/migration.md b/python-twisted/migration.md new file mode 100644 index 0000000..10d03ae --- /dev/null +++ b/python-twisted/migration.md @@ -0,0 +1,164 @@ +## PubNub 3.5.0 Web Data Push Cloud-hosted API - PYTHON +#### www.pubnub.com - PubNub Web Data Push Service in the Cloud. +#### http://github.com/pubnub/python + + +#### Init + + + +``` + +# Pre 3.5: +# + +# New in 3.5+ +pubnub = Pubnub(publish_key="demo", subscribe_key="demo", ssl_on=False) + +``` + +#### PUBLISH + +``` +channel = 'hello_world' +message = 'Hello World !!!' + +# Pre 3.5: +# + +# New in 3.5+ + +# Synchronous usage +print pubnub.publish(channel='hello_world', message='Hello World !!!') + +# Asynchronous usage + +def callback(message): + print(message) + +pubnub.publish(channel, message, callback=callback, error=callback) + +``` + + +#### SUBSCRIBE +Pre 3.5.x, subscribe was blocking and would only be terminated via a false return from the callback. In our latest version of the SDK, subscribe is asyncronous, and because of this, usage is a bit different, but the experience is more like our other async SDKs. + +``` + +# Listen for Messages + +channel = 'hello_world' + +# Pre 3.5: +# + +# New in 3.5+ + +def callback(message, channel): + print(message) + + +def error(message): + print("ERROR : " + str(message)) + + +def connect(message): + print("CONNECTED") + + +def reconnect(message): + print("RECONNECTED") + + +def disconnect(message): + print("DISCONNECTED") + + +pubnub.subscribe(channel, callback=callback, error=callback, + connect=connect, reconnect=reconnect, disconnect=disconnect) +``` + +#### Unsubscribe +Once subscribed, you can easily, gracefully, unsubscribe: + +``` +# Pre 3.5: +# + +# New in 3.5+ + +Unsub example +``` + +#### PRESENCE + +``` + +# Pre 3.5: +# + +# New in 3.5+ + +# Listen for Presence Event Messages + +channel = 'hello_world' + +def callback(message, channel): + print(message) + + +def error(message): + print("ERROR : " + str(message)) + + + +pubnub.presence(channel, callback=callback, error=callback) +``` + +#### HERE_NOW + +``` + +# Pre 3.5: +# + +# New in 3.5+ + +# Get info on who is here right now! + +channel = 'hello_world' + +# Synchronous usage +print pubnub.here_now(channel) + + +# Asynchronous usage + +def callback(message): + print(message) + +pubnub.here_now(channel, callback=callback, error=callback) +``` + +#### HISTORY + +``` + +# Pre 3.5: +# + +# New in 3.5+ + +# Synchronous usage + +print pubnub.history(channel, count=2) + +# Asynchronous usage + + +def callback(message): + print(message) + +pubnub.history(channel, count=2, callback=callback, error=callback) +``` diff --git a/python/README.md b/python/README.md index 10d03ae..14d767f 100644 --- a/python/README.md +++ b/python/README.md @@ -5,14 +5,7 @@ #### Init - - ``` - -# Pre 3.5: -# - -# New in 3.5+ pubnub = Pubnub(publish_key="demo", subscribe_key="demo", ssl_on=False) ``` @@ -23,11 +16,6 @@ pubnub = Pubnub(publish_key="demo", subscribe_key="demo", ssl_on=False) channel = 'hello_world' message = 'Hello World !!!' -# Pre 3.5: -# - -# New in 3.5+ - # Synchronous usage print pubnub.publish(channel='hello_world', message='Hello World !!!') @@ -42,19 +30,12 @@ pubnub.publish(channel, message, callback=callback, error=callback) #### SUBSCRIBE -Pre 3.5.x, subscribe was blocking and would only be terminated via a false return from the callback. In our latest version of the SDK, subscribe is asyncronous, and because of this, usage is a bit different, but the experience is more like our other async SDKs. ``` - # Listen for Messages channel = 'hello_world' -# Pre 3.5: -# - -# New in 3.5+ - def callback(message, channel): print(message) @@ -79,27 +60,10 @@ pubnub.subscribe(channel, callback=callback, error=callback, connect=connect, reconnect=reconnect, disconnect=disconnect) ``` -#### Unsubscribe -Once subscribed, you can easily, gracefully, unsubscribe: - -``` -# Pre 3.5: -# - -# New in 3.5+ - -Unsub example -``` #### PRESENCE ``` - -# Pre 3.5: -# - -# New in 3.5+ - # Listen for Presence Event Messages channel = 'hello_world' @@ -119,12 +83,6 @@ pubnub.presence(channel, callback=callback, error=callback) #### HERE_NOW ``` - -# Pre 3.5: -# - -# New in 3.5+ - # Get info on who is here right now! channel = 'hello_world' @@ -144,12 +102,6 @@ pubnub.here_now(channel, callback=callback, error=callback) #### HISTORY ``` - -# Pre 3.5: -# - -# New in 3.5+ - # Synchronous usage print pubnub.history(channel, count=2) diff --git a/python/migration.md b/python/migration.md new file mode 100644 index 0000000..10d03ae --- /dev/null +++ b/python/migration.md @@ -0,0 +1,164 @@ +## PubNub 3.5.0 Web Data Push Cloud-hosted API - PYTHON +#### www.pubnub.com - PubNub Web Data Push Service in the Cloud. +#### http://github.com/pubnub/python + + +#### Init + + + +``` + +# Pre 3.5: +# + +# New in 3.5+ +pubnub = Pubnub(publish_key="demo", subscribe_key="demo", ssl_on=False) + +``` + +#### PUBLISH + +``` +channel = 'hello_world' +message = 'Hello World !!!' + +# Pre 3.5: +# + +# New in 3.5+ + +# Synchronous usage +print pubnub.publish(channel='hello_world', message='Hello World !!!') + +# Asynchronous usage + +def callback(message): + print(message) + +pubnub.publish(channel, message, callback=callback, error=callback) + +``` + + +#### SUBSCRIBE +Pre 3.5.x, subscribe was blocking and would only be terminated via a false return from the callback. In our latest version of the SDK, subscribe is asyncronous, and because of this, usage is a bit different, but the experience is more like our other async SDKs. + +``` + +# Listen for Messages + +channel = 'hello_world' + +# Pre 3.5: +# + +# New in 3.5+ + +def callback(message, channel): + print(message) + + +def error(message): + print("ERROR : " + str(message)) + + +def connect(message): + print("CONNECTED") + + +def reconnect(message): + print("RECONNECTED") + + +def disconnect(message): + print("DISCONNECTED") + + +pubnub.subscribe(channel, callback=callback, error=callback, + connect=connect, reconnect=reconnect, disconnect=disconnect) +``` + +#### Unsubscribe +Once subscribed, you can easily, gracefully, unsubscribe: + +``` +# Pre 3.5: +# + +# New in 3.5+ + +Unsub example +``` + +#### PRESENCE + +``` + +# Pre 3.5: +# + +# New in 3.5+ + +# Listen for Presence Event Messages + +channel = 'hello_world' + +def callback(message, channel): + print(message) + + +def error(message): + print("ERROR : " + str(message)) + + + +pubnub.presence(channel, callback=callback, error=callback) +``` + +#### HERE_NOW + +``` + +# Pre 3.5: +# + +# New in 3.5+ + +# Get info on who is here right now! + +channel = 'hello_world' + +# Synchronous usage +print pubnub.here_now(channel) + + +# Asynchronous usage + +def callback(message): + print(message) + +pubnub.here_now(channel, callback=callback, error=callback) +``` + +#### HISTORY + +``` + +# Pre 3.5: +# + +# New in 3.5+ + +# Synchronous usage + +print pubnub.history(channel, count=2) + +# Asynchronous usage + + +def callback(message): + print(message) + +pubnub.history(channel, count=2, callback=callback, error=callback) +``` -- cgit v1.2.3 From b51ccae596536c3d0fd3401c46f387e0fa2ee358 Mon Sep 17 00:00:00 2001 From: devendram Date: Tue, 17 Jun 2014 02:52:36 +0530 Subject: Create README.md --- README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..05d6097 --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ + +##PubNub Python-based APIs for core Python, Twisted, and Tornado + +### PubNub 3.5.0 Web Data Push Cloud-hosted API +#### www.pubnub.com - PubNub Web Data Push Service in the Cloud. +#### http://github.com/pubnub/python + + +#### Installation +pip install pubnub==3.5.0 + +Examples are available in README and examples directories under specific +platforms. + +### Pubnub Console +Pubnub console is a command line app which allows you to do various +pubnub operations like publish, subscribe, getting history, here now, +presence etc from command line + +#### Installation + +pip install pubnub-console -- cgit v1.2.3 From 8b3a1cd7df862cad948020caf19b6d4e400628ec Mon Sep 17 00:00:00 2001 From: devendram Date: Tue, 17 Jun 2014 02:53:13 +0530 Subject: Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 05d6097..4cdd05c 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,9 @@ #### Installation +``` pip install pubnub==3.5.0 +``` Examples are available in README and examples directories under specific platforms. @@ -18,5 +20,6 @@ pubnub operations like publish, subscribe, getting history, here now, presence etc from command line #### Installation - +``` pip install pubnub-console +``` -- cgit v1.2.3 From 5dc6fd72d54d8ba615b9ecdc9ad8a79c4c1916e3 Mon Sep 17 00:00:00 2001 From: devendram Date: Tue, 17 Jun 2014 02:54:50 +0530 Subject: Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4cdd05c..4888087 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,8 @@ pip install pubnub==3.5.0 ``` -Examples are available in README and examples directories under specific -platforms. +Examples and instructions for migrating from older versions of sdk are available in +README.md, migration.md and examples directories under specific platforms. ### Pubnub Console Pubnub console is a command line app which allows you to do various -- cgit v1.2.3 From 9557b3b2f25dae7651d2f64d4378f4a41c459ac4 Mon Sep 17 00:00:00 2001 From: Geremy Cohen Date: Mon, 16 Jun 2014 14:36:22 -0700 Subject: Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4888087..9b92a26 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ ### PubNub 3.5.0 Web Data Push Cloud-hosted API #### www.pubnub.com - PubNub Web Data Push Service in the Cloud. -#### http://github.com/pubnub/python #### Installation @@ -14,6 +13,10 @@ pip install pubnub==3.5.0 Examples and instructions for migrating from older versions of sdk are available in README.md, migration.md and examples directories under specific platforms. +[Base Python - Everyday python for your scripts and apps](python) +[Tornado - For use with the Python Tornado Framework](tornado) +[Twisted - For use with the Python Twisted Framework](twisted) + ### Pubnub Console Pubnub console is a command line app which allows you to do various pubnub operations like publish, subscribe, getting history, here now, -- cgit v1.2.3 From 8f3330cf211a1bfeb82fd92a028158320e492fdd Mon Sep 17 00:00:00 2001 From: Geremy Cohen Date: Mon, 16 Jun 2014 14:38:03 -0700 Subject: Update README.md --- README.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 9b92a26..cf595a4 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,9 @@ -##PubNub Python-based APIs for core Python, Twisted, and Tornado +#### PubNub 3.5.0 Web Data Push Cloud-hosted API +#### www.pubnub.com - PubNub Web Data Push Service in the Cloud Clients for Python, including Twisted and Tornado -### PubNub 3.5.0 Web Data Push Cloud-hosted API -#### www.pubnub.com - PubNub Web Data Push Service in the Cloud. - -#### Installation +## Installation ``` pip install pubnub==3.5.0 ``` @@ -13,16 +11,17 @@ pip install pubnub==3.5.0 Examples and instructions for migrating from older versions of sdk are available in README.md, migration.md and examples directories under specific platforms. -[Base Python - Everyday python for your scripts and apps](python) +Base Python - Everyday python for your scripts and apps](python) + [Tornado - For use with the Python Tornado Framework](tornado) + [Twisted - For use with the Python Twisted Framework](twisted) -### Pubnub Console +## Pubnub Console Pubnub console is a command line app which allows you to do various pubnub operations like publish, subscribe, getting history, here now, presence etc from command line -#### Installation ``` pip install pubnub-console ``` -- cgit v1.2.3 From abf5cf859b72b77b08b65a2456df51ad5184eeaf Mon Sep 17 00:00:00 2001 From: Geremy Cohen Date: Mon, 16 Jun 2014 14:38:18 -0700 Subject: Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cf595a4..e00d0be 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ pip install pubnub==3.5.0 Examples and instructions for migrating from older versions of sdk are available in README.md, migration.md and examples directories under specific platforms. -Base Python - Everyday python for your scripts and apps](python) +[Base Python - Everyday python for your scripts and apps](python) [Tornado - For use with the Python Tornado Framework](tornado) -- cgit v1.2.3 From 3e585aae16a3979b6979c9dcbf88002fa5e2631b Mon Sep 17 00:00:00 2001 From: Geremy Cohen Date: Mon, 16 Jun 2014 14:40:46 -0700 Subject: Update README.md --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e00d0be..67006cb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ +## Contact support@pubnub.com with any questions or comments -#### PubNub 3.5.0 Web Data Push Cloud-hosted API -#### www.pubnub.com - PubNub Web Data Push Service in the Cloud Clients for Python, including Twisted and Tornado +#### [PubNub](http://www.pubnub.com) Real-time Data Network +##### Clients for Python, including Twisted and Tornado ## Installation @@ -25,3 +26,5 @@ presence etc from command line ``` pip install pubnub-console ``` + +## Contact support@pubnub.com with any questions or comments -- cgit v1.2.3 From eed03469559dfca83a3ae320a674f2784b93ffc4 Mon Sep 17 00:00:00 2001 From: Geremy Cohen Date: Mon, 16 Jun 2014 14:41:16 -0700 Subject: Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 67006cb..8c1741c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## Contact support@pubnub.com with any questions or comments +## Contact support@pubnub.com for all questions #### [PubNub](http://www.pubnub.com) Real-time Data Network ##### Clients for Python, including Twisted and Tornado @@ -27,4 +27,4 @@ presence etc from command line pip install pubnub-console ``` -## Contact support@pubnub.com with any questions or comments +## Contact support@pubnub.com for all questions -- cgit v1.2.3 From c1f366829375593bf3946d5d2a761af57d521783 Mon Sep 17 00:00:00 2001 From: Devendra Date: Tue, 17 Jun 2014 03:15:19 +0530 Subject: adding migration files --- python-tornado/migration.md | 97 +++++++++++++++++++++++++++++++-------------- python/migration.md | 61 +++++++++++++++++++++++----- 2 files changed, 118 insertions(+), 40 deletions(-) diff --git a/python-tornado/migration.md b/python-tornado/migration.md index 10d03ae..5ce15b5 100644 --- a/python-tornado/migration.md +++ b/python-tornado/migration.md @@ -2,15 +2,28 @@ #### www.pubnub.com - PubNub Web Data Push Service in the Cloud. #### http://github.com/pubnub/python +#### Import -#### Init +``` +# Pre 3.5: +from Pubnub import Pubnub +# New in 3.5+ +from Pubnub import PubnubTornado as Pubnub + +``` +#### Init + ``` # Pre 3.5: -# +pubnub = Pubnub( + "demo", ## PUBLISH_KEY + "demo", ## SUBSCRIBE_KEY + False ## SSL_ON? +) # New in 3.5+ pubnub = Pubnub(publish_key="demo", subscribe_key="demo", ssl_on=False) @@ -24,14 +37,16 @@ channel = 'hello_world' message = 'Hello World !!!' # Pre 3.5: -# - -# New in 3.5+ +def callback(messages): + print(messages) -# Synchronous usage -print pubnub.publish(channel='hello_world', message='Hello World !!!') +pubnub.history( { + 'channel' : channel, + 'message' : message, + 'callback' : callback +}) -# Asynchronous usage +# New in 3.5+ def callback(message): print(message) @@ -42,7 +57,6 @@ pubnub.publish(channel, message, callback=callback, error=callback) #### SUBSCRIBE -Pre 3.5.x, subscribe was blocking and would only be terminated via a false return from the callback. In our latest version of the SDK, subscribe is asyncronous, and because of this, usage is a bit different, but the experience is more like our other async SDKs. ``` @@ -51,7 +65,17 @@ Pre 3.5.x, subscribe was blocking and would only be terminated via a false retur channel = 'hello_world' # Pre 3.5: -# +def connected() : + print('CONNECTED') + +def message_received(message): + print(message) + +pubnub.subscribe({ + 'channel' : channel, + 'connect' : connected, + 'callback' : message_received +}) # New in 3.5+ @@ -84,11 +108,13 @@ Once subscribed, you can easily, gracefully, unsubscribe: ``` # Pre 3.5: -# +pubnub.unsubscribe({ + 'channel' : 'hello_world' +}) # New in 3.5+ -Unsub example +pubnub.unsubscribe(channel='hello_world') ``` #### PRESENCE @@ -111,8 +137,6 @@ def callback(message, channel): def error(message): print("ERROR : " + str(message)) - - pubnub.presence(channel, callback=callback, error=callback) ``` @@ -120,20 +144,22 @@ pubnub.presence(channel, callback=callback, error=callback) ``` -# Pre 3.5: -# +channel = 'hello_world' -# New in 3.5+ +# Pre 3.5: +def callback(messages): + print(messages) -# Get info on who is here right now! +pubnub.here_now( { + 'channel' : channel, + 'callback' : callback +}) -channel = 'hello_world' -# Synchronous usage -print pubnub.here_now(channel) +# New in 3.5+ +# Get info on who is here right now! -# Asynchronous usage def callback(message): print(message) @@ -144,21 +170,34 @@ pubnub.here_now(channel, callback=callback, error=callback) #### HISTORY ``` +channel = 'hello_world' # Pre 3.5: -# - -# New in 3.5+ +def history_complete(messages): + print(messages) -# Synchronous usage +pubnub.history( { + 'channel' : channel, + 'limit' : 2, + 'callback' : history_complete +}) -print pubnub.history(channel, count=2) - -# Asynchronous usage +# New in 3.5+ def callback(message): print(message) pubnub.history(channel, count=2, callback=callback, error=callback) ``` + +#### IO Event Loop + +``` + +# Pre 3.5: +tornado.ioloop.IOLoop.instance().start() + +# New in 3.5+ +pubnub.start() +``` diff --git a/python/migration.md b/python/migration.md index 10d03ae..4567a7f 100644 --- a/python/migration.md +++ b/python/migration.md @@ -5,12 +5,14 @@ #### Init - - ``` # Pre 3.5: -# +pubnub = Pubnub( + "demo", ## PUBLISH_KEY + "demo", ## SUBSCRIBE_KEY + False ## SSL_ON? +) # New in 3.5+ pubnub = Pubnub(publish_key="demo", subscribe_key="demo", ssl_on=False) @@ -24,7 +26,11 @@ channel = 'hello_world' message = 'Hello World !!!' # Pre 3.5: -# +info = pubnub.publish({ + 'channel' : channel, + 'message' : message +}) +print(info) # New in 3.5+ @@ -51,7 +57,16 @@ Pre 3.5.x, subscribe was blocking and would only be terminated via a false retur channel = 'hello_world' # Pre 3.5: -# +# Listen for Messages *BLOCKING* +def receive(message) : + print(message) + return True + +pubnub.subscribe({ + 'channel' : channel, + 'callback' : receive +}) + # New in 3.5+ @@ -88,22 +103,31 @@ Once subscribed, you can easily, gracefully, unsubscribe: # New in 3.5+ -Unsub example +pubnub.unsubscribe(channel='hello_world') ``` #### PRESENCE ``` + +channel = 'hello_world' + # Pre 3.5: -# +def pres_event(message) : + print(message) + return True + +pubnub.presence({ + 'channel' : channel, + 'callback' : receive +}) + # New in 3.5+ # Listen for Presence Event Messages -channel = 'hello_world' - def callback(message, channel): print(message) @@ -121,7 +145,15 @@ pubnub.presence(channel, callback=callback, error=callback) ``` # Pre 3.5: -# +# Get info on who is here right now! + +here_now = pubnub.here_now({ + 'channel' : 'hello_world', +}) + +print(here_now['occupancy']) +print(here_now['uuids']) + # New in 3.5+ @@ -146,7 +178,14 @@ pubnub.here_now(channel, callback=callback, error=callback) ``` # Pre 3.5: -# +# Load Previously Published Messages +history = pubnub.detailedHistory({ + 'channel' : 'my_channel', + 'end' : my_end_time_token, # Optional + 'start' : my_start_time_token, # Optional + 'count' : num_of_msgs_to_return # Optional, default is 100 +}) +print(history) # New in 3.5+ -- cgit v1.2.3 From 7865970148139babf2921b4d7fe11917568be9e9 Mon Sep 17 00:00:00 2001 From: Devendra Date: Tue, 17 Jun 2014 03:18:40 +0530 Subject: typo --- python-tornado/migration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python-tornado/migration.md b/python-tornado/migration.md index 5ce15b5..7feb4ea 100644 --- a/python-tornado/migration.md +++ b/python-tornado/migration.md @@ -40,7 +40,7 @@ message = 'Hello World !!!' def callback(messages): print(messages) -pubnub.history( { +pubnub.publish( { 'channel' : channel, 'message' : message, 'callback' : callback -- cgit v1.2.3 From 2419ac0419fe74b582b94ed7784b3732049db9f2 Mon Sep 17 00:00:00 2001 From: Devendra Date: Tue, 17 Jun 2014 03:27:05 +0530 Subject: readme changes --- python-tornado/README.md | 14 +++++++ python-twisted/README.md | 14 +++++++ python-twisted/migration.md | 97 +++++++++++++++++++++++++++++++-------------- 3 files changed, 96 insertions(+), 29 deletions(-) diff --git a/python-tornado/README.md b/python-tornado/README.md index 1d210f9..406b556 100644 --- a/python-tornado/README.md +++ b/python-tornado/README.md @@ -11,6 +11,20 @@ from Pubnub import PubnubTornado as Pubnub pubnub = Pubnub(publish_key="demo", subscribe_key="demo", ssl_on=False) +#### Publish Example +``` +channel = 'hello_world' +message = 'Hello World !!!' + +# Asynchronous usage + + +def callback(message): + print(message) + +pubnub.publish(channel, message, callback=callback, error=callback) +``` + #### IO Event Loop ##### VERY IMPORTANT TO ADD THIS LINE AT THE VERY BOTTOM! diff --git a/python-twisted/README.md b/python-twisted/README.md index 47045f5..2abefd5 100644 --- a/python-twisted/README.md +++ b/python-twisted/README.md @@ -10,6 +10,20 @@ from Pubnub import PubnubTwisted as Pubnub #### Init pubnub = Pubnub(publish_key="demo", subscribe_key="demo", ssl_on=False) +#### Publish Example +``` +channel = 'hello_world' +message = 'Hello World !!!' + +# Asynchronous usage + + +def callback(message): + print(message) + +pubnub.publish(channel, message, callback=callback, error=callback) +``` + #### IO Event Loop ##### VERY IMPORTANT TO ADD THIS LINE AT THE VERY BOTTOM! diff --git a/python-twisted/migration.md b/python-twisted/migration.md index 10d03ae..fcde163 100644 --- a/python-twisted/migration.md +++ b/python-twisted/migration.md @@ -2,15 +2,28 @@ #### www.pubnub.com - PubNub Web Data Push Service in the Cloud. #### http://github.com/pubnub/python +#### Import -#### Init +``` +# Pre 3.5: +from Pubnub import Pubnub +# New in 3.5+ +from Pubnub import PubnubTwisted as Pubnub + +``` +#### Init + ``` # Pre 3.5: -# +pubnub = Pubnub( + "demo", ## PUBLISH_KEY + "demo", ## SUBSCRIBE_KEY + False ## SSL_ON? +) # New in 3.5+ pubnub = Pubnub(publish_key="demo", subscribe_key="demo", ssl_on=False) @@ -24,14 +37,16 @@ channel = 'hello_world' message = 'Hello World !!!' # Pre 3.5: -# - -# New in 3.5+ +def callback(messages): + print(messages) -# Synchronous usage -print pubnub.publish(channel='hello_world', message='Hello World !!!') +pubnub.publish( { + 'channel' : channel, + 'message' : message, + 'callback' : callback +}) -# Asynchronous usage +# New in 3.5+ def callback(message): print(message) @@ -42,7 +57,6 @@ pubnub.publish(channel, message, callback=callback, error=callback) #### SUBSCRIBE -Pre 3.5.x, subscribe was blocking and would only be terminated via a false return from the callback. In our latest version of the SDK, subscribe is asyncronous, and because of this, usage is a bit different, but the experience is more like our other async SDKs. ``` @@ -51,7 +65,17 @@ Pre 3.5.x, subscribe was blocking and would only be terminated via a false retur channel = 'hello_world' # Pre 3.5: -# +def connected() : + print('CONNECTED') + +def message_received(message): + print(message) + +pubnub.subscribe({ + 'channel' : channel, + 'connect' : connected, + 'callback' : message_received +}) # New in 3.5+ @@ -84,11 +108,13 @@ Once subscribed, you can easily, gracefully, unsubscribe: ``` # Pre 3.5: -# +pubnub.unsubscribe({ + 'channel' : 'hello_world' +}) # New in 3.5+ -Unsub example +pubnub.unsubscribe(channel='hello_world') ``` #### PRESENCE @@ -111,8 +137,6 @@ def callback(message, channel): def error(message): print("ERROR : " + str(message)) - - pubnub.presence(channel, callback=callback, error=callback) ``` @@ -120,20 +144,22 @@ pubnub.presence(channel, callback=callback, error=callback) ``` -# Pre 3.5: -# +channel = 'hello_world' -# New in 3.5+ +# Pre 3.5: +def callback(messages): + print(messages) -# Get info on who is here right now! +pubnub.here_now( { + 'channel' : channel, + 'callback' : callback +}) -channel = 'hello_world' -# Synchronous usage -print pubnub.here_now(channel) +# New in 3.5+ +# Get info on who is here right now! -# Asynchronous usage def callback(message): print(message) @@ -144,21 +170,34 @@ pubnub.here_now(channel, callback=callback, error=callback) #### HISTORY ``` +channel = 'hello_world' # Pre 3.5: -# - -# New in 3.5+ +def history_complete(messages): + print(messages) -# Synchronous usage +pubnub.history( { + 'channel' : channel, + 'limit' : 2, + 'callback' : history_complete +}) -print pubnub.history(channel, count=2) - -# Asynchronous usage +# New in 3.5+ def callback(message): print(message) pubnub.history(channel, count=2, callback=callback, error=callback) ``` + +#### IO Event Loop + +``` + +# Pre 3.5: +reactor.run() + +# New in 3.5+ +pubnub.start() +``` -- cgit v1.2.3 From 6363edd8797f914af23612bd576462dcceb408f2 Mon Sep 17 00:00:00 2001 From: Devendra Date: Tue, 17 Jun 2014 03:31:40 +0530 Subject: readme changes --- python-tornado/README.md | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/python-tornado/README.md b/python-tornado/README.md index 406b556..61146ea 100644 --- a/python-tornado/README.md +++ b/python-tornado/README.md @@ -8,8 +8,9 @@ from Pubnub import PubnubTornado as Pubnub ``` #### Init +``` pubnub = Pubnub(publish_key="demo", subscribe_key="demo", ssl_on=False) - +``` #### Publish Example ``` @@ -68,6 +69,32 @@ def callback(message): pubnub.history(channel, count=2, callback=callback, error=callback) ``` +#### Here Now Example +``` +def callback(message): + print(message) + +pubnub.here_now(channel, callback=callback, error=callback) +``` + +#### Presence Example +``` +channel = 'hello_world' + +def callback(message, channel): + print(message) + + +def error(message): + print("ERROR : " + str(message)) + +pubnub.presence(channel, callback=callback, error=callback) +``` + +#### Unsubscribe Example +``` +pubnub.unsubscribe(channel='hello_world') +``` #### IO Event Loop start ``` -- cgit v1.2.3 From 0c90b0ce532d01e3a2232a8416362923bb76f3f5 Mon Sep 17 00:00:00 2001 From: Devendra Date: Tue, 17 Jun 2014 03:37:51 +0530 Subject: readme change --- python-twisted/README.md | 29 ++++++++++++++++++++++++++++- python/README.md | 10 ++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/python-twisted/README.md b/python-twisted/README.md index 2abefd5..ef56afb 100644 --- a/python-twisted/README.md +++ b/python-twisted/README.md @@ -8,7 +8,9 @@ from Pubnub import PubnubTwisted as Pubnub ``` #### Init +``` pubnub = Pubnub(publish_key="demo", subscribe_key="demo", ssl_on=False) +``` #### Publish Example ``` @@ -24,7 +26,6 @@ def callback(message): pubnub.publish(channel, message, callback=callback, error=callback) ``` - #### IO Event Loop ##### VERY IMPORTANT TO ADD THIS LINE AT THE VERY BOTTOM! @@ -68,6 +69,32 @@ def callback(message): pubnub.history(channel, count=2, callback=callback, error=callback) ``` +#### Here Now Example +``` +def callback(message): + print(message) + +pubnub.here_now(channel, callback=callback, error=callback) +``` + +#### Presence Example +``` +channel = 'hello_world' + +def callback(message, channel): + print(message) + + +def error(message): + print("ERROR : " + str(message)) + +pubnub.presence(channel, callback=callback, error=callback) +``` + +#### Unsubscribe Example +``` +pubnub.unsubscribe(channel='hello_world') +``` #### IO Event Loop start ``` diff --git a/python/README.md b/python/README.md index 14d767f..8b46275 100644 --- a/python/README.md +++ b/python/README.md @@ -60,6 +60,16 @@ pubnub.subscribe(channel, callback=callback, error=callback, connect=connect, reconnect=reconnect, disconnect=disconnect) ``` +#### UNSUBSCRIBE + +``` +# Listen for Messages + +channel = 'hello_world' + +pubnub.unsubscribe(channel=channel) +``` + #### PRESENCE -- cgit v1.2.3 From ad6940a700748a6e432002f439a11c6f31e149dc Mon Sep 17 00:00:00 2001 From: Devendra Date: Tue, 17 Jun 2014 04:02:02 +0530 Subject: readme changes --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 8c1741c..b65f6d0 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,12 @@ pip install pubnub==3.5.0 ``` +If you prefer to use the previous version of PubNub, run this pip commandline to revert +``` +pip install pubnub==3.3.5 +``` + + Examples and instructions for migrating from older versions of sdk are available in README.md, migration.md and examples directories under specific platforms. -- cgit v1.2.3 From 7c0df06dbe0eb8441b0c62b4e8cffe9bfe7ff739 Mon Sep 17 00:00:00 2001 From: Devendra Date: Tue, 17 Jun 2014 04:08:07 +0530 Subject: readme --- README.md | 101 -------------------------------------------------------------- 1 file changed, 101 deletions(-) diff --git a/README.md b/README.md index 5f5fc62..b65f6d0 100644 --- a/README.md +++ b/README.md @@ -34,104 +34,3 @@ pip install pubnub-console ``` ## Contact support@pubnub.com for all questions -======= -## PubNub 3.3 Web Data Push Cloud-hosted API - PYTHON -#### www.pubnub.com - PubNub Web Data Push Service in the Cloud. -#### http://github.com/pubnub/python - -## Major Upgrade to 3.6 underway! In the meantime, we've provided Python 3 beta support in the python3 branch. - -Contact us at support@pubnub.com if you have any questions in the meantime. - -#### Init - -``` -pubnub = Pubnub( - "demo", ## PUBLISH_KEY - "demo", ## SUBSCRIBE_KEY - None, ## SECRET_KEY - False ## SSL_ON? -) -``` - -#### PUBLISH - -``` -info = pubnub.publish({ - 'channel' : 'hello_world', - 'message' : { - 'some_text' : 'Hello my World' - } -}) -print(info) -``` - - -#### SUBSCRIBE - -``` -# Listen for Messages *BLOCKING* -def receive(message) : - print(message) - return True - -pubnub.subscribe({ - 'channel' : 'hello_world', - 'callback' : receive -}) -``` - - -#### PRESENCE - -``` -# Listen for Presence Event Messages *BLOCKING* - -def pres_event(message) : - print(message) - return True - -pubnub.presence({ - 'channel' : 'hello_world', - 'callback' : receive -}) -``` - -#### HERE_NOW - -``` -# Get info on who is here right now! - -here_now = pubnub.here_now({ - 'channel' : 'hello_world', -}) - -print(here_now['occupancy']) -print(here_now['uuids']) -``` - -#### Channel Analytics - -``` -analytics = pubnub.analytics({ - 'channel' : 'channel-name-here', ## Leave blank for all channels - 'limit' : 100, ## aggregation range - 'ago' : 0, ## minutes ago to look backward - 'duration' : 100 ## minutes offset -}) -print(analytics) - -``` - -#### HISTORY - -``` -# Load Previously Published Messages -history = pubnub.detailedHistory({ - 'channel' : 'my_channel', - 'end' : my_end_time_token, # Optional - 'start' : my_start_time_token, # Optional - 'count' : num_of_msgs_to_return # Optional, default is 100 -}) -print(history) -``` -- cgit v1.2.3 From 69060f3c81bea0c4ea3df174f00bb872da44ae48 Mon Sep 17 00:00:00 2001 From: Geremy Cohen Date: Mon, 16 Jun 2014 15:45:30 -0700 Subject: Update README.md --- python/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/python/README.md b/python/README.md index 8b46275..c077918 100644 --- a/python/README.md +++ b/python/README.md @@ -1,7 +1,7 @@ -## PubNub 3.5.0 Web Data Push Cloud-hosted API - PYTHON -#### www.pubnub.com - PubNub Web Data Push Service in the Cloud. -#### http://github.com/pubnub/python +## Contact support@pubnub.com for all questions +#### [PubNub](http://www.pubnub.com) Real-time Data Network +##### Standalone Python Client #### Init @@ -124,3 +124,4 @@ def callback(message): pubnub.history(channel, count=2, callback=callback, error=callback) ``` +## Contact support@pubnub.com for all questions -- cgit v1.2.3 From a66d137b3b98928786c7e70cfcda87cf4c996be8 Mon Sep 17 00:00:00 2001 From: Geremy Cohen Date: Mon, 16 Jun 2014 15:45:32 -0700 Subject: Update README.md --- python-twisted/README.md | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/python-twisted/README.md b/python-twisted/README.md index ef56afb..ea4173c 100644 --- a/python-twisted/README.md +++ b/python-twisted/README.md @@ -1,6 +1,14 @@ -## PubNub 3.5.0 Web Data Push Cloud-hosted API - PYTHON TWISTED -#### www.pubnub.com - PubNub Web Data Push Service in the Cloud. -#### http://github.com/pubnub/python +## Contact support@pubnub.com for all questions + +#### [PubNub](http://www.pubnub.com) Real-time Data Network +##### Twisted Client + +## IO Event Loop +Be sure to eventually start the event loop or PubNub won't run! + +``` +pubnub.start() +``` #### Import ``` @@ -26,13 +34,6 @@ def callback(message): pubnub.publish(channel, message, callback=callback, error=callback) ``` -#### IO Event Loop -##### VERY IMPORTANT TO ADD THIS LINE AT THE VERY BOTTOM! - -``` -pubnub.start() -``` - #### Subscribe Example ``` channel = 'hello_world' @@ -99,4 +100,6 @@ pubnub.unsubscribe(channel='hello_world') #### IO Event Loop start ``` pubnub.start() -``` \ No newline at end of file +``` + +## Contact support@pubnub.com for all questions -- cgit v1.2.3 From 1c997e33c70095b7bb3af36120e9a384e6a512d9 Mon Sep 17 00:00:00 2001 From: Geremy Cohen Date: Mon, 16 Jun 2014 15:45:35 -0700 Subject: Update README.md --- python-tornado/README.md | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/python-tornado/README.md b/python-tornado/README.md index 61146ea..53aad32 100644 --- a/python-tornado/README.md +++ b/python-tornado/README.md @@ -1,6 +1,14 @@ -## PubNub 3.5.0 Web Data Push Cloud-hosted API - PYTHON TORNADO -#### www.pubnub.com - PubNub Web Data Push Service in the Cloud. -#### http://github.com/pubnub/python +## Contact support@pubnub.com for all questions + +#### [PubNub](http://www.pubnub.com) Real-time Data Network +##### Tornado Client + +## IO Event Loop +Be sure to eventually start the event loop or PubNub won't run! + +``` +pubnub.start() +``` #### Import ``` @@ -26,13 +34,6 @@ def callback(message): pubnub.publish(channel, message, callback=callback, error=callback) ``` -#### IO Event Loop -##### VERY IMPORTANT TO ADD THIS LINE AT THE VERY BOTTOM! - -``` -pubnub.start() -``` - #### Subscribe Example ``` channel = 'hello_world' @@ -99,4 +100,6 @@ pubnub.unsubscribe(channel='hello_world') #### IO Event Loop start ``` pubnub.start() -``` \ No newline at end of file +``` + +## Contact support@pubnub.com for all questions -- cgit v1.2.3 From 391a87882310a7db681f3b976fe60b7781c493be Mon Sep 17 00:00:00 2001 From: Geremy Cohen Date: Mon, 16 Jun 2014 15:46:16 -0700 Subject: Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b65f6d0..385cc9c 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ pip install pubnub==3.3.5 Examples and instructions for migrating from older versions of sdk are available in README.md, migration.md and examples directories under specific platforms. -[Base Python - Everyday python for your scripts and apps](python) +[Standalone Python - Everyday python for your scripts and apps](python) [Tornado - For use with the Python Tornado Framework](tornado) -- cgit v1.2.3 From f14b2fc84d1313d95c9a35be0c327d851ac99dc6 Mon Sep 17 00:00:00 2001 From: Geremy Cohen Date: Mon, 16 Jun 2014 15:56:03 -0700 Subject: Update README.md --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 385cc9c..0e85549 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ #### [PubNub](http://www.pubnub.com) Real-time Data Network ##### Clients for Python, including Twisted and Tornado - ## Installation ``` pip install pubnub==3.5.0 @@ -19,10 +18,13 @@ Examples and instructions for migrating from older versions of sdk are available README.md, migration.md and examples directories under specific platforms. [Standalone Python - Everyday python for your scripts and apps](python) +Migration docs for Python Standalone are [found here.](python/migration.md) -[Tornado - For use with the Python Tornado Framework](tornado) +[Tornado - For use with the Python Tornado Framework](python-tornado) +Migration docs for Tornado are [found here.](python-tornado/migration.md) -[Twisted - For use with the Python Twisted Framework](twisted) +[Twisted - For use with the Python Twisted Framework](python-twisted) +Migration docs for Twisted [found here.](python-twisted/migration.md) ## Pubnub Console Pubnub console is a command line app which allows you to do various -- cgit v1.2.3 From 03343820fc654ca761b73f917df17269f29c24ae Mon Sep 17 00:00:00 2001 From: Geremy Cohen Date: Mon, 16 Jun 2014 16:00:07 -0700 Subject: Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0e85549..b23199c 100644 --- a/README.md +++ b/README.md @@ -8,14 +8,14 @@ pip install pubnub==3.5.0 ``` +## Migration and Reversion If you prefer to use the previous version of PubNub, run this pip commandline to revert + ``` pip install pubnub==3.3.5 ``` - -Examples and instructions for migrating from older versions of sdk are available in -README.md, migration.md and examples directories under specific platforms. +Examples and instructions for migrating from older versions of the SDK are available in their acompanying README.md, migration.md and examples directories under specific platforms. [Standalone Python - Everyday python for your scripts and apps](python) Migration docs for Python Standalone are [found here.](python/migration.md) -- cgit v1.2.3 From f46d2069d62cf76242bdc8a92a086b81b874a947 Mon Sep 17 00:00:00 2001 From: Geremy Cohen Date: Mon, 16 Jun 2014 16:03:58 -0700 Subject: Update README.md --- README.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b23199c..0f9bf01 100644 --- a/README.md +++ b/README.md @@ -7,23 +7,27 @@ ``` pip install pubnub==3.5.0 ``` +Examples and instructions for the SDK are available in their acompanying README.md, migration.md and examples directories under their specific platform directories: + +[Standalone Python - Everyday python for your scripts and apps](python) + +[Tornado - For use with the Python Tornado Framework](python-tornado) + +[Twisted - For use with the Python Twisted Framework](python-twisted) ## Migration and Reversion -If you prefer to use the previous version of PubNub, run this pip commandline to revert +If you need to revert to the previous version of PubNub, run this commandline: ``` pip install pubnub==3.3.5 ``` -Examples and instructions for migrating from older versions of the SDK are available in their acompanying README.md, migration.md and examples directories under specific platforms. +Migration information for the SDK are available in their migration.md under their specific platform directories: -[Standalone Python - Everyday python for your scripts and apps](python) Migration docs for Python Standalone are [found here.](python/migration.md) -[Tornado - For use with the Python Tornado Framework](python-tornado) Migration docs for Tornado are [found here.](python-tornado/migration.md) -[Twisted - For use with the Python Twisted Framework](python-twisted) Migration docs for Twisted [found here.](python-twisted/migration.md) ## Pubnub Console -- cgit v1.2.3 From 34c4843b766a80df4b60f996fcd5cbc65d361158 Mon Sep 17 00:00:00 2001 From: Geremy Cohen Date: Mon, 16 Jun 2014 16:06:28 -0700 Subject: Update migration.md --- python-twisted/migration.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/python-twisted/migration.md b/python-twisted/migration.md index fcde163..49de5a9 100644 --- a/python-twisted/migration.md +++ b/python-twisted/migration.md @@ -1,6 +1,7 @@ -## PubNub 3.5.0 Web Data Push Cloud-hosted API - PYTHON -#### www.pubnub.com - PubNub Web Data Push Service in the Cloud. -#### http://github.com/pubnub/python +## Contact support@pubnub.com for all questions + +#### [PubNub](http://www.pubnub.com) Real-time Data Network +##### Twisted Migration #### Import @@ -201,3 +202,4 @@ reactor.run() # New in 3.5+ pubnub.start() ``` +## Contact support@pubnub.com for all questions -- cgit v1.2.3 From 2ad738eb629128fb822794c385feb47bcf356c44 Mon Sep 17 00:00:00 2001 From: Geremy Cohen Date: Mon, 16 Jun 2014 16:06:34 -0700 Subject: Update migration.md --- python-tornado/migration.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/python-tornado/migration.md b/python-tornado/migration.md index 7feb4ea..d5fd8f0 100644 --- a/python-tornado/migration.md +++ b/python-tornado/migration.md @@ -1,6 +1,7 @@ -## PubNub 3.5.0 Web Data Push Cloud-hosted API - PYTHON -#### www.pubnub.com - PubNub Web Data Push Service in the Cloud. -#### http://github.com/pubnub/python +## Contact support@pubnub.com for all questions + +#### [PubNub](http://www.pubnub.com) Real-time Data Network +##### Tornado Migration #### Import @@ -201,3 +202,4 @@ tornado.ioloop.IOLoop.instance().start() # New in 3.5+ pubnub.start() ``` +## Contact support@pubnub.com for all questions -- cgit v1.2.3 From fb51ee8353088d58986a490118a8eef5a00f3f6b Mon Sep 17 00:00:00 2001 From: Geremy Cohen Date: Mon, 16 Jun 2014 16:06:44 -0700 Subject: Update migration.md --- python/migration.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/python/migration.md b/python/migration.md index 4567a7f..61cf203 100644 --- a/python/migration.md +++ b/python/migration.md @@ -1,7 +1,7 @@ -## PubNub 3.5.0 Web Data Push Cloud-hosted API - PYTHON -#### www.pubnub.com - PubNub Web Data Push Service in the Cloud. -#### http://github.com/pubnub/python +## Contact support@pubnub.com for all questions +#### [PubNub](http://www.pubnub.com) Real-time Data Network +##### Standalone Python Migration #### Init @@ -201,3 +201,5 @@ def callback(message): pubnub.history(channel, count=2, callback=callback, error=callback) ``` + +## Contact support@pubnub.com for all questions -- cgit v1.2.3 From 083127cde127dd78fc88ffe2b3b82144b2c07038 Mon Sep 17 00:00:00 2001 From: Geremy Cohen Date: Mon, 16 Jun 2014 17:11:17 -0700 Subject: Create CHANGELOG --- CHANGELOG | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 CHANGELOG diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..cf87ccd --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,4 @@ +3.5.0 - 6-16-14 +New version! Complete re-write! +. Async subscribe allows for MX, unsubscribe calls +. New method signatures -- be sure to check migration doc if upgrading -- cgit v1.2.3