aboutsummaryrefslogtreecommitdiffstats
path: root/python/examples/pubnub-console
diff options
context:
space:
mode:
Diffstat (limited to 'python/examples/pubnub-console')
-rw-r--r--python/examples/pubnub-console/pubnub-console691
-rw-r--r--python/examples/pubnub-console/setup.py27
2 files changed, 718 insertions, 0 deletions
diff --git a/python/examples/pubnub-console/pubnub-console b/python/examples/pubnub-console/pubnub-console
new file mode 100644
index 0000000..058253f
--- /dev/null
+++ b/python/examples/pubnub-console/pubnub-console
@@ -0,0 +1,691 @@
+#!/usr/bin/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 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
+
+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")
+
+
+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_normal(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_normal(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()
+
+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):
+ 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')
+ print_ok('Unsubscribed from : ' + str(channels))
+
+
+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()
+ 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 = " ["
+ 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=None, help="Publish Key"),
+ make_option('-s', '--subscribe-key', action="store",
+ default=None, help="Subscribe Key"),
+ make_option('-k', '--secret-key', action="store",
+ default=None, help="cipher Key"),
+ make_option('-c', '--cipher-key', action="store",
+ 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=None, help="Origin"),
+ make_option('-u', '--uuid', action="store",
+ 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
+ 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"""
+ 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
+
+ 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
+
+ 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
+
+ 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..a9fa506
--- /dev/null
+++ b/python/examples/pubnub-console/setup.py
@@ -0,0 +1,27 @@
+from setuptools import setup, find_packages
+
+setup(
+ name='pubnub-console',
+ version='3.5.0',
+ description='PubNub Developer Console',
+ author='Stephen Blum',
+ author_email='support@pubnub.com',
+ url='http://pubnub.com',
+ 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',
+ 'cmd2>=0.6.7',
+ 'pygments >= 1.6'
+ ],
+ zip_safe=False,
+)