6 commits - development.ini moksha/api moksha/apps moksha/hub
by Luke Macken
development.ini | 5 ++-
moksha/api/streams/datastream.py | 2 -
moksha/apps/feeds/moksha/apps/feeds/consumer.py | 4 ++
moksha/apps/feeds/moksha/apps/feeds/streams.py | 36 ++++++++++++++++++++----
moksha/apps/knowledge/pavement.py | 32 ---------------------
moksha/apps/knowledge/pavement.py.disabled | 32 +++++++++++++++++++++
moksha/hub/hub.py | 3 +-
7 files changed, 72 insertions(+), 42 deletions(-)
New commits:
commit dca67789bacbe6da03dc3191aa4d7cbdcae3f740
Author: Luke Macken <lmacken(a)redhat.com>
Date: Thu Jan 27 17:27:00 2011 -0500
When using stomp, resort to passing the default message body the consumer if we
can't decode it from JSON
diff --git a/moksha/hub/hub.py b/moksha/hub/hub.py
index 4fc155c..219abc1 100644
--- a/moksha/hub/hub.py
+++ b/moksha/hub/hub.py
@@ -146,7 +146,8 @@ class MokshaHub(StompHub, AMQPHub):
body = json.decode(message['body'])
except Exception, e:
log.warning('Cannot decode message from JSON: %s' % e)
- body = {}
+ #body = {}
+ body = message['body']
# feed all of our consumers
for callback in self.topics.get(topic, []):
commit da650ad74e649d33e9f38457a55c4e6ea8c246a6
Author: Luke Macken <lmacken(a)redhat.com>
Date: Thu Jan 27 17:25:43 2011 -0500
Allow for pluggable feed 'post-processors' in our feed app.
This allows people to plug in a custom method into the
`moksha.feeds.post_processor` entry-point, which will be called by the Feed
Streamer with each feed entry before it is sent to the message broker. This
allows people to customize the data in each feed entry.
diff --git a/moksha/apps/feeds/moksha/apps/feeds/streams.py b/moksha/apps/feeds/moksha/apps/feeds/streams.py
index 3f89f0f..f892da5 100644
--- a/moksha/apps/feeds/moksha/apps/feeds/streams.py
+++ b/moksha/apps/feeds/moksha/apps/feeds/streams.py
@@ -17,6 +17,7 @@
import logging
import feedparser
+import pkg_resources
import time
import os
@@ -130,6 +131,10 @@ class FeederProtocol(object):
def __init__(self):
self.parsed = 1
self.hub = MokshaHub()
+ self.post_processors = []
+ for entry in pkg_resources.iter_entry_points('moksha.feeds.post_processor'):
+ log.info('Registering feed post-processor: %s' % entry.name)
+ self.post_processors.append(entry.load())
def is_cached(self, site):
already_got = feed_storage.get(site)
@@ -215,8 +220,19 @@ class FeederProtocol(object):
channel_link = entry.get('channel', {'link': addr})['link']
if entry['title'] not in oldtitles:
log.info('New feed entry found: %s' % entry['title'])
- self.hub.send_message('moksha.feeds.%s' % channel_link,
- {'title': entry_title, 'link': entry.get('link')})
+ if self.post_processors:
+ for processor in self.post_processors:
+ entry = processor(entry)
+ try:
+ self.hub.send_message('moksha.feeds.%s' % channel_link, entry)
+ except Exception, e: # Usually JSON encoding issues.
+ log.error(str(e))
+ log.debug('Sending just the title and link instead')
+ self.hub.send_message('moksha.feeds.%s' % channel_link,
+ {'title': entry_title, 'link': entry.get('link')})
+ else:
+ self.hub.send_message('moksha.feeds.%s' % channel_link,
+ {'title': entry_title, 'link': entry.get('link')})
def get_page(self, data, args):
return conditional_get_page(args, timeout=self.timeout)
commit fc454a46f4e874c472a4b8cdc9d26d168aee9354
Author: Luke Macken <lmacken(a)redhat.com>
Date: Thu Jan 27 17:25:24 2011 -0500
If we can't figure out the timestamp, try stripping off the timezone
diff --git a/moksha/apps/feeds/moksha/apps/feeds/streams.py b/moksha/apps/feeds/moksha/apps/feeds/streams.py
index c78535f..3f89f0f 100644
--- a/moksha/apps/feeds/moksha/apps/feeds/streams.py
+++ b/moksha/apps/feeds/moksha/apps/feeds/streams.py
@@ -82,7 +82,13 @@ class ConditionalHTTPClientFactory(HTTPClientFactory):
self.deferred = defer.Deferred()
def lastModified(self, modtime):
- t = time.mktime(time.strptime(modtime[0], '%a, %d %b %Y %H:%M:%S %Z'))
+ try:
+ t = time.mktime(time.strptime(modtime[0], '%a, %d %b %Y %H:%M:%S %Z'))
+ except ValueError:
+ # Try stripping off the timezone?
+ t = time.mktime(time.strptime(' '.join(modtime[0].split()[:-1]),
+ '%a, %d %b %Y %H:%M:%S'))
+
parsed_feed = {}
if self.url in feed_storage:
commit bb9767e4c71549072f928d04621abd160f2b48bf
Author: Luke Macken <lmacken(a)redhat.com>
Date: Thu Jan 27 17:25:08 2011 -0500
Use the simple feed cache by default
diff --git a/development.ini b/development.ini
index 4e9ff99..d856ef0 100644
--- a/development.ini
+++ b/development.ini
@@ -61,12 +61,11 @@ moksha.socket.notify = True
# Number of seconds between polling feeds
feed.poll_frequency = 35
# Where to store the feed caches.
-feed_cache = sqlite:///%(here)s/feeds.db
+#feed_cache = sqlite:///%(here)s/feeds.db
# Max age (in seconds) of each feed in the cache
feed.max_age = 300
# Timeout in seconds for the web request
feed.timeout = 60
-
# The number of simultaneous connections
feed.deferred_groups = 3
diff --git a/moksha/apps/feeds/moksha/apps/feeds/consumer.py b/moksha/apps/feeds/moksha/apps/feeds/consumer.py
index 57a833b..6af349d 100644
--- a/moksha/apps/feeds/moksha/apps/feeds/consumer.py
+++ b/moksha/apps/feeds/moksha/apps/feeds/consumer.py
@@ -37,7 +37,9 @@ class MokshaFeedConsumer(Consumer):
def __init__(self):
super(MokshaFeedConsumer, self).__init__()
- self.feed_storage = Shove(config['feed_cache'], compress=True)
+ self.feed_storage = Shove(config.get('feed_store', 'simple://'),
+ config.get('feed_cache', 'simple://'),
+ compress=True)
def consume(self, message):
self.log.debug('MokshaFeedConsumer.consume(%s)' % message)
diff --git a/moksha/apps/feeds/moksha/apps/feeds/streams.py b/moksha/apps/feeds/moksha/apps/feeds/streams.py
index 67a85a8..c78535f 100644
--- a/moksha/apps/feeds/moksha/apps/feeds/streams.py
+++ b/moksha/apps/feeds/moksha/apps/feeds/streams.py
@@ -39,7 +39,7 @@ from moksha.api.streams import PollingDataStream
log = logging.getLogger('moksha.hub')
-feed_storage = Shove(config['feed_cache'], compress=True)
+feed_storage = Shove(config.get('feed_cache', 'simple://'), compress=True)
feed_cache = Cache(feed_storage)
class ConditionalHTTPPageGetter(HTTPPageGetter):
commit d8f01ab3e947b3c1eb28eb3c505e4a19da6d1abb
Author: Luke Macken <lmacken(a)redhat.com>
Date: Thu Jan 27 17:24:27 2011 -0500
Make our feed polling frequency configurable via the 'feeds.poll_frequency' options
diff --git a/development.ini b/development.ini
index 0ff234a..4e9ff99 100644
--- a/development.ini
+++ b/development.ini
@@ -58,6 +58,8 @@ moksha.csrf_protection = True
# jGrowl notifications for socket state changes
moksha.socket.notify = True
+# Number of seconds between polling feeds
+feed.poll_frequency = 35
# Where to store the feed caches.
feed_cache = sqlite:///%(here)s/feeds.db
# Max age (in seconds) of each feed in the cache
diff --git a/moksha/api/streams/datastream.py b/moksha/api/streams/datastream.py
index 8ee6d13..5c10e0e 100644
--- a/moksha/api/streams/datastream.py
+++ b/moksha/api/streams/datastream.py
@@ -69,7 +69,7 @@ class PollingDataStream(DataStream):
(self.frequency.microseconds / 1000000.0)
else:
seconds = self.frequency
- log.debug("Setting a %s second timers" % seconds)
+ log.debug("Setting a %s second timer" % seconds)
self.timer.start(seconds, now=self.now)
def poll(self):
diff --git a/moksha/apps/feeds/moksha/apps/feeds/streams.py b/moksha/apps/feeds/moksha/apps/feeds/streams.py
index 38f261f..67a85a8 100644
--- a/moksha/apps/feeds/moksha/apps/feeds/streams.py
+++ b/moksha/apps/feeds/moksha/apps/feeds/streams.py
@@ -271,9 +271,13 @@ class MokshaFeedStream(PollingDataStream):
then Moksha will automatically handle polling it. Upon new entries,
AMQP messages will be sent to the `feeds.$URL` queue.
"""
- frequency = timedelta(minutes=15)
+ #frequency = timedelta(minutes=1)
now = True
+ def __init__(self):
+ self.frequency = int(config.get('feed.poll_frequency', 900))
+ super(MokshaFeedStream, self).__init__()
+
def poll(self):
""" Poll all feeds in our feed cache """
log.debug('FeedStream.poll()')
commit 81db213fc2676d49ad7a7d9cb16e7fa141969170
Author: Luke Macken <lmacken(a)redhat.com>
Date: Thu Jan 27 11:32:43 2011 -0500
Disable our knowledge app from being installed automatically when people do ./start-moksha
diff --git a/moksha/apps/knowledge/pavement.py b/moksha/apps/knowledge/pavement.py
deleted file mode 100644
index 6133bcd..0000000
--- a/moksha/apps/knowledge/pavement.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# -*- coding: utf-8 -*-
-from paver.easy import *
-from paver.setuputils import (setup, find_package_data, find_packages,
- install_distutils_tasks)
-install_distutils_tasks()
-from moksha.lib.paver_tasks import *
-
-options(
- setup=Bunch(
- name="moksha.knowledge",
- version="0.1",
- release="1",
- url="http://moksha.fedorahosted.org",
- description="Describe your package here",
- license="ASL 2.0",
- long_description="",
- author="",
- author_email="",
- rpm_name='moksha-apps-knowledge',
- packages=find_packages(),
- package_data=find_package_data(),
- namespace_packages=[
- 'moksha',
- 'moksha.apps',
- ],
- install_requires=["Moksha", "tgext.crud"],
- entry_points="""
- [moksha.application]
- moksha.apps.knowledge = moksha.apps.knowledge.controllers.root:RootController
- """,
- ),
-)
diff --git a/moksha/apps/knowledge/pavement.py.disabled b/moksha/apps/knowledge/pavement.py.disabled
new file mode 100644
index 0000000..6133bcd
--- /dev/null
+++ b/moksha/apps/knowledge/pavement.py.disabled
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+from paver.easy import *
+from paver.setuputils import (setup, find_package_data, find_packages,
+ install_distutils_tasks)
+install_distutils_tasks()
+from moksha.lib.paver_tasks import *
+
+options(
+ setup=Bunch(
+ name="moksha.knowledge",
+ version="0.1",
+ release="1",
+ url="http://moksha.fedorahosted.org",
+ description="Describe your package here",
+ license="ASL 2.0",
+ long_description="",
+ author="",
+ author_email="",
+ rpm_name='moksha-apps-knowledge',
+ packages=find_packages(),
+ package_data=find_package_data(),
+ namespace_packages=[
+ 'moksha',
+ 'moksha.apps',
+ ],
+ install_requires=["Moksha", "tgext.crud"],
+ entry_points="""
+ [moksha.application]
+ moksha.apps.knowledge = moksha.apps.knowledge.controllers.root:RootController
+ """,
+ ),
+)
13 years, 3 months
website/css website/index.html
by Luke Macken
website/css/moksha-website.css | 3 ---
website/index.html | 2 +-
2 files changed, 1 insertion(+), 4 deletions(-)
New commits:
commit a94cdc86ea3cbd6d11e1d8a0a8c2a22decc89818
Author: Luke Macken <lmacken(a)redhat.com>
Date: Thu Jan 27 10:47:35 2011 -0500
Fix our logo & text to look good on webkit
diff --git a/website/css/moksha-website.css b/website/css/moksha-website.css
index bddc0b9..1a9cd17 100644
--- a/website/css/moksha-website.css
+++ b/website/css/moksha-website.css
@@ -113,9 +113,6 @@ a:link, a:visited, a:active {
#logo h1 {
height: 124px;
width: 155px;
- background: url('../img/moksha-logo.png') no-repeat top left;
- text-ident: -99999px;
- font-size: 0;
}
h2#download {
diff --git a/website/index.html b/website/index.html
index a4e6475..319a208 100644
--- a/website/index.html
+++ b/website/index.html
@@ -23,7 +23,7 @@
<div id="header">
<div class="grid_6" id="logo">
<h1>
- <a href="http://moksha-project.org/">Moksha</a>
+ <a href="http://mokshaproject.net"><img src="img/moksha-logo.png" alt="Moksha"></a>
</h1>
</div>
<div class="grid_10 nav">
13 years, 3 months
website/img
by Luke Macken
website/img/moksha-architecture.png |binary
1 file changed
New commits:
commit 4ba15aba7180193a1b01e06d4a33acde61220e23
Author: Luke Macken <lmacken(a)redhat.com>
Date: Wed Jan 26 21:55:41 2011 -0500
Update our front page architecture diagram
diff --git a/website/img/moksha-architecture.png b/website/img/moksha-architecture.png
index 6389add..aa8e558 100644
Binary files a/website/img/moksha-architecture.png and b/website/img/moksha-architecture.png differ
13 years, 3 months
docs/main
by Luke Macken
docs/main/GettingStarted.rst | 8 ++++----
docs/main/RPMInstallation.rst | 6 +++---
docs/main/VirtualenvInstallation.rst | 4 ++--
3 files changed, 9 insertions(+), 9 deletions(-)
New commits:
commit 09c681ff6b75bd5eef30359c070677e43b5d86a7
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Jan 18 14:32:18 2011 -0500
Clean up our Getting Started docs
diff --git a/docs/main/GettingStarted.rst b/docs/main/GettingStarted.rst
index 84cdf92..5790bb3 100644
--- a/docs/main/GettingStarted.rst
+++ b/docs/main/GettingStarted.rst
@@ -5,16 +5,16 @@ Getting Started with Moksha
There are currently two ways of installing and running Moksha.
.. toctree::
- :maxdepth: 0
+ :maxdepth: 1
- RPMInstallation (Fedora, RHEL, CentOS)
- VirtualenvInstallation (Other linux distros, OSX, etc.)
+ RPMInstallation
+ VirtualenvInstallation
Once you have Moksha installed, there are many ways to start using it.
.. toctree::
- :maxdepth: 2
+ :maxdepth: 1
HelloWorld
IntegratingWithTG2
diff --git a/docs/main/RPMInstallation.rst b/docs/main/RPMInstallation.rst
index 7903970..3cfa605 100644
--- a/docs/main/RPMInstallation.rst
+++ b/docs/main/RPMInstallation.rst
@@ -1,6 +1,6 @@
-==============================================
-Setting up a Moksha RPM & mod_wsgi environment
-==============================================
+=====================================================================
+Setting up a Moksha RPM & mod_wsgi environment (Fedora, RHEL, CentOS)
+=====================================================================
Installing the Moksha Apache/mod_wsgi server
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/main/VirtualenvInstallation.rst b/docs/main/VirtualenvInstallation.rst
index 23b9fdb..dfa1277 100644
--- a/docs/main/VirtualenvInstallation.rst
+++ b/docs/main/VirtualenvInstallation.rst
@@ -1,5 +1,5 @@
-Virtualenv installation
------------------------
+Virtualenv installation (Other Linux distros, OSX, Windows, etc)
+----------------------------------------------------------------
This guide will help quickly get you up and running with a local copy of
Moksha. It will run the Moksha WSGI application using the Paste threaded http
13 years, 4 months
production/livesocket-injection.html
by Luke Macken
production/livesocket-injection.html | 15 +++++++++++++++
1 file changed, 15 insertions(+)
New commits:
commit 0b1f3619cd1e275453efa4392b810330fa7b6a73
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Jan 18 14:16:04 2011 -0500
Add our livesocket-injection demo
diff --git a/production/livesocket-injection.html b/production/livesocket-injection.html
new file mode 100644
index 0000000..ad7333b
--- /dev/null
+++ b/production/livesocket-injection.html
@@ -0,0 +1,15 @@
+<html>
+ <head>
+ <script src="http://code.jquery.com/jquery-latest.min.js"></script>
+ </head>
+ <body>
+ <a href="#" onclick="moksha.send_message('helloworld', {'msg': 'Hi there!'});">Send a message</a>
+ <ul id="data"/>
+ </body>
+ <script>
+ function consume_message(json) {
+ $('<li/>').text(json.msg).appendTo('#data')
+ }
+ </script>
+ <script type="text/javascript" src="http://localhost:8080/livesocket?topic=helloworld&callback=consume_message"></script>
+</html>
13 years, 4 months
19 commits - development.ini docs/main moksha/api moksha/apps moksha/controllers moksha/hub moksha/lib moksha/streams moksha/templates website/index.html
by Luke Macken
development.ini | 1
docs/main/GettingStarted.rst | 6 ++--
docs/main/UsingLiveSocketOutsideOfMoksha.rst | 32 +++++++++++++++++++---
moksha/api/hub/consumer.py | 36 +++++++++++++++++-------
moksha/apps/helloworld/demo/consumer.py | 7 ++++
moksha/controllers/root.py | 11 ++++---
moksha/hub/amqp/__init__.py | 16 ++++++-----
moksha/hub/amqp/pyamqplib.py | 13 ++++-----
moksha/hub/amqp/qpid010.py | 2 -
moksha/hub/hub.py | 39 +++++++++++++++------------
moksha/hub/messaging.py | 2 -
moksha/lib/helpers.py | 3 ++
moksha/templates/amqp_socket.mak | 23 ++++++++++++---
moksha/templates/stomp_socket.mak | 18 +++++++-----
website/index.html | 4 +-
15 files changed, 146 insertions(+), 67 deletions(-)
New commits:
commit 3cdef7ec02045c3266ba4ae1a37af104b60aa103
Merge: a7eb71b... 23b7796...
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Jan 18 14:15:24 2011 -0500
Merge branch 'dev'
commit 23b7796d91329e33550b45f51f921a2ef8cef486
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Jan 18 14:03:06 2011 -0500
Fetch our AMQP javascript from the appropriate server/port/path
diff --git a/moksha/controllers/root.py b/moksha/controllers/root.py
index 83dd198..b847858 100644
--- a/moksha/controllers/root.py
+++ b/moksha/controllers/root.py
@@ -81,8 +81,6 @@ class RootController(BaseController):
data['amqp_broker_port'] = config.get('amqp_broker_port', 5672)
data['amqp_broker_user'] = config.get('amqp_broker_user', 'guest')
data['amqp_broker_pass'] = config.get('amqp_broker_pass', 'guest')
- # TODO: dynamic widget url
- # 'toscawidgets.prefix': '/toscawidgets',
data['orbited_host'] = config.get('orbited_host', 'localhost')
data['orbited_port'] = config.get('orbited_port', 9000)
@@ -90,6 +88,11 @@ class RootController(BaseController):
data['orbited_url'] = '%s://%s:%s' % (data['orbited_scheme'],
data['orbited_host'], data['orbited_port'])
+ environ = pylons.request.environ
+ data['server'] = '%s://%s:%s%s' % (environ.get('wsgi.url_scheme', 'http'),
+ environ['SERVER_NAME'],
+ environ['SERVER_PORT'],
+ environ['toscawidgets.prefix'])
return data
@expose('mako:moksha.templates.login')
diff --git a/moksha/templates/amqp_socket.mak b/moksha/templates/amqp_socket.mak
index f982ae3..00a73fc 100644
--- a/moksha/templates/amqp_socket.mak
+++ b/moksha/templates/amqp_socket.mak
@@ -58,9 +58,9 @@ if (typeof moksha_amqp_conn == 'undefined') {
Orbited.settings.port = ${orbited_port};
Orbited.settings.hostname = '${orbited_host}';
Orbited.settings.streaming = true;
- $.getScript('/toscawidgets/resources/moksha.api.widgets.amqp.widgets/static/amqp.protocol.js', function() {
- $.getScript('/toscawidgets/resources/moksha.api.widgets.amqp.widgets/static/amqp.protocol_0_10.js', function() {
- $.getScript('/toscawidgets/resources/moksha.api.widgets.amqp.widgets/static/qpid_amqp.js', function() {
+ $.getScript('${server}/resources/moksha.api.widgets.amqp.widgets/static/amqp.protocol.js', function() {
+ $.getScript('${server}/resources/moksha.api.widgets.amqp.widgets/static/amqp.protocol_0_10.js', function() {
+ $.getScript('${server}/resources/moksha.api.widgets.amqp.widgets/static/qpid_amqp.js', function() {
moksha_amqp_conn = new amqp.Connection({
host: '${amqp_broker_host}',
port: ${amqp_broker_port},
commit fad10c338537385946e4cf0294b3b98280987042
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Jan 18 14:02:35 2011 -0500
Update our "Using the live socket outside of moksha" documentation
diff --git a/docs/main/UsingLiveSocketOutsideOfMoksha.rst b/docs/main/UsingLiveSocketOutsideOfMoksha.rst
index daa193c..f42b7f7 100644
--- a/docs/main/UsingLiveSocketOutsideOfMoksha.rst
+++ b/docs/main/UsingLiveSocketOutsideOfMoksha.rst
@@ -10,10 +10,16 @@ web page without having to write a line of Python code.
This means that you can have your web site listen to topics from your message
broker, and run javascript when new messages arrive.
+Subscribing to real-time message streams
+----------------------------------------
+
All you need to do is add a single ``<script>`` tag to your web site that
specifies the topic that you wish to listen to, and the javascript function
that should be called with each new message as they arrive.
+The Moksha live socket will automatically handle decoding the message body to
+JSON before passing it to your callback.
+
.. code-block:: html
<html>
@@ -24,14 +30,32 @@ that should be called with each new message as they arrive.
<ul id="data"/>
</body>
<script>
- function consume_message(msg) {
- $('<li/>').text(msg).appendTo('#data')
+ function consume_message(json) {
+ $('<li/>').text(json.msg).appendTo('#data')
}
</script>
<script type="text/javascript" src="http://localhost:8080/livesocket?topic=helloworld&callback=consume_message"></script>
</html>
+
+Sending messages to the broker
+------------------------------
+
+You can easily send messages to a given topic using the ``moksha.send_message``
+function. This function will automatically handle converting your javascript
+objects to JSON for you.
+
+.. code-block:: html
+
+ <a href="#" onclick="moksha.send_message('helloworld', {'msg': 'Hi there!'});">Send message</a>
+
+
+.. note::
+
+ In order for the live sockets to work properly, Moksha (specifically
+ Orbited) must be running under the same domain as your web site.
+
.. note::
- In order for the live sockets to work properly, Moksha (specifically Orbited) must be running
- under the same domain as your web site.
+ You can disable the automatic JSON encoding/decoding by passing
+ ``json=False`` to the livesocket URL.
commit 208ee045e0ede9bc7b322bc89d910cc282175316
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Jan 18 14:02:14 2011 -0500
Make the auto JSON decoding/encoding of our live socket configurable
diff --git a/moksha/controllers/root.py b/moksha/controllers/root.py
index 79eaf18..83dd198 100644
--- a/moksha/controllers/root.py
+++ b/moksha/controllers/root.py
@@ -58,7 +58,7 @@ class RootController(BaseController):
return DefaultRootController(), remainder
@expose()
- def livesocket(self, topic=None, callback=None):
+ def livesocket(self, topic=None, callback=None, json=True):
"""Returns a raw Moksha live socket, for use in non-Moksha apps.
<script> function bar(msg) { alert('bar(' + msg + ')'); } </script>
@@ -67,7 +67,7 @@ class RootController(BaseController):
</script>
"""
- data = {'topic': topic, 'callback': callback}
+ data = {'topic': topic, 'callback': callback, 'json': json}
backend = config.get('moksha.livesocket.backend', 'stomp').lower()
if backend == 'stomp':
override_template(self.livesocket, 'mako:moksha.templates.stomp_socket')
diff --git a/moksha/templates/amqp_socket.mak b/moksha/templates/amqp_socket.mak
index 667119f..f982ae3 100644
--- a/moksha/templates/amqp_socket.mak
+++ b/moksha/templates/amqp_socket.mak
@@ -5,7 +5,11 @@ moksha = {
accept_mode: 1,
acquire_mode: 1,
destination: 'amq.topic',
- _body: $.toJSON(body),
+% if json:
+ _body: JSON.stringify(body),
+% else:
+ _body: body,
+% endif
_header: {
delivery_properties: {
routing_key: topic
@@ -21,9 +25,18 @@ if (typeof moksha_amqp_conn == 'undefined') {
moksha_amqp_queue = null;
moksha_amqp_on_message = function(msg) {
var dest = msg.header.delivery_properties.routing_key;
+ var json = msg.body;
+% if json:
+ try {
+ var json = JSON.parse(msg.body);
+ } catch(err) {
+ console.log("Unable to decode JSON message body:");
+ console.log(f.body);
+ }
+% endif
if (moksha_callbacks[dest]) {
for (var i=0; i < moksha_callbacks[dest].length; i++) {
- moksha_callbacks[dest][i](msg.body);
+ moksha_callbacks[dest][i](json);
}
}
}
diff --git a/moksha/templates/stomp_socket.mak b/moksha/templates/stomp_socket.mak
index bcf252a..cbe1383 100644
--- a/moksha/templates/stomp_socket.mak
+++ b/moksha/templates/stomp_socket.mak
@@ -1,7 +1,11 @@
moksha = {
/* Send a STOMP message to a given topic */
send_message: function(topic, body) {
- stomp.send($.toJSON(body), topic)
+% if json:
+ stomp.send(JSON.stringify(body), topic)
+% else:
+ stomp.send(body, topic)
+% endif
},
}
@@ -41,18 +45,18 @@ if (typeof TCPSocket == 'undefined') {
};
stomp.onmessageframe = function(f){
var dest = f.headers.destination;
-/*
- var json = null;
+ var json = f.body;
+% if json:
try {
- var json = $.parseJSON(f.body);
+ var json = JSON.parse(f.body);
} catch(err) {
console.log("Unable to decode JSON message body:");
- console.log(f.body);
+ console.log(f);
}
-*/
+% endif
if (moksha_callbacks[dest]) {
for (var i=0; i < moksha_callbacks[dest].length; i++) {
- moksha_callbacks[dest][i](f.body);
+ moksha_callbacks[dest][i](json);
}
}
};
commit 585e7e9885630474824bd774781694aa5bf1af5c
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Jan 18 11:30:06 2011 -0500
Deprecate to_unicode
diff --git a/moksha/lib/helpers.py b/moksha/lib/helpers.py
index be3bd77..365dd7d 100644
--- a/moksha/lib/helpers.py
+++ b/moksha/lib/helpers.py
@@ -812,6 +812,9 @@ def create_app_engine(app):
def to_unicode(obj, encoding='utf-8', errors='replace'):
+ """
+ :deprecated: by to_unicode in http://python-kitchen.fedorahosted.org
+ """
if isinstance(obj, basestring):
if not isinstance(obj, unicode):
obj = unicode(obj, encoding, errors)
commit 77bce25a53d5b15b19370f18bd79eca024311739
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Jan 18 11:29:42 2011 -0500
Make sure we can run w/o amqplib
diff --git a/moksha/hub/amqp/pyamqplib.py b/moksha/hub/amqp/pyamqplib.py
index 32c1f31..faf306f 100644
--- a/moksha/hub/amqp/pyamqplib.py
+++ b/moksha/hub/amqp/pyamqplib.py
@@ -17,7 +17,10 @@
import logging
-import amqplib.client_0_8 as amqp
+try:
+ import amqplib.client_0_8 as amqp
+except ImportError:
+ pass
from moksha.lib.helpers import trace
from moksha.hub.amqp.base import BaseAMQPHub
commit 93bac52ec4c4fc551135b39599b6a3496bede1db
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Jan 18 11:29:22 2011 -0500
doc title changes
diff --git a/docs/main/GettingStarted.rst b/docs/main/GettingStarted.rst
index 6c08639..84cdf92 100644
--- a/docs/main/GettingStarted.rst
+++ b/docs/main/GettingStarted.rst
@@ -5,10 +5,10 @@ Getting Started with Moksha
There are currently two ways of installing and running Moksha.
.. toctree::
- :maxdepth: 1
+ :maxdepth: 0
- RPMInstallation
- VirtualenvInstallation
+ RPMInstallation (Fedora, RHEL, CentOS)
+ VirtualenvInstallation (Other linux distros, OSX, etc.)
Once you have Moksha installed, there are many ways to start using it.
commit a7eb71bcd64964f78d17cbd006b60fdae5bfe867
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Jan 18 11:28:53 2011 -0500
More rhetoric tweaks
diff --git a/website/index.html b/website/index.html
index 1c2e6b0..a4e6475 100644
--- a/website/index.html
+++ b/website/index.html
@@ -49,7 +49,7 @@
<!-- add 2x2 grid here -->
<div class="alpha grid_5">
<h3>A Platform</h3>
- <p>Moksha is a highly-scalable platform for creating dashboards of live widgets. Moksha makes it simple for these widgets to extract and extend data from arbitrary resources in an intuitive and efficient manner.</p>
+ <p>Moksha is a highly-scalable platform for creating dashboards of live widgets. Moksha makes it simple for these widgets to extract and extend data from arbitrary resources.</p>
</div>
<div class="omega grid_5">
<h3>An Architecture</h3>
@@ -60,7 +60,7 @@
<p>Built using best-of-breed components, Moksha applications are written using stable pre-existing modules that allow for the rapid creation of powerful applications.</p>
</div>
<div class="omega grid_5">
- <h3>A Hub</h3>
+ <h3>A Messaging Hub</h3>
<p>Moksha acts as real-time messaging middleware for your web application, allowing you to publish and subscribe to message queues both on server and from the clients web browser.</p>
</div>
commit 1aa7c69fb76d66e4be2db8b0c8218972ecff1548
Author: Luke Macken <lmacken(a)redhat.com>
Date: Sun Jan 16 22:07:29 2011 -0500
log.info when the hub starts
diff --git a/moksha/hub/hub.py b/moksha/hub/hub.py
index a0c6987..4fc155c 100644
--- a/moksha/hub/hub.py
+++ b/moksha/hub/hub.py
@@ -161,6 +161,7 @@ class CentralMokshaHub(MokshaHub):
producers = None # [<Producer>,]
def __init__(self):
+ log.info('Loading the Moksha Hub')
self.topics = defaultdict(list)
self.__init_consumers()
commit de6efd68aea3f98e0cb53fe382465636d49ae418
Author: Luke Macken <lmacken(a)redhat.com>
Date: Sun Jan 16 22:04:49 2011 -0500
Update our hub to use more up to date terminology with variable/method names
diff --git a/moksha/hub/hub.py b/moksha/hub/hub.py
index 5371474..a0c6987 100644
--- a/moksha/hub/hub.py
+++ b/moksha/hub/hub.py
@@ -158,7 +158,7 @@ class CentralMokshaHub(MokshaHub):
The Moksha Hub is responsible for initializing all of the Hooks,
AMQP queues, exchanges, etc.
"""
- data_streams = None # [<DataStream>,]
+ producers = None # [<Producer>,]
def __init__(self):
self.topics = defaultdict(list)
@@ -170,9 +170,11 @@ class CentralMokshaHub(MokshaHub):
self.__init_amqp()
self.__run_consumers()
- self.__init_data_streams()
+ self.__init_producers()
def __init_amqp(self):
+ # Ok this looks odd at first. I think this is only used when we are briding stomp/amqp,
+ # Since each producer and consumer opens up their own AMQP connections anyway
if self.stomp_broker:
log.debug("Initializing local AMQP queue...")
self.server_queue_name = 'moksha_hub_' + self.session.name
@@ -187,7 +189,7 @@ class CentralMokshaHub(MokshaHub):
def __init_consumers(self):
""" Initialize all Moksha Consumer objects """
- log.info('Loading Moksha Consumers')
+ log.info('Loading Consumers')
for consumer in pkg_resources.iter_entry_points('moksha.consumer'):
c_class = consumer.load()
log.info("%s consumer is watching the %r topic" % (
@@ -203,15 +205,16 @@ class CentralMokshaHub(MokshaHub):
self.consumers.append(c)
self.topics[topic][i] = c.consume
- def __init_data_streams(self):
- """ Initialize all data streams """
- self.data_streams = []
+ def __init_producers(self):
+ """ Initialize all producers (aka data streams) """
+ log.info('Loading Producers')
+ self.producers = []
for entry in ('moksha.producer', 'moksha.stream'):
- for stream in pkg_resources.iter_entry_points(entry):
- stream_class = stream.load()
- log.info('Loading %s producer' % stream_class.__name__)
- stream_obj = stream_class()
- self.data_streams.append(stream_obj)
+ for producer in pkg_resources.iter_entry_points(entry):
+ producer_class = producer.load()
+ log.info('Loading %s producer' % producer_class.__name__)
+ producer_obj = producer_class()
+ self.producers.append(producer_obj)
@trace
def create_topic(self, topic):
@@ -225,10 +228,10 @@ class CentralMokshaHub(MokshaHub):
def stop(self):
log.debug("Stopping the CentralMokshaHub")
MokshaHub.close(self)
- if self.data_streams:
- for stream in self.data_streams:
- log.debug("Stopping data stream %s" % stream)
- stream.stop()
+ if self.producers:
+ for producer in self.producers:
+ log.debug("Stopping producer %s" % producer)
+ producer.stop()
if self.consumers:
for consumer in self.consumers:
log.debug("Stopping consumer %s" % consumer)
commit d842655d335dd690e6ba954a8e17e65a9824ce99
Author: Luke Macken <lmacken(a)redhat.com>
Date: Sun Jan 16 21:56:06 2011 -0500
Get rid of moksha.streams
diff --git a/moksha/streams/__init__.py b/moksha/streams/__init__.py
deleted file mode 100644
index e69de29..0000000
commit 0ea2e2c3d207837cc894996fefdc7ba9cf6cdb2e
Author: Luke Macken <lmacken(a)redhat.com>
Date: Sat Jan 15 15:12:25 2011 -0500
Commit our db changes in our HelloWorld Consumer every 100 entries.
diff --git a/moksha/apps/helloworld/demo/consumer.py b/moksha/apps/helloworld/demo/consumer.py
index 10f4e3b..dec4cfd 100644
--- a/moksha/apps/helloworld/demo/consumer.py
+++ b/moksha/apps/helloworld/demo/consumer.py
@@ -4,6 +4,7 @@ from demo.model import HelloWorldModel
class HelloWorldConsumer(Consumer):
topic = 'helloworld'
app = 'helloworld'
+ i = 0
def consume(self, message):
self.log.info('Received message: ' + message['body']['msg'])
@@ -11,4 +12,8 @@ class HelloWorldConsumer(Consumer):
entry = HelloWorldModel()
entry.message = message['body']['msg']
self.DBSession.add(entry)
- self.DBSession.commit()
+
+ self.i += 1
+ if self.i % 100 == 0:
+ self.DBSession.commit()
+
commit 92145193e14be58e8d36b19a4cbacc065d0cd8c9
Author: Luke Macken <lmacken(a)redhat.com>
Date: Wed Jan 12 17:39:35 2011 -0500
Some method renaming in our AMQP stack to prevent conflicts with STOMP
diff --git a/moksha/api/hub/consumer.py b/moksha/api/hub/consumer.py
index 1c5712c..0d24094 100644
--- a/moksha/api/hub/consumer.py
+++ b/moksha/api/hub/consumer.py
@@ -54,9 +54,9 @@ class Consumer(object):
self.hub.queue_declare(queue=queue_name, exclusive=True)
self.hub.exchange_bind(queue_name, binding_key=topic)
if self.jsonify:
- self.hub.subscribe(queue_name, self._consume_json)
+ self.hub.queue_subscribe(queue_name, self._consume_json)
else:
- self.hub.subscribe(queue_name, self._consume)
+ self.hub.queue_subscribe(queue_name, self._consume)
else:
# Assume we're using Qpid then.
server_queue_name = 'moksha_consumer_' + self.hub.session.name
diff --git a/moksha/hub/amqp/pyamqplib.py b/moksha/hub/amqp/pyamqplib.py
index e6a031f..32c1f31 100644
--- a/moksha/hub/amqp/pyamqplib.py
+++ b/moksha/hub/amqp/pyamqplib.py
@@ -77,13 +77,12 @@ class AMQPLibHub(BaseAMQPHub):
msg = self.channel.basic_get(queue, no_ack=True)
return msg
- def subscribe(self, queue, callback, no_ack=True):
+ def queue_subscribe(self, queue, callback, no_ack=True):
"""
Consume messages from a given `queue`, passing each to `callback`
"""
self.channel.basic_consume(queue, callback=callback, no_ack=no_ack)
-
def wait(self):
self.channel.wait()
commit e89f2a4aa5a70402e1887fcb3bf4fe6883434a47
Author: Luke Macken <lmacken(a)redhat.com>
Date: Wed Jan 12 17:06:09 2011 -0500
Remove a tracing decorator, which may be causing problems
diff --git a/moksha/hub/amqp/pyamqplib.py b/moksha/hub/amqp/pyamqplib.py
index b9ab46c..e6a031f 100644
--- a/moksha/hub/amqp/pyamqplib.py
+++ b/moksha/hub/amqp/pyamqplib.py
@@ -77,7 +77,6 @@ class AMQPLibHub(BaseAMQPHub):
msg = self.channel.basic_get(queue, no_ack=True)
return msg
- @trace
def subscribe(self, queue, callback, no_ack=True):
"""
Consume messages from a given `queue`, passing each to `callback`
commit fc36b9bc2970c611a4fb5063463f27cfd96df21d
Author: Luke Macken <lmacken(a)redhat.com>
Date: Wed Jan 12 17:00:40 2011 -0500
Update our MessagingHub.subscribe method arguments
diff --git a/moksha/hub/messaging.py b/moksha/hub/messaging.py
index dc6fc08..56eb782 100644
--- a/moksha/hub/messaging.py
+++ b/moksha/hub/messaging.py
@@ -25,5 +25,5 @@ class MessagingHub(object):
def send_message(self, topic, message):
raise NotImplementedError
- def subscribe(self, topic):
+ def subscribe(self, topic, callback):
raise NotImplementedError
commit 349423f0cb112ae2ba663ad3c217897d462ef503
Author: Luke Macken <lmacken(a)redhat.com>
Date: Fri Jan 7 20:14:15 2011 -0500
Typo
diff --git a/moksha/api/hub/consumer.py b/moksha/api/hub/consumer.py
index 5ce870f..1c5712c 100644
--- a/moksha/api/hub/consumer.py
+++ b/moksha/api/hub/consumer.py
@@ -25,6 +25,7 @@ loaded, and receives each message for the specified topic through the
.. moduleauthor:: Luke Macken <lmacken(a)redhat.com>
"""
+import uuid
import logging
log = logging.getLogger('moksha.hub')
@@ -49,8 +50,7 @@ class Consumer(object):
if isinstance(self.hub, AMQPLibHub):
# AMQPLibHub specific
- import uuid
- queue_name = str(uuid.uiud4())
+ queue_name = str(uuid.uuid4())
self.hub.queue_declare(queue=queue_name, exclusive=True)
self.hub.exchange_bind(queue_name, binding_key=topic)
if self.jsonify:
commit 057ea1b0ef3457f3af04ce1a3b9ff6df86b6a4e6
Author: Luke Macken <lmacken(a)redhat.com>
Date: Fri Jan 7 20:12:48 2011 -0500
Temporary hack around our leaking amqphub abstraction
diff --git a/moksha/api/hub/consumer.py b/moksha/api/hub/consumer.py
index 83b528f..5ce870f 100644
--- a/moksha/api/hub/consumer.py
+++ b/moksha/api/hub/consumer.py
@@ -29,6 +29,7 @@ import logging
log = logging.getLogger('moksha.hub')
from moksha.hub.hub import MokshaHub
+from moksha.hub.amqp.pyamqplib import AMQPLibHub
from moksha.lib.helpers import listify, create_app_engine, json
from sqlalchemy.orm import sessionmaker
@@ -45,18 +46,31 @@ class Consumer(object):
if self.hub.amqp_broker and not self.hub.stomp_broker:
for topic in listify(self.topic):
log.debug('Subscribing to consumer topic %s' % topic)
- server_queue_name = 'moksha_consumer_' + self.hub.session.name
- self.hub.queue_declare(queue=server_queue_name, exclusive=True)
- self.hub.exchange_bind(server_queue_name, binding_key=topic)
- local_queue_name = 'moksha_consumer_' + self.hub.session.name
- self.hub.local_queue = self.hub.session.incoming(local_queue_name)
- self.hub.message_subscribe(queue=server_queue_name,
- destination=local_queue_name)
- self.hub.local_queue.start()
- if self.jsonify:
- self.hub.local_queue.listen(self._consume_json)
+
+ if isinstance(self.hub, AMQPLibHub):
+ # AMQPLibHub specific
+ import uuid
+ queue_name = str(uuid.uiud4())
+ self.hub.queue_declare(queue=queue_name, exclusive=True)
+ self.hub.exchange_bind(queue_name, binding_key=topic)
+ if self.jsonify:
+ self.hub.subscribe(queue_name, self._consume_json)
+ else:
+ self.hub.subscribe(queue_name, self._consume)
else:
- self.hub.local_queue.listen(self._consume)
+ # Assume we're using Qpid then.
+ server_queue_name = 'moksha_consumer_' + self.hub.session.name
+ self.hub.queue_declare(queue=server_queue_name, exclusive=True)
+ self.hub.exchange_bind(server_queue_name, binding_key=topic)
+ local_queue_name = 'moksha_consumer_' + self.hub.session.name
+ self.hub.local_queue = self.hub.session.incoming(local_queue_name)
+ self.hub.message_subscribe(queue=server_queue_name,
+ destination=local_queue_name)
+ self.hub.local_queue.start()
+ if self.jsonify:
+ self.hub.local_queue.listen(self._consume_json)
+ else:
+ self.hub.local_queue.listen(self._consume)
# If the consumer specifies an 'app', then setup `self.engine` to
# be a SQLAlchemy engine, along with a configured DBSession
commit 66056971ccd26c619630f33030706befd62b60e2
Author: Luke Macken <lmacken(a)redhat.com>
Date: Fri Jan 7 17:03:41 2011 -0500
Pass some more AMQP broker configuration through to the pyamqplib layer
diff --git a/development.ini b/development.ini
index 7b938e8..0ff234a 100644
--- a/development.ini
+++ b/development.ini
@@ -105,6 +105,7 @@ stomp_pass = guest
#amqp_broker_port = 5672
#amqp_broker_user = guest
#amqp_broker_pass = guest
+#amqp_broker_ssl = False
# Documentation directory
docs_dir = docs
diff --git a/moksha/hub/amqp/pyamqplib.py b/moksha/hub/amqp/pyamqplib.py
index fc0f5e4..b9ab46c 100644
--- a/moksha/hub/amqp/pyamqplib.py
+++ b/moksha/hub/amqp/pyamqplib.py
@@ -29,8 +29,8 @@ NONPERSISTENT_DELIVERY = PERSISTENT_DELIVERY = range(1, 3)
class AMQPLibHub(BaseAMQPHub):
""" An AMQPHub implemention using the amqplib module """
- def __init__(self, broker, username=None, password=None, ssl=False):
- self.conn = amqp.Connection(host=broker, ssl=ssl,
+ def __init__(self, broker, username=None, password=None, ssl=False, threaded=False):
+ self.conn = amqp.Connection(host=broker, ssl=ssl, use_threading=threaded,
userid=username, password=password)
self.channel = self.conn.channel()
self.channel.access_request('/data', active=True, write=True, read=True)
diff --git a/moksha/hub/amqp/qpid010.py b/moksha/hub/amqp/qpid010.py
index 980c67e..0460420 100644
--- a/moksha/hub/amqp/qpid010.py
+++ b/moksha/hub/amqp/qpid010.py
@@ -35,7 +35,7 @@ class QpidAMQPHub(BaseAMQPHub):
"""
- def __init__(self, broker):
+ def __init__(self, broker, **kw):
self.set_broker(broker)
self.socket = connect(self.host, self.port)
if self.url.scheme == URL.AMQPS:
diff --git a/moksha/hub/hub.py b/moksha/hub/hub.py
index 819f098..5371474 100644
--- a/moksha/hub/hub.py
+++ b/moksha/hub/hub.py
@@ -72,7 +72,10 @@ class MokshaHub(StompHub, AMQPHub):
self.topics[topic].append(callback)
if self.amqp_broker:
- AMQPHub.__init__(self, self.amqp_broker)
+ AMQPHub.__init__(self, self.amqp_broker,
+ username=config.get('amqp_broker_user', 'guest'),
+ password=config.get('amqp_broker_pass', 'guest'),
+ ssl=config.get('amqp_broker_ssl', False))
if self.stomp_broker:
log.info('Initializing STOMP support')
commit a23bea017d53dc56adad9edcaacee97236667237
Author: Luke Macken <lmacken(a)redhat.com>
Date: Fri Jan 7 16:19:25 2011 -0500
Try to fall back to pyamqplib if qpid doesn't exist
diff --git a/moksha/hub/amqp/__init__.py b/moksha/hub/amqp/__init__.py
index 7ab1ec9..98ada27 100644
--- a/moksha/hub/amqp/__init__.py
+++ b/moksha/hub/amqp/__init__.py
@@ -23,10 +23,14 @@ try:
from qpid010 import QpidAMQPHub
AMQPHub = QpidAMQPHub
except ImportError:
- log.debug("Unable to import qpid module")
- class FakeHub(object):
- pass
- AMQPHub = FakeHub
+ log.debug("Cannot find qpid python module")
+ try:
+ from pyamqplib import AMQPLibHub
+ AMQPHub = AMQPLibHub
+ except ImportError:
+ log.debug("Cannot find pyamqplib")
+ log.debug("Using FakeHub AMQP broker. Don't expect AMQP to work")
+ class FakeHub(object):
+ pass
+ AMQPHub = FakeHub
-#from pyamqplib import AMQPLibHub
-#AMQPHub = AMQPLibHub
13 years, 4 months
Branch 'dev' - 3 commits - docs/main moksha/controllers moksha/templates
by Luke Macken
docs/main/UsingLiveSocketOutsideOfMoksha.rst | 32 +++++++++++++++++++++++----
moksha/controllers/root.py | 9 +++++--
moksha/templates/amqp_socket.mak | 23 +++++++++++++++----
moksha/templates/stomp_socket.mak | 18 +++++++++------
4 files changed, 64 insertions(+), 18 deletions(-)
New commits:
commit 8facec0398ec0d215a19d57f99965e52bb743a52
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Jan 18 14:03:06 2011 -0500
Fetch our AMQP javascript from the appropriate server/port/path
diff --git a/moksha/controllers/root.py b/moksha/controllers/root.py
index 83dd198..ac51c1d 100644
--- a/moksha/controllers/root.py
+++ b/moksha/controllers/root.py
@@ -90,6 +90,11 @@ class RootController(BaseController):
data['orbited_url'] = '%s://%s:%s' % (data['orbited_scheme'],
data['orbited_host'], data['orbited_port'])
+ environ = pylons.request.environ
+ data['server'] = '%s://%s:%s/%s' % (environ.get('wsgi.url_scheme', 'http'),
+ environ['SERVER_NAME'],
+ environ['SERVER_PORT'],
+ environ['toscawidgets.prefix'])
return data
@expose('mako:moksha.templates.login')
diff --git a/moksha/templates/amqp_socket.mak b/moksha/templates/amqp_socket.mak
index f982ae3..432c68d 100644
--- a/moksha/templates/amqp_socket.mak
+++ b/moksha/templates/amqp_socket.mak
@@ -58,9 +58,9 @@ if (typeof moksha_amqp_conn == 'undefined') {
Orbited.settings.port = ${orbited_port};
Orbited.settings.hostname = '${orbited_host}';
Orbited.settings.streaming = true;
- $.getScript('/toscawidgets/resources/moksha.api.widgets.amqp.widgets/static/amqp.protocol.js', function() {
- $.getScript('/toscawidgets/resources/moksha.api.widgets.amqp.widgets/static/amqp.protocol_0_10.js', function() {
- $.getScript('/toscawidgets/resources/moksha.api.widgets.amqp.widgets/static/qpid_amqp.js', function() {
+ $.getScript('${server}/toscawidgets/resources/moksha.api.widgets.amqp.widgets/static/amqp.protocol.js', function() {
+ $.getScript('${server}/toscawidgets/resources/moksha.api.widgets.amqp.widgets/static/amqp.protocol_0_10.js', function() {
+ $.getScript('${server}/toscawidgets/resources/moksha.api.widgets.amqp.widgets/static/qpid_amqp.js', function() {
moksha_amqp_conn = new amqp.Connection({
host: '${amqp_broker_host}',
port: ${amqp_broker_port},
commit fad10c338537385946e4cf0294b3b98280987042
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Jan 18 14:02:35 2011 -0500
Update our "Using the live socket outside of moksha" documentation
diff --git a/docs/main/UsingLiveSocketOutsideOfMoksha.rst b/docs/main/UsingLiveSocketOutsideOfMoksha.rst
index daa193c..f42b7f7 100644
--- a/docs/main/UsingLiveSocketOutsideOfMoksha.rst
+++ b/docs/main/UsingLiveSocketOutsideOfMoksha.rst
@@ -10,10 +10,16 @@ web page without having to write a line of Python code.
This means that you can have your web site listen to topics from your message
broker, and run javascript when new messages arrive.
+Subscribing to real-time message streams
+----------------------------------------
+
All you need to do is add a single ``<script>`` tag to your web site that
specifies the topic that you wish to listen to, and the javascript function
that should be called with each new message as they arrive.
+The Moksha live socket will automatically handle decoding the message body to
+JSON before passing it to your callback.
+
.. code-block:: html
<html>
@@ -24,14 +30,32 @@ that should be called with each new message as they arrive.
<ul id="data"/>
</body>
<script>
- function consume_message(msg) {
- $('<li/>').text(msg).appendTo('#data')
+ function consume_message(json) {
+ $('<li/>').text(json.msg).appendTo('#data')
}
</script>
<script type="text/javascript" src="http://localhost:8080/livesocket?topic=helloworld&callback=consume_message"></script>
</html>
+
+Sending messages to the broker
+------------------------------
+
+You can easily send messages to a given topic using the ``moksha.send_message``
+function. This function will automatically handle converting your javascript
+objects to JSON for you.
+
+.. code-block:: html
+
+ <a href="#" onclick="moksha.send_message('helloworld', {'msg': 'Hi there!'});">Send message</a>
+
+
+.. note::
+
+ In order for the live sockets to work properly, Moksha (specifically
+ Orbited) must be running under the same domain as your web site.
+
.. note::
- In order for the live sockets to work properly, Moksha (specifically Orbited) must be running
- under the same domain as your web site.
+ You can disable the automatic JSON encoding/decoding by passing
+ ``json=False`` to the livesocket URL.
commit 208ee045e0ede9bc7b322bc89d910cc282175316
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Jan 18 14:02:14 2011 -0500
Make the auto JSON decoding/encoding of our live socket configurable
diff --git a/moksha/controllers/root.py b/moksha/controllers/root.py
index 79eaf18..83dd198 100644
--- a/moksha/controllers/root.py
+++ b/moksha/controllers/root.py
@@ -58,7 +58,7 @@ class RootController(BaseController):
return DefaultRootController(), remainder
@expose()
- def livesocket(self, topic=None, callback=None):
+ def livesocket(self, topic=None, callback=None, json=True):
"""Returns a raw Moksha live socket, for use in non-Moksha apps.
<script> function bar(msg) { alert('bar(' + msg + ')'); } </script>
@@ -67,7 +67,7 @@ class RootController(BaseController):
</script>
"""
- data = {'topic': topic, 'callback': callback}
+ data = {'topic': topic, 'callback': callback, 'json': json}
backend = config.get('moksha.livesocket.backend', 'stomp').lower()
if backend == 'stomp':
override_template(self.livesocket, 'mako:moksha.templates.stomp_socket')
diff --git a/moksha/templates/amqp_socket.mak b/moksha/templates/amqp_socket.mak
index 667119f..f982ae3 100644
--- a/moksha/templates/amqp_socket.mak
+++ b/moksha/templates/amqp_socket.mak
@@ -5,7 +5,11 @@ moksha = {
accept_mode: 1,
acquire_mode: 1,
destination: 'amq.topic',
- _body: $.toJSON(body),
+% if json:
+ _body: JSON.stringify(body),
+% else:
+ _body: body,
+% endif
_header: {
delivery_properties: {
routing_key: topic
@@ -21,9 +25,18 @@ if (typeof moksha_amqp_conn == 'undefined') {
moksha_amqp_queue = null;
moksha_amqp_on_message = function(msg) {
var dest = msg.header.delivery_properties.routing_key;
+ var json = msg.body;
+% if json:
+ try {
+ var json = JSON.parse(msg.body);
+ } catch(err) {
+ console.log("Unable to decode JSON message body:");
+ console.log(f.body);
+ }
+% endif
if (moksha_callbacks[dest]) {
for (var i=0; i < moksha_callbacks[dest].length; i++) {
- moksha_callbacks[dest][i](msg.body);
+ moksha_callbacks[dest][i](json);
}
}
}
diff --git a/moksha/templates/stomp_socket.mak b/moksha/templates/stomp_socket.mak
index bcf252a..cbe1383 100644
--- a/moksha/templates/stomp_socket.mak
+++ b/moksha/templates/stomp_socket.mak
@@ -1,7 +1,11 @@
moksha = {
/* Send a STOMP message to a given topic */
send_message: function(topic, body) {
- stomp.send($.toJSON(body), topic)
+% if json:
+ stomp.send(JSON.stringify(body), topic)
+% else:
+ stomp.send(body, topic)
+% endif
},
}
@@ -41,18 +45,18 @@ if (typeof TCPSocket == 'undefined') {
};
stomp.onmessageframe = function(f){
var dest = f.headers.destination;
-/*
- var json = null;
+ var json = f.body;
+% if json:
try {
- var json = $.parseJSON(f.body);
+ var json = JSON.parse(f.body);
} catch(err) {
console.log("Unable to decode JSON message body:");
- console.log(f.body);
+ console.log(f);
}
-*/
+% endif
if (moksha_callbacks[dest]) {
for (var i=0; i < moksha_callbacks[dest].length; i++) {
- moksha_callbacks[dest][i](f.body);
+ moksha_callbacks[dest][i](json);
}
}
};
13 years, 4 months
Branch 'dev' - 7 commits - docs/main moksha/apps moksha/hub moksha/lib moksha/streams
by Luke Macken
docs/main/GettingStarted.rst | 6 ++---
moksha/apps/helloworld/demo/consumer.py | 7 +++++-
moksha/hub/amqp/pyamqplib.py | 5 +++-
moksha/hub/hub.py | 34 +++++++++++++++++---------------
moksha/lib/helpers.py | 3 ++
5 files changed, 35 insertions(+), 20 deletions(-)
New commits:
commit 585e7e9885630474824bd774781694aa5bf1af5c
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Jan 18 11:30:06 2011 -0500
Deprecate to_unicode
diff --git a/moksha/lib/helpers.py b/moksha/lib/helpers.py
index be3bd77..365dd7d 100644
--- a/moksha/lib/helpers.py
+++ b/moksha/lib/helpers.py
@@ -812,6 +812,9 @@ def create_app_engine(app):
def to_unicode(obj, encoding='utf-8', errors='replace'):
+ """
+ :deprecated: by to_unicode in http://python-kitchen.fedorahosted.org
+ """
if isinstance(obj, basestring):
if not isinstance(obj, unicode):
obj = unicode(obj, encoding, errors)
commit 77bce25a53d5b15b19370f18bd79eca024311739
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Jan 18 11:29:42 2011 -0500
Make sure we can run w/o amqplib
diff --git a/moksha/hub/amqp/pyamqplib.py b/moksha/hub/amqp/pyamqplib.py
index 32c1f31..faf306f 100644
--- a/moksha/hub/amqp/pyamqplib.py
+++ b/moksha/hub/amqp/pyamqplib.py
@@ -17,7 +17,10 @@
import logging
-import amqplib.client_0_8 as amqp
+try:
+ import amqplib.client_0_8 as amqp
+except ImportError:
+ pass
from moksha.lib.helpers import trace
from moksha.hub.amqp.base import BaseAMQPHub
commit 93bac52ec4c4fc551135b39599b6a3496bede1db
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Jan 18 11:29:22 2011 -0500
doc title changes
diff --git a/docs/main/GettingStarted.rst b/docs/main/GettingStarted.rst
index 6c08639..84cdf92 100644
--- a/docs/main/GettingStarted.rst
+++ b/docs/main/GettingStarted.rst
@@ -5,10 +5,10 @@ Getting Started with Moksha
There are currently two ways of installing and running Moksha.
.. toctree::
- :maxdepth: 1
+ :maxdepth: 0
- RPMInstallation
- VirtualenvInstallation
+ RPMInstallation (Fedora, RHEL, CentOS)
+ VirtualenvInstallation (Other linux distros, OSX, etc.)
Once you have Moksha installed, there are many ways to start using it.
commit 1aa7c69fb76d66e4be2db8b0c8218972ecff1548
Author: Luke Macken <lmacken(a)redhat.com>
Date: Sun Jan 16 22:07:29 2011 -0500
log.info when the hub starts
diff --git a/moksha/hub/hub.py b/moksha/hub/hub.py
index a0c6987..4fc155c 100644
--- a/moksha/hub/hub.py
+++ b/moksha/hub/hub.py
@@ -161,6 +161,7 @@ class CentralMokshaHub(MokshaHub):
producers = None # [<Producer>,]
def __init__(self):
+ log.info('Loading the Moksha Hub')
self.topics = defaultdict(list)
self.__init_consumers()
commit de6efd68aea3f98e0cb53fe382465636d49ae418
Author: Luke Macken <lmacken(a)redhat.com>
Date: Sun Jan 16 22:04:49 2011 -0500
Update our hub to use more up to date terminology with variable/method names
diff --git a/moksha/hub/hub.py b/moksha/hub/hub.py
index 5371474..a0c6987 100644
--- a/moksha/hub/hub.py
+++ b/moksha/hub/hub.py
@@ -158,7 +158,7 @@ class CentralMokshaHub(MokshaHub):
The Moksha Hub is responsible for initializing all of the Hooks,
AMQP queues, exchanges, etc.
"""
- data_streams = None # [<DataStream>,]
+ producers = None # [<Producer>,]
def __init__(self):
self.topics = defaultdict(list)
@@ -170,9 +170,11 @@ class CentralMokshaHub(MokshaHub):
self.__init_amqp()
self.__run_consumers()
- self.__init_data_streams()
+ self.__init_producers()
def __init_amqp(self):
+ # Ok this looks odd at first. I think this is only used when we are briding stomp/amqp,
+ # Since each producer and consumer opens up their own AMQP connections anyway
if self.stomp_broker:
log.debug("Initializing local AMQP queue...")
self.server_queue_name = 'moksha_hub_' + self.session.name
@@ -187,7 +189,7 @@ class CentralMokshaHub(MokshaHub):
def __init_consumers(self):
""" Initialize all Moksha Consumer objects """
- log.info('Loading Moksha Consumers')
+ log.info('Loading Consumers')
for consumer in pkg_resources.iter_entry_points('moksha.consumer'):
c_class = consumer.load()
log.info("%s consumer is watching the %r topic" % (
@@ -203,15 +205,16 @@ class CentralMokshaHub(MokshaHub):
self.consumers.append(c)
self.topics[topic][i] = c.consume
- def __init_data_streams(self):
- """ Initialize all data streams """
- self.data_streams = []
+ def __init_producers(self):
+ """ Initialize all producers (aka data streams) """
+ log.info('Loading Producers')
+ self.producers = []
for entry in ('moksha.producer', 'moksha.stream'):
- for stream in pkg_resources.iter_entry_points(entry):
- stream_class = stream.load()
- log.info('Loading %s producer' % stream_class.__name__)
- stream_obj = stream_class()
- self.data_streams.append(stream_obj)
+ for producer in pkg_resources.iter_entry_points(entry):
+ producer_class = producer.load()
+ log.info('Loading %s producer' % producer_class.__name__)
+ producer_obj = producer_class()
+ self.producers.append(producer_obj)
@trace
def create_topic(self, topic):
@@ -225,10 +228,10 @@ class CentralMokshaHub(MokshaHub):
def stop(self):
log.debug("Stopping the CentralMokshaHub")
MokshaHub.close(self)
- if self.data_streams:
- for stream in self.data_streams:
- log.debug("Stopping data stream %s" % stream)
- stream.stop()
+ if self.producers:
+ for producer in self.producers:
+ log.debug("Stopping producer %s" % producer)
+ producer.stop()
if self.consumers:
for consumer in self.consumers:
log.debug("Stopping consumer %s" % consumer)
commit d842655d335dd690e6ba954a8e17e65a9824ce99
Author: Luke Macken <lmacken(a)redhat.com>
Date: Sun Jan 16 21:56:06 2011 -0500
Get rid of moksha.streams
diff --git a/moksha/streams/__init__.py b/moksha/streams/__init__.py
deleted file mode 100644
index e69de29..0000000
commit 0ea2e2c3d207837cc894996fefdc7ba9cf6cdb2e
Author: Luke Macken <lmacken(a)redhat.com>
Date: Sat Jan 15 15:12:25 2011 -0500
Commit our db changes in our HelloWorld Consumer every 100 entries.
diff --git a/moksha/apps/helloworld/demo/consumer.py b/moksha/apps/helloworld/demo/consumer.py
index 10f4e3b..dec4cfd 100644
--- a/moksha/apps/helloworld/demo/consumer.py
+++ b/moksha/apps/helloworld/demo/consumer.py
@@ -4,6 +4,7 @@ from demo.model import HelloWorldModel
class HelloWorldConsumer(Consumer):
topic = 'helloworld'
app = 'helloworld'
+ i = 0
def consume(self, message):
self.log.info('Received message: ' + message['body']['msg'])
@@ -11,4 +12,8 @@ class HelloWorldConsumer(Consumer):
entry = HelloWorldModel()
entry.message = message['body']['msg']
self.DBSession.add(entry)
- self.DBSession.commit()
+
+ self.i += 1
+ if self.i % 100 == 0:
+ self.DBSession.commit()
+
13 years, 4 months
Branch 'dev' - moksha/api moksha/hub
by Luke Macken
moksha/api/hub/consumer.py | 4 ++--
moksha/hub/amqp/pyamqplib.py | 3 +--
2 files changed, 3 insertions(+), 4 deletions(-)
New commits:
commit 92145193e14be58e8d36b19a4cbacc065d0cd8c9
Author: Luke Macken <lmacken(a)redhat.com>
Date: Wed Jan 12 17:39:35 2011 -0500
Some method renaming in our AMQP stack to prevent conflicts with STOMP
diff --git a/moksha/api/hub/consumer.py b/moksha/api/hub/consumer.py
index 1c5712c..0d24094 100644
--- a/moksha/api/hub/consumer.py
+++ b/moksha/api/hub/consumer.py
@@ -54,9 +54,9 @@ class Consumer(object):
self.hub.queue_declare(queue=queue_name, exclusive=True)
self.hub.exchange_bind(queue_name, binding_key=topic)
if self.jsonify:
- self.hub.subscribe(queue_name, self._consume_json)
+ self.hub.queue_subscribe(queue_name, self._consume_json)
else:
- self.hub.subscribe(queue_name, self._consume)
+ self.hub.queue_subscribe(queue_name, self._consume)
else:
# Assume we're using Qpid then.
server_queue_name = 'moksha_consumer_' + self.hub.session.name
diff --git a/moksha/hub/amqp/pyamqplib.py b/moksha/hub/amqp/pyamqplib.py
index e6a031f..32c1f31 100644
--- a/moksha/hub/amqp/pyamqplib.py
+++ b/moksha/hub/amqp/pyamqplib.py
@@ -77,13 +77,12 @@ class AMQPLibHub(BaseAMQPHub):
msg = self.channel.basic_get(queue, no_ack=True)
return msg
- def subscribe(self, queue, callback, no_ack=True):
+ def queue_subscribe(self, queue, callback, no_ack=True):
"""
Consume messages from a given `queue`, passing each to `callback`
"""
self.channel.basic_consume(queue, callback=callback, no_ack=no_ack)
-
def wait(self):
self.channel.wait()
13 years, 4 months
Branch 'dev' - moksha/hub
by Luke Macken
moksha/hub/amqp/pyamqplib.py | 1 -
1 file changed, 1 deletion(-)
New commits:
commit e89f2a4aa5a70402e1887fcb3bf4fe6883434a47
Author: Luke Macken <lmacken(a)redhat.com>
Date: Wed Jan 12 17:06:09 2011 -0500
Remove a tracing decorator, which may be causing problems
diff --git a/moksha/hub/amqp/pyamqplib.py b/moksha/hub/amqp/pyamqplib.py
index b9ab46c..e6a031f 100644
--- a/moksha/hub/amqp/pyamqplib.py
+++ b/moksha/hub/amqp/pyamqplib.py
@@ -77,7 +77,6 @@ class AMQPLibHub(BaseAMQPHub):
msg = self.channel.basic_get(queue, no_ack=True)
return msg
- @trace
def subscribe(self, queue, callback, no_ack=True):
"""
Consume messages from a given `queue`, passing each to `callback`
13 years, 4 months